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/Module.h"
16 #include "llvm/IR/ModuleSummaryIndex.h"
17 #include "llvm/Support/MemoryBuffer.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include <system_error>
23 static bool parseAssemblyInto(MemoryBufferRef F
, Module
*M
,
24 ModuleSummaryIndex
*Index
, SMDiagnostic
&Err
,
25 SlotMapping
*Slots
, bool UpgradeDebugInfo
,
26 DataLayoutCallbackTy DataLayoutCallback
) {
28 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(F
);
29 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
31 std::optional
<LLVMContext
> OptContext
;
32 return LLParser(F
.getBuffer(), SM
, Err
, M
, Index
,
33 M
? M
->getContext() : OptContext
.emplace(), Slots
)
34 .Run(UpgradeDebugInfo
, DataLayoutCallback
);
37 bool llvm::parseAssemblyInto(MemoryBufferRef F
, Module
*M
,
38 ModuleSummaryIndex
*Index
, SMDiagnostic
&Err
,
40 DataLayoutCallbackTy DataLayoutCallback
) {
41 return ::parseAssemblyInto(F
, M
, Index
, Err
, Slots
,
42 /*UpgradeDebugInfo*/ true, DataLayoutCallback
);
45 std::unique_ptr
<Module
>
46 llvm::parseAssembly(MemoryBufferRef F
, SMDiagnostic
&Err
, LLVMContext
&Context
,
48 DataLayoutCallbackTy DataLayoutCallback
) {
49 std::unique_ptr
<Module
> M
=
50 std::make_unique
<Module
>(F
.getBufferIdentifier(), Context
);
52 if (parseAssemblyInto(F
, M
.get(), nullptr, Err
, Slots
, DataLayoutCallback
))
58 std::unique_ptr
<Module
> llvm::parseAssemblyFile(StringRef Filename
,
62 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> FileOrErr
=
63 MemoryBuffer::getFileOrSTDIN(Filename
);
64 if (std::error_code EC
= FileOrErr
.getError()) {
65 Err
= SMDiagnostic(Filename
, SourceMgr::DK_Error
,
66 "Could not open input file: " + EC
.message());
70 return parseAssembly(FileOrErr
.get()->getMemBufferRef(), Err
, Context
, Slots
);
73 static ParsedModuleAndIndex
74 parseAssemblyWithIndex(MemoryBufferRef F
, SMDiagnostic
&Err
,
75 LLVMContext
&Context
, SlotMapping
*Slots
,
76 bool UpgradeDebugInfo
,
77 DataLayoutCallbackTy DataLayoutCallback
) {
78 std::unique_ptr
<Module
> M
=
79 std::make_unique
<Module
>(F
.getBufferIdentifier(), Context
);
80 std::unique_ptr
<ModuleSummaryIndex
> Index
=
81 std::make_unique
<ModuleSummaryIndex
>(/*HaveGVs=*/true);
83 if (parseAssemblyInto(F
, M
.get(), Index
.get(), Err
, Slots
, UpgradeDebugInfo
,
85 return {nullptr, nullptr};
87 return {std::move(M
), std::move(Index
)};
90 ParsedModuleAndIndex
llvm::parseAssemblyWithIndex(MemoryBufferRef F
,
94 return ::parseAssemblyWithIndex(
95 F
, Err
, Context
, Slots
,
96 /*UpgradeDebugInfo*/ true,
97 [](StringRef
, StringRef
) { return std::nullopt
; });
100 static ParsedModuleAndIndex
101 parseAssemblyFileWithIndex(StringRef Filename
, SMDiagnostic
&Err
,
102 LLVMContext
&Context
, SlotMapping
*Slots
,
103 bool UpgradeDebugInfo
,
104 DataLayoutCallbackTy DataLayoutCallback
) {
105 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> FileOrErr
=
106 MemoryBuffer::getFileOrSTDIN(Filename
, /*IsText=*/true);
107 if (std::error_code EC
= FileOrErr
.getError()) {
108 Err
= SMDiagnostic(Filename
, SourceMgr::DK_Error
,
109 "Could not open input file: " + EC
.message());
110 return {nullptr, nullptr};
113 return parseAssemblyWithIndex(FileOrErr
.get()->getMemBufferRef(), Err
,
114 Context
, Slots
, UpgradeDebugInfo
,
119 llvm::parseAssemblyFileWithIndex(StringRef Filename
, SMDiagnostic
&Err
,
120 LLVMContext
&Context
, SlotMapping
*Slots
,
121 DataLayoutCallbackTy DataLayoutCallback
) {
122 return ::parseAssemblyFileWithIndex(Filename
, Err
, Context
, Slots
,
123 /*UpgradeDebugInfo*/ true,
127 ParsedModuleAndIndex
llvm::parseAssemblyFileWithIndexNoUpgradeDebugInfo(
128 StringRef Filename
, SMDiagnostic
&Err
, LLVMContext
&Context
,
129 SlotMapping
*Slots
, DataLayoutCallbackTy DataLayoutCallback
) {
130 return ::parseAssemblyFileWithIndex(Filename
, Err
, Context
, Slots
,
131 /*UpgradeDebugInfo*/ false,
135 std::unique_ptr
<Module
> llvm::parseAssemblyString(StringRef AsmString
,
137 LLVMContext
&Context
,
138 SlotMapping
*Slots
) {
139 MemoryBufferRef
F(AsmString
, "<string>");
140 return parseAssembly(F
, Err
, Context
, Slots
);
143 static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F
,
144 ModuleSummaryIndex
&Index
,
147 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(F
);
148 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
150 // The parser holds a reference to a context that is unused when parsing the
151 // index, but we need to initialize it.
152 LLVMContext unusedContext
;
153 return LLParser(F
.getBuffer(), SM
, Err
, nullptr, &Index
, unusedContext
)
154 .Run(true, [](StringRef
, StringRef
) { return std::nullopt
; });
157 std::unique_ptr
<ModuleSummaryIndex
>
158 llvm::parseSummaryIndexAssembly(MemoryBufferRef F
, SMDiagnostic
&Err
) {
159 std::unique_ptr
<ModuleSummaryIndex
> Index
=
160 std::make_unique
<ModuleSummaryIndex
>(/*HaveGVs=*/false);
162 if (parseSummaryIndexAssemblyInto(F
, *Index
, Err
))
168 std::unique_ptr
<ModuleSummaryIndex
>
169 llvm::parseSummaryIndexAssemblyFile(StringRef Filename
, SMDiagnostic
&Err
) {
170 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> FileOrErr
=
171 MemoryBuffer::getFileOrSTDIN(Filename
);
172 if (std::error_code EC
= FileOrErr
.getError()) {
173 Err
= SMDiagnostic(Filename
, SourceMgr::DK_Error
,
174 "Could not open input file: " + EC
.message());
178 return parseSummaryIndexAssembly(FileOrErr
.get()->getMemBufferRef(), Err
);
181 std::unique_ptr
<ModuleSummaryIndex
>
182 llvm::parseSummaryIndexAssemblyString(StringRef AsmString
, SMDiagnostic
&Err
) {
183 MemoryBufferRef
F(AsmString
, "<string>");
184 return parseSummaryIndexAssembly(F
, Err
);
187 Constant
*llvm::parseConstantValue(StringRef Asm
, SMDiagnostic
&Err
,
188 const Module
&M
, const SlotMapping
*Slots
) {
190 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
191 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
193 if (LLParser(Asm
, SM
, Err
, const_cast<Module
*>(&M
), nullptr, M
.getContext())
194 .parseStandaloneConstantValue(C
, Slots
))
199 Type
*llvm::parseType(StringRef Asm
, SMDiagnostic
&Err
, const Module
&M
,
200 const SlotMapping
*Slots
) {
202 Type
*Ty
= parseTypeAtBeginning(Asm
, Read
, Err
, M
, Slots
);
205 if (Read
!= Asm
.size()) {
207 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
208 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
209 Err
= SM
.GetMessage(SMLoc::getFromPointer(Asm
.begin() + Read
),
210 SourceMgr::DK_Error
, "expected end of string");
215 Type
*llvm::parseTypeAtBeginning(StringRef Asm
, unsigned &Read
,
216 SMDiagnostic
&Err
, const Module
&M
,
217 const SlotMapping
*Slots
) {
219 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
220 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
222 if (LLParser(Asm
, SM
, Err
, const_cast<Module
*>(&M
), nullptr, M
.getContext())
223 .parseTypeAtBeginning(Ty
, Read
, Slots
))