1 //===- llvm/unittest/AsmParser/AsmParserTest.cpp - asm parser unittests ---===//
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 #include "llvm/ADT/StringRef.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/AsmParser/SlotMapping.h"
12 #include "llvm/IR/Constants.h"
13 #include "llvm/IR/LLVMContext.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/Support/SourceMgr.h"
16 #include "gtest/gtest.h"
22 TEST(AsmParserTest
, NullTerminatedInput
) {
24 StringRef Source
= "; Empty module \n";
26 auto Mod
= parseAssemblyString(Source
, Error
, Ctx
);
28 EXPECT_TRUE(Mod
!= nullptr);
29 EXPECT_TRUE(Error
.getMessage().empty());
32 #ifdef GTEST_HAS_DEATH_TEST
35 TEST(AsmParserTest
, NonNullTerminatedInput
) {
37 StringRef Source
= "; Empty module \n\1\2";
39 std::unique_ptr
<Module
> Mod
;
40 EXPECT_DEATH(Mod
= parseAssemblyString(Source
.substr(0, Source
.size() - 2),
42 "Buffer is not null terminated!");
48 TEST(AsmParserTest
, SlotMappingTest
) {
50 StringRef Source
= "@0 = global i32 0\n !0 = !{}\n !42 = !{i32 42}";
53 auto Mod
= parseAssemblyString(Source
, Error
, Ctx
, &Mapping
);
55 EXPECT_TRUE(Mod
!= nullptr);
56 EXPECT_TRUE(Error
.getMessage().empty());
58 ASSERT_EQ(Mapping
.GlobalValues
.size(), 1u);
59 EXPECT_TRUE(isa
<GlobalVariable
>(Mapping
.GlobalValues
[0]));
61 EXPECT_EQ(Mapping
.MetadataNodes
.size(), 2u);
62 EXPECT_EQ(Mapping
.MetadataNodes
.count(0), 1u);
63 EXPECT_EQ(Mapping
.MetadataNodes
.count(42), 1u);
64 EXPECT_EQ(Mapping
.MetadataNodes
.count(1), 0u);
67 TEST(AsmParserTest
, TypeAndConstantValueParsing
) {
70 StringRef Source
= "define void @test() {\n entry:\n ret void\n}";
71 auto Mod
= parseAssemblyString(Source
, Error
, Ctx
);
72 ASSERT_TRUE(Mod
!= nullptr);
76 V
= parseConstantValue("double 3.5", Error
, M
);
78 EXPECT_TRUE(V
->getType()->isDoubleTy());
79 ASSERT_TRUE(isa
<ConstantFP
>(V
));
80 EXPECT_TRUE(cast
<ConstantFP
>(V
)->isExactlyValue(3.5));
82 V
= parseConstantValue("i32 42", Error
, M
);
84 EXPECT_TRUE(V
->getType()->isIntegerTy());
85 ASSERT_TRUE(isa
<ConstantInt
>(V
));
86 EXPECT_TRUE(cast
<ConstantInt
>(V
)->equalsInt(42));
88 V
= parseConstantValue("<4 x i32> <i32 0, i32 1, i32 2, i32 3>", Error
, M
);
90 EXPECT_TRUE(V
->getType()->isVectorTy());
91 ASSERT_TRUE(isa
<ConstantDataVector
>(V
));
93 V
= parseConstantValue("i32 add (i32 1, i32 2)", Error
, M
);
95 ASSERT_TRUE(isa
<ConstantInt
>(V
));
97 V
= parseConstantValue("i8* blockaddress(@test, %entry)", Error
, M
);
99 ASSERT_TRUE(isa
<BlockAddress
>(V
));
101 V
= parseConstantValue("i8** undef", Error
, M
);
103 ASSERT_TRUE(isa
<UndefValue
>(V
));
105 EXPECT_FALSE(parseConstantValue("duble 3.25", Error
, M
));
106 EXPECT_EQ(Error
.getMessage(), "expected type");
108 EXPECT_FALSE(parseConstantValue("i32 3.25", Error
, M
));
109 EXPECT_EQ(Error
.getMessage(), "floating point constant invalid for type");
111 EXPECT_FALSE(parseConstantValue("i32* @foo", Error
, M
));
112 EXPECT_EQ(Error
.getMessage(), "expected a constant value");
114 EXPECT_FALSE(parseConstantValue("i32 3, ", Error
, M
));
115 EXPECT_EQ(Error
.getMessage(), "expected end of string");
118 TEST(AsmParserTest
, TypeAndConstantValueWithSlotMappingParsing
) {
122 "%st = type { i32, i32 }\n"
123 "@v = common global [50 x %st] zeroinitializer, align 16\n"
124 "%0 = type { i32, i32, i32, i32 }\n"
125 "@g = common global [50 x %0] zeroinitializer, align 16\n"
126 "define void @marker4(i64 %d) {\n"
128 " %conv = trunc i64 %d to i32\n"
129 " store i32 %conv, i32* getelementptr inbounds "
130 " ([50 x %st], [50 x %st]* @v, i64 0, i64 0, i32 0), align 16\n"
131 " store i32 %conv, i32* getelementptr inbounds "
132 " ([50 x %0], [50 x %0]* @g, i64 0, i64 0, i32 0), align 16\n"
136 auto Mod
= parseAssemblyString(Source
, Error
, Ctx
, &Mapping
);
137 ASSERT_TRUE(Mod
!= nullptr);
141 V
= parseConstantValue("i32* getelementptr inbounds ([50 x %st], [50 x %st]* "
142 "@v, i64 0, i64 0, i32 0)",
145 ASSERT_TRUE(isa
<ConstantExpr
>(V
));
147 V
= parseConstantValue("i32* getelementptr inbounds ([50 x %0], [50 x %0]* "
148 "@g, i64 0, i64 0, i32 0)",
151 ASSERT_TRUE(isa
<ConstantExpr
>(V
));
154 TEST(AsmParserTest
, TypeWithSlotMappingParsing
) {
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"
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"
172 auto Mod
= parseAssemblyString(Source
, Error
, Ctx
, &Mapping
);
173 ASSERT_TRUE(Mod
!= nullptr);
176 // Check we properly parse integer types.
178 Ty
= parseType("i32", Error
, M
, &Mapping
);
180 ASSERT_TRUE(Ty
->isIntegerTy());
181 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 32);
183 // Check we properly parse integer types with exotic size.
184 Ty
= parseType("i13", Error
, M
, &Mapping
);
186 ASSERT_TRUE(Ty
->isIntegerTy());
187 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 13);
189 // Check we properly parse floating point types.
190 Ty
= parseType("float", Error
, M
, &Mapping
);
192 ASSERT_TRUE(Ty
->isFloatTy());
194 Ty
= parseType("double", Error
, M
, &Mapping
);
196 ASSERT_TRUE(Ty
->isDoubleTy());
198 // Check we properly parse struct types.
200 Ty
= parseType("%st", Error
, M
, &Mapping
);
202 ASSERT_TRUE(Ty
->isStructTy());
204 // Check the details of the struct.
205 StructType
*ST
= cast
<StructType
>(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);
214 Ty
= parseType("%0", Error
, M
, &Mapping
);
216 ASSERT_TRUE(Ty
->isStructTy());
218 // Check the details of the struct.
219 ST
= cast
<StructType
>(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);
227 // Check we properly parse vector types.
228 Ty
= parseType("<5 x i32>", Error
, M
, &Mapping
);
230 ASSERT_TRUE(Ty
->isVectorTy());
232 // Check the details of the vector.
233 VectorType
*VT
= cast
<VectorType
>(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);
241 Ty
= parseType("%opaque", Error
, M
, &Mapping
);
243 ASSERT_TRUE(Ty
->isStructTy());
245 ST
= cast
<StructType
>(Ty
);
246 ASSERT_TRUE(ST
->isOpaque());
248 // Check we properly parse pointer types.
250 Ty
= parseType("i32*", Error
, M
, &Mapping
);
252 ASSERT_TRUE(Ty
->isPointerTy());
254 PointerType
*PT
= cast
<PointerType
>(Ty
);
255 Ty
= PT
->getElementType();
256 ASSERT_TRUE(Ty
->isIntegerTy());
257 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 32);
260 Ty
= parseType("i32**", Error
, M
, &Mapping
);
262 ASSERT_TRUE(Ty
->isPointerTy());
264 PT
= cast
<PointerType
>(Ty
);
265 Ty
= PT
->getElementType();
266 ASSERT_TRUE(Ty
->isPointerTy());
268 PT
= cast
<PointerType
>(Ty
);
269 Ty
= PT
->getElementType();
270 ASSERT_TRUE(Ty
->isIntegerTy());
271 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 32);
273 // Check that we reject types with garbage.
274 Ty
= parseType("i32 garbage", Error
, M
, &Mapping
);
278 TEST(AsmParserTest
, TypeAtBeginningWithSlotMappingParsing
) {
282 "%st = type { i32, i32 }\n"
283 "@v = common global [50 x %st] zeroinitializer, align 16\n"
284 "%0 = type { i32, i32, i32, i32 }\n"
285 "@g = common global [50 x %0] zeroinitializer, align 16\n"
286 "define void @marker4(i64 %d) {\n"
288 " %conv = trunc i64 %d to i32\n"
289 " store i32 %conv, i32* getelementptr inbounds "
290 " ([50 x %st], [50 x %st]* @v, i64 0, i64 0, i32 0), align 16\n"
291 " store i32 %conv, i32* getelementptr inbounds "
292 " ([50 x %0], [50 x %0]* @g, i64 0, i64 0, i32 0), align 16\n"
296 auto Mod
= parseAssemblyString(Source
, Error
, Ctx
, &Mapping
);
297 ASSERT_TRUE(Mod
!= nullptr);
301 // Check we properly parse integer types.
303 Ty
= parseTypeAtBeginning("i32", Read
, Error
, M
, &Mapping
);
305 ASSERT_TRUE(Ty
->isIntegerTy());
306 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 32);
307 ASSERT_TRUE(Read
== 3);
309 // Check we properly parse integer types with exotic size.
310 Ty
= parseTypeAtBeginning("i13", Read
, Error
, M
, &Mapping
);
312 ASSERT_TRUE(Ty
->isIntegerTy());
313 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 13);
314 ASSERT_TRUE(Read
== 3);
316 // Check we properly parse floating point types.
317 Ty
= parseTypeAtBeginning("float", Read
, Error
, M
, &Mapping
);
319 ASSERT_TRUE(Ty
->isFloatTy());
320 ASSERT_TRUE(Read
== 5);
322 Ty
= parseTypeAtBeginning("double", Read
, Error
, M
, &Mapping
);
324 ASSERT_TRUE(Ty
->isDoubleTy());
325 ASSERT_TRUE(Read
== 6);
327 // Check we properly parse struct types.
329 Ty
= parseTypeAtBeginning("%st", Read
, Error
, M
, &Mapping
);
331 ASSERT_TRUE(Ty
->isStructTy());
332 ASSERT_TRUE(Read
== 3);
334 // Check the details of the struct.
335 StructType
*ST
= cast
<StructType
>(Ty
);
336 ASSERT_TRUE(ST
->getNumElements() == 2);
337 for (unsigned i
= 0, e
= ST
->getNumElements(); i
!= e
; ++i
) {
338 Ty
= ST
->getElementType(i
);
339 ASSERT_TRUE(Ty
->isIntegerTy());
340 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 32);
344 Ty
= parseTypeAtBeginning("%0", Read
, Error
, M
, &Mapping
);
346 ASSERT_TRUE(Ty
->isStructTy());
347 ASSERT_TRUE(Read
== 2);
349 // Check the details of the struct.
350 ST
= cast
<StructType
>(Ty
);
351 ASSERT_TRUE(ST
->getNumElements() == 4);
352 for (unsigned i
= 0, e
= ST
->getNumElements(); i
!= e
; ++i
) {
353 Ty
= ST
->getElementType(i
);
354 ASSERT_TRUE(Ty
->isIntegerTy());
355 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 32);
358 // Check we properly parse vector types.
359 Ty
= parseTypeAtBeginning("<5 x i32>", Read
, Error
, M
, &Mapping
);
361 ASSERT_TRUE(Ty
->isVectorTy());
362 ASSERT_TRUE(Read
== 9);
364 // Check the details of the vector.
365 VectorType
*VT
= cast
<VectorType
>(Ty
);
366 ASSERT_TRUE(VT
->getNumElements() == 5);
367 ASSERT_TRUE(VT
->getBitWidth() == 160);
368 Ty
= VT
->getElementType();
369 ASSERT_TRUE(Ty
->isIntegerTy());
370 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 32);
373 Ty
= parseTypeAtBeginning("%opaque", Read
, Error
, M
, &Mapping
);
375 ASSERT_TRUE(Ty
->isStructTy());
376 ASSERT_TRUE(Read
== 7);
378 ST
= cast
<StructType
>(Ty
);
379 ASSERT_TRUE(ST
->isOpaque());
381 // Check we properly parse pointer types.
383 Ty
= parseTypeAtBeginning("i32*", Read
, Error
, M
, &Mapping
);
385 ASSERT_TRUE(Ty
->isPointerTy());
386 ASSERT_TRUE(Read
== 4);
388 PointerType
*PT
= cast
<PointerType
>(Ty
);
389 Ty
= PT
->getElementType();
390 ASSERT_TRUE(Ty
->isIntegerTy());
391 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 32);
394 Ty
= parseTypeAtBeginning("i32**", Read
, Error
, M
, &Mapping
);
396 ASSERT_TRUE(Ty
->isPointerTy());
397 ASSERT_TRUE(Read
== 5);
399 PT
= cast
<PointerType
>(Ty
);
400 Ty
= PT
->getElementType();
401 ASSERT_TRUE(Ty
->isPointerTy());
403 PT
= cast
<PointerType
>(Ty
);
404 Ty
= PT
->getElementType();
405 ASSERT_TRUE(Ty
->isIntegerTy());
406 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 32);
408 // Check that we reject types with garbage.
409 Ty
= parseTypeAtBeginning("i32 garbage", Read
, Error
, M
, &Mapping
);
411 ASSERT_TRUE(Ty
->isIntegerTy());
412 ASSERT_TRUE(Ty
->getPrimitiveSizeInBits() == 32);
413 // We go to the next token, i.e., we read "i32" + ' '.
414 ASSERT_TRUE(Read
== 4);
417 } // end anonymous namespace