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