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