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/ADT/STLExtras.h"
15 #include "llvm/AsmParser/LLParser.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"
21 #include <system_error>
25 static bool parseAssemblyInto(MemoryBufferRef F
, Module
*M
,
26 ModuleSummaryIndex
*Index
, SMDiagnostic
&Err
,
27 SlotMapping
*Slots
, bool UpgradeDebugInfo
,
28 DataLayoutCallbackTy DataLayoutCallback
) {
30 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(F
);
31 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
34 return LLParser(F
.getBuffer(), SM
, Err
, M
, Index
,
35 M
? M
->getContext() : Context
, Slots
)
36 .Run(UpgradeDebugInfo
, DataLayoutCallback
);
39 bool llvm::parseAssemblyInto(MemoryBufferRef F
, Module
*M
,
40 ModuleSummaryIndex
*Index
, SMDiagnostic
&Err
,
42 DataLayoutCallbackTy DataLayoutCallback
) {
43 return ::parseAssemblyInto(F
, M
, Index
, Err
, Slots
,
44 /*UpgradeDebugInfo*/ true, DataLayoutCallback
);
47 std::unique_ptr
<Module
>
48 llvm::parseAssembly(MemoryBufferRef F
, SMDiagnostic
&Err
, LLVMContext
&Context
,
50 DataLayoutCallbackTy DataLayoutCallback
) {
51 std::unique_ptr
<Module
> M
=
52 std::make_unique
<Module
>(F
.getBufferIdentifier(), Context
);
54 if (parseAssemblyInto(F
, M
.get(), nullptr, Err
, Slots
, DataLayoutCallback
))
60 std::unique_ptr
<Module
> llvm::parseAssemblyFile(StringRef Filename
,
64 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> FileOrErr
=
65 MemoryBuffer::getFileOrSTDIN(Filename
);
66 if (std::error_code EC
= FileOrErr
.getError()) {
67 Err
= SMDiagnostic(Filename
, SourceMgr::DK_Error
,
68 "Could not open input file: " + EC
.message());
72 return parseAssembly(FileOrErr
.get()->getMemBufferRef(), Err
, Context
, Slots
);
75 static ParsedModuleAndIndex
76 parseAssemblyWithIndex(MemoryBufferRef F
, SMDiagnostic
&Err
,
77 LLVMContext
&Context
, SlotMapping
*Slots
,
78 bool UpgradeDebugInfo
,
79 DataLayoutCallbackTy DataLayoutCallback
) {
80 std::unique_ptr
<Module
> M
=
81 std::make_unique
<Module
>(F
.getBufferIdentifier(), Context
);
82 std::unique_ptr
<ModuleSummaryIndex
> Index
=
83 std::make_unique
<ModuleSummaryIndex
>(/*HaveGVs=*/true);
85 if (parseAssemblyInto(F
, M
.get(), Index
.get(), Err
, Slots
, UpgradeDebugInfo
,
87 return {nullptr, nullptr};
89 return {std::move(M
), std::move(Index
)};
92 ParsedModuleAndIndex
llvm::parseAssemblyWithIndex(MemoryBufferRef F
,
96 return ::parseAssemblyWithIndex(F
, Err
, Context
, Slots
,
97 /*UpgradeDebugInfo*/ true,
98 [](StringRef
) { return None
; });
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
) { return None
; });
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 Constant
*llvm::parseConstantValue(StringRef Asm
, SMDiagnostic
&Err
,
183 const Module
&M
, const SlotMapping
*Slots
) {
185 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
186 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
188 if (LLParser(Asm
, SM
, Err
, const_cast<Module
*>(&M
), nullptr, M
.getContext())
189 .parseStandaloneConstantValue(C
, Slots
))
194 Type
*llvm::parseType(StringRef Asm
, SMDiagnostic
&Err
, const Module
&M
,
195 const SlotMapping
*Slots
) {
197 Type
*Ty
= parseTypeAtBeginning(Asm
, Read
, Err
, M
, Slots
);
200 if (Read
!= Asm
.size()) {
202 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
203 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
204 Err
= SM
.GetMessage(SMLoc::getFromPointer(Asm
.begin() + Read
),
205 SourceMgr::DK_Error
, "expected end of string");
210 Type
*llvm::parseTypeAtBeginning(StringRef Asm
, unsigned &Read
,
211 SMDiagnostic
&Err
, const Module
&M
,
212 const SlotMapping
*Slots
) {
214 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
215 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
217 if (LLParser(Asm
, SM
, Err
, const_cast<Module
*>(&M
), nullptr, M
.getContext())
218 .parseTypeAtBeginning(Ty
, Read
, Slots
))