Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / AsmParser / AsmParserTest.cpp
bloba70c061d3e30443f75803533fe91ab6335a091e3
1 //===- llvm/unittest/AsmParser/AsmParserTest.cpp - asm parser unittests ---===//
2 //
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
6 //
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/DataLayout.h"
14 #include "llvm/IR/DebugInfoMetadata.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/Support/Error.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include "gtest/gtest.h"
21 using namespace llvm;
23 namespace {
25 TEST(AsmParserTest, NullTerminatedInput) {
26 LLVMContext Ctx;
27 StringRef Source = "; Empty module \n";
28 SMDiagnostic Error;
29 auto Mod = parseAssemblyString(Source, Error, Ctx);
31 EXPECT_TRUE(Mod != nullptr);
32 EXPECT_TRUE(Error.getMessage().empty());
35 #ifdef GTEST_HAS_DEATH_TEST
36 #ifndef NDEBUG
38 TEST(AsmParserTest, NonNullTerminatedInput) {
39 LLVMContext Ctx;
40 StringRef Source = "; Empty module \n\1\2";
41 SMDiagnostic Error;
42 std::unique_ptr<Module> Mod;
43 EXPECT_DEATH(Mod = parseAssemblyString(Source.substr(0, Source.size() - 2),
44 Error, Ctx),
45 "Buffer is not null terminated!");
48 #endif
49 #endif
51 TEST(AsmParserTest, SlotMappingTest) {
52 LLVMContext Ctx;
53 StringRef Source = "@0 = global i32 0\n !0 = !{}\n !42 = !{i32 42}";
54 SMDiagnostic Error;
55 SlotMapping Mapping;
56 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
58 EXPECT_TRUE(Mod != nullptr);
59 EXPECT_TRUE(Error.getMessage().empty());
61 ASSERT_EQ(Mapping.GlobalValues.getNext(), 1u);
62 EXPECT_TRUE(isa<GlobalVariable>(Mapping.GlobalValues.get(0)));
64 EXPECT_EQ(Mapping.MetadataNodes.size(), 2u);
65 EXPECT_EQ(Mapping.MetadataNodes.count(0), 1u);
66 EXPECT_EQ(Mapping.MetadataNodes.count(42), 1u);
67 EXPECT_EQ(Mapping.MetadataNodes.count(1), 0u);
70 TEST(AsmParserTest, TypeAndConstantValueParsing) {
71 LLVMContext Ctx;
72 SMDiagnostic Error;
73 StringRef Source = "define void @test() {\n entry:\n ret void\n}";
74 auto Mod = parseAssemblyString(Source, Error, Ctx);
75 ASSERT_TRUE(Mod != nullptr);
76 auto &M = *Mod;
78 const Value *V;
79 V = parseConstantValue("double 3.5", Error, M);
80 ASSERT_TRUE(V);
81 EXPECT_TRUE(V->getType()->isDoubleTy());
82 ASSERT_TRUE(isa<ConstantFP>(V));
83 EXPECT_TRUE(cast<ConstantFP>(V)->isExactlyValue(3.5));
85 V = parseConstantValue("i32 42", Error, M);
86 ASSERT_TRUE(V);
87 EXPECT_TRUE(V->getType()->isIntegerTy());
88 ASSERT_TRUE(isa<ConstantInt>(V));
89 EXPECT_TRUE(cast<ConstantInt>(V)->equalsInt(42));
91 V = parseConstantValue("<4 x i32> <i32 0, i32 1, i32 2, i32 3>", Error, M);
92 ASSERT_TRUE(V);
93 EXPECT_TRUE(V->getType()->isVectorTy());
94 ASSERT_TRUE(isa<ConstantDataVector>(V));
96 V = parseConstantValue("i32 add (i32 1, i32 2)", Error, M);
97 ASSERT_TRUE(V);
98 ASSERT_TRUE(isa<ConstantInt>(V));
100 V = parseConstantValue("ptr blockaddress(@test, %entry)", Error, M);
101 ASSERT_TRUE(V);
102 ASSERT_TRUE(isa<BlockAddress>(V));
104 V = parseConstantValue("ptr undef", Error, M);
105 ASSERT_TRUE(V);
106 ASSERT_TRUE(isa<UndefValue>(V));
108 EXPECT_FALSE(parseConstantValue("duble 3.25", Error, M));
109 EXPECT_EQ(Error.getMessage(), "expected type");
111 EXPECT_FALSE(parseConstantValue("i32 3.25", Error, M));
112 EXPECT_EQ(Error.getMessage(), "floating point constant invalid for type");
114 EXPECT_FALSE(parseConstantValue("ptr @foo", Error, M));
115 EXPECT_EQ(Error.getMessage(), "expected a constant value");
117 EXPECT_FALSE(parseConstantValue("i32 3, ", Error, M));
118 EXPECT_EQ(Error.getMessage(), "expected end of string");
121 TEST(AsmParserTest, TypeAndConstantValueWithSlotMappingParsing) {
122 LLVMContext Ctx;
123 SMDiagnostic Error;
124 StringRef Source =
125 "%st = type { i32, i32 }\n"
126 "@v = common global [50 x %st] zeroinitializer, align 16\n"
127 "%0 = type { i32, i32, i32, i32 }\n"
128 "@g = common global [50 x %0] zeroinitializer, align 16\n"
129 "define void @marker4(i64 %d) {\n"
130 "entry:\n"
131 " %conv = trunc i64 %d to i32\n"
132 " store i32 %conv, ptr getelementptr inbounds "
133 " ([50 x %st], ptr @v, i64 0, i64 1, i32 0), align 16\n"
134 " store i32 %conv, ptr getelementptr inbounds "
135 " ([50 x %0], ptr @g, i64 0, i64 1, i32 0), align 16\n"
136 " ret void\n"
137 "}";
138 SlotMapping Mapping;
139 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
140 ASSERT_TRUE(Mod != nullptr);
141 auto &M = *Mod;
143 const Value *V;
144 V = parseConstantValue("ptr getelementptr inbounds ([50 x %st], ptr "
145 "@v, i64 0, i64 1, i32 0)",
146 Error, M, &Mapping);
147 ASSERT_TRUE(V);
148 ASSERT_TRUE(isa<ConstantExpr>(V));
150 V = parseConstantValue("ptr getelementptr inbounds ([50 x %0], ptr "
151 "@g, i64 0, i64 1, i32 0)",
152 Error, M, &Mapping);
153 ASSERT_TRUE(V);
154 ASSERT_TRUE(isa<ConstantExpr>(V));
157 TEST(AsmParserTest, TypeWithSlotMappingParsing) {
158 LLVMContext Ctx;
159 SMDiagnostic Error;
160 StringRef Source =
161 "%st = type { i32, i32 }\n"
162 "@v = common global [50 x %st] zeroinitializer, align 16\n"
163 "%0 = type { i32, i32, i32, i32 }\n"
164 "@g = common global [50 x %0] zeroinitializer, align 16\n"
165 "define void @marker4(i64 %d) {\n"
166 "entry:\n"
167 " %conv = trunc i64 %d to i32\n"
168 " store i32 %conv, ptr getelementptr inbounds "
169 " ([50 x %st], ptr @v, i64 0, i64 0, i32 0), align 16\n"
170 " store i32 %conv, ptr getelementptr inbounds "
171 " ([50 x %0], ptr @g, i64 0, i64 0, i32 0), align 16\n"
172 " ret void\n"
173 "}";
174 SlotMapping Mapping;
175 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
176 ASSERT_TRUE(Mod != nullptr);
177 auto &M = *Mod;
179 // Check we properly parse integer types.
180 Type *Ty;
181 Ty = parseType("i32", Error, M, &Mapping);
182 ASSERT_TRUE(Ty);
183 ASSERT_TRUE(Ty->isIntegerTy());
184 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
186 // Check we properly parse integer types with exotic size.
187 Ty = parseType("i13", Error, M, &Mapping);
188 ASSERT_TRUE(Ty);
189 ASSERT_TRUE(Ty->isIntegerTy());
190 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 13);
192 // Check we properly parse floating point types.
193 Ty = parseType("float", Error, M, &Mapping);
194 ASSERT_TRUE(Ty);
195 ASSERT_TRUE(Ty->isFloatTy());
197 Ty = parseType("double", Error, M, &Mapping);
198 ASSERT_TRUE(Ty);
199 ASSERT_TRUE(Ty->isDoubleTy());
201 // Check we properly parse struct types.
202 // Named struct.
203 Ty = parseType("%st", Error, M, &Mapping);
204 ASSERT_TRUE(Ty);
205 ASSERT_TRUE(Ty->isStructTy());
207 // Check the details of the struct.
208 StructType *ST = cast<StructType>(Ty);
209 ASSERT_TRUE(ST->getNumElements() == 2);
210 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
211 Ty = ST->getElementType(i);
212 ASSERT_TRUE(Ty->isIntegerTy());
213 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
216 // Anonymous struct.
217 Ty = parseType("%0", Error, M, &Mapping);
218 ASSERT_TRUE(Ty);
219 ASSERT_TRUE(Ty->isStructTy());
221 // Check the details of the struct.
222 ST = cast<StructType>(Ty);
223 ASSERT_TRUE(ST->getNumElements() == 4);
224 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
225 Ty = ST->getElementType(i);
226 ASSERT_TRUE(Ty->isIntegerTy());
227 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
230 // Check we properly parse vector types.
231 Ty = parseType("<5 x i32>", Error, M, &Mapping);
232 ASSERT_TRUE(Ty);
233 ASSERT_TRUE(Ty->isVectorTy());
235 // Check the details of the vector.
236 auto *VT = cast<FixedVectorType>(Ty);
237 ASSERT_TRUE(VT->getNumElements() == 5);
238 ASSERT_TRUE(VT->getPrimitiveSizeInBits().getFixedValue() == 160);
239 Ty = VT->getElementType();
240 ASSERT_TRUE(Ty->isIntegerTy());
241 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
243 // Opaque struct.
244 Ty = parseType("%opaque", Error, M, &Mapping);
245 ASSERT_TRUE(Ty);
246 ASSERT_TRUE(Ty->isStructTy());
248 ST = cast<StructType>(Ty);
249 ASSERT_TRUE(ST->isOpaque());
251 // Check we properly parse pointer types.
252 Ty = parseType("ptr", Error, M, &Mapping);
253 ASSERT_TRUE(Ty);
254 ASSERT_TRUE(Ty->isPointerTy());
256 // Check that we reject types with garbage.
257 Ty = parseType("i32 garbage", Error, M, &Mapping);
258 ASSERT_TRUE(!Ty);
261 TEST(AsmParserTest, TypeAtBeginningWithSlotMappingParsing) {
262 LLVMContext Ctx;
263 SMDiagnostic Error;
264 StringRef Source =
265 "%st = type { i32, i32 }\n"
266 "@v = common global [50 x %st] zeroinitializer, align 16\n"
267 "%0 = type { i32, i32, i32, i32 }\n"
268 "@g = common global [50 x %0] zeroinitializer, align 16\n"
269 "define void @marker4(i64 %d) {\n"
270 "entry:\n"
271 " %conv = trunc i64 %d to i32\n"
272 " store i32 %conv, ptr getelementptr inbounds "
273 " ([50 x %st], ptr @v, i64 0, i64 0, i32 0), align 16\n"
274 " store i32 %conv, ptr getelementptr inbounds "
275 " ([50 x %0], ptr @g, i64 0, i64 0, i32 0), align 16\n"
276 " ret void\n"
277 "}";
278 SlotMapping Mapping;
279 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
280 ASSERT_TRUE(Mod != nullptr);
281 auto &M = *Mod;
282 unsigned Read;
284 // Check we properly parse integer types.
285 Type *Ty;
286 Ty = parseTypeAtBeginning("i32", Read, Error, M, &Mapping);
287 ASSERT_TRUE(Ty);
288 ASSERT_TRUE(Ty->isIntegerTy());
289 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
290 ASSERT_TRUE(Read == 3);
292 // Check we properly parse integer types with exotic size.
293 Ty = parseTypeAtBeginning("i13", Read, Error, M, &Mapping);
294 ASSERT_TRUE(Ty);
295 ASSERT_TRUE(Ty->isIntegerTy());
296 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 13);
297 ASSERT_TRUE(Read == 3);
299 // Check we properly parse floating point types.
300 Ty = parseTypeAtBeginning("float", Read, Error, M, &Mapping);
301 ASSERT_TRUE(Ty);
302 ASSERT_TRUE(Ty->isFloatTy());
303 ASSERT_TRUE(Read == 5);
305 Ty = parseTypeAtBeginning("double", Read, Error, M, &Mapping);
306 ASSERT_TRUE(Ty);
307 ASSERT_TRUE(Ty->isDoubleTy());
308 ASSERT_TRUE(Read == 6);
310 // Check we properly parse struct types.
311 // Named struct.
312 Ty = parseTypeAtBeginning("%st", Read, Error, M, &Mapping);
313 ASSERT_TRUE(Ty);
314 ASSERT_TRUE(Ty->isStructTy());
315 ASSERT_TRUE(Read == 3);
317 // Check the details of the struct.
318 StructType *ST = cast<StructType>(Ty);
319 ASSERT_TRUE(ST->getNumElements() == 2);
320 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
321 Ty = ST->getElementType(i);
322 ASSERT_TRUE(Ty->isIntegerTy());
323 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
326 // Anonymous struct.
327 Ty = parseTypeAtBeginning("%0", Read, Error, M, &Mapping);
328 ASSERT_TRUE(Ty);
329 ASSERT_TRUE(Ty->isStructTy());
330 ASSERT_TRUE(Read == 2);
332 // Check the details of the struct.
333 ST = cast<StructType>(Ty);
334 ASSERT_TRUE(ST->getNumElements() == 4);
335 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
336 Ty = ST->getElementType(i);
337 ASSERT_TRUE(Ty->isIntegerTy());
338 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
341 // Check we properly parse vector types.
342 Ty = parseTypeAtBeginning("<5 x i32>", Read, Error, M, &Mapping);
343 ASSERT_TRUE(Ty);
344 ASSERT_TRUE(Ty->isVectorTy());
345 ASSERT_TRUE(Read == 9);
347 // Check the details of the vector.
348 auto *VT = cast<FixedVectorType>(Ty);
349 ASSERT_TRUE(VT->getNumElements() == 5);
350 ASSERT_TRUE(VT->getPrimitiveSizeInBits().getFixedValue() == 160);
351 Ty = VT->getElementType();
352 ASSERT_TRUE(Ty->isIntegerTy());
353 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
355 // Opaque struct.
356 Ty = parseTypeAtBeginning("%opaque", Read, Error, M, &Mapping);
357 ASSERT_TRUE(Ty);
358 ASSERT_TRUE(Ty->isStructTy());
359 ASSERT_TRUE(Read == 7);
361 ST = cast<StructType>(Ty);
362 ASSERT_TRUE(ST->isOpaque());
364 // Check we properly parse pointer types.
365 // One indirection.
366 Ty = parseTypeAtBeginning("ptr", Read, Error, M, &Mapping);
367 ASSERT_TRUE(Ty);
368 ASSERT_TRUE(Ty->isPointerTy());
369 ASSERT_TRUE(Read == 3);
371 // Check that we reject types with garbage.
372 Ty = parseTypeAtBeginning("i32 garbage", Read, Error, M, &Mapping);
373 ASSERT_TRUE(Ty);
374 ASSERT_TRUE(Ty->isIntegerTy());
375 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
376 // We go to the next token, i.e., we read "i32" + ' '.
377 ASSERT_TRUE(Read == 4);
380 TEST(AsmParserTest, InvalidDataLayoutStringCallback) {
381 LLVMContext Ctx;
382 SMDiagnostic Error;
383 // Note the invalid i8:7 part
384 // Overalign i32 as marker so we can check that indeed this DL was used,
385 // and not some default.
386 StringRef InvalidDLStr =
387 "e-m:e-p:64:64-i8:7-i16:16-i32:64-i64:64-f80:128-n8:16:32:64";
388 StringRef FixedDLStr =
389 "e-m:e-p:64:64-i8:8-i16:16-i32:64-i64:64-f80:128-n8:16:32:64";
390 Expected<DataLayout> ExpectedFixedDL = DataLayout::parse(FixedDLStr);
391 ASSERT_TRUE(!ExpectedFixedDL.takeError());
392 DataLayout FixedDL = ExpectedFixedDL.get();
393 std::string Source = ("target datalayout = \"" + InvalidDLStr + "\"\n").str();
394 MemoryBufferRef SourceBuffer(Source, "<string>");
396 // Check that we reject the source without a DL override.
397 SlotMapping Mapping1;
398 auto Mod1 = parseAssembly(SourceBuffer, Error, Ctx, &Mapping1);
399 EXPECT_TRUE(Mod1 == nullptr);
401 // Check that we pass the correct DL str to the callback,
402 // that fixing the DL str from the callback works,
403 // and that the resulting module has the correct DL.
404 SlotMapping Mapping2;
405 auto Mod2 = parseAssembly(
406 SourceBuffer, Error, Ctx, &Mapping2,
407 [&](StringRef Triple, StringRef DLStr) -> std::optional<std::string> {
408 EXPECT_EQ(DLStr, InvalidDLStr);
409 return std::string{FixedDLStr};
411 ASSERT_TRUE(Mod2 != nullptr);
412 EXPECT_EQ(Mod2->getDataLayout(), FixedDL);
415 TEST(AsmParserTest, DIExpressionBodyAtBeginningWithSlotMappingParsing) {
416 LLVMContext Ctx;
417 SMDiagnostic Error;
418 StringRef Source = "";
419 SlotMapping Mapping;
420 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
421 ASSERT_TRUE(Mod != nullptr);
422 auto &M = *Mod;
423 unsigned Read;
425 ASSERT_EQ(Mapping.MetadataNodes.size(), 0u);
427 DIExpression *Expr;
429 Expr = parseDIExpressionBodyAtBeginning("()", Read, Error, M, &Mapping);
430 ASSERT_TRUE(Expr);
431 ASSERT_EQ(Expr->getNumElements(), 0u);
433 Expr = parseDIExpressionBodyAtBeginning("(0)", Read, Error, M, &Mapping);
434 ASSERT_TRUE(Expr);
435 ASSERT_EQ(Expr->getNumElements(), 1u);
437 Expr = parseDIExpressionBodyAtBeginning("(DW_OP_LLVM_fragment, 0, 1)", Read,
438 Error, M, &Mapping);
439 ASSERT_TRUE(Expr);
440 ASSERT_EQ(Expr->getNumElements(), 3u);
442 Expr = parseDIExpressionBodyAtBeginning(
443 "(DW_OP_LLVM_fragment, 0, 1) trailing source", Read, Error, M, &Mapping);
444 ASSERT_TRUE(Expr);
445 ASSERT_EQ(Expr->getNumElements(), 3u);
446 ASSERT_EQ(Read, StringRef("(DW_OP_LLVM_fragment, 0, 1) ").size());
448 Error = {};
449 Expr = parseDIExpressionBodyAtBeginning("i32", Read, Error, M, &Mapping);
450 ASSERT_FALSE(Expr);
451 ASSERT_EQ(Error.getMessage(), "expected '(' here");
453 Error = {};
454 Expr = parseDIExpressionBodyAtBeginning(
455 "!DIExpression(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping);
456 ASSERT_FALSE(Expr);
457 ASSERT_EQ(Error.getMessage(), "expected '(' here");
459 ASSERT_EQ(Mapping.MetadataNodes.size(), 0u);
462 } // end anonymous namespace