10b57cec5SDimitry Andric //===- Parser.cpp - Main dispatch module for the Parser library -----------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This library implements the functionality defined in llvm/AsmParser/Parser.h 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/AsmParser/Parser.h" 14fe6060f1SDimitry Andric #include "llvm/AsmParser/LLParser.h" 15*0fca6ea1SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 160b57cec5SDimitry Andric #include "llvm/IR/Module.h" 170b57cec5SDimitry Andric #include "llvm/IR/ModuleSummaryIndex.h" 180b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 190b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h" 200b57cec5SDimitry Andric #include <system_error> 215ffd83dbSDimitry Andric 220b57cec5SDimitry Andric using namespace llvm; 230b57cec5SDimitry Andric 245ffd83dbSDimitry Andric static bool parseAssemblyInto(MemoryBufferRef F, Module *M, 250b57cec5SDimitry Andric ModuleSummaryIndex *Index, SMDiagnostic &Err, 260b57cec5SDimitry Andric SlotMapping *Slots, bool UpgradeDebugInfo, 275ffd83dbSDimitry Andric DataLayoutCallbackTy DataLayoutCallback) { 280b57cec5SDimitry Andric SourceMgr SM; 290b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F); 300b57cec5SDimitry Andric SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 310b57cec5SDimitry Andric 3206c3fb27SDimitry Andric std::optional<LLVMContext> OptContext; 330b57cec5SDimitry Andric return LLParser(F.getBuffer(), SM, Err, M, Index, 3406c3fb27SDimitry Andric M ? M->getContext() : OptContext.emplace(), Slots) 355ffd83dbSDimitry Andric .Run(UpgradeDebugInfo, DataLayoutCallback); 365ffd83dbSDimitry Andric } 375ffd83dbSDimitry Andric 385ffd83dbSDimitry Andric bool llvm::parseAssemblyInto(MemoryBufferRef F, Module *M, 395ffd83dbSDimitry Andric ModuleSummaryIndex *Index, SMDiagnostic &Err, 405ffd83dbSDimitry Andric SlotMapping *Slots, 415ffd83dbSDimitry Andric DataLayoutCallbackTy DataLayoutCallback) { 425ffd83dbSDimitry Andric return ::parseAssemblyInto(F, M, Index, Err, Slots, 435ffd83dbSDimitry Andric /*UpgradeDebugInfo*/ true, DataLayoutCallback); 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric std::unique_ptr<Module> 470b57cec5SDimitry Andric llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, 485ffd83dbSDimitry Andric SlotMapping *Slots, 495ffd83dbSDimitry Andric DataLayoutCallbackTy DataLayoutCallback) { 500b57cec5SDimitry Andric std::unique_ptr<Module> M = 518bcb0991SDimitry Andric std::make_unique<Module>(F.getBufferIdentifier(), Context); 520b57cec5SDimitry Andric 535ffd83dbSDimitry Andric if (parseAssemblyInto(F, M.get(), nullptr, Err, Slots, DataLayoutCallback)) 540b57cec5SDimitry Andric return nullptr; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric return M; 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric 595ffd83dbSDimitry Andric std::unique_ptr<Module> llvm::parseAssemblyFile(StringRef Filename, 605ffd83dbSDimitry Andric SMDiagnostic &Err, 615ffd83dbSDimitry Andric LLVMContext &Context, 625ffd83dbSDimitry Andric SlotMapping *Slots) { 630b57cec5SDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 640b57cec5SDimitry Andric MemoryBuffer::getFileOrSTDIN(Filename); 650b57cec5SDimitry Andric if (std::error_code EC = FileOrErr.getError()) { 660b57cec5SDimitry Andric Err = SMDiagnostic(Filename, SourceMgr::DK_Error, 670b57cec5SDimitry Andric "Could not open input file: " + EC.message()); 680b57cec5SDimitry Andric return nullptr; 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 715ffd83dbSDimitry Andric return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots); 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric 745ffd83dbSDimitry Andric static ParsedModuleAndIndex 755ffd83dbSDimitry Andric parseAssemblyWithIndex(MemoryBufferRef F, SMDiagnostic &Err, 765ffd83dbSDimitry Andric LLVMContext &Context, SlotMapping *Slots, 775ffd83dbSDimitry Andric bool UpgradeDebugInfo, 785ffd83dbSDimitry Andric DataLayoutCallbackTy DataLayoutCallback) { 790b57cec5SDimitry Andric std::unique_ptr<Module> M = 808bcb0991SDimitry Andric std::make_unique<Module>(F.getBufferIdentifier(), Context); 810b57cec5SDimitry Andric std::unique_ptr<ModuleSummaryIndex> Index = 828bcb0991SDimitry Andric std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/true); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric if (parseAssemblyInto(F, M.get(), Index.get(), Err, Slots, UpgradeDebugInfo, 855ffd83dbSDimitry Andric DataLayoutCallback)) 860b57cec5SDimitry Andric return {nullptr, nullptr}; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric return {std::move(M), std::move(Index)}; 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 915ffd83dbSDimitry Andric ParsedModuleAndIndex llvm::parseAssemblyWithIndex(MemoryBufferRef F, 925ffd83dbSDimitry Andric SMDiagnostic &Err, 935ffd83dbSDimitry Andric LLVMContext &Context, 945ffd83dbSDimitry Andric SlotMapping *Slots) { 95bdd1243dSDimitry Andric return ::parseAssemblyWithIndex( 96bdd1243dSDimitry Andric F, Err, Context, Slots, 975ffd83dbSDimitry Andric /*UpgradeDebugInfo*/ true, 98bdd1243dSDimitry Andric [](StringRef, StringRef) { return std::nullopt; }); 995ffd83dbSDimitry Andric } 1005ffd83dbSDimitry Andric 1015ffd83dbSDimitry Andric static ParsedModuleAndIndex 1025ffd83dbSDimitry Andric parseAssemblyFileWithIndex(StringRef Filename, SMDiagnostic &Err, 1035ffd83dbSDimitry Andric LLVMContext &Context, SlotMapping *Slots, 1045ffd83dbSDimitry Andric bool UpgradeDebugInfo, 1055ffd83dbSDimitry Andric DataLayoutCallbackTy DataLayoutCallback) { 1060b57cec5SDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 107fe6060f1SDimitry Andric MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true); 1080b57cec5SDimitry Andric if (std::error_code EC = FileOrErr.getError()) { 1090b57cec5SDimitry Andric Err = SMDiagnostic(Filename, SourceMgr::DK_Error, 1100b57cec5SDimitry Andric "Could not open input file: " + EC.message()); 1110b57cec5SDimitry Andric return {nullptr, nullptr}; 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric return parseAssemblyWithIndex(FileOrErr.get()->getMemBufferRef(), Err, 1150b57cec5SDimitry Andric Context, Slots, UpgradeDebugInfo, 1165ffd83dbSDimitry Andric DataLayoutCallback); 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric 1195ffd83dbSDimitry Andric ParsedModuleAndIndex 1205ffd83dbSDimitry Andric llvm::parseAssemblyFileWithIndex(StringRef Filename, SMDiagnostic &Err, 1210b57cec5SDimitry Andric LLVMContext &Context, SlotMapping *Slots, 1225ffd83dbSDimitry Andric DataLayoutCallbackTy DataLayoutCallback) { 1235ffd83dbSDimitry Andric return ::parseAssemblyFileWithIndex(Filename, Err, Context, Slots, 1245ffd83dbSDimitry Andric /*UpgradeDebugInfo*/ true, 1255ffd83dbSDimitry Andric DataLayoutCallback); 1265ffd83dbSDimitry Andric } 1275ffd83dbSDimitry Andric 1285ffd83dbSDimitry Andric ParsedModuleAndIndex llvm::parseAssemblyFileWithIndexNoUpgradeDebugInfo( 1295ffd83dbSDimitry Andric StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, 1305ffd83dbSDimitry Andric SlotMapping *Slots, DataLayoutCallbackTy DataLayoutCallback) { 1315ffd83dbSDimitry Andric return ::parseAssemblyFileWithIndex(Filename, Err, Context, Slots, 1325ffd83dbSDimitry Andric /*UpgradeDebugInfo*/ false, 1335ffd83dbSDimitry Andric DataLayoutCallback); 1345ffd83dbSDimitry Andric } 1355ffd83dbSDimitry Andric 1365ffd83dbSDimitry Andric std::unique_ptr<Module> llvm::parseAssemblyString(StringRef AsmString, 1375ffd83dbSDimitry Andric SMDiagnostic &Err, 1385ffd83dbSDimitry Andric LLVMContext &Context, 1395ffd83dbSDimitry Andric SlotMapping *Slots) { 1400b57cec5SDimitry Andric MemoryBufferRef F(AsmString, "<string>"); 1415ffd83dbSDimitry Andric return parseAssembly(F, Err, Context, Slots); 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F, 1450b57cec5SDimitry Andric ModuleSummaryIndex &Index, 1460b57cec5SDimitry Andric SMDiagnostic &Err) { 1470b57cec5SDimitry Andric SourceMgr SM; 1480b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F); 1490b57cec5SDimitry Andric SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric // The parser holds a reference to a context that is unused when parsing the 1520b57cec5SDimitry Andric // index, but we need to initialize it. 1530b57cec5SDimitry Andric LLVMContext unusedContext; 1545ffd83dbSDimitry Andric return LLParser(F.getBuffer(), SM, Err, nullptr, &Index, unusedContext) 155bdd1243dSDimitry Andric .Run(true, [](StringRef, StringRef) { return std::nullopt; }); 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric std::unique_ptr<ModuleSummaryIndex> 1590b57cec5SDimitry Andric llvm::parseSummaryIndexAssembly(MemoryBufferRef F, SMDiagnostic &Err) { 1600b57cec5SDimitry Andric std::unique_ptr<ModuleSummaryIndex> Index = 1618bcb0991SDimitry Andric std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false); 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric if (parseSummaryIndexAssemblyInto(F, *Index, Err)) 1640b57cec5SDimitry Andric return nullptr; 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric return Index; 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric std::unique_ptr<ModuleSummaryIndex> 1700b57cec5SDimitry Andric llvm::parseSummaryIndexAssemblyFile(StringRef Filename, SMDiagnostic &Err) { 1710b57cec5SDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 1720b57cec5SDimitry Andric MemoryBuffer::getFileOrSTDIN(Filename); 1730b57cec5SDimitry Andric if (std::error_code EC = FileOrErr.getError()) { 1740b57cec5SDimitry Andric Err = SMDiagnostic(Filename, SourceMgr::DK_Error, 1750b57cec5SDimitry Andric "Could not open input file: " + EC.message()); 1760b57cec5SDimitry Andric return nullptr; 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric return parseSummaryIndexAssembly(FileOrErr.get()->getMemBufferRef(), Err); 1800b57cec5SDimitry Andric } 1810b57cec5SDimitry Andric 182bdd1243dSDimitry Andric std::unique_ptr<ModuleSummaryIndex> 183bdd1243dSDimitry Andric llvm::parseSummaryIndexAssemblyString(StringRef AsmString, SMDiagnostic &Err) { 184bdd1243dSDimitry Andric MemoryBufferRef F(AsmString, "<string>"); 185bdd1243dSDimitry Andric return parseSummaryIndexAssembly(F, Err); 186bdd1243dSDimitry Andric } 187bdd1243dSDimitry Andric 1880b57cec5SDimitry Andric Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err, 1890b57cec5SDimitry Andric const Module &M, const SlotMapping *Slots) { 1900b57cec5SDimitry Andric SourceMgr SM; 1910b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); 1920b57cec5SDimitry Andric SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 1930b57cec5SDimitry Andric Constant *C; 1940b57cec5SDimitry Andric if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext()) 1950b57cec5SDimitry Andric .parseStandaloneConstantValue(C, Slots)) 1960b57cec5SDimitry Andric return nullptr; 1970b57cec5SDimitry Andric return C; 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric Type *llvm::parseType(StringRef Asm, SMDiagnostic &Err, const Module &M, 2010b57cec5SDimitry Andric const SlotMapping *Slots) { 2020b57cec5SDimitry Andric unsigned Read; 2030b57cec5SDimitry Andric Type *Ty = parseTypeAtBeginning(Asm, Read, Err, M, Slots); 2040b57cec5SDimitry Andric if (!Ty) 2050b57cec5SDimitry Andric return nullptr; 2060b57cec5SDimitry Andric if (Read != Asm.size()) { 2070b57cec5SDimitry Andric SourceMgr SM; 2080b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); 2090b57cec5SDimitry Andric SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 2100b57cec5SDimitry Andric Err = SM.GetMessage(SMLoc::getFromPointer(Asm.begin() + Read), 2110b57cec5SDimitry Andric SourceMgr::DK_Error, "expected end of string"); 2120b57cec5SDimitry Andric return nullptr; 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric return Ty; 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric Type *llvm::parseTypeAtBeginning(StringRef Asm, unsigned &Read, 2170b57cec5SDimitry Andric SMDiagnostic &Err, const Module &M, 2180b57cec5SDimitry Andric const SlotMapping *Slots) { 2190b57cec5SDimitry Andric SourceMgr SM; 2200b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); 2210b57cec5SDimitry Andric SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 2220b57cec5SDimitry Andric Type *Ty; 2230b57cec5SDimitry Andric if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext()) 2240b57cec5SDimitry Andric .parseTypeAtBeginning(Ty, Read, Slots)) 2250b57cec5SDimitry Andric return nullptr; 2260b57cec5SDimitry Andric return Ty; 2270b57cec5SDimitry Andric } 228*0fca6ea1SDimitry Andric 229*0fca6ea1SDimitry Andric DIExpression *llvm::parseDIExpressionBodyAtBeginning(StringRef Asm, 230*0fca6ea1SDimitry Andric unsigned &Read, 231*0fca6ea1SDimitry Andric SMDiagnostic &Err, 232*0fca6ea1SDimitry Andric const Module &M, 233*0fca6ea1SDimitry Andric const SlotMapping *Slots) { 234*0fca6ea1SDimitry Andric SourceMgr SM; 235*0fca6ea1SDimitry Andric std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); 236*0fca6ea1SDimitry Andric SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); 237*0fca6ea1SDimitry Andric MDNode *MD; 238*0fca6ea1SDimitry Andric if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext()) 239*0fca6ea1SDimitry Andric .parseDIExpressionBodyAtBeginning(MD, Read, Slots)) 240*0fca6ea1SDimitry Andric return nullptr; 241*0fca6ea1SDimitry Andric return dyn_cast<DIExpression>(MD); 242*0fca6ea1SDimitry Andric } 243