Home | History | Annotate | Download | only in AsmParser
      1 //===- Parser.cpp - Main dispatch module for the Parser library -----------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This library implements the functionality defined in llvm/AsmParser/Parser.h
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/AsmParser/Parser.h"
     15 #include "LLParser.h"
     16 #include "llvm/ADT/STLExtras.h"
     17 #include "llvm/IR/Module.h"
     18 #include "llvm/IR/ModuleSummaryIndex.h"
     19 #include "llvm/Support/MemoryBuffer.h"
     20 #include "llvm/Support/SourceMgr.h"
     21 #include "llvm/Support/raw_ostream.h"
     22 #include <cstring>
     23 #include <system_error>
     24 using namespace llvm;
     25 
     26 bool llvm::parseAssemblyInto(MemoryBufferRef F, Module *M,
     27                              ModuleSummaryIndex *Index, SMDiagnostic &Err,
     28                              SlotMapping *Slots, bool UpgradeDebugInfo,
     29                              StringRef DataLayoutString) {
     30   SourceMgr SM;
     31   std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F);
     32   SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
     33 
     34   LLVMContext Context;
     35   return LLParser(F.getBuffer(), SM, Err, M, Index,
     36                   M ? M->getContext() : Context, Slots, UpgradeDebugInfo,
     37                   DataLayoutString)
     38       .Run();
     39 }
     40 
     41 std::unique_ptr<Module>
     42 llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context,
     43                     SlotMapping *Slots, bool UpgradeDebugInfo,
     44                     StringRef DataLayoutString) {
     45   std::unique_ptr<Module> M =
     46       make_unique<Module>(F.getBufferIdentifier(), Context);
     47 
     48   if (parseAssemblyInto(F, M.get(), nullptr, Err, Slots, UpgradeDebugInfo,
     49                         DataLayoutString))
     50     return nullptr;
     51 
     52   return M;
     53 }
     54 
     55 std::unique_ptr<Module>
     56 llvm::parseAssemblyFile(StringRef Filename, SMDiagnostic &Err,
     57                         LLVMContext &Context, SlotMapping *Slots,
     58                         bool UpgradeDebugInfo, StringRef DataLayoutString) {
     59   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
     60       MemoryBuffer::getFileOrSTDIN(Filename);
     61   if (std::error_code EC = FileOrErr.getError()) {
     62     Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
     63                        "Could not open input file: " + EC.message());
     64     return nullptr;
     65   }
     66 
     67   return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots,
     68                        UpgradeDebugInfo, DataLayoutString);
     69 }
     70 
     71 ParsedModuleAndIndex llvm::parseAssemblyWithIndex(
     72     MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context,
     73     SlotMapping *Slots, bool UpgradeDebugInfo, StringRef DataLayoutString) {
     74   std::unique_ptr<Module> M =
     75       make_unique<Module>(F.getBufferIdentifier(), Context);
     76   std::unique_ptr<ModuleSummaryIndex> Index =
     77       make_unique<ModuleSummaryIndex>(/*HaveGVs=*/true);
     78 
     79   if (parseAssemblyInto(F, M.get(), Index.get(), Err, Slots, UpgradeDebugInfo,
     80                         DataLayoutString))
     81     return {nullptr, nullptr};
     82 
     83   return {std::move(M), std::move(Index)};
     84 }
     85 
     86 ParsedModuleAndIndex llvm::parseAssemblyFileWithIndex(
     87     StringRef Filename, SMDiagnostic &Err, LLVMContext &Context,
     88     SlotMapping *Slots, bool UpgradeDebugInfo, StringRef DataLayoutString) {
     89   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
     90       MemoryBuffer::getFileOrSTDIN(Filename);
     91   if (std::error_code EC = FileOrErr.getError()) {
     92     Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
     93                        "Could not open input file: " + EC.message());
     94     return {nullptr, nullptr};
     95   }
     96 
     97   return parseAssemblyWithIndex(FileOrErr.get()->getMemBufferRef(), Err,
     98                                 Context, Slots, UpgradeDebugInfo,
     99                                 DataLayoutString);
    100 }
    101 
    102 std::unique_ptr<Module>
    103 llvm::parseAssemblyString(StringRef AsmString, SMDiagnostic &Err,
    104                           LLVMContext &Context, SlotMapping *Slots,
    105                           bool UpgradeDebugInfo, StringRef DataLayoutString) {
    106   MemoryBufferRef F(AsmString, "<string>");
    107   return parseAssembly(F, Err, Context, Slots, UpgradeDebugInfo,
    108                        DataLayoutString);
    109 }
    110 
    111 static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F,
    112                                           ModuleSummaryIndex &Index,
    113                                           SMDiagnostic &Err) {
    114   SourceMgr SM;
    115   std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F);
    116   SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
    117 
    118   // The parser holds a reference to a context that is unused when parsing the
    119   // index, but we need to initialize it.
    120   LLVMContext unusedContext;
    121   return LLParser(F.getBuffer(), SM, Err, nullptr, &Index, unusedContext).Run();
    122 }
    123 
    124 std::unique_ptr<ModuleSummaryIndex>
    125 llvm::parseSummaryIndexAssembly(MemoryBufferRef F, SMDiagnostic &Err) {
    126   std::unique_ptr<ModuleSummaryIndex> Index =
    127       make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
    128 
    129   if (parseSummaryIndexAssemblyInto(F, *Index, Err))
    130     return nullptr;
    131 
    132   return Index;
    133 }
    134 
    135 std::unique_ptr<ModuleSummaryIndex>
    136 llvm::parseSummaryIndexAssemblyFile(StringRef Filename, SMDiagnostic &Err) {
    137   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
    138       MemoryBuffer::getFileOrSTDIN(Filename);
    139   if (std::error_code EC = FileOrErr.getError()) {
    140     Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
    141                        "Could not open input file: " + EC.message());
    142     return nullptr;
    143   }
    144 
    145   return parseSummaryIndexAssembly(FileOrErr.get()->getMemBufferRef(), Err);
    146 }
    147 
    148 Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err,
    149                                    const Module &M, const SlotMapping *Slots) {
    150   SourceMgr SM;
    151   std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
    152   SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
    153   Constant *C;
    154   if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext())
    155           .parseStandaloneConstantValue(C, Slots))
    156     return nullptr;
    157   return C;
    158 }
    159 
    160 Type *llvm::parseType(StringRef Asm, SMDiagnostic &Err, const Module &M,
    161                       const SlotMapping *Slots) {
    162   unsigned Read;
    163   Type *Ty = parseTypeAtBeginning(Asm, Read, Err, M, Slots);
    164   if (!Ty)
    165     return nullptr;
    166   if (Read != Asm.size()) {
    167     SourceMgr SM;
    168     std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
    169     SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
    170     Err = SM.GetMessage(SMLoc::getFromPointer(Asm.begin() + Read),
    171                         SourceMgr::DK_Error, "expected end of string");
    172     return nullptr;
    173   }
    174   return Ty;
    175 }
    176 Type *llvm::parseTypeAtBeginning(StringRef Asm, unsigned &Read,
    177                                  SMDiagnostic &Err, const Module &M,
    178                                  const SlotMapping *Slots) {
    179   SourceMgr SM;
    180   std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
    181   SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
    182   Type *Ty;
    183   if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext())
    184           .parseTypeAtBeginning(Ty, Read, Slots))
    185     return nullptr;
    186   return Ty;
    187 }
    188