llvm.org GIT mirror llvm / 2ba0323
[AsmParser] Add a function to parse a standalone type. This is useful for MIR serialization. Indeed generic machine instructions must have a type and we don't want to duplicate the logic in the MIParser. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@262868 91177308-0d34-0410-b5e6-96231b3b80d8 Quentin Colombet 4 years ago
5 changed file(s) with 155 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
2222 class Module;
2323 struct SlotMapping;
2424 class SMDiagnostic;
25 class Type;
2526
2627 /// This function is the main interface to the LLVM Assembly Parser. It parses
2728 /// an ASCII file that (presumably) contains LLVM Assembly code. It returns a
9091 Constant *parseConstantValue(StringRef Asm, SMDiagnostic &Err, const Module &M,
9192 const SlotMapping *Slots = nullptr);
9293
94 /// Parse a type in the given string.
95 ///
96 /// \param Slots The optional slot mapping that will restore the parsing state
97 /// of the module.
98 /// \return null on error.
99 Type *parseType(StringRef Asm, SMDiagnostic &Err, const Module &M,
100 const SlotMapping *Slots = nullptr);
101
93102 } // End llvm namespace
94103
95104 #endif
5656
5757 Type *Ty = nullptr;
5858 if (ParseType(Ty) || parseConstantValue(Ty, C))
59 return true;
60 if (Lex.getKind() != lltok::Eof)
61 return Error(Lex.getLoc(), "expected end of string");
62 return false;
63 }
64
65 bool LLParser::parseStandaloneType(Type *&Ty, const SlotMapping *Slots) {
66 restoreParsingState(Slots);
67 Lex.Lex();
68
69 Ty = nullptr;
70 if (ParseType(Ty))
5971 return true;
6072 if (Lex.getKind() != lltok::Eof)
6173 return Error(Lex.getLoc(), "expected end of string");
146146 bool Run();
147147
148148 bool parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots);
149
150 bool parseStandaloneType(Type *&Ty, const SlotMapping *Slots);
149151
150152 LLVMContext &getContext() { return Context; }
151153
7777 return nullptr;
7878 return C;
7979 }
80
81 Type *llvm::parseType(StringRef Asm, SMDiagnostic &Err, const Module &M,
82 const SlotMapping *Slots) {
83 SourceMgr SM;
84 std::unique_ptr Buf = MemoryBuffer::getMemBuffer(Asm);
85 SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
86 Type *Ty;
87 if (LLParser(Asm, SM, Err, const_cast(&M))
88 .parseStandaloneType(Ty, Slots))
89 return nullptr;
90 return Ty;
91 }
151151 ASSERT_TRUE(isa(V));
152152 }
153153
154 TEST(AsmParserTest, TypeWithSlotMappingParsing) {
155 LLVMContext &Ctx = getGlobalContext();
156 SMDiagnostic Error;
157 StringRef Source =
158 "%st = type { i32, i32 }\n"
159 "@v = common global [50 x %st] zeroinitializer, align 16\n"
160 "%0 = type { i32, i32, i32, i32 }\n"
161 "@g = common global [50 x %0] zeroinitializer, align 16\n"
162 "define void @marker4(i64 %d) {\n"
163 "entry:\n"
164 " %conv = trunc i64 %d to i32\n"
165 " store i32 %conv, i32* getelementptr inbounds "
166 " ([50 x %st], [50 x %st]* @v, i64 0, i64 0, i32 0), align 16\n"
167 " store i32 %conv, i32* getelementptr inbounds "
168 " ([50 x %0], [50 x %0]* @g, i64 0, i64 0, i32 0), align 16\n"
169 " ret void\n"
170 "}";
171 SlotMapping Mapping;
172 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
173 ASSERT_TRUE(Mod != nullptr);
174 auto &M = *Mod;
175
176 // Check we properly parse integer types.
177 Type *Ty;
178 Ty = parseType("i32", Error, M, &Mapping);
179 ASSERT_TRUE(Ty);
180 ASSERT_TRUE(Ty->isIntegerTy());
181 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
182
183 // Check we properly parse integer types with exotic size.
184 Ty = parseType("i13", Error, M, &Mapping);
185 ASSERT_TRUE(Ty);
186 ASSERT_TRUE(Ty->isIntegerTy());
187 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 13);
188
189 // Check we properly parse floating point types.
190 Ty = parseType("float", Error, M, &Mapping);
191 ASSERT_TRUE(Ty);
192 ASSERT_TRUE(Ty->isFloatTy());
193
194 Ty = parseType("double", Error, M, &Mapping);
195 ASSERT_TRUE(Ty);
196 ASSERT_TRUE(Ty->isDoubleTy());
197
198 // Check we properly parse struct types.
199 // Named struct.
200 Ty = parseType("%st", Error, M, &Mapping);
201 ASSERT_TRUE(Ty);
202 ASSERT_TRUE(Ty->isStructTy());
203
204 // Check the details of the struct.
205 StructType *ST = cast(Ty);
206 ASSERT_TRUE(ST->getNumElements() == 2);
207 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
208 Ty = ST->getElementType(i);
209 ASSERT_TRUE(Ty->isIntegerTy());
210 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
211 }
212
213 // Anonymous struct.
214 Ty = parseType("%0", Error, M, &Mapping);
215 ASSERT_TRUE(Ty);
216 ASSERT_TRUE(Ty->isStructTy());
217
218 // Check the details of the struct.
219 ST = cast(Ty);
220 ASSERT_TRUE(ST->getNumElements() == 4);
221 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
222 Ty = ST->getElementType(i);
223 ASSERT_TRUE(Ty->isIntegerTy());
224 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
225 }
226
227 // Check we properly parse vector types.
228 Ty = parseType("<5 x i32>", Error, M, &Mapping);
229 ASSERT_TRUE(Ty);
230 ASSERT_TRUE(Ty->isVectorTy());
231
232 // Check the details of the vector.
233 VectorType *VT = cast(Ty);
234 ASSERT_TRUE(VT->getNumElements() == 5);
235 ASSERT_TRUE(VT->getBitWidth() == 160);
236 Ty = VT->getElementType();
237 ASSERT_TRUE(Ty->isIntegerTy());
238 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
239
240 // Opaque struct.
241 Ty = parseType("%opaque", Error, M, &Mapping);
242 ASSERT_TRUE(Ty);
243 ASSERT_TRUE(Ty->isStructTy());
244
245 ST = cast(Ty);
246 ASSERT_TRUE(ST->isOpaque());
247
248 // Check we properly parse pointer types.
249 // One indirection.
250 Ty = parseType("i32*", Error, M, &Mapping);
251 ASSERT_TRUE(Ty);
252 ASSERT_TRUE(Ty->isPointerTy());
253
254 PointerType *PT = cast(Ty);
255 Ty = PT->getElementType();
256 ASSERT_TRUE(Ty->isIntegerTy());
257 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
258
259 // Two indirections.
260 Ty = parseType("i32**", Error, M, &Mapping);
261 ASSERT_TRUE(Ty);
262 ASSERT_TRUE(Ty->isPointerTy());
263
264 PT = cast(Ty);
265 Ty = PT->getElementType();
266 ASSERT_TRUE(Ty->isPointerTy());
267
268 PT = cast(Ty);
269 Ty = PT->getElementType();
270 ASSERT_TRUE(Ty->isIntegerTy());
271 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
272 }
273
154274 } // end anonymous namespace