1 //===- Parser.cpp - Main dispatch module for the Parser library -----------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This library implements the functionality defined in llvm/AsmParser/Parser.h
11 //===----------------------------------------------------------------------===//
13 #include "llvm/AsmParser/Parser.h"
14 #include "llvm/AsmParser/LLParser.h"
15 #include "llvm/IR/DebugInfoMetadata.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/ModuleSummaryIndex.h"
18 #include "llvm/Support/MemoryBuffer.h"
19 #include "llvm/Support/SourceMgr.h"
20 #include <system_error>
24 static bool parseAssemblyInto(MemoryBufferRef F
, Module
*M
,
25 ModuleSummaryIndex
*Index
, SMDiagnostic
&Err
,
26 SlotMapping
*Slots
, bool UpgradeDebugInfo
,
27 DataLayoutCallbackTy DataLayoutCallback
) {
29 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(F
);
30 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
32 std::optional
<LLVMContext
> OptContext
;
33 return LLParser(F
.getBuffer(), SM
, Err
, M
, Index
,
34 M
? M
->getContext() : OptContext
.emplace(), Slots
)
35 .Run(UpgradeDebugInfo
, DataLayoutCallback
);
38 bool llvm::parseAssemblyInto(MemoryBufferRef F
, Module
*M
,
39 ModuleSummaryIndex
*Index
, SMDiagnostic
&Err
,
41 DataLayoutCallbackTy DataLayoutCallback
) {
42 return ::parseAssemblyInto(F
, M
, Index
, Err
, Slots
,
43 /*UpgradeDebugInfo*/ true, DataLayoutCallback
);
46 std::unique_ptr
<Module
>
47 llvm::parseAssembly(MemoryBufferRef F
, SMDiagnostic
&Err
, LLVMContext
&Context
,
49 DataLayoutCallbackTy DataLayoutCallback
) {
50 std::unique_ptr
<Module
> M
=
51 std::make_unique
<Module
>(F
.getBufferIdentifier(), Context
);
53 if (parseAssemblyInto(F
, M
.get(), nullptr, Err
, Slots
, DataLayoutCallback
))
59 std::unique_ptr
<Module
> llvm::parseAssemblyFile(StringRef Filename
,
63 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> FileOrErr
=
64 MemoryBuffer::getFileOrSTDIN(Filename
);
65 if (std::error_code EC
= FileOrErr
.getError()) {
66 Err
= SMDiagnostic(Filename
, SourceMgr::DK_Error
,
67 "Could not open input file: " + EC
.message());
71 return parseAssembly(FileOrErr
.get()->getMemBufferRef(), Err
, Context
, Slots
);
74 static ParsedModuleAndIndex
75 parseAssemblyWithIndex(MemoryBufferRef F
, SMDiagnostic
&Err
,
76 LLVMContext
&Context
, SlotMapping
*Slots
,
77 bool UpgradeDebugInfo
,
78 DataLayoutCallbackTy DataLayoutCallback
) {
79 std::unique_ptr
<Module
> M
=
80 std::make_unique
<Module
>(F
.getBufferIdentifier(), Context
);
81 std::unique_ptr
<ModuleSummaryIndex
> Index
=
82 std::make_unique
<ModuleSummaryIndex
>(/*HaveGVs=*/true);
84 if (parseAssemblyInto(F
, M
.get(), Index
.get(), Err
, Slots
, UpgradeDebugInfo
,
86 return {nullptr, nullptr};
88 return {std::move(M
), std::move(Index
)};
91 ParsedModuleAndIndex
llvm::parseAssemblyWithIndex(MemoryBufferRef F
,
95 return ::parseAssemblyWithIndex(
96 F
, Err
, Context
, Slots
,
97 /*UpgradeDebugInfo*/ true,
98 [](StringRef
, StringRef
) { return std::nullopt
; });
101 static ParsedModuleAndIndex
102 parseAssemblyFileWithIndex(StringRef Filename
, SMDiagnostic
&Err
,
103 LLVMContext
&Context
, SlotMapping
*Slots
,
104 bool UpgradeDebugInfo
,
105 DataLayoutCallbackTy DataLayoutCallback
) {
106 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> FileOrErr
=
107 MemoryBuffer::getFileOrSTDIN(Filename
, /*IsText=*/true);
108 if (std::error_code EC
= FileOrErr
.getError()) {
109 Err
= SMDiagnostic(Filename
, SourceMgr::DK_Error
,
110 "Could not open input file: " + EC
.message());
111 return {nullptr, nullptr};
114 return parseAssemblyWithIndex(FileOrErr
.get()->getMemBufferRef(), Err
,
115 Context
, Slots
, UpgradeDebugInfo
,
120 llvm::parseAssemblyFileWithIndex(StringRef Filename
, SMDiagnostic
&Err
,
121 LLVMContext
&Context
, SlotMapping
*Slots
,
122 DataLayoutCallbackTy DataLayoutCallback
) {
123 return ::parseAssemblyFileWithIndex(Filename
, Err
, Context
, Slots
,
124 /*UpgradeDebugInfo*/ true,
128 ParsedModuleAndIndex
llvm::parseAssemblyFileWithIndexNoUpgradeDebugInfo(
129 StringRef Filename
, SMDiagnostic
&Err
, LLVMContext
&Context
,
130 SlotMapping
*Slots
, DataLayoutCallbackTy DataLayoutCallback
) {
131 return ::parseAssemblyFileWithIndex(Filename
, Err
, Context
, Slots
,
132 /*UpgradeDebugInfo*/ false,
136 std::unique_ptr
<Module
> llvm::parseAssemblyString(StringRef AsmString
,
138 LLVMContext
&Context
,
139 SlotMapping
*Slots
) {
140 MemoryBufferRef
F(AsmString
, "<string>");
141 return parseAssembly(F
, Err
, Context
, Slots
);
144 static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F
,
145 ModuleSummaryIndex
&Index
,
148 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(F
);
149 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
151 // The parser holds a reference to a context that is unused when parsing the
152 // index, but we need to initialize it.
153 LLVMContext unusedContext
;
154 return LLParser(F
.getBuffer(), SM
, Err
, nullptr, &Index
, unusedContext
)
155 .Run(true, [](StringRef
, StringRef
) { return std::nullopt
; });
158 std::unique_ptr
<ModuleSummaryIndex
>
159 llvm::parseSummaryIndexAssembly(MemoryBufferRef F
, SMDiagnostic
&Err
) {
160 std::unique_ptr
<ModuleSummaryIndex
> Index
=
161 std::make_unique
<ModuleSummaryIndex
>(/*HaveGVs=*/false);
163 if (parseSummaryIndexAssemblyInto(F
, *Index
, Err
))
169 std::unique_ptr
<ModuleSummaryIndex
>
170 llvm::parseSummaryIndexAssemblyFile(StringRef Filename
, SMDiagnostic
&Err
) {
171 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> FileOrErr
=
172 MemoryBuffer::getFileOrSTDIN(Filename
);
173 if (std::error_code EC
= FileOrErr
.getError()) {
174 Err
= SMDiagnostic(Filename
, SourceMgr::DK_Error
,
175 "Could not open input file: " + EC
.message());
179 return parseSummaryIndexAssembly(FileOrErr
.get()->getMemBufferRef(), Err
);
182 std::unique_ptr
<ModuleSummaryIndex
>
183 llvm::parseSummaryIndexAssemblyString(StringRef AsmString
, SMDiagnostic
&Err
) {
184 MemoryBufferRef
F(AsmString
, "<string>");
185 return parseSummaryIndexAssembly(F
, Err
);
188 Constant
*llvm::parseConstantValue(StringRef Asm
, SMDiagnostic
&Err
,
189 const Module
&M
, const SlotMapping
*Slots
) {
191 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
192 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
194 if (LLParser(Asm
, SM
, Err
, const_cast<Module
*>(&M
), nullptr, M
.getContext())
195 .parseStandaloneConstantValue(C
, Slots
))
200 Type
*llvm::parseType(StringRef Asm
, SMDiagnostic
&Err
, const Module
&M
,
201 const SlotMapping
*Slots
) {
203 Type
*Ty
= parseTypeAtBeginning(Asm
, Read
, Err
, M
, Slots
);
206 if (Read
!= Asm
.size()) {
208 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
209 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
210 Err
= SM
.GetMessage(SMLoc::getFromPointer(Asm
.begin() + Read
),
211 SourceMgr::DK_Error
, "expected end of string");
216 Type
*llvm::parseTypeAtBeginning(StringRef Asm
, unsigned &Read
,
217 SMDiagnostic
&Err
, const Module
&M
,
218 const SlotMapping
*Slots
) {
220 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
221 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
223 if (LLParser(Asm
, SM
, Err
, const_cast<Module
*>(&M
), nullptr, M
.getContext())
224 .parseTypeAtBeginning(Ty
, Read
, Slots
))
229 DIExpression
*llvm::parseDIExpressionBodyAtBeginning(StringRef Asm
,
233 const SlotMapping
*Slots
) {
235 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
236 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
238 if (LLParser(Asm
, SM
, Err
, const_cast<Module
*>(&M
), nullptr, M
.getContext())
239 .parseDIExpressionBodyAtBeginning(MD
, Read
, Slots
))
241 return dyn_cast
<DIExpression
>(MD
);