xref: /freebsd-src/contrib/llvm-project/llvm/lib/AsmParser/Parser.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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