1 //===- llvm/unittest/AsmParser/AsmParserTest.cpp - asm parser unittests ---===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/StringRef.h" 11 #include "llvm/AsmParser/Parser.h" 12 #include "llvm/AsmParser/SlotMapping.h" 13 #include "llvm/IR/Constants.h" 14 #include "llvm/IR/LLVMContext.h" 15 #include "llvm/IR/Module.h" 16 #include "llvm/Support/SourceMgr.h" 17 #include "gtest/gtest.h" 18 19 using namespace llvm; 20 21 namespace { 22 23 TEST(AsmParserTest, NullTerminatedInput) { 24 LLVMContext Ctx; 25 StringRef Source = "; Empty module \n"; 26 SMDiagnostic Error; 27 auto Mod = parseAssemblyString(Source, Error, Ctx); 28 29 EXPECT_TRUE(Mod != nullptr); 30 EXPECT_TRUE(Error.getMessage().empty()); 31 } 32 33 #ifdef GTEST_HAS_DEATH_TEST 34 #ifndef NDEBUG 35 36 TEST(AsmParserTest, NonNullTerminatedInput) { 37 LLVMContext Ctx; 38 StringRef Source = "; Empty module \n\1\2"; 39 SMDiagnostic Error; 40 std::unique_ptr<Module> Mod; 41 EXPECT_DEATH(Mod = parseAssemblyString(Source.substr(0, Source.size() - 2), 42 Error, Ctx), 43 "Buffer is not null terminated!"); 44 } 45 46 #endif 47 #endif 48 49 TEST(AsmParserTest, SlotMappingTest) { 50 LLVMContext Ctx; 51 StringRef Source = "@0 = global i32 0\n !0 = !{}\n !42 = !{i32 42}"; 52 SMDiagnostic Error; 53 SlotMapping Mapping; 54 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping); 55 56 EXPECT_TRUE(Mod != nullptr); 57 EXPECT_TRUE(Error.getMessage().empty()); 58 59 ASSERT_EQ(Mapping.GlobalValues.size(), 1u); 60 EXPECT_TRUE(isa<GlobalVariable>(Mapping.GlobalValues[0])); 61 62 EXPECT_EQ(Mapping.MetadataNodes.size(), 2u); 63 EXPECT_EQ(Mapping.MetadataNodes.count(0), 1u); 64 EXPECT_EQ(Mapping.MetadataNodes.count(42), 1u); 65 EXPECT_EQ(Mapping.MetadataNodes.count(1), 0u); 66 } 67 68 TEST(AsmParserTest, TypeAndConstantValueParsing) { 69 LLVMContext Ctx; 70 SMDiagnostic Error; 71 StringRef Source = "define void @test() {\n entry:\n ret void\n}"; 72 auto Mod = parseAssemblyString(Source, Error, Ctx); 73 ASSERT_TRUE(Mod != nullptr); 74 auto &M = *Mod; 75 76 const Value *V; 77 V = parseConstantValue("double 3.5", Error, M); 78 ASSERT_TRUE(V); 79 EXPECT_TRUE(V->getType()->isDoubleTy()); 80 ASSERT_TRUE(isa<ConstantFP>(V)); 81 EXPECT_TRUE(cast<ConstantFP>(V)->isExactlyValue(3.5)); 82 83 V = parseConstantValue("i32 42", Error, M); 84 ASSERT_TRUE(V); 85 EXPECT_TRUE(V->getType()->isIntegerTy()); 86 ASSERT_TRUE(isa<ConstantInt>(V)); 87 EXPECT_TRUE(cast<ConstantInt>(V)->equalsInt(42)); 88 89 V = parseConstantValue("<4 x i32> <i32 0, i32 1, i32 2, i32 3>", Error, M); 90 ASSERT_TRUE(V); 91 EXPECT_TRUE(V->getType()->isVectorTy()); 92 ASSERT_TRUE(isa<ConstantDataVector>(V)); 93 94 V = parseConstantValue("i32 add (i32 1, i32 2)", Error, M); 95 ASSERT_TRUE(V); 96 ASSERT_TRUE(isa<ConstantInt>(V)); 97 98 V = parseConstantValue("i8* blockaddress(@test, %entry)", Error, M); 99 ASSERT_TRUE(V); 100 ASSERT_TRUE(isa<BlockAddress>(V)); 101 102 V = parseConstantValue("i8** undef", Error, M); 103 ASSERT_TRUE(V); 104 ASSERT_TRUE(isa<UndefValue>(V)); 105 106 EXPECT_FALSE(parseConstantValue("duble 3.25", Error, M)); 107 EXPECT_EQ(Error.getMessage(), "expected type"); 108 109 EXPECT_FALSE(parseConstantValue("i32 3.25", Error, M)); 110 EXPECT_EQ(Error.getMessage(), "floating point constant invalid for type"); 111 112 EXPECT_FALSE(parseConstantValue("i32* @foo", Error, M)); 113 EXPECT_EQ(Error.getMessage(), "expected a constant value"); 114 115 EXPECT_FALSE(parseConstantValue("i32 3, ", Error, M)); 116 EXPECT_EQ(Error.getMessage(), "expected end of string"); 117 } 118 119 TEST(AsmParserTest, TypeAndConstantValueWithSlotMappingParsing) { 120 LLVMContext Ctx; 121 SMDiagnostic Error; 122 StringRef Source = 123 "%st = type { i32, i32 }\n" 124 "@v = common global [50 x %st] zeroinitializer, align 16\n" 125 "%0 = type { i32, i32, i32, i32 }\n" 126 "@g = common global [50 x %0] zeroinitializer, align 16\n" 127 "define void @marker4(i64 %d) {\n" 128 "entry:\n" 129 " %conv = trunc i64 %d to i32\n" 130 " store i32 %conv, i32* getelementptr inbounds " 131 " ([50 x %st], [50 x %st]* @v, i64 0, i64 0, i32 0), align 16\n" 132 " store i32 %conv, i32* getelementptr inbounds " 133 " ([50 x %0], [50 x %0]* @g, i64 0, i64 0, i32 0), align 16\n" 134 " ret void\n" 135 "}"; 136 SlotMapping Mapping; 137 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping); 138 ASSERT_TRUE(Mod != nullptr); 139 auto &M = *Mod; 140 141 const Value *V; 142 V = parseConstantValue("i32* getelementptr inbounds ([50 x %st], [50 x %st]* " 143 "@v, i64 0, i64 0, i32 0)", 144 Error, M, &Mapping); 145 ASSERT_TRUE(V); 146 ASSERT_TRUE(isa<ConstantExpr>(V)); 147 148 V = parseConstantValue("i32* getelementptr inbounds ([50 x %0], [50 x %0]* " 149 "@g, i64 0, i64 0, i32 0)", 150 Error, M, &Mapping); 151 ASSERT_TRUE(V); 152 ASSERT_TRUE(isa<ConstantExpr>(V)); 153 } 154 155 TEST(AsmParserTest, TypeWithSlotMappingParsing) { 156 LLVMContext Ctx; 157 SMDiagnostic Error; 158 StringRef Source = 159 "%st = type { i32, i32 }\n" 160 "@v = common global [50 x %st] zeroinitializer, align 16\n" 161 "%0 = type { i32, i32, i32, i32 }\n" 162 "@g = common global [50 x %0] zeroinitializer, align 16\n" 163 "define void @marker4(i64 %d) {\n" 164 "entry:\n" 165 " %conv = trunc i64 %d to i32\n" 166 " store i32 %conv, i32* getelementptr inbounds " 167 " ([50 x %st], [50 x %st]* @v, i64 0, i64 0, i32 0), align 16\n" 168 " store i32 %conv, i32* getelementptr inbounds " 169 " ([50 x %0], [50 x %0]* @g, i64 0, i64 0, i32 0), align 16\n" 170 " ret void\n" 171 "}"; 172 SlotMapping Mapping; 173 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping); 174 ASSERT_TRUE(Mod != nullptr); 175 auto &M = *Mod; 176 177 // Check we properly parse integer types. 178 Type *Ty; 179 Ty = parseType("i32", Error, M, &Mapping); 180 ASSERT_TRUE(Ty); 181 ASSERT_TRUE(Ty->isIntegerTy()); 182 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 183 184 // Check we properly parse integer types with exotic size. 185 Ty = parseType("i13", Error, M, &Mapping); 186 ASSERT_TRUE(Ty); 187 ASSERT_TRUE(Ty->isIntegerTy()); 188 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 13); 189 190 // Check we properly parse floating point types. 191 Ty = parseType("float", Error, M, &Mapping); 192 ASSERT_TRUE(Ty); 193 ASSERT_TRUE(Ty->isFloatTy()); 194 195 Ty = parseType("double", Error, M, &Mapping); 196 ASSERT_TRUE(Ty); 197 ASSERT_TRUE(Ty->isDoubleTy()); 198 199 // Check we properly parse struct types. 200 // Named struct. 201 Ty = parseType("%st", Error, M, &Mapping); 202 ASSERT_TRUE(Ty); 203 ASSERT_TRUE(Ty->isStructTy()); 204 205 // Check the details of the struct. 206 StructType *ST = cast<StructType>(Ty); 207 ASSERT_TRUE(ST->getNumElements() == 2); 208 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) { 209 Ty = ST->getElementType(i); 210 ASSERT_TRUE(Ty->isIntegerTy()); 211 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 212 } 213 214 // Anonymous struct. 215 Ty = parseType("%0", Error, M, &Mapping); 216 ASSERT_TRUE(Ty); 217 ASSERT_TRUE(Ty->isStructTy()); 218 219 // Check the details of the struct. 220 ST = cast<StructType>(Ty); 221 ASSERT_TRUE(ST->getNumElements() == 4); 222 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) { 223 Ty = ST->getElementType(i); 224 ASSERT_TRUE(Ty->isIntegerTy()); 225 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 226 } 227 228 // Check we properly parse vector types. 229 Ty = parseType("<5 x i32>", Error, M, &Mapping); 230 ASSERT_TRUE(Ty); 231 ASSERT_TRUE(Ty->isVectorTy()); 232 233 // Check the details of the vector. 234 VectorType *VT = cast<VectorType>(Ty); 235 ASSERT_TRUE(VT->getNumElements() == 5); 236 ASSERT_TRUE(VT->getBitWidth() == 160); 237 Ty = VT->getElementType(); 238 ASSERT_TRUE(Ty->isIntegerTy()); 239 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 240 241 // Opaque struct. 242 Ty = parseType("%opaque", Error, M, &Mapping); 243 ASSERT_TRUE(Ty); 244 ASSERT_TRUE(Ty->isStructTy()); 245 246 ST = cast<StructType>(Ty); 247 ASSERT_TRUE(ST->isOpaque()); 248 249 // Check we properly parse pointer types. 250 // One indirection. 251 Ty = parseType("i32*", Error, M, &Mapping); 252 ASSERT_TRUE(Ty); 253 ASSERT_TRUE(Ty->isPointerTy()); 254 255 PointerType *PT = cast<PointerType>(Ty); 256 Ty = PT->getElementType(); 257 ASSERT_TRUE(Ty->isIntegerTy()); 258 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 259 260 // Two indirections. 261 Ty = parseType("i32**", Error, M, &Mapping); 262 ASSERT_TRUE(Ty); 263 ASSERT_TRUE(Ty->isPointerTy()); 264 265 PT = cast<PointerType>(Ty); 266 Ty = PT->getElementType(); 267 ASSERT_TRUE(Ty->isPointerTy()); 268 269 PT = cast<PointerType>(Ty); 270 Ty = PT->getElementType(); 271 ASSERT_TRUE(Ty->isIntegerTy()); 272 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 273 274 // Check that we reject types with garbage. 275 Ty = parseType("i32 garbage", Error, M, &Mapping); 276 ASSERT_TRUE(!Ty); 277 } 278 279 TEST(AsmParserTest, TypeAtBeginningWithSlotMappingParsing) { 280 LLVMContext Ctx; 281 SMDiagnostic Error; 282 StringRef Source = 283 "%st = type { i32, i32 }\n" 284 "@v = common global [50 x %st] zeroinitializer, align 16\n" 285 "%0 = type { i32, i32, i32, i32 }\n" 286 "@g = common global [50 x %0] zeroinitializer, align 16\n" 287 "define void @marker4(i64 %d) {\n" 288 "entry:\n" 289 " %conv = trunc i64 %d to i32\n" 290 " store i32 %conv, i32* getelementptr inbounds " 291 " ([50 x %st], [50 x %st]* @v, i64 0, i64 0, i32 0), align 16\n" 292 " store i32 %conv, i32* getelementptr inbounds " 293 " ([50 x %0], [50 x %0]* @g, i64 0, i64 0, i32 0), align 16\n" 294 " ret void\n" 295 "}"; 296 SlotMapping Mapping; 297 auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping); 298 ASSERT_TRUE(Mod != nullptr); 299 auto &M = *Mod; 300 unsigned Read; 301 302 // Check we properly parse integer types. 303 Type *Ty; 304 Ty = parseTypeAtBeginning("i32", Read, Error, M, &Mapping); 305 ASSERT_TRUE(Ty); 306 ASSERT_TRUE(Ty->isIntegerTy()); 307 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 308 ASSERT_TRUE(Read == 3); 309 310 // Check we properly parse integer types with exotic size. 311 Ty = parseTypeAtBeginning("i13", Read, Error, M, &Mapping); 312 ASSERT_TRUE(Ty); 313 ASSERT_TRUE(Ty->isIntegerTy()); 314 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 13); 315 ASSERT_TRUE(Read == 3); 316 317 // Check we properly parse floating point types. 318 Ty = parseTypeAtBeginning("float", Read, Error, M, &Mapping); 319 ASSERT_TRUE(Ty); 320 ASSERT_TRUE(Ty->isFloatTy()); 321 ASSERT_TRUE(Read == 5); 322 323 Ty = parseTypeAtBeginning("double", Read, Error, M, &Mapping); 324 ASSERT_TRUE(Ty); 325 ASSERT_TRUE(Ty->isDoubleTy()); 326 ASSERT_TRUE(Read == 6); 327 328 // Check we properly parse struct types. 329 // Named struct. 330 Ty = parseTypeAtBeginning("%st", Read, Error, M, &Mapping); 331 ASSERT_TRUE(Ty); 332 ASSERT_TRUE(Ty->isStructTy()); 333 ASSERT_TRUE(Read == 3); 334 335 // Check the details of the struct. 336 StructType *ST = cast<StructType>(Ty); 337 ASSERT_TRUE(ST->getNumElements() == 2); 338 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) { 339 Ty = ST->getElementType(i); 340 ASSERT_TRUE(Ty->isIntegerTy()); 341 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 342 } 343 344 // Anonymous struct. 345 Ty = parseTypeAtBeginning("%0", Read, Error, M, &Mapping); 346 ASSERT_TRUE(Ty); 347 ASSERT_TRUE(Ty->isStructTy()); 348 ASSERT_TRUE(Read == 2); 349 350 // Check the details of the struct. 351 ST = cast<StructType>(Ty); 352 ASSERT_TRUE(ST->getNumElements() == 4); 353 for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) { 354 Ty = ST->getElementType(i); 355 ASSERT_TRUE(Ty->isIntegerTy()); 356 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 357 } 358 359 // Check we properly parse vector types. 360 Ty = parseTypeAtBeginning("<5 x i32>", Read, Error, M, &Mapping); 361 ASSERT_TRUE(Ty); 362 ASSERT_TRUE(Ty->isVectorTy()); 363 ASSERT_TRUE(Read == 9); 364 365 // Check the details of the vector. 366 VectorType *VT = cast<VectorType>(Ty); 367 ASSERT_TRUE(VT->getNumElements() == 5); 368 ASSERT_TRUE(VT->getBitWidth() == 160); 369 Ty = VT->getElementType(); 370 ASSERT_TRUE(Ty->isIntegerTy()); 371 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 372 373 // Opaque struct. 374 Ty = parseTypeAtBeginning("%opaque", Read, Error, M, &Mapping); 375 ASSERT_TRUE(Ty); 376 ASSERT_TRUE(Ty->isStructTy()); 377 ASSERT_TRUE(Read == 7); 378 379 ST = cast<StructType>(Ty); 380 ASSERT_TRUE(ST->isOpaque()); 381 382 // Check we properly parse pointer types. 383 // One indirection. 384 Ty = parseTypeAtBeginning("i32*", Read, Error, M, &Mapping); 385 ASSERT_TRUE(Ty); 386 ASSERT_TRUE(Ty->isPointerTy()); 387 ASSERT_TRUE(Read == 4); 388 389 PointerType *PT = cast<PointerType>(Ty); 390 Ty = PT->getElementType(); 391 ASSERT_TRUE(Ty->isIntegerTy()); 392 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 393 394 // Two indirections. 395 Ty = parseTypeAtBeginning("i32**", Read, Error, M, &Mapping); 396 ASSERT_TRUE(Ty); 397 ASSERT_TRUE(Ty->isPointerTy()); 398 ASSERT_TRUE(Read == 5); 399 400 PT = cast<PointerType>(Ty); 401 Ty = PT->getElementType(); 402 ASSERT_TRUE(Ty->isPointerTy()); 403 404 PT = cast<PointerType>(Ty); 405 Ty = PT->getElementType(); 406 ASSERT_TRUE(Ty->isIntegerTy()); 407 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 408 409 // Check that we reject types with garbage. 410 Ty = parseTypeAtBeginning("i32 garbage", Read, Error, M, &Mapping); 411 ASSERT_TRUE(Ty); 412 ASSERT_TRUE(Ty->isIntegerTy()); 413 ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32); 414 // We go to the next token, i.e., we read "i32" + ' '. 415 ASSERT_TRUE(Read == 4); 416 } 417 418 } // end anonymous namespace 419