1 //===- Parser.cpp - Main dispatch module for the Parser library -----------===//
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
7 //===----------------------------------------------------------------------===//
9 // This library implements the functionality defined in llvm/AsmParser/Parser.h
11 //===----------------------------------------------------------------------===//
13 #include "llvm/AsmParser/Parser.h"
15 #include "llvm/ADT/STLExtras.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 "llvm/Support/raw_ostream.h"
22 #include <system_error>
25 bool llvm::parseAssemblyInto(MemoryBufferRef F
, Module
*M
,
26 ModuleSummaryIndex
*Index
, SMDiagnostic
&Err
,
27 SlotMapping
*Slots
, bool UpgradeDebugInfo
,
28 StringRef DataLayoutString
) {
30 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(F
);
31 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
34 return LLParser(F
.getBuffer(), SM
, Err
, M
, Index
,
35 M
? M
->getContext() : Context
, Slots
, UpgradeDebugInfo
,
40 std::unique_ptr
<Module
>
41 llvm::parseAssembly(MemoryBufferRef F
, SMDiagnostic
&Err
, LLVMContext
&Context
,
42 SlotMapping
*Slots
, bool UpgradeDebugInfo
,
43 StringRef DataLayoutString
) {
44 std::unique_ptr
<Module
> M
=
45 std::make_unique
<Module
>(F
.getBufferIdentifier(), Context
);
47 if (parseAssemblyInto(F
, M
.get(), nullptr, Err
, Slots
, UpgradeDebugInfo
,
54 std::unique_ptr
<Module
>
55 llvm::parseAssemblyFile(StringRef Filename
, SMDiagnostic
&Err
,
56 LLVMContext
&Context
, SlotMapping
*Slots
,
57 bool UpgradeDebugInfo
, StringRef DataLayoutString
) {
58 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> FileOrErr
=
59 MemoryBuffer::getFileOrSTDIN(Filename
);
60 if (std::error_code EC
= FileOrErr
.getError()) {
61 Err
= SMDiagnostic(Filename
, SourceMgr::DK_Error
,
62 "Could not open input file: " + EC
.message());
66 return parseAssembly(FileOrErr
.get()->getMemBufferRef(), Err
, Context
, Slots
,
67 UpgradeDebugInfo
, DataLayoutString
);
70 ParsedModuleAndIndex
llvm::parseAssemblyWithIndex(
71 MemoryBufferRef F
, SMDiagnostic
&Err
, LLVMContext
&Context
,
72 SlotMapping
*Slots
, bool UpgradeDebugInfo
, StringRef DataLayoutString
) {
73 std::unique_ptr
<Module
> M
=
74 std::make_unique
<Module
>(F
.getBufferIdentifier(), Context
);
75 std::unique_ptr
<ModuleSummaryIndex
> Index
=
76 std::make_unique
<ModuleSummaryIndex
>(/*HaveGVs=*/true);
78 if (parseAssemblyInto(F
, M
.get(), Index
.get(), Err
, Slots
, UpgradeDebugInfo
,
80 return {nullptr, nullptr};
82 return {std::move(M
), std::move(Index
)};
85 ParsedModuleAndIndex
llvm::parseAssemblyFileWithIndex(
86 StringRef Filename
, SMDiagnostic
&Err
, LLVMContext
&Context
,
87 SlotMapping
*Slots
, bool UpgradeDebugInfo
, StringRef DataLayoutString
) {
88 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> FileOrErr
=
89 MemoryBuffer::getFileOrSTDIN(Filename
);
90 if (std::error_code EC
= FileOrErr
.getError()) {
91 Err
= SMDiagnostic(Filename
, SourceMgr::DK_Error
,
92 "Could not open input file: " + EC
.message());
93 return {nullptr, nullptr};
96 return parseAssemblyWithIndex(FileOrErr
.get()->getMemBufferRef(), Err
,
97 Context
, Slots
, UpgradeDebugInfo
,
101 std::unique_ptr
<Module
>
102 llvm::parseAssemblyString(StringRef AsmString
, SMDiagnostic
&Err
,
103 LLVMContext
&Context
, SlotMapping
*Slots
,
104 bool UpgradeDebugInfo
, StringRef DataLayoutString
) {
105 MemoryBufferRef
F(AsmString
, "<string>");
106 return parseAssembly(F
, Err
, Context
, Slots
, UpgradeDebugInfo
,
110 static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F
,
111 ModuleSummaryIndex
&Index
,
114 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(F
);
115 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
117 // The parser holds a reference to a context that is unused when parsing the
118 // index, but we need to initialize it.
119 LLVMContext unusedContext
;
120 return LLParser(F
.getBuffer(), SM
, Err
, nullptr, &Index
, unusedContext
).Run();
123 std::unique_ptr
<ModuleSummaryIndex
>
124 llvm::parseSummaryIndexAssembly(MemoryBufferRef F
, SMDiagnostic
&Err
) {
125 std::unique_ptr
<ModuleSummaryIndex
> Index
=
126 std::make_unique
<ModuleSummaryIndex
>(/*HaveGVs=*/false);
128 if (parseSummaryIndexAssemblyInto(F
, *Index
, Err
))
134 std::unique_ptr
<ModuleSummaryIndex
>
135 llvm::parseSummaryIndexAssemblyFile(StringRef Filename
, SMDiagnostic
&Err
) {
136 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> FileOrErr
=
137 MemoryBuffer::getFileOrSTDIN(Filename
);
138 if (std::error_code EC
= FileOrErr
.getError()) {
139 Err
= SMDiagnostic(Filename
, SourceMgr::DK_Error
,
140 "Could not open input file: " + EC
.message());
144 return parseSummaryIndexAssembly(FileOrErr
.get()->getMemBufferRef(), Err
);
147 Constant
*llvm::parseConstantValue(StringRef Asm
, SMDiagnostic
&Err
,
148 const Module
&M
, const SlotMapping
*Slots
) {
150 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
151 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
153 if (LLParser(Asm
, SM
, Err
, const_cast<Module
*>(&M
), nullptr, M
.getContext())
154 .parseStandaloneConstantValue(C
, Slots
))
159 Type
*llvm::parseType(StringRef Asm
, SMDiagnostic
&Err
, const Module
&M
,
160 const SlotMapping
*Slots
) {
162 Type
*Ty
= parseTypeAtBeginning(Asm
, Read
, Err
, M
, Slots
);
165 if (Read
!= Asm
.size()) {
167 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
168 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
169 Err
= SM
.GetMessage(SMLoc::getFromPointer(Asm
.begin() + Read
),
170 SourceMgr::DK_Error
, "expected end of string");
175 Type
*llvm::parseTypeAtBeginning(StringRef Asm
, unsigned &Read
,
176 SMDiagnostic
&Err
, const Module
&M
,
177 const SlotMapping
*Slots
) {
179 std::unique_ptr
<MemoryBuffer
> Buf
= MemoryBuffer::getMemBuffer(Asm
);
180 SM
.AddNewSourceBuffer(std::move(Buf
), SMLoc());
182 if (LLParser(Asm
, SM
, Err
, const_cast<Module
*>(&M
), nullptr, M
.getContext())
183 .parseTypeAtBeginning(Ty
, Read
, Slots
))