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 "LLParser.h" 15 #include "llvm/ADT/STLExtras.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 "llvm/Support/raw_ostream.h" 21 #include <cstring> 22 #include <system_error> 23 using namespace llvm; 24 25 bool llvm::parseAssemblyInto(MemoryBufferRef F, Module *M, 26 ModuleSummaryIndex *Index, SMDiagnostic &Err, 27 SlotMapping *Slots, bool UpgradeDebugInfo, 28 StringRef DataLayoutString) { 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, UpgradeDebugInfo, 36 DataLayoutString) 37 .Run(); 38 } 39 40 std::unique_ptr<Module> 41 llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, 42 SlotMapping *Slots, bool UpgradeDebugInfo, 43 StringRef DataLayoutString) { 44 std::unique_ptr<Module> M = 45 std::make_unique<Module>(F.getBufferIdentifier(), Context); 46 47 if (parseAssemblyInto(F, M.get(), nullptr, Err, Slots, UpgradeDebugInfo, 48 DataLayoutString)) 49 return nullptr; 50 51 return M; 52 } 53 54 std::unique_ptr<Module> 55 llvm::parseAssemblyFile(StringRef Filename, SMDiagnostic &Err, 56 LLVMContext &Context, SlotMapping *Slots, 57 bool UpgradeDebugInfo, StringRef DataLayoutString) { 58 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 59 MemoryBuffer::getFileOrSTDIN(Filename); 60 if (std::error_code EC = FileOrErr.getError()) { 61 Err = SMDiagnostic(Filename, SourceMgr::DK_Error, 62 "Could not open input file: " + EC.message()); 63 return nullptr; 64 } 65 66 return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots, 67 UpgradeDebugInfo, DataLayoutString); 68 } 69 70 ParsedModuleAndIndex llvm::parseAssemblyWithIndex( 71 MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, 72 SlotMapping *Slots, bool UpgradeDebugInfo, StringRef DataLayoutString) { 73 std::unique_ptr<Module> M = 74 std::make_unique<Module>(F.getBufferIdentifier(), Context); 75 std::unique_ptr<ModuleSummaryIndex> Index = 76 std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/true); 77 78 if (parseAssemblyInto(F, M.get(), Index.get(), Err, Slots, UpgradeDebugInfo, 79 DataLayoutString)) 80 return {nullptr, nullptr}; 81 82 return {std::move(M), std::move(Index)}; 83 } 84 85 ParsedModuleAndIndex llvm::parseAssemblyFileWithIndex( 86 StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, 87 SlotMapping *Slots, bool UpgradeDebugInfo, StringRef DataLayoutString) { 88 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 89 MemoryBuffer::getFileOrSTDIN(Filename); 90 if (std::error_code EC = FileOrErr.getError()) { 91 Err = SMDiagnostic(Filename, SourceMgr::DK_Error, 92 "Could not open input file: " + EC.message()); 93 return {nullptr, nullptr}; 94 } 95 96 return parseAssemblyWithIndex(FileOrErr.get()->getMemBufferRef(), Err, 97 Context, Slots, UpgradeDebugInfo, 98 DataLayoutString); 99 } 100 101 std::unique_ptr<Module> 102 llvm::parseAssemblyString(StringRef AsmString, SMDiagnostic &Err, 103 LLVMContext &Context, SlotMapping *Slots, 104 bool UpgradeDebugInfo, StringRef DataLayoutString) { 105 MemoryBufferRef F(AsmString, "<string>"); 106 return parseAssembly(F, Err, Context, Slots, UpgradeDebugInfo, 107 DataLayoutString); 108 } 109 110 static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F, 111 ModuleSummaryIndex &Index, 112 SMDiagnostic &Err) { 113 SourceMgr SM; 114 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F); 115 SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 116 117 // The parser holds a reference to a context that is unused when parsing the 118 // index, but we need to initialize it. 119 LLVMContext unusedContext; 120 return LLParser(F.getBuffer(), SM, Err, nullptr, &Index, unusedContext).Run(); 121 } 122 123 std::unique_ptr<ModuleSummaryIndex> 124 llvm::parseSummaryIndexAssembly(MemoryBufferRef F, SMDiagnostic &Err) { 125 std::unique_ptr<ModuleSummaryIndex> Index = 126 std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false); 127 128 if (parseSummaryIndexAssemblyInto(F, *Index, Err)) 129 return nullptr; 130 131 return Index; 132 } 133 134 std::unique_ptr<ModuleSummaryIndex> 135 llvm::parseSummaryIndexAssemblyFile(StringRef Filename, SMDiagnostic &Err) { 136 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 137 MemoryBuffer::getFileOrSTDIN(Filename); 138 if (std::error_code EC = FileOrErr.getError()) { 139 Err = SMDiagnostic(Filename, SourceMgr::DK_Error, 140 "Could not open input file: " + EC.message()); 141 return nullptr; 142 } 143 144 return parseSummaryIndexAssembly(FileOrErr.get()->getMemBufferRef(), Err); 145 } 146 147 Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err, 148 const Module &M, const SlotMapping *Slots) { 149 SourceMgr SM; 150 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); 151 SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 152 Constant *C; 153 if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext()) 154 .parseStandaloneConstantValue(C, Slots)) 155 return nullptr; 156 return C; 157 } 158 159 Type *llvm::parseType(StringRef Asm, SMDiagnostic &Err, const Module &M, 160 const SlotMapping *Slots) { 161 unsigned Read; 162 Type *Ty = parseTypeAtBeginning(Asm, Read, Err, M, Slots); 163 if (!Ty) 164 return nullptr; 165 if (Read != Asm.size()) { 166 SourceMgr SM; 167 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); 168 SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 169 Err = SM.GetMessage(SMLoc::getFromPointer(Asm.begin() + Read), 170 SourceMgr::DK_Error, "expected end of string"); 171 return nullptr; 172 } 173 return Ty; 174 } 175 Type *llvm::parseTypeAtBeginning(StringRef Asm, unsigned &Read, 176 SMDiagnostic &Err, const Module &M, 177 const SlotMapping *Slots) { 178 SourceMgr SM; 179 std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); 180 SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 181 Type *Ty; 182 if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext()) 183 .parseTypeAtBeginning(Ty, Read, Slots)) 184 return nullptr; 185 return Ty; 186 } 187