| //===- Parser.cpp - Main dispatch module for the Parser library -----------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This library implements the functionality defined in llvm/AsmParser/Parser.h | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/AsmParser/Parser.h" | |
| #include "LLParser.h" | |
| #include "llvm/ADT/STLExtras.h" | |
| #include "llvm/IR/Module.h" | |
| #include "llvm/IR/ModuleSummaryIndex.h" | |
| #include "llvm/Support/MemoryBuffer.h" | |
| #include "llvm/Support/SourceMgr.h" | |
| #include "llvm/Support/raw_ostream.h" | |
| #include <cstring> | |
| #include <system_error> | |
| using namespace llvm; | |
| bool llvm::parseAssemblyInto(MemoryBufferRef F, Module *M, | |
| ModuleSummaryIndex *Index, SMDiagnostic &Err, | |
| SlotMapping *Slots, bool UpgradeDebugInfo, | |
| StringRef DataLayoutString) { | |
| SourceMgr SM; | |
| std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F); | |
| SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); | |
| LLVMContext Context; | |
| return LLParser(F.getBuffer(), SM, Err, M, Index, | |
| M ? M->getContext() : Context, Slots, UpgradeDebugInfo, | |
| DataLayoutString) | |
| .Run(); | |
| } | |
| std::unique_ptr<Module> | |
| llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, | |
| SlotMapping *Slots, bool UpgradeDebugInfo, | |
| StringRef DataLayoutString) { | |
| std::unique_ptr<Module> M = | |
| make_unique<Module>(F.getBufferIdentifier(), Context); | |
| if (parseAssemblyInto(F, M.get(), nullptr, Err, Slots, UpgradeDebugInfo, | |
| DataLayoutString)) | |
| return nullptr; | |
| return M; | |
| } | |
| std::unique_ptr<Module> | |
| llvm::parseAssemblyFile(StringRef Filename, SMDiagnostic &Err, | |
| LLVMContext &Context, SlotMapping *Slots, | |
| bool UpgradeDebugInfo, StringRef DataLayoutString) { | |
| ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = | |
| MemoryBuffer::getFileOrSTDIN(Filename); | |
| if (std::error_code EC = FileOrErr.getError()) { | |
| Err = SMDiagnostic(Filename, SourceMgr::DK_Error, | |
| "Could not open input file: " + EC.message()); | |
| return nullptr; | |
| } | |
| return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots, | |
| UpgradeDebugInfo, DataLayoutString); | |
| } | |
| ParsedModuleAndIndex llvm::parseAssemblyWithIndex( | |
| MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, | |
| SlotMapping *Slots, bool UpgradeDebugInfo, StringRef DataLayoutString) { | |
| std::unique_ptr<Module> M = | |
| make_unique<Module>(F.getBufferIdentifier(), Context); | |
| std::unique_ptr<ModuleSummaryIndex> Index = | |
| make_unique<ModuleSummaryIndex>(/*HaveGVs=*/true); | |
| if (parseAssemblyInto(F, M.get(), Index.get(), Err, Slots, UpgradeDebugInfo, | |
| DataLayoutString)) | |
| return {nullptr, nullptr}; | |
| return {std::move(M), std::move(Index)}; | |
| } | |
| ParsedModuleAndIndex llvm::parseAssemblyFileWithIndex( | |
| StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, | |
| SlotMapping *Slots, bool UpgradeDebugInfo, StringRef DataLayoutString) { | |
| ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = | |
| MemoryBuffer::getFileOrSTDIN(Filename); | |
| if (std::error_code EC = FileOrErr.getError()) { | |
| Err = SMDiagnostic(Filename, SourceMgr::DK_Error, | |
| "Could not open input file: " + EC.message()); | |
| return {nullptr, nullptr}; | |
| } | |
| return parseAssemblyWithIndex(FileOrErr.get()->getMemBufferRef(), Err, | |
| Context, Slots, UpgradeDebugInfo, | |
| DataLayoutString); | |
| } | |
| std::unique_ptr<Module> | |
| llvm::parseAssemblyString(StringRef AsmString, SMDiagnostic &Err, | |
| LLVMContext &Context, SlotMapping *Slots, | |
| bool UpgradeDebugInfo, StringRef DataLayoutString) { | |
| MemoryBufferRef F(AsmString, "<string>"); | |
| return parseAssembly(F, Err, Context, Slots, UpgradeDebugInfo, | |
| DataLayoutString); | |
| } | |
| static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F, | |
| ModuleSummaryIndex &Index, | |
| SMDiagnostic &Err) { | |
| SourceMgr SM; | |
| std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F); | |
| SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); | |
| // The parser holds a reference to a context that is unused when parsing the | |
| // index, but we need to initialize it. | |
| LLVMContext unusedContext; | |
| return LLParser(F.getBuffer(), SM, Err, nullptr, &Index, unusedContext).Run(); | |
| } | |
| std::unique_ptr<ModuleSummaryIndex> | |
| llvm::parseSummaryIndexAssembly(MemoryBufferRef F, SMDiagnostic &Err) { | |
| std::unique_ptr<ModuleSummaryIndex> Index = | |
| make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false); | |
| if (parseSummaryIndexAssemblyInto(F, *Index, Err)) | |
| return nullptr; | |
| return Index; | |
| } | |
| std::unique_ptr<ModuleSummaryIndex> | |
| llvm::parseSummaryIndexAssemblyFile(StringRef Filename, SMDiagnostic &Err) { | |
| ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = | |
| MemoryBuffer::getFileOrSTDIN(Filename); | |
| if (std::error_code EC = FileOrErr.getError()) { | |
| Err = SMDiagnostic(Filename, SourceMgr::DK_Error, | |
| "Could not open input file: " + EC.message()); | |
| return nullptr; | |
| } | |
| return parseSummaryIndexAssembly(FileOrErr.get()->getMemBufferRef(), Err); | |
| } | |
| Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err, | |
| const Module &M, const SlotMapping *Slots) { | |
| SourceMgr SM; | |
| std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); | |
| SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); | |
| Constant *C; | |
| if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext()) | |
| .parseStandaloneConstantValue(C, Slots)) | |
| return nullptr; | |
| return C; | |
| } | |
| Type *llvm::parseType(StringRef Asm, SMDiagnostic &Err, const Module &M, | |
| const SlotMapping *Slots) { | |
| unsigned Read; | |
| Type *Ty = parseTypeAtBeginning(Asm, Read, Err, M, Slots); | |
| if (!Ty) | |
| return nullptr; | |
| if (Read != Asm.size()) { | |
| SourceMgr SM; | |
| std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); | |
| SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); | |
| Err = SM.GetMessage(SMLoc::getFromPointer(Asm.begin() + Read), | |
| SourceMgr::DK_Error, "expected end of string"); | |
| return nullptr; | |
| } | |
| return Ty; | |
| } | |
| Type *llvm::parseTypeAtBeginning(StringRef Asm, unsigned &Read, | |
| SMDiagnostic &Err, const Module &M, | |
| const SlotMapping *Slots) { | |
| SourceMgr SM; | |
| std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); | |
| SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); | |
| Type *Ty; | |
| if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext()) | |
| .parseTypeAtBeginning(Ty, Read, Slots)) | |
| return nullptr; | |
| return Ty; | |
| } |