1 //===- Parser.cpp - Main dispatch module for the Parser library -----------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This library implements the functionality defined in llvm/AsmParser/Parser.h
10 //
11 //===----------------------------------------------------------------------===//
12
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>
20
21 using namespace llvm;
22
parseAssemblyInto(MemoryBufferRef F,Module * M,ModuleSummaryIndex * Index,SMDiagnostic & Err,SlotMapping * Slots,bool UpgradeDebugInfo,DataLayoutCallbackTy DataLayoutCallback)23 static bool parseAssemblyInto(MemoryBufferRef F, Module *M,
24 ModuleSummaryIndex *Index, SMDiagnostic &Err,
25 SlotMapping *Slots, bool UpgradeDebugInfo,
26 DataLayoutCallbackTy DataLayoutCallback) {
27 SourceMgr SM;
28 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F);
29 SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
30
31 LLVMContext Context;
32 return LLParser(F.getBuffer(), SM, Err, M, Index,
33 M ? M->getContext() : Context, Slots)
34 .Run(UpgradeDebugInfo, DataLayoutCallback);
35 }
36
parseAssemblyInto(MemoryBufferRef F,Module * M,ModuleSummaryIndex * Index,SMDiagnostic & Err,SlotMapping * Slots,DataLayoutCallbackTy DataLayoutCallback)37 bool llvm::parseAssemblyInto(MemoryBufferRef F, Module *M,
38 ModuleSummaryIndex *Index, SMDiagnostic &Err,
39 SlotMapping *Slots,
40 DataLayoutCallbackTy DataLayoutCallback) {
41 return ::parseAssemblyInto(F, M, Index, Err, Slots,
42 /*UpgradeDebugInfo*/ true, DataLayoutCallback);
43 }
44
45 std::unique_ptr<Module>
parseAssembly(MemoryBufferRef F,SMDiagnostic & Err,LLVMContext & Context,SlotMapping * Slots,DataLayoutCallbackTy DataLayoutCallback)46 llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context,
47 SlotMapping *Slots,
48 DataLayoutCallbackTy DataLayoutCallback) {
49 std::unique_ptr<Module> M =
50 std::make_unique<Module>(F.getBufferIdentifier(), Context);
51
52 if (parseAssemblyInto(F, M.get(), nullptr, Err, Slots, DataLayoutCallback))
53 return nullptr;
54
55 return M;
56 }
57
parseAssemblyFile(StringRef Filename,SMDiagnostic & Err,LLVMContext & Context,SlotMapping * Slots)58 std::unique_ptr<Module> llvm::parseAssemblyFile(StringRef Filename,
59 SMDiagnostic &Err,
60 LLVMContext &Context,
61 SlotMapping *Slots) {
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());
67 return nullptr;
68 }
69
70 return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots);
71 }
72
73 static ParsedModuleAndIndex
parseAssemblyWithIndex(MemoryBufferRef F,SMDiagnostic & Err,LLVMContext & Context,SlotMapping * Slots,bool UpgradeDebugInfo,DataLayoutCallbackTy DataLayoutCallback)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);
82
83 if (parseAssemblyInto(F, M.get(), Index.get(), Err, Slots, UpgradeDebugInfo,
84 DataLayoutCallback))
85 return {nullptr, nullptr};
86
87 return {std::move(M), std::move(Index)};
88 }
89
parseAssemblyWithIndex(MemoryBufferRef F,SMDiagnostic & Err,LLVMContext & Context,SlotMapping * Slots)90 ParsedModuleAndIndex llvm::parseAssemblyWithIndex(MemoryBufferRef F,
91 SMDiagnostic &Err,
92 LLVMContext &Context,
93 SlotMapping *Slots) {
94 return ::parseAssemblyWithIndex(F, Err, Context, Slots,
95 /*UpgradeDebugInfo*/ true,
96 [](StringRef) { return None; });
97 }
98
99 static ParsedModuleAndIndex
parseAssemblyFileWithIndex(StringRef Filename,SMDiagnostic & Err,LLVMContext & Context,SlotMapping * Slots,bool UpgradeDebugInfo,DataLayoutCallbackTy DataLayoutCallback)100 parseAssemblyFileWithIndex(StringRef Filename, SMDiagnostic &Err,
101 LLVMContext &Context, SlotMapping *Slots,
102 bool UpgradeDebugInfo,
103 DataLayoutCallbackTy DataLayoutCallback) {
104 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
105 MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
106 if (std::error_code EC = FileOrErr.getError()) {
107 Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
108 "Could not open input file: " + EC.message());
109 return {nullptr, nullptr};
110 }
111
112 return parseAssemblyWithIndex(FileOrErr.get()->getMemBufferRef(), Err,
113 Context, Slots, UpgradeDebugInfo,
114 DataLayoutCallback);
115 }
116
117 ParsedModuleAndIndex
parseAssemblyFileWithIndex(StringRef Filename,SMDiagnostic & Err,LLVMContext & Context,SlotMapping * Slots,DataLayoutCallbackTy DataLayoutCallback)118 llvm::parseAssemblyFileWithIndex(StringRef Filename, SMDiagnostic &Err,
119 LLVMContext &Context, SlotMapping *Slots,
120 DataLayoutCallbackTy DataLayoutCallback) {
121 return ::parseAssemblyFileWithIndex(Filename, Err, Context, Slots,
122 /*UpgradeDebugInfo*/ true,
123 DataLayoutCallback);
124 }
125
parseAssemblyFileWithIndexNoUpgradeDebugInfo(StringRef Filename,SMDiagnostic & Err,LLVMContext & Context,SlotMapping * Slots,DataLayoutCallbackTy DataLayoutCallback)126 ParsedModuleAndIndex llvm::parseAssemblyFileWithIndexNoUpgradeDebugInfo(
127 StringRef Filename, SMDiagnostic &Err, LLVMContext &Context,
128 SlotMapping *Slots, DataLayoutCallbackTy DataLayoutCallback) {
129 return ::parseAssemblyFileWithIndex(Filename, Err, Context, Slots,
130 /*UpgradeDebugInfo*/ false,
131 DataLayoutCallback);
132 }
133
parseAssemblyString(StringRef AsmString,SMDiagnostic & Err,LLVMContext & Context,SlotMapping * Slots)134 std::unique_ptr<Module> llvm::parseAssemblyString(StringRef AsmString,
135 SMDiagnostic &Err,
136 LLVMContext &Context,
137 SlotMapping *Slots) {
138 MemoryBufferRef F(AsmString, "<string>");
139 return parseAssembly(F, Err, Context, Slots);
140 }
141
parseSummaryIndexAssemblyInto(MemoryBufferRef F,ModuleSummaryIndex & Index,SMDiagnostic & Err)142 static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F,
143 ModuleSummaryIndex &Index,
144 SMDiagnostic &Err) {
145 SourceMgr SM;
146 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F);
147 SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
148
149 // The parser holds a reference to a context that is unused when parsing the
150 // index, but we need to initialize it.
151 LLVMContext unusedContext;
152 return LLParser(F.getBuffer(), SM, Err, nullptr, &Index, unusedContext)
153 .Run(true, [](StringRef) { return None; });
154 }
155
156 std::unique_ptr<ModuleSummaryIndex>
parseSummaryIndexAssembly(MemoryBufferRef F,SMDiagnostic & Err)157 llvm::parseSummaryIndexAssembly(MemoryBufferRef F, SMDiagnostic &Err) {
158 std::unique_ptr<ModuleSummaryIndex> Index =
159 std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
160
161 if (parseSummaryIndexAssemblyInto(F, *Index, Err))
162 return nullptr;
163
164 return Index;
165 }
166
167 std::unique_ptr<ModuleSummaryIndex>
parseSummaryIndexAssemblyFile(StringRef Filename,SMDiagnostic & Err)168 llvm::parseSummaryIndexAssemblyFile(StringRef Filename, SMDiagnostic &Err) {
169 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
170 MemoryBuffer::getFileOrSTDIN(Filename);
171 if (std::error_code EC = FileOrErr.getError()) {
172 Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
173 "Could not open input file: " + EC.message());
174 return nullptr;
175 }
176
177 return parseSummaryIndexAssembly(FileOrErr.get()->getMemBufferRef(), Err);
178 }
179
parseConstantValue(StringRef Asm,SMDiagnostic & Err,const Module & M,const SlotMapping * Slots)180 Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err,
181 const Module &M, const SlotMapping *Slots) {
182 SourceMgr SM;
183 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
184 SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
185 Constant *C;
186 if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext())
187 .parseStandaloneConstantValue(C, Slots))
188 return nullptr;
189 return C;
190 }
191
parseType(StringRef Asm,SMDiagnostic & Err,const Module & M,const SlotMapping * Slots)192 Type *llvm::parseType(StringRef Asm, SMDiagnostic &Err, const Module &M,
193 const SlotMapping *Slots) {
194 unsigned Read;
195 Type *Ty = parseTypeAtBeginning(Asm, Read, Err, M, Slots);
196 if (!Ty)
197 return nullptr;
198 if (Read != Asm.size()) {
199 SourceMgr SM;
200 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
201 SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
202 Err = SM.GetMessage(SMLoc::getFromPointer(Asm.begin() + Read),
203 SourceMgr::DK_Error, "expected end of string");
204 return nullptr;
205 }
206 return Ty;
207 }
parseTypeAtBeginning(StringRef Asm,unsigned & Read,SMDiagnostic & Err,const Module & M,const SlotMapping * Slots)208 Type *llvm::parseTypeAtBeginning(StringRef Asm, unsigned &Read,
209 SMDiagnostic &Err, const Module &M,
210 const SlotMapping *Slots) {
211 SourceMgr SM;
212 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
213 SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
214 Type *Ty;
215 if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext())
216 .parseTypeAtBeginning(Ty, Read, Slots))
217 return nullptr;
218 return Ty;
219 }
220