llvm.org GIT mirror llvm / 0e99876
AsmParser: Save and restore the parsing state for types using SlotMapping. This commit extends the 'SlotMapping' structure and includes mappings for named and numbered types in it. The LLParser is extended accordingly to fill out those mappings at the end of module parsing. This information is useful when we want to parse standalone constant values at a later stage using the 'parseConstantValue' method. The constant values can be constant expressions, which can contain references to types. In order to parse such constant values, we have to restore the internal named and numbered mappings for the types in LLParser, otherwise the parser will report a parsing error. Therefore, this commit also introduces a new method called 'restoreParsingState' to LLParser, which uses the slot mappings to restore some of its internal parsing state. This commit is required to serialize constant value pointers in the machine memory operands for the MIR format. Reviewers: Duncan P. N. Exon Smith git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245740 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Lorenz 5 years ago
6 changed file(s) with 77 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
8484 /// The constant value can be any LLVM constant, including a constant
8585 /// expression.
8686 ///
87 /// \param Slots The optional slot mapping that will restore the parsing state
88 /// of the module.
8789 /// \return null on error.
88 Constant *parseConstantValue(StringRef Asm, SMDiagnostic &Err, const Module &M);
90 Constant *parseConstantValue(StringRef Asm, SMDiagnostic &Err, const Module &M,
91 const SlotMapping *Slots = nullptr);
8992
9093 } // End llvm namespace
9194
1313 #ifndef LLVM_ASMPARSER_SLOTMAPPING_H
1414 #define LLVM_ASMPARSER_SLOTMAPPING_H
1515
16 #include "llvm/ADT/StringMap.h"
1617 #include "llvm/IR/TrackingMDRef.h"
1718 #include
1819 #include
2021 namespace llvm {
2122
2223 class GlobalValue;
24 class Type;
2325
24 /// This struct contains the mapping from the slot numbers to unnamed metadata
25 /// nodes and global values.
26 /// This struct contains the mappings from the slot numbers to unnamed metadata
27 /// nodes, global values and types. It also contains the mapping for the named
28 /// types.
29 /// It can be used to save the parsing state of an LLVM IR module so that the
30 /// textual references to the values in the module can be parsed outside of the
31 /// module's source.
2632 struct SlotMapping {
2733 std::vector GlobalValues;
2834 std::map MetadataNodes;
35 StringMap NamedTypes;
36 std::map Types;
2937 };
3038
3139 } // end namespace llvm
4848 ValidateEndOfModule();
4949 }
5050
51 bool LLParser::parseStandaloneConstantValue(Constant *&C) {
51 bool LLParser::parseStandaloneConstantValue(Constant *&C,
52 const SlotMapping *Slots) {
53 restoreParsingState(Slots);
5254 Lex.Lex();
5355
5456 Type *Ty = nullptr;
5759 if (Lex.getKind() != lltok::Eof)
5860 return Error(Lex.getLoc(), "expected end of string");
5961 return false;
62 }
63
64 void LLParser::restoreParsingState(const SlotMapping *Slots) {
65 if (!Slots)
66 return;
67 NumberedVals = Slots->GlobalValues;
68 NumberedMetadata = Slots->MetadataNodes;
69 for (const auto &I : Slots->NamedTypes)
70 NamedTypes.insert(
71 std::make_pair(I.getKey(), std::make_pair(I.second, LocTy())));
72 for (const auto &I : Slots->Types)
73 NumberedTypes.insert(
74 std::make_pair(I.first, std::make_pair(I.second, LocTy())));
6075 }
6176
6277 /// ValidateEndOfModule - Do final validity and sanity checks at the end of the
180195 // the mapping from LLParser as it doesn't need it anymore.
181196 Slots->GlobalValues = std::move(NumberedVals);
182197 Slots->MetadataNodes = std::move(NumberedMetadata);
198 for (const auto &I : NamedTypes)
199 Slots->NamedTypes.insert(std::make_pair(I.getKey(), I.second.first));
200 for (const auto &I : NumberedTypes)
201 Slots->Types.insert(std::make_pair(I.first, I.second.first));
183202
184203 return false;
185204 }
145145 Slots(Slots), BlockAddressPFS(nullptr) {}
146146 bool Run();
147147
148 bool parseStandaloneConstantValue(Constant *&C);
148 bool parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots);
149149
150150 LLVMContext &getContext() { return Context; }
151151
157157 bool TokError(const Twine &Msg) const {
158158 return Error(Lex.getLoc(), Msg);
159159 }
160
161 /// Restore the internal name and slot mappings using the mappings that
162 /// were created at an earlier parsing stage.
163 void restoreParsingState(const SlotMapping *Slots);
160164
161165 /// GetGlobalVal - Get a value with the specified name or ID, creating a
162166 /// forward reference record if needed. This can return null if the value
6767 }
6868
6969 Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err,
70 const Module &M) {
70 const Module &M, const SlotMapping *Slots) {
7171 SourceMgr SM;
7272 std::unique_ptr Buf = MemoryBuffer::getMemBuffer(Asm);
7373 SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
7474 Constant *C;
7575 if (LLParser(Asm, SM, Err, const_cast(&M))
76 .parseStandaloneConstantValue(C))
76 .parseStandaloneConstantValue(C, Slots))
7777 return nullptr;
7878 return C;
7979 }
111111 EXPECT_EQ(Error.getMessage(), "expected end of string");
112112 }
113113
114 TEST(AsmParserTest, TypeAndConstantValueWithSlotMappingParsing) {
115 LLVMContext &Ctx = getGlobalContext();
116 SMDiagnostic Error;
117 StringRef Source =
118 "%st = type { i32, i32 }\n"
119 "@v = common global [50 x %st] zeroinitializer, align 16\n"
120 "%0 = type { i32, i32, i32, i32 }\n"
121 "@g = common global [50 x %0] zeroinitializer, align 16\n"
122 "define void @marker4(i64 %d) {\n"
123 "entry:\n"
124 " %conv = trunc i64 %d to i32\n"
125 " store i32 %conv, i32* getelementptr inbounds "
126 " ([50 x %st], [50 x %st]* @v, i64 0, i64 0, i32 0), align 16\n"
127 " store i32 %conv, i32* getelementptr inbounds "
128 " ([50 x %0], [50 x %0]* @g, i64 0, i64 0, i32 0), align 16\n"
129 " ret void\n"
130 "}";
131 SlotMapping Mapping;
132 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
133 ASSERT_TRUE(Mod != nullptr);
134 auto &M = *Mod;
135
136 const Value *V;
137 V = parseConstantValue("i32* getelementptr inbounds ([50 x %st], [50 x %st]* "
138 "@v, i64 0, i64 0, i32 0)",
139 Error, M, &Mapping);
140 ASSERT_TRUE(V);
141 ASSERT_TRUE(isa(V));
142
143 V = parseConstantValue("i32* getelementptr inbounds ([50 x %0], [50 x %0]* "
144 "@g, i64 0, i64 0, i32 0)",
145 Error, M, &Mapping);
146 ASSERT_TRUE(V);
147 ASSERT_TRUE(isa(V));
148 }
149
114150 } // end anonymous namespace