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/Support/MemoryBuffer.h"
19 #include "llvm/Support/SourceMgr.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include <cstring>
22 #include <system_error>
23 using namespace llvm;
24 
25 bool llvm::parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err,
26                              SlotMapping *Slots, bool UpgradeDebugInfo) {
27   SourceMgr SM;
28   std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F);
29   SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
30 
31   return LLParser(F.getBuffer(), SM, Err, &M, Slots, UpgradeDebugInfo).Run();
32 }
33 
34 std::unique_ptr<Module>
35 llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context,
36                     SlotMapping *Slots, bool UpgradeDebugInfo) {
37   std::unique_ptr<Module> M =
38       make_unique<Module>(F.getBufferIdentifier(), Context);
39 
40   if (parseAssemblyInto(F, *M, Err, Slots, UpgradeDebugInfo))
41     return nullptr;
42 
43   return M;
44 }
45 
46 std::unique_ptr<Module> llvm::parseAssemblyFile(StringRef Filename,
47                                                 SMDiagnostic &Err,
48                                                 LLVMContext &Context,
49                                                 SlotMapping *Slots,
50                                                 bool UpgradeDebugInfo) {
51   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
52       MemoryBuffer::getFileOrSTDIN(Filename);
53   if (std::error_code EC = FileOrErr.getError()) {
54     Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
55                        "Could not open input file: " + EC.message());
56     return nullptr;
57   }
58 
59   return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots,
60                        UpgradeDebugInfo);
61 }
62 
63 std::unique_ptr<Module> llvm::parseAssemblyString(StringRef AsmString,
64                                                   SMDiagnostic &Err,
65                                                   LLVMContext &Context,
66                                                   SlotMapping *Slots,
67                                                   bool UpgradeDebugInfo) {
68   MemoryBufferRef F(AsmString, "<string>");
69   return parseAssembly(F, Err, Context, Slots, UpgradeDebugInfo);
70 }
71 
72 Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err,
73                                    const Module &M, const SlotMapping *Slots) {
74   SourceMgr SM;
75   std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
76   SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
77   Constant *C;
78   if (LLParser(Asm, SM, Err, const_cast<Module *>(&M))
79           .parseStandaloneConstantValue(C, Slots))
80     return nullptr;
81   return C;
82 }
83 
84 Type *llvm::parseType(StringRef Asm, SMDiagnostic &Err, const Module &M,
85                       const SlotMapping *Slots) {
86   unsigned Read;
87   Type *Ty = parseTypeAtBeginning(Asm, Read, Err, M, Slots);
88   if (!Ty)
89     return nullptr;
90   if (Read != Asm.size()) {
91     SourceMgr SM;
92     std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
93     SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
94     Err = SM.GetMessage(SMLoc::getFromPointer(Asm.begin() + Read),
95                         SourceMgr::DK_Error, "expected end of string");
96     return nullptr;
97   }
98   return Ty;
99 }
100 Type *llvm::parseTypeAtBeginning(StringRef Asm, unsigned &Read,
101                                  SMDiagnostic &Err, const Module &M,
102                                  const SlotMapping *Slots) {
103   SourceMgr SM;
104   std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
105   SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
106   Type *Ty;
107   if (LLParser(Asm, SM, Err, const_cast<Module *>(&M))
108           .parseTypeAtBeginning(Ty, Read, Slots))
109     return nullptr;
110   return Ty;
111 }
112