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/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" 20 #include <cstring> 21 #include <system_error> 22 23 using namespace llvm; 24 25 static bool parseAssemblyInto(MemoryBufferRef F, Module *M, 26 ModuleSummaryIndex *Index, SMDiagnostic &Err, 27 SlotMapping *Slots, bool UpgradeDebugInfo, 28 DataLayoutCallbackTy DataLayoutCallback) { 29 SourceMgr SM; 30 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F); 31 SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 32 33 LLVMContext Context; 34 return LLParser(F.getBuffer(), SM, Err, M, Index, 35 M ? M->getContext() : Context, Slots) 36 .Run(UpgradeDebugInfo, DataLayoutCallback); 37 } 38 39 bool llvm::parseAssemblyInto(MemoryBufferRef F, Module *M, 40 ModuleSummaryIndex *Index, SMDiagnostic &Err, 41 SlotMapping *Slots, 42 DataLayoutCallbackTy DataLayoutCallback) { 43 return ::parseAssemblyInto(F, M, Index, Err, Slots, 44 /*UpgradeDebugInfo*/ true, DataLayoutCallback); 45 } 46 47 std::unique_ptr<Module> 48 llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, 49 SlotMapping *Slots, 50 DataLayoutCallbackTy DataLayoutCallback) { 51 std::unique_ptr<Module> M = 52 std::make_unique<Module>(F.getBufferIdentifier(), Context); 53 54 if (parseAssemblyInto(F, M.get(), nullptr, Err, Slots, DataLayoutCallback)) 55 return nullptr; 56 57 return M; 58 } 59 60 std::unique_ptr<Module> llvm::parseAssemblyFile(StringRef Filename, 61 SMDiagnostic &Err, 62 LLVMContext &Context, 63 SlotMapping *Slots) { 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()); 69 return nullptr; 70 } 71 72 return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots); 73 } 74 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); 84 85 if (parseAssemblyInto(F, M.get(), Index.get(), Err, Slots, UpgradeDebugInfo, 86 DataLayoutCallback)) 87 return {nullptr, nullptr}; 88 89 return {std::move(M), std::move(Index)}; 90 } 91 92 ParsedModuleAndIndex llvm::parseAssemblyWithIndex(MemoryBufferRef F, 93 SMDiagnostic &Err, 94 LLVMContext &Context, 95 SlotMapping *Slots) { 96 return ::parseAssemblyWithIndex(F, Err, Context, Slots, 97 /*UpgradeDebugInfo*/ true, 98 [](StringRef) { return None; }); 99 } 100 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}; 112 } 113 114 return parseAssemblyWithIndex(FileOrErr.get()->getMemBufferRef(), Err, 115 Context, Slots, UpgradeDebugInfo, 116 DataLayoutCallback); 117 } 118 119 ParsedModuleAndIndex 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, 125 DataLayoutCallback); 126 } 127 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, 133 DataLayoutCallback); 134 } 135 136 std::unique_ptr<Module> llvm::parseAssemblyString(StringRef AsmString, 137 SMDiagnostic &Err, 138 LLVMContext &Context, 139 SlotMapping *Slots) { 140 MemoryBufferRef F(AsmString, "<string>"); 141 return parseAssembly(F, Err, Context, Slots); 142 } 143 144 static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F, 145 ModuleSummaryIndex &Index, 146 SMDiagnostic &Err) { 147 SourceMgr SM; 148 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F); 149 SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 150 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; }); 156 } 157 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); 162 163 if (parseSummaryIndexAssemblyInto(F, *Index, Err)) 164 return nullptr; 165 166 return Index; 167 } 168 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()); 176 return nullptr; 177 } 178 179 return parseSummaryIndexAssembly(FileOrErr.get()->getMemBufferRef(), Err); 180 } 181 182 Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err, 183 const Module &M, const SlotMapping *Slots) { 184 SourceMgr SM; 185 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); 186 SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 187 Constant *C; 188 if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext()) 189 .parseStandaloneConstantValue(C, Slots)) 190 return nullptr; 191 return C; 192 } 193 194 Type *llvm::parseType(StringRef Asm, SMDiagnostic &Err, const Module &M, 195 const SlotMapping *Slots) { 196 unsigned Read; 197 Type *Ty = parseTypeAtBeginning(Asm, Read, Err, M, Slots); 198 if (!Ty) 199 return nullptr; 200 if (Read != Asm.size()) { 201 SourceMgr SM; 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"); 206 return nullptr; 207 } 208 return Ty; 209 } 210 Type *llvm::parseTypeAtBeginning(StringRef Asm, unsigned &Read, 211 SMDiagnostic &Err, const Module &M, 212 const SlotMapping *Slots) { 213 SourceMgr SM; 214 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); 215 SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 216 Type *Ty; 217 if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext()) 218 .parseTypeAtBeginning(Ty, Read, Slots)) 219 return nullptr; 220 return Ty; 221 } 222