1 //===- unittests/IR/MetadataTest.cpp - Metadata unit tests ----------------===// 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 //===----------------------------------------------------------------------===// 8 9 #include "llvm/IR/Metadata.h" 10 #include "llvm/ADT/DenseMap.h" 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/IR/Constants.h" 13 #include "llvm/IR/DIBuilder.h" 14 #include "llvm/IR/DebugInfo.h" 15 #include "llvm/IR/DebugInfoMetadata.h" 16 #include "llvm/IR/Function.h" 17 #include "llvm/IR/Instructions.h" 18 #include "llvm/IR/LLVMContext.h" 19 #include "llvm/IR/Module.h" 20 #include "llvm/IR/ModuleSlotTracker.h" 21 #include "llvm/IR/Type.h" 22 #include "llvm/IR/Verifier.h" 23 #include "llvm/Support/raw_ostream.h" 24 #include "gtest/gtest.h" 25 #include <optional> 26 using namespace llvm; 27 28 namespace { 29 30 TEST(ContextAndReplaceableUsesTest, FromContext) { 31 LLVMContext Context; 32 ContextAndReplaceableUses CRU(Context); 33 EXPECT_EQ(&Context, &CRU.getContext()); 34 EXPECT_FALSE(CRU.hasReplaceableUses()); 35 EXPECT_FALSE(CRU.getReplaceableUses()); 36 } 37 38 TEST(ContextAndReplaceableUsesTest, FromReplaceableUses) { 39 LLVMContext Context; 40 ContextAndReplaceableUses CRU(std::make_unique<ReplaceableMetadataImpl>(Context)); 41 EXPECT_EQ(&Context, &CRU.getContext()); 42 EXPECT_TRUE(CRU.hasReplaceableUses()); 43 EXPECT_TRUE(CRU.getReplaceableUses()); 44 } 45 46 TEST(ContextAndReplaceableUsesTest, makeReplaceable) { 47 LLVMContext Context; 48 ContextAndReplaceableUses CRU(Context); 49 CRU.makeReplaceable(std::make_unique<ReplaceableMetadataImpl>(Context)); 50 EXPECT_EQ(&Context, &CRU.getContext()); 51 EXPECT_TRUE(CRU.hasReplaceableUses()); 52 EXPECT_TRUE(CRU.getReplaceableUses()); 53 } 54 55 TEST(ContextAndReplaceableUsesTest, takeReplaceableUses) { 56 LLVMContext Context; 57 auto ReplaceableUses = std::make_unique<ReplaceableMetadataImpl>(Context); 58 auto *Ptr = ReplaceableUses.get(); 59 ContextAndReplaceableUses CRU(std::move(ReplaceableUses)); 60 ReplaceableUses = CRU.takeReplaceableUses(); 61 EXPECT_EQ(&Context, &CRU.getContext()); 62 EXPECT_FALSE(CRU.hasReplaceableUses()); 63 EXPECT_FALSE(CRU.getReplaceableUses()); 64 EXPECT_EQ(Ptr, ReplaceableUses.get()); 65 } 66 67 class MetadataTest : public testing::Test { 68 public: 69 MetadataTest() : M("test", Context), Counter(0) {} 70 71 protected: 72 LLVMContext Context; 73 Module M; 74 int Counter; 75 76 MDNode *getNode() { return MDNode::get(Context, {}); } 77 MDNode *getNode(Metadata *MD) { return MDNode::get(Context, MD); } 78 MDNode *getNode(Metadata *MD1, Metadata *MD2) { 79 Metadata *MDs[] = {MD1, MD2}; 80 return MDNode::get(Context, MDs); 81 } 82 83 MDTuple *getTuple() { return MDTuple::getDistinct(Context, {}); } 84 DISubroutineType *getSubroutineType() { 85 return DISubroutineType::getDistinct(Context, DINode::FlagZero, 0, 86 getNode(nullptr)); 87 } 88 DISubprogram *getSubprogram() { 89 return DISubprogram::getDistinct( 90 Context, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0, 91 DINode::FlagZero, DISubprogram::SPFlagZero, nullptr); 92 } 93 DIFile *getFile() { 94 return DIFile::getDistinct(Context, "file.c", "/path/to/dir"); 95 } 96 DICompileUnit *getUnit() { 97 return DICompileUnit::getDistinct( 98 Context, 1, getFile(), "clang", false, "-g", 2, "", 99 DICompileUnit::FullDebug, getTuple(), getTuple(), getTuple(), 100 getTuple(), getTuple(), 0, true, false, 101 DICompileUnit::DebugNameTableKind::Default, false, "/", ""); 102 } 103 DIType *getBasicType(StringRef Name) { 104 return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name); 105 } 106 DIType *getDerivedType() { 107 return DIDerivedType::getDistinct( 108 Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, 109 getBasicType("basictype"), 1, 2, 0, std::nullopt, {}, DINode::FlagZero); 110 } 111 Constant *getConstant() { 112 return ConstantInt::get(Type::getInt32Ty(Context), Counter++); 113 } 114 ConstantAsMetadata *getConstantAsMetadata() { 115 return ConstantAsMetadata::get(getConstant()); 116 } 117 DIType *getCompositeType() { 118 return DICompositeType::getDistinct( 119 Context, dwarf::DW_TAG_structure_type, "", nullptr, 0, nullptr, nullptr, 120 32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, ""); 121 } 122 Function *getFunction(StringRef Name) { 123 return Function::Create( 124 FunctionType::get(Type::getVoidTy(Context), {}, false), 125 Function::ExternalLinkage, Name, M); 126 } 127 }; 128 typedef MetadataTest MDStringTest; 129 130 // Test that construction of MDString with different value produces different 131 // MDString objects, even with the same string pointer and nulls in the string. 132 TEST_F(MDStringTest, CreateDifferent) { 133 char x[3] = { 'f', 0, 'A' }; 134 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); 135 x[2] = 'B'; 136 MDString *s2 = MDString::get(Context, StringRef(&x[0], 3)); 137 EXPECT_NE(s1, s2); 138 } 139 140 // Test that creation of MDStrings with the same string contents produces the 141 // same MDString object, even with different pointers. 142 TEST_F(MDStringTest, CreateSame) { 143 char x[4] = { 'a', 'b', 'c', 'X' }; 144 char y[4] = { 'a', 'b', 'c', 'Y' }; 145 146 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); 147 MDString *s2 = MDString::get(Context, StringRef(&y[0], 3)); 148 EXPECT_EQ(s1, s2); 149 } 150 151 // Test that MDString prints out the string we fed it. 152 TEST_F(MDStringTest, PrintingSimple) { 153 char str[14] = "testing 1 2 3"; 154 MDString *s = MDString::get(Context, StringRef(&str[0], 13)); 155 strncpy(str, "aaaaaaaaaaaaa", 14); 156 157 std::string Str; 158 raw_string_ostream oss(Str); 159 s->print(oss); 160 EXPECT_STREQ("!\"testing 1 2 3\"", Str.c_str()); 161 } 162 163 // Test printing of MDString with non-printable characters. 164 TEST_F(MDStringTest, PrintingComplex) { 165 char str[5] = {0, '\n', '"', '\\', (char)-1}; 166 MDString *s = MDString::get(Context, StringRef(str+0, 5)); 167 std::string Str; 168 raw_string_ostream oss(Str); 169 s->print(oss); 170 EXPECT_STREQ("!\"\\00\\0A\\22\\\\\\FF\"", Str.c_str()); 171 } 172 173 typedef MetadataTest MDNodeTest; 174 175 // Test the two constructors, and containing other Constants. 176 TEST_F(MDNodeTest, Simple) { 177 char x[3] = { 'a', 'b', 'c' }; 178 char y[3] = { '1', '2', '3' }; 179 180 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); 181 MDString *s2 = MDString::get(Context, StringRef(&y[0], 3)); 182 ConstantAsMetadata *CI = 183 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); 184 185 std::vector<Metadata *> V; 186 V.push_back(s1); 187 V.push_back(CI); 188 V.push_back(s2); 189 190 MDNode *n1 = MDNode::get(Context, V); 191 Metadata *const c1 = n1; 192 MDNode *n2 = MDNode::get(Context, c1); 193 Metadata *const c2 = n2; 194 MDNode *n3 = MDNode::get(Context, V); 195 MDNode *n4 = MDNode::getIfExists(Context, V); 196 MDNode *n5 = MDNode::getIfExists(Context, c1); 197 MDNode *n6 = MDNode::getIfExists(Context, c2); 198 EXPECT_NE(n1, n2); 199 EXPECT_EQ(n1, n3); 200 EXPECT_EQ(n4, n1); 201 EXPECT_EQ(n5, n2); 202 EXPECT_EQ(n6, (Metadata *)nullptr); 203 204 EXPECT_EQ(3u, n1->getNumOperands()); 205 EXPECT_EQ(s1, n1->getOperand(0)); 206 EXPECT_EQ(CI, n1->getOperand(1)); 207 EXPECT_EQ(s2, n1->getOperand(2)); 208 209 EXPECT_EQ(1u, n2->getNumOperands()); 210 EXPECT_EQ(n1, n2->getOperand(0)); 211 } 212 213 TEST_F(MDNodeTest, Delete) { 214 Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 1); 215 Instruction *I = new BitCastInst(C, Type::getInt32Ty(Context)); 216 217 Metadata *const V = LocalAsMetadata::get(I); 218 MDNode *n = MDNode::get(Context, V); 219 TrackingMDRef wvh(n); 220 221 EXPECT_EQ(n, wvh); 222 223 I->deleteValue(); 224 } 225 226 TEST_F(MDNodeTest, SelfReference) { 227 // !0 = !{!0} 228 // !1 = !{!0} 229 { 230 auto Temp = MDNode::getTemporary(Context, {}); 231 Metadata *Args[] = {Temp.get()}; 232 MDNode *Self = MDNode::get(Context, Args); 233 Self->replaceOperandWith(0, Self); 234 ASSERT_EQ(Self, Self->getOperand(0)); 235 236 // Self-references should be distinct, so MDNode::get() should grab a 237 // uniqued node that references Self, not Self. 238 Args[0] = Self; 239 MDNode *Ref1 = MDNode::get(Context, Args); 240 MDNode *Ref2 = MDNode::get(Context, Args); 241 EXPECT_NE(Self, Ref1); 242 EXPECT_EQ(Ref1, Ref2); 243 } 244 245 // !0 = !{!0, !{}} 246 // !1 = !{!0, !{}} 247 { 248 auto Temp = MDNode::getTemporary(Context, {}); 249 Metadata *Args[] = {Temp.get(), MDNode::get(Context, {})}; 250 MDNode *Self = MDNode::get(Context, Args); 251 Self->replaceOperandWith(0, Self); 252 ASSERT_EQ(Self, Self->getOperand(0)); 253 254 // Self-references should be distinct, so MDNode::get() should grab a 255 // uniqued node that references Self, not Self itself. 256 Args[0] = Self; 257 MDNode *Ref1 = MDNode::get(Context, Args); 258 MDNode *Ref2 = MDNode::get(Context, Args); 259 EXPECT_NE(Self, Ref1); 260 EXPECT_EQ(Ref1, Ref2); 261 } 262 } 263 264 TEST_F(MDNodeTest, Print) { 265 Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 7); 266 MDString *S = MDString::get(Context, "foo"); 267 MDNode *N0 = getNode(); 268 MDNode *N1 = getNode(N0); 269 MDNode *N2 = getNode(N0, N1); 270 271 Metadata *Args[] = {ConstantAsMetadata::get(C), S, nullptr, N0, N1, N2}; 272 MDNode *N = MDNode::get(Context, Args); 273 274 std::string Expected; 275 { 276 raw_string_ostream OS(Expected); 277 OS << "<" << (void *)N << "> = !{"; 278 C->printAsOperand(OS); 279 OS << ", "; 280 S->printAsOperand(OS); 281 OS << ", null"; 282 MDNode *Nodes[] = {N0, N1, N2}; 283 for (auto *Node : Nodes) 284 OS << ", <" << (void *)Node << ">"; 285 OS << "}"; 286 } 287 288 std::string Actual; 289 { 290 raw_string_ostream OS(Actual); 291 N->print(OS); 292 } 293 294 EXPECT_EQ(Expected, Actual); 295 } 296 297 #define EXPECT_PRINTER_EQ(EXPECTED, PRINT) \ 298 do { \ 299 std::string Actual_; \ 300 raw_string_ostream OS(Actual_); \ 301 PRINT; \ 302 std::string Expected_(EXPECTED); \ 303 EXPECT_EQ(Expected_, Actual_); \ 304 } while (false) 305 306 TEST_F(MDNodeTest, PrintTemporary) { 307 MDNode *Arg = getNode(); 308 TempMDNode Temp = MDNode::getTemporary(Context, Arg); 309 MDNode *N = getNode(Temp.get()); 310 Module M("test", Context); 311 NamedMDNode *NMD = M.getOrInsertNamedMetadata("named"); 312 NMD->addOperand(N); 313 314 EXPECT_PRINTER_EQ("!0 = !{!1}", N->print(OS, &M)); 315 EXPECT_PRINTER_EQ("!1 = <temporary!> !{!2}", Temp->print(OS, &M)); 316 EXPECT_PRINTER_EQ("!2 = !{}", Arg->print(OS, &M)); 317 318 // Cleanup. 319 Temp->replaceAllUsesWith(Arg); 320 } 321 322 TEST_F(MDNodeTest, PrintFromModule) { 323 Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 7); 324 MDString *S = MDString::get(Context, "foo"); 325 MDNode *N0 = getNode(); 326 MDNode *N1 = getNode(N0); 327 MDNode *N2 = getNode(N0, N1); 328 329 Metadata *Args[] = {ConstantAsMetadata::get(C), S, nullptr, N0, N1, N2}; 330 MDNode *N = MDNode::get(Context, Args); 331 Module M("test", Context); 332 NamedMDNode *NMD = M.getOrInsertNamedMetadata("named"); 333 NMD->addOperand(N); 334 335 std::string Expected; 336 { 337 raw_string_ostream OS(Expected); 338 OS << "!0 = !{"; 339 C->printAsOperand(OS); 340 OS << ", "; 341 S->printAsOperand(OS); 342 OS << ", null, !1, !2, !3}"; 343 } 344 345 EXPECT_PRINTER_EQ(Expected, N->print(OS, &M)); 346 } 347 348 TEST_F(MDNodeTest, PrintFromFunction) { 349 Module M("test", Context); 350 auto *FTy = FunctionType::get(Type::getVoidTy(Context), false); 351 auto *F0 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F0", &M); 352 auto *F1 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F1", &M); 353 auto *BB0 = BasicBlock::Create(Context, "entry", F0); 354 auto *BB1 = BasicBlock::Create(Context, "entry", F1); 355 auto *R0 = ReturnInst::Create(Context, BB0); 356 auto *R1 = ReturnInst::Create(Context, BB1); 357 auto *N0 = MDNode::getDistinct(Context, {}); 358 auto *N1 = MDNode::getDistinct(Context, {}); 359 R0->setMetadata("md", N0); 360 R1->setMetadata("md", N1); 361 362 EXPECT_PRINTER_EQ("!0 = distinct !{}", N0->print(OS, &M)); 363 EXPECT_PRINTER_EQ("!1 = distinct !{}", N1->print(OS, &M)); 364 365 ModuleSlotTracker MST(&M); 366 EXPECT_PRINTER_EQ("!0 = distinct !{}", N0->print(OS, MST)); 367 EXPECT_PRINTER_EQ("!1 = distinct !{}", N1->print(OS, MST)); 368 } 369 370 TEST_F(MDNodeTest, PrintFromMetadataAsValue) { 371 Module M("test", Context); 372 373 auto *Intrinsic = 374 Function::Create(FunctionType::get(Type::getVoidTy(Context), 375 Type::getMetadataTy(Context), false), 376 GlobalValue::ExternalLinkage, "llvm.intrinsic", &M); 377 378 auto *FTy = FunctionType::get(Type::getVoidTy(Context), false); 379 auto *F0 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F0", &M); 380 auto *F1 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F1", &M); 381 auto *BB0 = BasicBlock::Create(Context, "entry", F0); 382 auto *BB1 = BasicBlock::Create(Context, "entry", F1); 383 auto *N0 = MDNode::getDistinct(Context, {}); 384 auto *N1 = MDNode::getDistinct(Context, {}); 385 auto *MAV0 = MetadataAsValue::get(Context, N0); 386 auto *MAV1 = MetadataAsValue::get(Context, N1); 387 CallInst::Create(Intrinsic, MAV0, "", BB0); 388 CallInst::Create(Intrinsic, MAV1, "", BB1); 389 390 EXPECT_PRINTER_EQ("!0 = distinct !{}", MAV0->print(OS)); 391 EXPECT_PRINTER_EQ("!1 = distinct !{}", MAV1->print(OS)); 392 EXPECT_PRINTER_EQ("!0", MAV0->printAsOperand(OS, false)); 393 EXPECT_PRINTER_EQ("!1", MAV1->printAsOperand(OS, false)); 394 EXPECT_PRINTER_EQ("metadata !0", MAV0->printAsOperand(OS, true)); 395 EXPECT_PRINTER_EQ("metadata !1", MAV1->printAsOperand(OS, true)); 396 397 ModuleSlotTracker MST(&M); 398 EXPECT_PRINTER_EQ("!0 = distinct !{}", MAV0->print(OS, MST)); 399 EXPECT_PRINTER_EQ("!1 = distinct !{}", MAV1->print(OS, MST)); 400 EXPECT_PRINTER_EQ("!0", MAV0->printAsOperand(OS, false, MST)); 401 EXPECT_PRINTER_EQ("!1", MAV1->printAsOperand(OS, false, MST)); 402 EXPECT_PRINTER_EQ("metadata !0", MAV0->printAsOperand(OS, true, MST)); 403 EXPECT_PRINTER_EQ("metadata !1", MAV1->printAsOperand(OS, true, MST)); 404 } 405 406 TEST_F(MDNodeTest, PrintWithDroppedCallOperand) { 407 Module M("test", Context); 408 409 auto *FTy = FunctionType::get(Type::getVoidTy(Context), false); 410 auto *F0 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F0", &M); 411 auto *F1 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F1", &M); 412 auto *BB0 = BasicBlock::Create(Context, "entry", F0); 413 414 CallInst *CI0 = CallInst::Create(F1, "", BB0); 415 CI0->dropAllReferences(); 416 417 auto *R0 = ReturnInst::Create(Context, BB0); 418 auto *N0 = MDNode::getDistinct(Context, {}); 419 R0->setMetadata("md", N0); 420 421 // Printing the metadata node would previously result in a failed assertion 422 // due to the call instruction's dropped function operand. 423 ModuleSlotTracker MST(&M); 424 EXPECT_PRINTER_EQ("!0 = distinct !{}", N0->print(OS, MST)); 425 } 426 427 TEST_F(MDNodeTest, PrintTree) { 428 DILocalScope *Scope = getSubprogram(); 429 DIFile *File = getFile(); 430 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 431 { 432 DIType *Type = getDerivedType(); 433 auto *Var = DILocalVariable::get(Context, Scope, "foo", File, 434 /*LineNo=*/8, Type, /*ArgNo=*/2, Flags, 435 /*Align=*/8, nullptr); 436 std::string Expected; 437 { 438 raw_string_ostream SS(Expected); 439 Var->print(SS); 440 // indent level 1 441 Scope->print((SS << "\n").indent(2)); 442 File->print((SS << "\n").indent(2)); 443 Type->print((SS << "\n").indent(2)); 444 // indent level 2 445 auto *BaseType = cast<DIDerivedType>(Type)->getBaseType(); 446 BaseType->print((SS << "\n").indent(4)); 447 } 448 449 EXPECT_PRINTER_EQ(Expected, Var->printTree(OS)); 450 } 451 452 { 453 // Test if printTree works correctly when there is 454 // a cycle in the MDNode and its dependencies. 455 // 456 // We're trying to create type like this: 457 // struct LinkedList { 458 // LinkedList *Head; 459 // }; 460 auto *StructTy = cast<DICompositeType>(getCompositeType()); 461 DIType *PointerTy = DIDerivedType::getDistinct( 462 Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, StructTy, 463 1, 2, 0, std::nullopt, {}, DINode::FlagZero); 464 StructTy->replaceElements(MDTuple::get(Context, PointerTy)); 465 466 auto *Var = DILocalVariable::get(Context, Scope, "foo", File, 467 /*LineNo=*/8, StructTy, /*ArgNo=*/2, Flags, 468 /*Align=*/8, nullptr); 469 std::string Expected; 470 { 471 raw_string_ostream SS(Expected); 472 Var->print(SS); 473 // indent level 1 474 Scope->print((SS << "\n").indent(2)); 475 File->print((SS << "\n").indent(2)); 476 StructTy->print((SS << "\n").indent(2)); 477 // indent level 2 478 StructTy->getRawElements()->print((SS << "\n").indent(4)); 479 // indent level 3 480 auto Elements = StructTy->getElements(); 481 Elements[0]->print((SS << "\n").indent(6)); 482 } 483 484 EXPECT_PRINTER_EQ(Expected, Var->printTree(OS)); 485 } 486 } 487 #undef EXPECT_PRINTER_EQ 488 489 TEST_F(MDNodeTest, NullOperand) { 490 // metadata !{} 491 MDNode *Empty = MDNode::get(Context, {}); 492 493 // metadata !{metadata !{}} 494 Metadata *Ops[] = {Empty}; 495 MDNode *N = MDNode::get(Context, Ops); 496 ASSERT_EQ(Empty, N->getOperand(0)); 497 498 // metadata !{metadata !{}} => metadata !{null} 499 N->replaceOperandWith(0, nullptr); 500 ASSERT_EQ(nullptr, N->getOperand(0)); 501 502 // metadata !{null} 503 Ops[0] = nullptr; 504 MDNode *NullOp = MDNode::get(Context, Ops); 505 ASSERT_EQ(nullptr, NullOp->getOperand(0)); 506 EXPECT_EQ(N, NullOp); 507 } 508 509 TEST_F(MDNodeTest, DistinctOnUniquingCollision) { 510 // !{} 511 MDNode *Empty = MDNode::get(Context, {}); 512 ASSERT_TRUE(Empty->isResolved()); 513 EXPECT_FALSE(Empty->isDistinct()); 514 515 // !{!{}} 516 Metadata *Wrapped1Ops[] = {Empty}; 517 MDNode *Wrapped1 = MDNode::get(Context, Wrapped1Ops); 518 ASSERT_EQ(Empty, Wrapped1->getOperand(0)); 519 ASSERT_TRUE(Wrapped1->isResolved()); 520 EXPECT_FALSE(Wrapped1->isDistinct()); 521 522 // !{!{!{}}} 523 Metadata *Wrapped2Ops[] = {Wrapped1}; 524 MDNode *Wrapped2 = MDNode::get(Context, Wrapped2Ops); 525 ASSERT_EQ(Wrapped1, Wrapped2->getOperand(0)); 526 ASSERT_TRUE(Wrapped2->isResolved()); 527 EXPECT_FALSE(Wrapped2->isDistinct()); 528 529 // !{!{!{}}} => !{!{}} 530 Wrapped2->replaceOperandWith(0, Empty); 531 ASSERT_EQ(Empty, Wrapped2->getOperand(0)); 532 EXPECT_TRUE(Wrapped2->isDistinct()); 533 EXPECT_FALSE(Wrapped1->isDistinct()); 534 } 535 536 TEST_F(MDNodeTest, UniquedOnDeletedOperand) { 537 // temp !{} 538 TempMDTuple T = MDTuple::getTemporary(Context, {}); 539 540 // !{temp !{}} 541 Metadata *Ops[] = {T.get()}; 542 MDTuple *N = MDTuple::get(Context, Ops); 543 544 // !{temp !{}} => !{null} 545 T.reset(); 546 ASSERT_TRUE(N->isUniqued()); 547 Metadata *NullOps[] = {nullptr}; 548 ASSERT_EQ(N, MDTuple::get(Context, NullOps)); 549 } 550 551 TEST_F(MDNodeTest, DistinctOnDeletedValueOperand) { 552 // i1* @GV 553 Type *Ty = PointerType::getUnqual(Context); 554 std::unique_ptr<GlobalVariable> GV( 555 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 556 ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get()); 557 558 // !{i1* @GV} 559 Metadata *Ops[] = {Op}; 560 MDTuple *N = MDTuple::get(Context, Ops); 561 562 // !{i1* @GV} => !{null} 563 GV.reset(); 564 ASSERT_TRUE(N->isDistinct()); 565 ASSERT_EQ(nullptr, N->getOperand(0)); 566 Metadata *NullOps[] = {nullptr}; 567 ASSERT_NE(N, MDTuple::get(Context, NullOps)); 568 } 569 570 TEST_F(MDNodeTest, getDistinct) { 571 // !{} 572 MDNode *Empty = MDNode::get(Context, {}); 573 ASSERT_TRUE(Empty->isResolved()); 574 ASSERT_FALSE(Empty->isDistinct()); 575 ASSERT_EQ(Empty, MDNode::get(Context, {})); 576 577 // distinct !{} 578 MDNode *Distinct1 = MDNode::getDistinct(Context, {}); 579 MDNode *Distinct2 = MDNode::getDistinct(Context, {}); 580 EXPECT_TRUE(Distinct1->isResolved()); 581 EXPECT_TRUE(Distinct2->isDistinct()); 582 EXPECT_NE(Empty, Distinct1); 583 EXPECT_NE(Empty, Distinct2); 584 EXPECT_NE(Distinct1, Distinct2); 585 586 // !{} 587 ASSERT_EQ(Empty, MDNode::get(Context, {})); 588 } 589 590 TEST_F(MDNodeTest, isUniqued) { 591 MDNode *U = MDTuple::get(Context, {}); 592 MDNode *D = MDTuple::getDistinct(Context, {}); 593 auto T = MDTuple::getTemporary(Context, {}); 594 EXPECT_TRUE(U->isUniqued()); 595 EXPECT_FALSE(D->isUniqued()); 596 EXPECT_FALSE(T->isUniqued()); 597 } 598 599 TEST_F(MDNodeTest, isDistinct) { 600 MDNode *U = MDTuple::get(Context, {}); 601 MDNode *D = MDTuple::getDistinct(Context, {}); 602 auto T = MDTuple::getTemporary(Context, {}); 603 EXPECT_FALSE(U->isDistinct()); 604 EXPECT_TRUE(D->isDistinct()); 605 EXPECT_FALSE(T->isDistinct()); 606 } 607 608 TEST_F(MDNodeTest, isTemporary) { 609 MDNode *U = MDTuple::get(Context, {}); 610 MDNode *D = MDTuple::getDistinct(Context, {}); 611 auto T = MDTuple::getTemporary(Context, {}); 612 EXPECT_FALSE(U->isTemporary()); 613 EXPECT_FALSE(D->isTemporary()); 614 EXPECT_TRUE(T->isTemporary()); 615 } 616 617 TEST_F(MDNodeTest, getDistinctWithUnresolvedOperands) { 618 // temporary !{} 619 auto Temp = MDTuple::getTemporary(Context, {}); 620 ASSERT_FALSE(Temp->isResolved()); 621 622 // distinct !{temporary !{}} 623 Metadata *Ops[] = {Temp.get()}; 624 MDNode *Distinct = MDNode::getDistinct(Context, Ops); 625 EXPECT_TRUE(Distinct->isResolved()); 626 EXPECT_EQ(Temp.get(), Distinct->getOperand(0)); 627 628 // temporary !{} => !{} 629 MDNode *Empty = MDNode::get(Context, {}); 630 Temp->replaceAllUsesWith(Empty); 631 EXPECT_EQ(Empty, Distinct->getOperand(0)); 632 } 633 634 TEST_F(MDNodeTest, handleChangedOperandRecursion) { 635 // !0 = !{} 636 MDNode *N0 = MDNode::get(Context, {}); 637 638 // !1 = !{!3, null} 639 auto Temp3 = MDTuple::getTemporary(Context, {}); 640 Metadata *Ops1[] = {Temp3.get(), nullptr}; 641 MDNode *N1 = MDNode::get(Context, Ops1); 642 643 // !2 = !{!3, !0} 644 Metadata *Ops2[] = {Temp3.get(), N0}; 645 MDNode *N2 = MDNode::get(Context, Ops2); 646 647 // !3 = !{!2} 648 Metadata *Ops3[] = {N2}; 649 MDNode *N3 = MDNode::get(Context, Ops3); 650 Temp3->replaceAllUsesWith(N3); 651 652 // !4 = !{!1} 653 Metadata *Ops4[] = {N1}; 654 MDNode *N4 = MDNode::get(Context, Ops4); 655 656 // Confirm that the cycle prevented RAUW from getting dropped. 657 EXPECT_TRUE(N0->isResolved()); 658 EXPECT_FALSE(N1->isResolved()); 659 EXPECT_FALSE(N2->isResolved()); 660 EXPECT_FALSE(N3->isResolved()); 661 EXPECT_FALSE(N4->isResolved()); 662 663 // Create a couple of distinct nodes to observe what's going on. 664 // 665 // !5 = distinct !{!2} 666 // !6 = distinct !{!3} 667 Metadata *Ops5[] = {N2}; 668 MDNode *N5 = MDNode::getDistinct(Context, Ops5); 669 Metadata *Ops6[] = {N3}; 670 MDNode *N6 = MDNode::getDistinct(Context, Ops6); 671 672 // Mutate !2 to look like !1, causing a uniquing collision (and an RAUW). 673 // This will ripple up, with !3 colliding with !4, and RAUWing. Since !2 674 // references !3, this can cause a re-entry of handleChangedOperand() when !3 675 // is not ready for it. 676 // 677 // !2->replaceOperandWith(1, nullptr) 678 // !2: !{!3, !0} => !{!3, null} 679 // !2->replaceAllUsesWith(!1) 680 // !3: !{!2] => !{!1} 681 // !3->replaceAllUsesWith(!4) 682 N2->replaceOperandWith(1, nullptr); 683 684 // If all has gone well, N2 and N3 will have been RAUW'ed and deleted from 685 // under us. Just check that the other nodes are sane. 686 // 687 // !1 = !{!4, null} 688 // !4 = !{!1} 689 // !5 = distinct !{!1} 690 // !6 = distinct !{!4} 691 EXPECT_EQ(N4, N1->getOperand(0)); 692 EXPECT_EQ(N1, N4->getOperand(0)); 693 EXPECT_EQ(N1, N5->getOperand(0)); 694 EXPECT_EQ(N4, N6->getOperand(0)); 695 } 696 697 TEST_F(MDNodeTest, replaceResolvedOperand) { 698 // Check code for replacing one resolved operand with another. If doing this 699 // directly (via replaceOperandWith()) becomes illegal, change the operand to 700 // a global value that gets RAUW'ed. 701 // 702 // Use a temporary node to keep N from being resolved. 703 auto Temp = MDTuple::getTemporary(Context, {}); 704 Metadata *Ops[] = {nullptr, Temp.get()}; 705 706 MDNode *Empty = MDTuple::get(Context, ArrayRef<Metadata *>()); 707 MDNode *N = MDTuple::get(Context, Ops); 708 EXPECT_EQ(nullptr, N->getOperand(0)); 709 ASSERT_FALSE(N->isResolved()); 710 711 // Check code for replacing resolved nodes. 712 N->replaceOperandWith(0, Empty); 713 EXPECT_EQ(Empty, N->getOperand(0)); 714 715 // Check code for adding another unresolved operand. 716 N->replaceOperandWith(0, Temp.get()); 717 EXPECT_EQ(Temp.get(), N->getOperand(0)); 718 719 // Remove the references to Temp; required for teardown. 720 Temp->replaceAllUsesWith(nullptr); 721 } 722 723 TEST_F(MDNodeTest, replaceWithUniqued) { 724 auto *Empty = MDTuple::get(Context, {}); 725 MDTuple *FirstUniqued; 726 { 727 Metadata *Ops[] = {Empty}; 728 auto Temp = MDTuple::getTemporary(Context, Ops); 729 EXPECT_TRUE(Temp->isTemporary()); 730 731 // Don't expect a collision. 732 auto *Current = Temp.get(); 733 FirstUniqued = MDNode::replaceWithUniqued(std::move(Temp)); 734 EXPECT_TRUE(FirstUniqued->isUniqued()); 735 EXPECT_TRUE(FirstUniqued->isResolved()); 736 EXPECT_EQ(Current, FirstUniqued); 737 } 738 { 739 Metadata *Ops[] = {Empty}; 740 auto Temp = MDTuple::getTemporary(Context, Ops); 741 EXPECT_TRUE(Temp->isTemporary()); 742 743 // Should collide with Uniqued above this time. 744 auto *Uniqued = MDNode::replaceWithUniqued(std::move(Temp)); 745 EXPECT_TRUE(Uniqued->isUniqued()); 746 EXPECT_TRUE(Uniqued->isResolved()); 747 EXPECT_EQ(FirstUniqued, Uniqued); 748 } 749 { 750 auto Unresolved = MDTuple::getTemporary(Context, {}); 751 Metadata *Ops[] = {Unresolved.get()}; 752 auto Temp = MDTuple::getTemporary(Context, Ops); 753 EXPECT_TRUE(Temp->isTemporary()); 754 755 // Shouldn't be resolved. 756 auto *Uniqued = MDNode::replaceWithUniqued(std::move(Temp)); 757 EXPECT_TRUE(Uniqued->isUniqued()); 758 EXPECT_FALSE(Uniqued->isResolved()); 759 760 // Should be a different node. 761 EXPECT_NE(FirstUniqued, Uniqued); 762 763 // Should resolve when we update its node (note: be careful to avoid a 764 // collision with any other nodes above). 765 Uniqued->replaceOperandWith(0, nullptr); 766 EXPECT_TRUE(Uniqued->isResolved()); 767 } 768 } 769 770 TEST_F(MDNodeTest, replaceWithUniquedResolvingOperand) { 771 // temp !{} 772 MDTuple *Op = MDTuple::getTemporary(Context, {}).release(); 773 EXPECT_FALSE(Op->isResolved()); 774 775 // temp !{temp !{}} 776 Metadata *Ops[] = {Op}; 777 MDTuple *N = MDTuple::getTemporary(Context, Ops).release(); 778 EXPECT_FALSE(N->isResolved()); 779 780 // temp !{temp !{}} => !{temp !{}} 781 ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N))); 782 EXPECT_FALSE(N->isResolved()); 783 784 // !{temp !{}} => !{!{}} 785 ASSERT_EQ(Op, MDNode::replaceWithUniqued(TempMDTuple(Op))); 786 EXPECT_TRUE(Op->isResolved()); 787 EXPECT_TRUE(N->isResolved()); 788 } 789 790 TEST_F(MDNodeTest, replaceWithUniquedDeletedOperand) { 791 // i1* @GV 792 Type *Ty = PointerType::getUnqual(Context); 793 std::unique_ptr<GlobalVariable> GV( 794 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 795 ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get()); 796 797 // temp !{i1* @GV} 798 Metadata *Ops[] = {Op}; 799 MDTuple *N = MDTuple::getTemporary(Context, Ops).release(); 800 801 // temp !{i1* @GV} => !{i1* @GV} 802 ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N))); 803 ASSERT_TRUE(N->isUniqued()); 804 805 // !{i1* @GV} => !{null} 806 GV.reset(); 807 ASSERT_TRUE(N->isDistinct()); 808 ASSERT_EQ(nullptr, N->getOperand(0)); 809 Metadata *NullOps[] = {nullptr}; 810 ASSERT_NE(N, MDTuple::get(Context, NullOps)); 811 } 812 813 TEST_F(MDNodeTest, replaceWithUniquedChangedOperand) { 814 // i1* @GV 815 Type *Ty = PointerType::getUnqual(Context); 816 std::unique_ptr<GlobalVariable> GV( 817 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 818 ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get()); 819 820 // temp !{i1* @GV} 821 Metadata *Ops[] = {Op}; 822 MDTuple *N = MDTuple::getTemporary(Context, Ops).release(); 823 824 // temp !{i1* @GV} => !{i1* @GV} 825 ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N))); 826 ASSERT_TRUE(N->isUniqued()); 827 828 // !{i1* @GV} => !{i1* @GV2} 829 std::unique_ptr<GlobalVariable> GV2( 830 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 831 GV->replaceAllUsesWith(GV2.get()); 832 ASSERT_TRUE(N->isUniqued()); 833 Metadata *NullOps[] = {ConstantAsMetadata::get(GV2.get())}; 834 ASSERT_EQ(N, MDTuple::get(Context, NullOps)); 835 } 836 837 TEST_F(MDNodeTest, replaceWithDistinct) { 838 { 839 auto *Empty = MDTuple::get(Context, {}); 840 Metadata *Ops[] = {Empty}; 841 auto Temp = MDTuple::getTemporary(Context, Ops); 842 EXPECT_TRUE(Temp->isTemporary()); 843 844 // Don't expect a collision. 845 auto *Current = Temp.get(); 846 auto *Distinct = MDNode::replaceWithDistinct(std::move(Temp)); 847 EXPECT_TRUE(Distinct->isDistinct()); 848 EXPECT_TRUE(Distinct->isResolved()); 849 EXPECT_EQ(Current, Distinct); 850 } 851 { 852 auto Unresolved = MDTuple::getTemporary(Context, {}); 853 Metadata *Ops[] = {Unresolved.get()}; 854 auto Temp = MDTuple::getTemporary(Context, Ops); 855 EXPECT_TRUE(Temp->isTemporary()); 856 857 // Don't expect a collision. 858 auto *Current = Temp.get(); 859 auto *Distinct = MDNode::replaceWithDistinct(std::move(Temp)); 860 EXPECT_TRUE(Distinct->isDistinct()); 861 EXPECT_TRUE(Distinct->isResolved()); 862 EXPECT_EQ(Current, Distinct); 863 864 // Cleanup; required for teardown. 865 Unresolved->replaceAllUsesWith(nullptr); 866 } 867 } 868 869 TEST_F(MDNodeTest, replaceWithPermanent) { 870 Metadata *Ops[] = {nullptr}; 871 auto Temp = MDTuple::getTemporary(Context, Ops); 872 auto *T = Temp.get(); 873 874 // U is a normal, uniqued node that references T. 875 auto *U = MDTuple::get(Context, T); 876 EXPECT_TRUE(U->isUniqued()); 877 878 // Make Temp self-referencing. 879 Temp->replaceOperandWith(0, T); 880 881 // Try to uniquify Temp. This should, despite the name in the API, give a 882 // 'distinct' node, since self-references aren't allowed to be uniqued. 883 // 884 // Since it's distinct, N should have the same address as when it was a 885 // temporary (i.e., be equal to T not U). 886 auto *N = MDNode::replaceWithPermanent(std::move(Temp)); 887 EXPECT_EQ(N, T); 888 EXPECT_TRUE(N->isDistinct()); 889 890 // U should be the canonical unique node with N as the argument. 891 EXPECT_EQ(U, MDTuple::get(Context, N)); 892 EXPECT_TRUE(U->isUniqued()); 893 894 // This temporary should collide with U when replaced, but it should still be 895 // uniqued. 896 EXPECT_EQ(U, MDNode::replaceWithPermanent(MDTuple::getTemporary(Context, N))); 897 EXPECT_TRUE(U->isUniqued()); 898 899 // This temporary should become a new uniqued node. 900 auto Temp2 = MDTuple::getTemporary(Context, U); 901 auto *V = Temp2.get(); 902 EXPECT_EQ(V, MDNode::replaceWithPermanent(std::move(Temp2))); 903 EXPECT_TRUE(V->isUniqued()); 904 EXPECT_EQ(U, V->getOperand(0)); 905 } 906 907 TEST_F(MDNodeTest, deleteTemporaryWithTrackingRef) { 908 TrackingMDRef Ref; 909 EXPECT_EQ(nullptr, Ref.get()); 910 { 911 auto Temp = MDTuple::getTemporary(Context, {}); 912 Ref.reset(Temp.get()); 913 EXPECT_EQ(Temp.get(), Ref.get()); 914 } 915 EXPECT_EQ(nullptr, Ref.get()); 916 } 917 918 typedef MetadataTest DILocationTest; 919 920 TEST_F(DILocationTest, Merge) { 921 DISubprogram *N = getSubprogram(); 922 DIScope *S = DILexicalBlock::get(Context, N, getFile(), 3, 4); 923 924 { 925 // Identical. 926 auto *A = DILocation::get(Context, 2, 7, N); 927 auto *B = DILocation::get(Context, 2, 7, N); 928 auto *M = DILocation::getMergedLocation(A, B); 929 EXPECT_EQ(2u, M->getLine()); 930 EXPECT_EQ(7u, M->getColumn()); 931 EXPECT_EQ(N, M->getScope()); 932 } 933 934 { 935 // Identical, different scopes. 936 auto *A = DILocation::get(Context, 2, 7, N); 937 auto *B = DILocation::get(Context, 2, 7, S); 938 auto *M = DILocation::getMergedLocation(A, B); 939 EXPECT_EQ(2u, M->getLine()); 940 EXPECT_EQ(7u, M->getColumn()); 941 EXPECT_EQ(N, M->getScope()); 942 } 943 944 { 945 // Same line, different column. 946 auto *A = DILocation::get(Context, 2, 7, N); 947 auto *B = DILocation::get(Context, 2, 10, S); 948 auto *M0 = DILocation::getMergedLocation(A, B); 949 auto *M1 = DILocation::getMergedLocation(B, A); 950 for (auto *M : {M0, M1}) { 951 EXPECT_EQ(2u, M->getLine()); 952 EXPECT_EQ(0u, M->getColumn()); 953 EXPECT_EQ(N, M->getScope()); 954 } 955 } 956 957 { 958 // Different lines, same scopes. 959 auto *A = DILocation::get(Context, 1, 6, N); 960 auto *B = DILocation::get(Context, 2, 7, N); 961 auto *M = DILocation::getMergedLocation(A, B); 962 EXPECT_EQ(0u, M->getLine()); 963 EXPECT_EQ(0u, M->getColumn()); 964 EXPECT_EQ(N, M->getScope()); 965 } 966 967 { 968 // Twisty locations, all different, same function. 969 auto *A = DILocation::get(Context, 1, 6, N); 970 auto *B = DILocation::get(Context, 2, 7, S); 971 auto *M = DILocation::getMergedLocation(A, B); 972 EXPECT_EQ(0u, M->getLine()); 973 EXPECT_EQ(0u, M->getColumn()); 974 EXPECT_EQ(N, M->getScope()); 975 } 976 977 { 978 // Different function, same inlined-at. 979 auto *F = getFile(); 980 auto *SP1 = DISubprogram::getDistinct(Context, F, "a", "a", F, 0, nullptr, 981 0, nullptr, 0, 0, DINode::FlagZero, 982 DISubprogram::SPFlagZero, nullptr); 983 auto *SP2 = DISubprogram::getDistinct(Context, F, "b", "b", F, 0, nullptr, 984 0, nullptr, 0, 0, DINode::FlagZero, 985 DISubprogram::SPFlagZero, nullptr); 986 987 auto *I = DILocation::get(Context, 2, 7, N); 988 auto *A = DILocation::get(Context, 1, 6, SP1, I); 989 auto *B = DILocation::get(Context, 3, 8, SP2, I); 990 auto *M = DILocation::getMergedLocation(A, B); 991 EXPECT_EQ(2u, M->getLine()); 992 EXPECT_EQ(7u, M->getColumn()); 993 EXPECT_EQ(N, M->getScope()); 994 EXPECT_EQ(nullptr, M->getInlinedAt()); 995 } 996 997 { 998 // Different function, inlined-at same line, but different column. 999 auto *F = getFile(); 1000 auto *SP1 = DISubprogram::getDistinct(Context, F, "a", "a", F, 0, nullptr, 1001 0, nullptr, 0, 0, DINode::FlagZero, 1002 DISubprogram::SPFlagZero, nullptr); 1003 auto *SP2 = DISubprogram::getDistinct(Context, F, "b", "b", F, 0, nullptr, 1004 0, nullptr, 0, 0, DINode::FlagZero, 1005 DISubprogram::SPFlagZero, nullptr); 1006 1007 auto *IA = DILocation::get(Context, 2, 7, N); 1008 auto *IB = DILocation::get(Context, 2, 8, N); 1009 auto *A = DILocation::get(Context, 1, 6, SP1, IA); 1010 auto *B = DILocation::get(Context, 3, 8, SP2, IB); 1011 auto *M = DILocation::getMergedLocation(A, B); 1012 EXPECT_EQ(2u, M->getLine()); 1013 EXPECT_EQ(0u, M->getColumn()); 1014 EXPECT_EQ(N, M->getScope()); 1015 EXPECT_EQ(nullptr, M->getInlinedAt()); 1016 } 1017 1018 { 1019 // Completely different. 1020 auto *I = DILocation::get(Context, 2, 7, N); 1021 auto *A = DILocation::get(Context, 1, 6, S, I); 1022 auto *B = DILocation::get(Context, 2, 7, getSubprogram()); 1023 auto *M = DILocation::getMergedLocation(A, B); 1024 EXPECT_EQ(0u, M->getLine()); 1025 EXPECT_EQ(0u, M->getColumn()); 1026 EXPECT_TRUE(isa<DILocalScope>(M->getScope())); 1027 EXPECT_EQ(S, M->getScope()); 1028 EXPECT_EQ(nullptr, M->getInlinedAt()); 1029 } 1030 1031 // Two locations, same line/column different file, inlined at the same place. 1032 { 1033 auto *FA = getFile(); 1034 auto *FB = getFile(); 1035 auto *FI = getFile(); 1036 1037 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr, 1038 0, nullptr, 0, 0, DINode::FlagZero, 1039 DISubprogram::SPFlagZero, nullptr); 1040 1041 auto *SPB = DISubprogram::getDistinct(Context, FB, "b", "b", FB, 0, nullptr, 1042 0, nullptr, 0, 0, DINode::FlagZero, 1043 DISubprogram::SPFlagZero, nullptr); 1044 1045 auto *SPI = DISubprogram::getDistinct(Context, FI, "i", "i", FI, 0, nullptr, 1046 0, nullptr, 0, 0, DINode::FlagZero, 1047 DISubprogram::SPFlagZero, nullptr); 1048 1049 auto *I = DILocation::get(Context, 3, 8, SPI); 1050 auto *A = DILocation::get(Context, 2, 7, SPA, I); 1051 auto *B = DILocation::get(Context, 2, 7, SPB, I); 1052 auto *M = DILocation::getMergedLocation(A, B); 1053 EXPECT_EQ(3u, M->getLine()); 1054 EXPECT_EQ(8u, M->getColumn()); 1055 EXPECT_TRUE(isa<DILocalScope>(M->getScope())); 1056 EXPECT_EQ(SPI, M->getScope()); 1057 EXPECT_EQ(nullptr, M->getInlinedAt()); 1058 } 1059 1060 // Two locations, same line/column different file, one location with 2 scopes, 1061 // inlined at the same place. 1062 { 1063 auto *FA = getFile(); 1064 auto *FB = getFile(); 1065 auto *FI = getFile(); 1066 1067 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr, 1068 0, nullptr, 0, 0, DINode::FlagZero, 1069 DISubprogram::SPFlagZero, nullptr); 1070 1071 auto *SPB = DISubprogram::getDistinct(Context, FB, "b", "b", FB, 0, nullptr, 1072 0, nullptr, 0, 0, DINode::FlagZero, 1073 DISubprogram::SPFlagZero, nullptr); 1074 1075 auto *SPI = DISubprogram::getDistinct(Context, FI, "i", "i", FI, 0, nullptr, 1076 0, nullptr, 0, 0, DINode::FlagZero, 1077 DISubprogram::SPFlagZero, nullptr); 1078 1079 auto *SPAScope = DILexicalBlock::getDistinct(Context, SPA, FA, 4, 9); 1080 1081 auto *I = DILocation::get(Context, 3, 8, SPI); 1082 auto *A = DILocation::get(Context, 2, 7, SPAScope, I); 1083 auto *B = DILocation::get(Context, 2, 7, SPB, I); 1084 auto *M = DILocation::getMergedLocation(A, B); 1085 EXPECT_EQ(3u, M->getLine()); 1086 EXPECT_EQ(8u, M->getColumn()); 1087 EXPECT_TRUE(isa<DILocalScope>(M->getScope())); 1088 EXPECT_EQ(SPI, M->getScope()); 1089 EXPECT_EQ(nullptr, M->getInlinedAt()); 1090 } 1091 1092 // Merge a location in C, which is inlined-at in B that is inlined in A, 1093 // with a location in A that has the same scope, line and column as B's 1094 // inlined-at location. 1095 { 1096 auto *FA = getFile(); 1097 auto *FB = getFile(); 1098 auto *FC = getFile(); 1099 1100 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr, 1101 0, nullptr, 0, 0, DINode::FlagZero, 1102 DISubprogram::SPFlagZero, nullptr); 1103 1104 auto *SPB = DISubprogram::getDistinct(Context, FB, "b", "b", FB, 0, nullptr, 1105 0, nullptr, 0, 0, DINode::FlagZero, 1106 DISubprogram::SPFlagZero, nullptr); 1107 1108 auto *SPC = DISubprogram::getDistinct(Context, FC, "c", "c", FC, 0, nullptr, 1109 0, nullptr, 0, 0, DINode::FlagZero, 1110 DISubprogram::SPFlagZero, nullptr); 1111 1112 auto *A = DILocation::get(Context, 3, 2, SPA); 1113 auto *B = DILocation::get(Context, 2, 4, SPB, A); 1114 auto *C = DILocation::get(Context, 13, 2, SPC, B); 1115 auto *M = DILocation::getMergedLocation(A, C); 1116 EXPECT_EQ(3u, M->getLine()); 1117 EXPECT_EQ(2u, M->getColumn()); 1118 EXPECT_TRUE(isa<DILocalScope>(M->getScope())); 1119 EXPECT_EQ(SPA, M->getScope()); 1120 EXPECT_EQ(nullptr, M->getInlinedAt()); 1121 } 1122 1123 // Two inlined locations with the same scope, line and column 1124 // in the same inlined-at function at different line and column. 1125 { 1126 auto *FA = getFile(); 1127 auto *FB = getFile(); 1128 auto *FC = getFile(); 1129 1130 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr, 1131 0, nullptr, 0, 0, DINode::FlagZero, 1132 DISubprogram::SPFlagZero, nullptr); 1133 1134 auto *SPB = DISubprogram::getDistinct(Context, FB, "b", "b", FB, 0, nullptr, 1135 0, nullptr, 0, 0, DINode::FlagZero, 1136 DISubprogram::SPFlagZero, nullptr); 1137 1138 auto *SPC = DISubprogram::getDistinct(Context, FC, "c", "c", FC, 0, nullptr, 1139 0, nullptr, 0, 0, DINode::FlagZero, 1140 DISubprogram::SPFlagZero, nullptr); 1141 1142 auto *A = DILocation::get(Context, 10, 20, SPA); 1143 auto *B1 = DILocation::get(Context, 3, 2, SPB, A); 1144 auto *B2 = DILocation::get(Context, 4, 5, SPB, A); 1145 auto *C1 = DILocation::get(Context, 2, 4, SPC, B1); 1146 auto *C2 = DILocation::get(Context, 2, 4, SPC, B2); 1147 1148 auto *M = DILocation::getMergedLocation(C1, C2); 1149 EXPECT_EQ(2u, M->getLine()); 1150 EXPECT_EQ(4u, M->getColumn()); 1151 EXPECT_EQ(SPC, M->getScope()); 1152 ASSERT_NE(nullptr, M->getInlinedAt()); 1153 1154 auto *I1 = M->getInlinedAt(); 1155 EXPECT_EQ(0u, I1->getLine()); 1156 EXPECT_EQ(0u, I1->getColumn()); 1157 EXPECT_EQ(SPB, I1->getScope()); 1158 EXPECT_EQ(A, I1->getInlinedAt()); 1159 } 1160 1161 // Two locations, different line/column and scope in the same subprogram, 1162 // inlined at the same place. This should result in a 0:0 location with 1163 // the nearest common scope in the inlined function. 1164 { 1165 auto *FA = getFile(); 1166 auto *FI = getFile(); 1167 1168 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr, 1169 0, nullptr, 0, 0, DINode::FlagZero, 1170 DISubprogram::SPFlagZero, nullptr); 1171 1172 auto *SPI = DISubprogram::getDistinct(Context, FI, "i", "i", FI, 0, nullptr, 1173 0, nullptr, 0, 0, DINode::FlagZero, 1174 DISubprogram::SPFlagZero, nullptr); 1175 1176 // Nearest common scope for the two locations in a. 1177 auto *SPAScope1 = DILexicalBlock::getDistinct(Context, SPA, FA, 4, 9); 1178 1179 // Scope for the first location in a. 1180 auto *SPAScope2 = 1181 DILexicalBlock::getDistinct(Context, SPAScope1, FA, 10, 12); 1182 1183 // Scope for the second location in a. 1184 auto *SPAScope3 = 1185 DILexicalBlock::getDistinct(Context, SPAScope1, FA, 20, 8); 1186 auto *SPAScope4 = 1187 DILexicalBlock::getDistinct(Context, SPAScope3, FA, 21, 12); 1188 1189 auto *I = DILocation::get(Context, 3, 8, SPI); 1190 auto *A1 = DILocation::get(Context, 12, 7, SPAScope2, I); 1191 auto *A2 = DILocation::get(Context, 21, 15, SPAScope4, I); 1192 auto *M = DILocation::getMergedLocation(A1, A2); 1193 EXPECT_EQ(0u, M->getLine()); 1194 EXPECT_EQ(0u, M->getColumn()); 1195 EXPECT_TRUE(isa<DILocalScope>(M->getScope())); 1196 EXPECT_EQ(SPAScope1, M->getScope()); 1197 EXPECT_EQ(I, M->getInlinedAt()); 1198 } 1199 1200 // Regression test to catch a case where an iterator was invalidated due to 1201 // handling the chain of inlined-at locations after the nearest common 1202 // location for the two arguments were found. 1203 { 1204 auto *FA = getFile(); 1205 auto *FB = getFile(); 1206 auto *FI = getFile(); 1207 1208 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr, 1209 0, nullptr, 0, 0, DINode::FlagZero, 1210 DISubprogram::SPFlagZero, nullptr); 1211 1212 auto *SPB = DISubprogram::getDistinct(Context, FB, "b", "b", FB, 0, nullptr, 1213 0, nullptr, 0, 0, DINode::FlagZero, 1214 DISubprogram::SPFlagZero, nullptr); 1215 1216 auto *SPI = DISubprogram::getDistinct(Context, FI, "i", "i", FI, 0, nullptr, 1217 0, nullptr, 0, 0, DINode::FlagZero, 1218 DISubprogram::SPFlagZero, nullptr); 1219 1220 auto *SPAScope1 = DILexicalBlock::getDistinct(Context, SPA, FA, 4, 9); 1221 auto *SPAScope2 = DILexicalBlock::getDistinct(Context, SPA, FA, 8, 3); 1222 1223 DILocation *InlinedAt = nullptr; 1224 1225 // Create a chain of inlined-at locations. 1226 for (int i = 0; i < 256; i++) { 1227 InlinedAt = DILocation::get(Context, 3 + i, 8 + i, SPI, InlinedAt); 1228 } 1229 1230 auto *A1 = DILocation::get(Context, 5, 9, SPAScope1, InlinedAt); 1231 auto *A2 = DILocation::get(Context, 9, 8, SPAScope2, InlinedAt); 1232 auto *B = DILocation::get(Context, 10, 3, SPB, A1); 1233 auto *M1 = DILocation::getMergedLocation(B, A2); 1234 EXPECT_EQ(0u, M1->getLine()); 1235 EXPECT_EQ(0u, M1->getColumn()); 1236 EXPECT_TRUE(isa<DILocalScope>(M1->getScope())); 1237 EXPECT_EQ(SPA, M1->getScope()); 1238 EXPECT_EQ(InlinedAt, M1->getInlinedAt()); 1239 1240 // Test the other argument order for good measure. 1241 auto *M2 = DILocation::getMergedLocation(A2, B); 1242 EXPECT_EQ(M1, M2); 1243 } 1244 } 1245 1246 TEST_F(DILocationTest, getDistinct) { 1247 MDNode *N = getSubprogram(); 1248 DILocation *L0 = DILocation::getDistinct(Context, 2, 7, N); 1249 EXPECT_TRUE(L0->isDistinct()); 1250 DILocation *L1 = DILocation::get(Context, 2, 7, N); 1251 EXPECT_FALSE(L1->isDistinct()); 1252 EXPECT_EQ(L1, DILocation::get(Context, 2, 7, N)); 1253 } 1254 1255 TEST_F(DILocationTest, getTemporary) { 1256 MDNode *N = MDNode::get(Context, {}); 1257 auto L = DILocation::getTemporary(Context, 2, 7, N); 1258 EXPECT_TRUE(L->isTemporary()); 1259 EXPECT_FALSE(L->isResolved()); 1260 } 1261 1262 TEST_F(DILocationTest, cloneTemporary) { 1263 MDNode *N = MDNode::get(Context, {}); 1264 auto L = DILocation::getTemporary(Context, 2, 7, N); 1265 EXPECT_TRUE(L->isTemporary()); 1266 auto L2 = L->clone(); 1267 EXPECT_TRUE(L2->isTemporary()); 1268 } 1269 1270 TEST_F(DILocationTest, discriminatorEncoding) { 1271 EXPECT_EQ(0U, *DILocation::encodeDiscriminator(0, 0, 0)); 1272 1273 // Encode base discriminator as a component: lsb is 0, then the value. 1274 // The other components are all absent, so we leave all the other bits 0. 1275 EXPECT_EQ(2U, *DILocation::encodeDiscriminator(1, 0, 0)); 1276 1277 // Base discriminator component is empty, so lsb is 1. Next component is not 1278 // empty, so its lsb is 0, then its value (1). Next component is empty. 1279 // So the bit pattern is 101. 1280 EXPECT_EQ(5U, *DILocation::encodeDiscriminator(0, 1, 0)); 1281 1282 // First 2 components are empty, so the bit pattern is 11. Then the 1283 // next component - ending up with 1011. 1284 EXPECT_EQ(0xbU, *DILocation::encodeDiscriminator(0, 0, 1)); 1285 1286 // The bit pattern for the first 2 components is 11. The next bit is 0, 1287 // because the last component is not empty. We have 29 bits usable for 1288 // encoding, but we cap it at 12 bits uniformously for all components. We 1289 // encode the last component over 14 bits. 1290 EXPECT_EQ(0xfffbU, *DILocation::encodeDiscriminator(0, 0, 0xfff)); 1291 1292 EXPECT_EQ(0x102U, *DILocation::encodeDiscriminator(1, 1, 0)); 1293 1294 EXPECT_EQ(0x13eU, *DILocation::encodeDiscriminator(0x1f, 1, 0)); 1295 1296 EXPECT_EQ(0x87feU, *DILocation::encodeDiscriminator(0x1ff, 1, 0)); 1297 1298 EXPECT_EQ(0x1f3eU, *DILocation::encodeDiscriminator(0x1f, 0x1f, 0)); 1299 1300 EXPECT_EQ(0x3ff3eU, *DILocation::encodeDiscriminator(0x1f, 0x1ff, 0)); 1301 1302 EXPECT_EQ(0x1ff87feU, *DILocation::encodeDiscriminator(0x1ff, 0x1ff, 0)); 1303 1304 EXPECT_EQ(0xfff9f3eU, *DILocation::encodeDiscriminator(0x1f, 0x1f, 0xfff)); 1305 1306 EXPECT_EQ(0xffc3ff3eU, *DILocation::encodeDiscriminator(0x1f, 0x1ff, 0x1ff)); 1307 1308 EXPECT_EQ(0xffcf87feU, *DILocation::encodeDiscriminator(0x1ff, 0x1f, 0x1ff)); 1309 1310 EXPECT_EQ(0xe1ff87feU, *DILocation::encodeDiscriminator(0x1ff, 0x1ff, 7)); 1311 } 1312 1313 TEST_F(DILocationTest, discriminatorEncodingNegativeTests) { 1314 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator(0, 0, 0x1000)); 1315 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator(0x1000, 0, 0)); 1316 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator(0, 0x1000, 0)); 1317 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator(0, 0, 0x1000)); 1318 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator(0x1ff, 0x1ff, 8)); 1319 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator( 1320 std::numeric_limits<uint32_t>::max(), 1321 std::numeric_limits<uint32_t>::max(), 0)); 1322 } 1323 1324 TEST_F(DILocationTest, discriminatorSpecialCases) { 1325 // We don't test getCopyIdentifier here because the only way 1326 // to set it is by constructing an encoded discriminator using 1327 // encodeDiscriminator, which is already tested. 1328 auto L1 = DILocation::get(Context, 1, 2, getSubprogram()); 1329 EXPECT_EQ(0U, L1->getBaseDiscriminator()); 1330 EXPECT_EQ(1U, L1->getDuplicationFactor()); 1331 1332 EXPECT_EQ(L1, *L1->cloneWithBaseDiscriminator(0)); 1333 EXPECT_EQ(L1, *L1->cloneByMultiplyingDuplicationFactor(0)); 1334 EXPECT_EQ(L1, *L1->cloneByMultiplyingDuplicationFactor(1)); 1335 1336 auto L2 = *L1->cloneWithBaseDiscriminator(1); 1337 EXPECT_EQ(0U, L1->getBaseDiscriminator()); 1338 EXPECT_EQ(1U, L1->getDuplicationFactor()); 1339 1340 EXPECT_EQ(1U, L2->getBaseDiscriminator()); 1341 EXPECT_EQ(1U, L2->getDuplicationFactor()); 1342 1343 auto L3 = *L2->cloneByMultiplyingDuplicationFactor(2); 1344 EXPECT_EQ(1U, L3->getBaseDiscriminator()); 1345 EXPECT_EQ(2U, L3->getDuplicationFactor()); 1346 1347 EXPECT_EQ(L2, *L2->cloneByMultiplyingDuplicationFactor(1)); 1348 1349 auto L4 = *L3->cloneByMultiplyingDuplicationFactor(4); 1350 EXPECT_EQ(1U, L4->getBaseDiscriminator()); 1351 EXPECT_EQ(8U, L4->getDuplicationFactor()); 1352 1353 auto L5 = *L4->cloneWithBaseDiscriminator(2); 1354 EXPECT_EQ(2U, L5->getBaseDiscriminator()); 1355 EXPECT_EQ(8U, L5->getDuplicationFactor()); 1356 1357 // Check extreme cases 1358 auto L6 = *L1->cloneWithBaseDiscriminator(0xfff); 1359 EXPECT_EQ(0xfffU, L6->getBaseDiscriminator()); 1360 EXPECT_EQ(0xfffU, (*L6->cloneByMultiplyingDuplicationFactor(0xfff)) 1361 ->getDuplicationFactor()); 1362 1363 // Check we return std::nullopt for unencodable cases. 1364 EXPECT_EQ(std::nullopt, L4->cloneWithBaseDiscriminator(0x1000)); 1365 EXPECT_EQ(std::nullopt, L4->cloneByMultiplyingDuplicationFactor(0x1000)); 1366 } 1367 1368 1369 typedef MetadataTest GenericDINodeTest; 1370 1371 TEST_F(GenericDINodeTest, get) { 1372 StringRef Header = "header"; 1373 auto *Empty = MDNode::get(Context, {}); 1374 Metadata *Ops1[] = {Empty}; 1375 auto *N = GenericDINode::get(Context, 15, Header, Ops1); 1376 EXPECT_EQ(15u, N->getTag()); 1377 EXPECT_EQ(2u, N->getNumOperands()); 1378 EXPECT_EQ(Header, N->getHeader()); 1379 EXPECT_EQ(MDString::get(Context, Header), N->getOperand(0)); 1380 EXPECT_EQ(1u, N->getNumDwarfOperands()); 1381 EXPECT_EQ(Empty, N->getDwarfOperand(0)); 1382 EXPECT_EQ(Empty, N->getOperand(1)); 1383 ASSERT_TRUE(N->isUniqued()); 1384 1385 EXPECT_EQ(N, GenericDINode::get(Context, 15, Header, Ops1)); 1386 1387 N->replaceOperandWith(1, nullptr); 1388 EXPECT_EQ(15u, N->getTag()); 1389 EXPECT_EQ(Header, N->getHeader()); 1390 EXPECT_EQ(nullptr, N->getDwarfOperand(0)); 1391 ASSERT_TRUE(N->isUniqued()); 1392 1393 Metadata *Ops2[] = {nullptr}; 1394 EXPECT_EQ(N, GenericDINode::get(Context, 15, Header, Ops2)); 1395 1396 N->replaceDwarfOperandWith(0, Empty); 1397 EXPECT_EQ(15u, N->getTag()); 1398 EXPECT_EQ(Header, N->getHeader()); 1399 EXPECT_EQ(Empty, N->getDwarfOperand(0)); 1400 ASSERT_TRUE(N->isUniqued()); 1401 EXPECT_EQ(N, GenericDINode::get(Context, 15, Header, Ops1)); 1402 1403 TempGenericDINode Temp = N->clone(); 1404 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1405 } 1406 1407 TEST_F(GenericDINodeTest, getEmptyHeader) { 1408 // Canonicalize !"" to null. 1409 auto *N = GenericDINode::get(Context, 15, StringRef(), {}); 1410 EXPECT_EQ(StringRef(), N->getHeader()); 1411 EXPECT_EQ(nullptr, N->getOperand(0)); 1412 } 1413 1414 typedef MetadataTest DISubrangeTest; 1415 1416 TEST_F(DISubrangeTest, get) { 1417 auto *N = DISubrange::get(Context, 5, 7); 1418 auto Count = N->getCount(); 1419 auto Lower = N->getLowerBound(); 1420 EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag()); 1421 ASSERT_TRUE(Count); 1422 ASSERT_TRUE(isa<ConstantInt *>(Count)); 1423 EXPECT_EQ(5, cast<ConstantInt *>(Count)->getSExtValue()); 1424 EXPECT_EQ(7, cast<ConstantInt *>(Lower)->getSExtValue()); 1425 EXPECT_EQ(N, DISubrange::get(Context, 5, 7)); 1426 EXPECT_EQ(DISubrange::get(Context, 5, 0), DISubrange::get(Context, 5)); 1427 1428 TempDISubrange Temp = N->clone(); 1429 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1430 } 1431 1432 TEST_F(DISubrangeTest, getEmptyArray) { 1433 auto *N = DISubrange::get(Context, -1, 0); 1434 auto Count = N->getCount(); 1435 auto Lower = N->getLowerBound(); 1436 EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag()); 1437 ASSERT_TRUE(Count); 1438 ASSERT_TRUE(isa<ConstantInt *>(Count)); 1439 EXPECT_EQ(-1, cast<ConstantInt *>(Count)->getSExtValue()); 1440 EXPECT_EQ(0, cast<ConstantInt *>(Lower)->getSExtValue()); 1441 EXPECT_EQ(N, DISubrange::get(Context, -1, 0)); 1442 } 1443 1444 TEST_F(DISubrangeTest, getVariableCount) { 1445 DILocalScope *Scope = getSubprogram(); 1446 DIFile *File = getFile(); 1447 DIType *Type = getDerivedType(); 1448 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1449 auto *VlaExpr = DILocalVariable::get(Context, Scope, "vla_expr", File, 8, 1450 Type, 2, Flags, 8, nullptr); 1451 1452 auto *N = DISubrange::get(Context, VlaExpr, 0); 1453 auto Count = N->getCount(); 1454 auto Lower = N->getLowerBound(); 1455 ASSERT_TRUE(Count); 1456 ASSERT_TRUE(isa<DIVariable *>(Count)); 1457 EXPECT_EQ(VlaExpr, cast<DIVariable *>(Count)); 1458 ASSERT_TRUE(isa<DIVariable>(N->getRawCountNode())); 1459 EXPECT_EQ(0, cast<ConstantInt *>(Lower)->getSExtValue()); 1460 EXPECT_EQ("vla_expr", cast<DIVariable *>(Count)->getName()); 1461 EXPECT_EQ(N, DISubrange::get(Context, VlaExpr, 0)); 1462 } 1463 1464 TEST_F(DISubrangeTest, fortranAllocatableInt) { 1465 DILocalScope *Scope = getSubprogram(); 1466 DIFile *File = getFile(); 1467 DIType *Type = getDerivedType(); 1468 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1469 auto *LI = ConstantAsMetadata::get( 1470 ConstantInt::getSigned(Type::getInt64Ty(Context), -10)); 1471 auto *UI = ConstantAsMetadata::get( 1472 ConstantInt::getSigned(Type::getInt64Ty(Context), 10)); 1473 auto *SI = ConstantAsMetadata::get( 1474 ConstantInt::getSigned(Type::getInt64Ty(Context), 4)); 1475 auto *UIother = ConstantAsMetadata::get( 1476 ConstantInt::getSigned(Type::getInt64Ty(Context), 20)); 1477 auto *UVother = DILocalVariable::get(Context, Scope, "ubother", File, 8, Type, 1478 2, Flags, 8, nullptr); 1479 auto *UEother = DIExpression::get(Context, {5, 6}); 1480 auto *LIZero = ConstantAsMetadata::get( 1481 ConstantInt::getSigned(Type::getInt64Ty(Context), 0)); 1482 auto *UIZero = ConstantAsMetadata::get( 1483 ConstantInt::getSigned(Type::getInt64Ty(Context), 0)); 1484 1485 auto *N = DISubrange::get(Context, nullptr, LI, UI, SI); 1486 1487 auto Lower = N->getLowerBound(); 1488 ASSERT_TRUE(Lower); 1489 ASSERT_TRUE(isa<ConstantInt *>(Lower)); 1490 EXPECT_EQ(cast<ConstantInt>(LI->getValue()), cast<ConstantInt *>(Lower)); 1491 1492 auto Upper = N->getUpperBound(); 1493 ASSERT_TRUE(Upper); 1494 ASSERT_TRUE(isa<ConstantInt *>(Upper)); 1495 EXPECT_EQ(cast<ConstantInt>(UI->getValue()), cast<ConstantInt *>(Upper)); 1496 1497 auto Stride = N->getStride(); 1498 ASSERT_TRUE(Stride); 1499 ASSERT_TRUE(isa<ConstantInt *>(Stride)); 1500 EXPECT_EQ(cast<ConstantInt>(SI->getValue()), cast<ConstantInt *>(Stride)); 1501 1502 EXPECT_EQ(N, DISubrange::get(Context, nullptr, LI, UI, SI)); 1503 1504 EXPECT_NE(N, DISubrange::get(Context, nullptr, LI, UIother, SI)); 1505 EXPECT_NE(N, DISubrange::get(Context, nullptr, LI, UEother, SI)); 1506 EXPECT_NE(N, DISubrange::get(Context, nullptr, LI, UVother, SI)); 1507 1508 auto *NZeroLower = DISubrange::get(Context, nullptr, LIZero, UI, SI); 1509 EXPECT_NE(NZeroLower, DISubrange::get(Context, nullptr, nullptr, UI, SI)); 1510 1511 auto *NZeroUpper = DISubrange::get(Context, nullptr, LI, UIZero, SI); 1512 EXPECT_NE(NZeroUpper, DISubrange::get(Context, nullptr, LI, nullptr, SI)); 1513 } 1514 1515 TEST_F(DISubrangeTest, fortranAllocatableVar) { 1516 DILocalScope *Scope = getSubprogram(); 1517 DIFile *File = getFile(); 1518 DIType *Type = getDerivedType(); 1519 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1520 auto *LV = 1521 DILocalVariable::get(Context, Scope, "lb", File, 8, Type, 2, Flags, 8, 1522 nullptr); 1523 auto *UV = 1524 DILocalVariable::get(Context, Scope, "ub", File, 8, Type, 2, Flags, 8, 1525 nullptr); 1526 auto *SV = 1527 DILocalVariable::get(Context, Scope, "st", File, 8, Type, 2, Flags, 8, 1528 nullptr); 1529 auto *SVother = DILocalVariable::get(Context, Scope, "stother", File, 8, Type, 1530 2, Flags, 8, nullptr); 1531 auto *SIother = ConstantAsMetadata::get( 1532 ConstantInt::getSigned(Type::getInt64Ty(Context), 20)); 1533 auto *SEother = DIExpression::get(Context, {5, 6}); 1534 1535 auto *N = DISubrange::get(Context, nullptr, LV, UV, SV); 1536 1537 auto Lower = N->getLowerBound(); 1538 ASSERT_TRUE(Lower); 1539 ASSERT_TRUE(isa<DIVariable *>(Lower)); 1540 EXPECT_EQ(LV, cast<DIVariable *>(Lower)); 1541 1542 auto Upper = N->getUpperBound(); 1543 ASSERT_TRUE(Upper); 1544 ASSERT_TRUE(isa<DIVariable *>(Upper)); 1545 EXPECT_EQ(UV, cast<DIVariable *>(Upper)); 1546 1547 auto Stride = N->getStride(); 1548 ASSERT_TRUE(Stride); 1549 ASSERT_TRUE(isa<DIVariable *>(Stride)); 1550 EXPECT_EQ(SV, cast<DIVariable *>(Stride)); 1551 1552 EXPECT_EQ(N, DISubrange::get(Context, nullptr, LV, UV, SV)); 1553 1554 EXPECT_NE(N, DISubrange::get(Context, nullptr, LV, UV, SVother)); 1555 EXPECT_NE(N, DISubrange::get(Context, nullptr, LV, UV, SEother)); 1556 EXPECT_NE(N, DISubrange::get(Context, nullptr, LV, UV, SIother)); 1557 } 1558 1559 TEST_F(DISubrangeTest, fortranAllocatableExpr) { 1560 DILocalScope *Scope = getSubprogram(); 1561 DIFile *File = getFile(); 1562 DIType *Type = getDerivedType(); 1563 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1564 auto *LE = DIExpression::get(Context, {1, 2}); 1565 auto *UE = DIExpression::get(Context, {2, 3}); 1566 auto *SE = DIExpression::get(Context, {3, 4}); 1567 auto *LEother = DIExpression::get(Context, {5, 6}); 1568 auto *LIother = ConstantAsMetadata::get( 1569 ConstantInt::getSigned(Type::getInt64Ty(Context), 20)); 1570 auto *LVother = DILocalVariable::get(Context, Scope, "lbother", File, 8, Type, 1571 2, Flags, 8, nullptr); 1572 1573 auto *N = DISubrange::get(Context, nullptr, LE, UE, SE); 1574 1575 auto Lower = N->getLowerBound(); 1576 ASSERT_TRUE(Lower); 1577 ASSERT_TRUE(isa<DIExpression *>(Lower)); 1578 EXPECT_EQ(LE, cast<DIExpression *>(Lower)); 1579 1580 auto Upper = N->getUpperBound(); 1581 ASSERT_TRUE(Upper); 1582 ASSERT_TRUE(isa<DIExpression *>(Upper)); 1583 EXPECT_EQ(UE, cast<DIExpression *>(Upper)); 1584 1585 auto Stride = N->getStride(); 1586 ASSERT_TRUE(Stride); 1587 ASSERT_TRUE(isa<DIExpression *>(Stride)); 1588 EXPECT_EQ(SE, cast<DIExpression *>(Stride)); 1589 1590 EXPECT_EQ(N, DISubrange::get(Context, nullptr, LE, UE, SE)); 1591 1592 EXPECT_NE(N, DISubrange::get(Context, nullptr, LEother, UE, SE)); 1593 EXPECT_NE(N, DISubrange::get(Context, nullptr, LIother, UE, SE)); 1594 EXPECT_NE(N, DISubrange::get(Context, nullptr, LVother, UE, SE)); 1595 } 1596 1597 typedef MetadataTest DIGenericSubrangeTest; 1598 1599 TEST_F(DIGenericSubrangeTest, fortranAssumedRankInt) { 1600 DILocalScope *Scope = getSubprogram(); 1601 DIFile *File = getFile(); 1602 DIType *Type = getDerivedType(); 1603 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1604 auto *LI = DIExpression::get( 1605 Context, {dwarf::DW_OP_consts, static_cast<uint64_t>(-10)}); 1606 auto *UI = DIExpression::get(Context, {dwarf::DW_OP_consts, 10}); 1607 auto *SI = DIExpression::get(Context, {dwarf::DW_OP_consts, 4}); 1608 auto *UIother = DIExpression::get(Context, {dwarf::DW_OP_consts, 20}); 1609 auto *UVother = DILocalVariable::get(Context, Scope, "ubother", File, 8, Type, 1610 2, Flags, 8, nullptr); 1611 auto *UEother = DIExpression::get(Context, {5, 6}); 1612 auto *LIZero = DIExpression::get(Context, {dwarf::DW_OP_consts, 0}); 1613 auto *UIZero = DIExpression::get(Context, {dwarf::DW_OP_consts, 0}); 1614 1615 auto *N = DIGenericSubrange::get(Context, nullptr, LI, UI, SI); 1616 1617 auto Lower = N->getLowerBound(); 1618 ASSERT_TRUE(Lower); 1619 ASSERT_TRUE(isa<DIExpression *>(Lower)); 1620 EXPECT_EQ(dyn_cast_or_null<DIExpression>(LI), cast<DIExpression *>(Lower)); 1621 1622 auto Upper = N->getUpperBound(); 1623 ASSERT_TRUE(Upper); 1624 ASSERT_TRUE(isa<DIExpression *>(Upper)); 1625 EXPECT_EQ(dyn_cast_or_null<DIExpression>(UI), cast<DIExpression *>(Upper)); 1626 1627 auto Stride = N->getStride(); 1628 ASSERT_TRUE(Stride); 1629 ASSERT_TRUE(isa<DIExpression *>(Stride)); 1630 EXPECT_EQ(dyn_cast_or_null<DIExpression>(SI), cast<DIExpression *>(Stride)); 1631 1632 EXPECT_EQ(N, DIGenericSubrange::get(Context, nullptr, LI, UI, SI)); 1633 1634 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LI, UIother, SI)); 1635 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LI, UEother, SI)); 1636 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LI, UVother, SI)); 1637 1638 auto *NZeroLower = DIGenericSubrange::get(Context, nullptr, LIZero, UI, SI); 1639 EXPECT_NE(NZeroLower, 1640 DIGenericSubrange::get(Context, nullptr, nullptr, UI, SI)); 1641 1642 auto *NZeroUpper = DIGenericSubrange::get(Context, nullptr, LI, UIZero, SI); 1643 EXPECT_NE(NZeroUpper, 1644 DIGenericSubrange::get(Context, nullptr, LI, nullptr, SI)); 1645 } 1646 1647 TEST_F(DIGenericSubrangeTest, fortranAssumedRankVar) { 1648 DILocalScope *Scope = getSubprogram(); 1649 DIFile *File = getFile(); 1650 DIType *Type = getDerivedType(); 1651 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1652 auto *LV = 1653 DILocalVariable::get(Context, Scope, "lb", File, 8, Type, 2, Flags, 8, 1654 nullptr); 1655 auto *UV = 1656 DILocalVariable::get(Context, Scope, "ub", File, 8, Type, 2, Flags, 8, 1657 nullptr); 1658 auto *SV = 1659 DILocalVariable::get(Context, Scope, "st", File, 8, Type, 2, Flags, 8, 1660 nullptr); 1661 auto *SVother = DILocalVariable::get(Context, Scope, "stother", File, 8, Type, 1662 2, Flags, 8, nullptr); 1663 auto *SIother = DIExpression::get( 1664 Context, {dwarf::DW_OP_consts, static_cast<uint64_t>(-1)}); 1665 auto *SEother = DIExpression::get(Context, {5, 6}); 1666 1667 auto *N = DIGenericSubrange::get(Context, nullptr, LV, UV, SV); 1668 1669 auto Lower = N->getLowerBound(); 1670 ASSERT_TRUE(Lower); 1671 ASSERT_TRUE(isa<DIVariable *>(Lower)); 1672 EXPECT_EQ(LV, cast<DIVariable *>(Lower)); 1673 1674 auto Upper = N->getUpperBound(); 1675 ASSERT_TRUE(Upper); 1676 ASSERT_TRUE(isa<DIVariable *>(Upper)); 1677 EXPECT_EQ(UV, cast<DIVariable *>(Upper)); 1678 1679 auto Stride = N->getStride(); 1680 ASSERT_TRUE(Stride); 1681 ASSERT_TRUE(isa<DIVariable *>(Stride)); 1682 EXPECT_EQ(SV, cast<DIVariable *>(Stride)); 1683 1684 EXPECT_EQ(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SV)); 1685 1686 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SVother)); 1687 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SEother)); 1688 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SIother)); 1689 } 1690 1691 TEST_F(DIGenericSubrangeTest, useDIBuilder) { 1692 DILocalScope *Scope = getSubprogram(); 1693 DIFile *File = getFile(); 1694 DIType *Type = getDerivedType(); 1695 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1696 auto *LV = 1697 DILocalVariable::get(Context, Scope, "lb", File, 8, Type, 2, Flags, 8, nullptr); 1698 auto *UE = DIExpression::get(Context, {2, 3}); 1699 auto *SE = DIExpression::get(Context, {3, 4}); 1700 1701 auto *LVother = DILocalVariable::get(Context, Scope, "lbother", File, 8, Type, 1702 2, Flags, 8, nullptr); 1703 auto *LIother = DIExpression::get( 1704 Context, {dwarf::DW_OP_consts, static_cast<uint64_t>(-1)}); 1705 1706 Module M("M", Context); 1707 DIBuilder DIB(M); 1708 1709 auto *N = DIB.getOrCreateGenericSubrange( 1710 DIGenericSubrange::BoundType(nullptr), DIGenericSubrange::BoundType(LV), 1711 DIGenericSubrange::BoundType(UE), DIGenericSubrange::BoundType(SE)); 1712 1713 auto Lower = N->getLowerBound(); 1714 ASSERT_TRUE(Lower); 1715 ASSERT_TRUE(isa<DIVariable *>(Lower)); 1716 EXPECT_EQ(LV, cast<DIVariable *>(Lower)); 1717 1718 auto Upper = N->getUpperBound(); 1719 ASSERT_TRUE(Upper); 1720 ASSERT_TRUE(isa<DIExpression *>(Upper)); 1721 EXPECT_EQ(UE, cast<DIExpression *>(Upper)); 1722 1723 auto Stride = N->getStride(); 1724 ASSERT_TRUE(Stride); 1725 ASSERT_TRUE(isa<DIExpression *>(Stride)); 1726 EXPECT_EQ(SE, cast<DIExpression *>(Stride)); 1727 1728 EXPECT_EQ( 1729 N, DIB.getOrCreateGenericSubrange(DIGenericSubrange::BoundType(nullptr), 1730 DIGenericSubrange::BoundType(LV), 1731 DIGenericSubrange::BoundType(UE), 1732 DIGenericSubrange::BoundType(SE))); 1733 1734 EXPECT_NE( 1735 N, DIB.getOrCreateGenericSubrange(DIGenericSubrange::BoundType(nullptr), 1736 DIGenericSubrange::BoundType(LVother), 1737 DIGenericSubrange::BoundType(UE), 1738 DIGenericSubrange::BoundType(SE))); 1739 EXPECT_NE( 1740 N, DIB.getOrCreateGenericSubrange(DIGenericSubrange::BoundType(nullptr), 1741 DIGenericSubrange::BoundType(LIother), 1742 DIGenericSubrange::BoundType(UE), 1743 DIGenericSubrange::BoundType(SE))); 1744 } 1745 typedef MetadataTest DIEnumeratorTest; 1746 1747 TEST_F(DIEnumeratorTest, get) { 1748 auto *N = DIEnumerator::get(Context, 7, false, "name"); 1749 EXPECT_EQ(dwarf::DW_TAG_enumerator, N->getTag()); 1750 EXPECT_EQ(7, N->getValue().getSExtValue()); 1751 EXPECT_FALSE(N->isUnsigned()); 1752 EXPECT_EQ("name", N->getName()); 1753 EXPECT_EQ(N, DIEnumerator::get(Context, 7, false, "name")); 1754 1755 EXPECT_NE(N, DIEnumerator::get(Context, 7, true, "name")); 1756 EXPECT_NE(N, DIEnumerator::get(Context, 8, false, "name")); 1757 EXPECT_NE(N, DIEnumerator::get(Context, 7, false, "nam")); 1758 1759 TempDIEnumerator Temp = N->clone(); 1760 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1761 } 1762 1763 TEST_F(DIEnumeratorTest, getWithLargeValues) { 1764 auto *N = DIEnumerator::get(Context, APInt::getMaxValue(128), false, "val"); 1765 EXPECT_EQ(128U, N->getValue().popcount()); 1766 EXPECT_EQ(N, 1767 DIEnumerator::get(Context, APInt::getMaxValue(128), false, "val")); 1768 EXPECT_NE(N, 1769 DIEnumerator::get(Context, APInt::getMinValue(128), false, "val")); 1770 } 1771 1772 typedef MetadataTest DIBasicTypeTest; 1773 1774 TEST_F(DIBasicTypeTest, get) { 1775 auto *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1776 26, 7, 100, DINode::FlagZero); 1777 EXPECT_EQ(dwarf::DW_TAG_base_type, N->getTag()); 1778 EXPECT_EQ("special", N->getName()); 1779 EXPECT_EQ(33u, N->getSizeInBits()); 1780 EXPECT_EQ(26u, N->getAlignInBits()); 1781 EXPECT_EQ(7u, N->getEncoding()); 1782 EXPECT_EQ(0u, N->getLine()); 1783 EXPECT_EQ(100u, N->getNumExtraInhabitants()); 1784 EXPECT_EQ(DINode::FlagZero, N->getFlags()); 1785 EXPECT_EQ(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1786 26, 7, 100, DINode::FlagZero)); 1787 1788 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, 1789 "special", 33, 26, 7, 100, DINode::FlagZero)); 1790 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 1791 7, 100, DINode::FlagZero)); 1792 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 32, 1793 26, 7, 100, DINode::FlagZero)); 1794 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1795 25, 7, 100, DINode::FlagZero)); 1796 1797 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1798 26, 7, 99, DINode::FlagZero)); 1799 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1800 26, 6, 100, DINode::FlagZero)); 1801 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1802 26, 7, 100, DINode::FlagBigEndian)); 1803 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1804 26, 7, 100, DINode::FlagLittleEndian)); 1805 1806 TempDIBasicType Temp = N->clone(); 1807 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1808 } 1809 1810 TEST_F(DIBasicTypeTest, getWithLargeValues) { 1811 auto *N = 1812 DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", UINT64_MAX, 1813 UINT32_MAX - 1, 7, UINT32_MAX, DINode::FlagZero); 1814 EXPECT_EQ(UINT64_MAX, N->getSizeInBits()); 1815 EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits()); 1816 EXPECT_EQ(UINT32_MAX, N->getNumExtraInhabitants()); 1817 } 1818 1819 TEST_F(DIBasicTypeTest, getUnspecified) { 1820 auto *N = 1821 DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, "unspecified"); 1822 EXPECT_EQ(dwarf::DW_TAG_unspecified_type, N->getTag()); 1823 EXPECT_EQ("unspecified", N->getName()); 1824 EXPECT_EQ(0u, N->getSizeInBits()); 1825 EXPECT_EQ(0u, N->getAlignInBits()); 1826 EXPECT_EQ(0u, N->getEncoding()); 1827 EXPECT_EQ(0u, N->getLine()); 1828 EXPECT_EQ(DINode::FlagZero, N->getFlags()); 1829 } 1830 1831 typedef MetadataTest DITypeTest; 1832 1833 TEST_F(DITypeTest, clone) { 1834 // Check that DIType has a specialized clone that returns TempDIType. 1835 DIType *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "int", 32, 32, 1836 0, dwarf::DW_ATE_signed, DINode::FlagZero); 1837 1838 TempDIType Temp = N->clone(); 1839 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1840 } 1841 1842 TEST_F(DITypeTest, cloneWithFlags) { 1843 // void (void) 1844 Metadata *TypesOps[] = {nullptr}; 1845 Metadata *Types = MDTuple::get(Context, TypesOps); 1846 1847 DIType *D = 1848 DISubroutineType::getDistinct(Context, DINode::FlagZero, 0, Types); 1849 EXPECT_EQ(DINode::FlagZero, D->getFlags()); 1850 TempDIType D2 = D->cloneWithFlags(DINode::FlagRValueReference); 1851 EXPECT_EQ(DINode::FlagRValueReference, D2->getFlags()); 1852 EXPECT_EQ(DINode::FlagZero, D->getFlags()); 1853 1854 TempDIType T = 1855 DISubroutineType::getTemporary(Context, DINode::FlagZero, 0, Types); 1856 EXPECT_EQ(DINode::FlagZero, T->getFlags()); 1857 TempDIType T2 = T->cloneWithFlags(DINode::FlagRValueReference); 1858 EXPECT_EQ(DINode::FlagRValueReference, T2->getFlags()); 1859 EXPECT_EQ(DINode::FlagZero, T->getFlags()); 1860 } 1861 1862 typedef MetadataTest DIDerivedTypeTest; 1863 1864 TEST_F(DIDerivedTypeTest, get) { 1865 DIFile *File = getFile(); 1866 DIScope *Scope = getSubprogram(); 1867 DIType *BaseType = getBasicType("basic"); 1868 MDTuple *ExtraData = getTuple(); 1869 unsigned DWARFAddressSpace = 8; 1870 DIDerivedType::PtrAuthData PtrAuthData(1, false, 1234, true, true); 1871 DIDerivedType::PtrAuthData PtrAuthData2(1, false, 1234, true, false); 1872 DINode::DIFlags Flags5 = static_cast<DINode::DIFlags>(5); 1873 DINode::DIFlags Flags4 = static_cast<DINode::DIFlags>(4); 1874 1875 auto *N = DIDerivedType::get( 1876 Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, 1877 BaseType, 2, 3, 4, DWARFAddressSpace, std::nullopt, Flags5, ExtraData); 1878 auto *N1 = DIDerivedType::get(Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", 1879 File, 1, Scope, N, 2, 3, 4, DWARFAddressSpace, 1880 PtrAuthData, Flags5, ExtraData); 1881 EXPECT_EQ(dwarf::DW_TAG_pointer_type, N->getTag()); 1882 EXPECT_EQ("something", N->getName()); 1883 EXPECT_EQ(File, N->getFile()); 1884 EXPECT_EQ(1u, N->getLine()); 1885 EXPECT_EQ(Scope, N->getScope()); 1886 EXPECT_EQ(BaseType, N->getBaseType()); 1887 EXPECT_EQ(2u, N->getSizeInBits()); 1888 EXPECT_EQ(3u, N->getAlignInBits()); 1889 EXPECT_EQ(4u, N->getOffsetInBits()); 1890 EXPECT_EQ(DWARFAddressSpace, *N->getDWARFAddressSpace()); 1891 EXPECT_EQ(std::nullopt, N->getPtrAuthData()); 1892 EXPECT_EQ(PtrAuthData, N1->getPtrAuthData()); 1893 EXPECT_NE(PtrAuthData2, N1->getPtrAuthData()); 1894 EXPECT_EQ(5u, N->getFlags()); 1895 EXPECT_EQ(ExtraData, N->getExtraData()); 1896 EXPECT_EQ(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1897 "something", File, 1, Scope, BaseType, 2, 3, 1898 4, DWARFAddressSpace, std::nullopt, Flags5, 1899 ExtraData)); 1900 1901 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_reference_type, 1902 "something", File, 1, Scope, BaseType, 2, 3, 1903 4, DWARFAddressSpace, std::nullopt, Flags5, 1904 ExtraData)); 1905 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "else", 1906 File, 1, Scope, BaseType, 2, 3, 4, 1907 DWARFAddressSpace, std::nullopt, Flags5, 1908 ExtraData)); 1909 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1910 "something", getFile(), 1, Scope, BaseType, 2, 1911 3, 4, DWARFAddressSpace, std::nullopt, Flags5, 1912 ExtraData)); 1913 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1914 "something", File, 2, Scope, BaseType, 2, 3, 1915 4, DWARFAddressSpace, std::nullopt, Flags5, 1916 ExtraData)); 1917 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1918 "something", File, 1, getSubprogram(), 1919 BaseType, 2, 3, 4, DWARFAddressSpace, 1920 std::nullopt, Flags5, ExtraData)); 1921 EXPECT_NE(N, DIDerivedType::get( 1922 Context, dwarf::DW_TAG_pointer_type, "something", File, 1, 1923 Scope, getBasicType("basic2"), 2, 3, 4, DWARFAddressSpace, 1924 std::nullopt, Flags5, ExtraData)); 1925 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1926 "something", File, 1, Scope, BaseType, 3, 3, 1927 4, DWARFAddressSpace, std::nullopt, Flags5, 1928 ExtraData)); 1929 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1930 "something", File, 1, Scope, BaseType, 2, 2, 1931 4, DWARFAddressSpace, std::nullopt, Flags5, 1932 ExtraData)); 1933 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1934 "something", File, 1, Scope, BaseType, 2, 3, 1935 5, DWARFAddressSpace, std::nullopt, Flags5, 1936 ExtraData)); 1937 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1938 "something", File, 1, Scope, BaseType, 2, 3, 1939 4, DWARFAddressSpace + 1, std::nullopt, 1940 Flags5, ExtraData)); 1941 EXPECT_NE(N1, 1942 DIDerivedType::get(Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", 1943 File, 1, Scope, N, 2, 3, 4, DWARFAddressSpace, 1944 std::nullopt, Flags5, ExtraData)); 1945 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1946 "something", File, 1, Scope, BaseType, 2, 3, 1947 4, DWARFAddressSpace, std::nullopt, Flags4, 1948 ExtraData)); 1949 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1950 "something", File, 1, Scope, BaseType, 2, 3, 1951 4, DWARFAddressSpace, std::nullopt, Flags5, 1952 getTuple())); 1953 1954 TempDIDerivedType Temp = N->clone(); 1955 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1956 TempDIDerivedType Temp1 = N1->clone(); 1957 EXPECT_EQ(N1, MDNode::replaceWithUniqued(std::move(Temp1))); 1958 } 1959 1960 TEST_F(DIDerivedTypeTest, getWithLargeValues) { 1961 DIFile *File = getFile(); 1962 DIScope *Scope = getSubprogram(); 1963 DIType *BaseType = getBasicType("basic"); 1964 MDTuple *ExtraData = getTuple(); 1965 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5); 1966 1967 auto *N = DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", 1968 File, 1, Scope, BaseType, UINT64_MAX, 1969 UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, 1970 std::nullopt, Flags, ExtraData); 1971 EXPECT_EQ(UINT64_MAX, N->getSizeInBits()); 1972 EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits()); 1973 EXPECT_EQ(UINT64_MAX - 2, N->getOffsetInBits()); 1974 EXPECT_EQ(UINT32_MAX - 3, *N->getDWARFAddressSpace()); 1975 1976 auto *N1 = DIDerivedType::get( 1977 Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", File, 1, Scope, N, 1978 UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, 1979 DIDerivedType::PtrAuthData(7, true, 0xffff, true, false), Flags, 1980 ExtraData); 1981 EXPECT_EQ(7U, N1->getPtrAuthData()->key()); 1982 EXPECT_EQ(true, N1->getPtrAuthData()->isAddressDiscriminated()); 1983 EXPECT_EQ(0xffffU, N1->getPtrAuthData()->extraDiscriminator()); 1984 } 1985 1986 typedef MetadataTest DICompositeTypeTest; 1987 1988 TEST_F(DICompositeTypeTest, get) { 1989 unsigned Tag = dwarf::DW_TAG_structure_type; 1990 StringRef Name = "some name"; 1991 DIFile *File = getFile(); 1992 unsigned Line = 1; 1993 DIScope *Scope = getSubprogram(); 1994 DIType *BaseType = getCompositeType(); 1995 uint64_t SizeInBits = 2; 1996 uint32_t AlignInBits = 3; 1997 uint64_t OffsetInBits = 4; 1998 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5); 1999 MDTuple *Elements = getTuple(); 2000 unsigned RuntimeLang = 6; 2001 DIType *VTableHolder = getCompositeType(); 2002 MDTuple *TemplateParams = getTuple(); 2003 StringRef Identifier = "some id"; 2004 2005 auto *N = DICompositeType::get(Context, Tag, Name, File, Line, Scope, 2006 BaseType, SizeInBits, AlignInBits, 2007 OffsetInBits, Flags, Elements, RuntimeLang, 2008 VTableHolder, TemplateParams, Identifier); 2009 EXPECT_EQ(Tag, N->getTag()); 2010 EXPECT_EQ(Name, N->getName()); 2011 EXPECT_EQ(File, N->getFile()); 2012 EXPECT_EQ(Line, N->getLine()); 2013 EXPECT_EQ(Scope, N->getScope()); 2014 EXPECT_EQ(BaseType, N->getBaseType()); 2015 EXPECT_EQ(SizeInBits, N->getSizeInBits()); 2016 EXPECT_EQ(AlignInBits, N->getAlignInBits()); 2017 EXPECT_EQ(OffsetInBits, N->getOffsetInBits()); 2018 EXPECT_EQ(Flags, N->getFlags()); 2019 EXPECT_EQ(Elements, N->getElements().get()); 2020 EXPECT_EQ(RuntimeLang, N->getRuntimeLang()); 2021 EXPECT_EQ(VTableHolder, N->getVTableHolder()); 2022 EXPECT_EQ(TemplateParams, N->getTemplateParams().get()); 2023 EXPECT_EQ(Identifier, N->getIdentifier()); 2024 2025 EXPECT_EQ(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, 2026 BaseType, SizeInBits, AlignInBits, 2027 OffsetInBits, Flags, Elements, RuntimeLang, 2028 VTableHolder, TemplateParams, Identifier)); 2029 2030 EXPECT_NE(N, DICompositeType::get(Context, Tag + 1, Name, File, Line, Scope, 2031 BaseType, SizeInBits, AlignInBits, 2032 OffsetInBits, Flags, Elements, RuntimeLang, 2033 VTableHolder, TemplateParams, Identifier)); 2034 EXPECT_NE(N, DICompositeType::get(Context, Tag, "abc", File, Line, Scope, 2035 BaseType, SizeInBits, AlignInBits, 2036 OffsetInBits, Flags, Elements, RuntimeLang, 2037 VTableHolder, TemplateParams, Identifier)); 2038 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, getFile(), Line, Scope, 2039 BaseType, SizeInBits, AlignInBits, 2040 OffsetInBits, Flags, Elements, RuntimeLang, 2041 VTableHolder, TemplateParams, Identifier)); 2042 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line + 1, Scope, 2043 BaseType, SizeInBits, AlignInBits, 2044 OffsetInBits, Flags, Elements, RuntimeLang, 2045 VTableHolder, TemplateParams, Identifier)); 2046 EXPECT_NE(N, DICompositeType::get( 2047 Context, Tag, Name, File, Line, getSubprogram(), BaseType, 2048 SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, 2049 RuntimeLang, VTableHolder, TemplateParams, Identifier)); 2050 EXPECT_NE(N, DICompositeType::get( 2051 Context, Tag, Name, File, Line, Scope, getBasicType("other"), 2052 SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, 2053 RuntimeLang, VTableHolder, TemplateParams, Identifier)); 2054 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, 2055 BaseType, SizeInBits + 1, AlignInBits, 2056 OffsetInBits, Flags, Elements, RuntimeLang, 2057 VTableHolder, TemplateParams, Identifier)); 2058 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, 2059 BaseType, SizeInBits, AlignInBits + 1, 2060 OffsetInBits, Flags, Elements, RuntimeLang, 2061 VTableHolder, TemplateParams, Identifier)); 2062 EXPECT_NE(N, DICompositeType::get( 2063 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 2064 AlignInBits, OffsetInBits + 1, Flags, Elements, RuntimeLang, 2065 VTableHolder, TemplateParams, Identifier)); 2066 DINode::DIFlags FlagsPOne = static_cast<DINode::DIFlags>(Flags + 1); 2067 EXPECT_NE(N, DICompositeType::get( 2068 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 2069 AlignInBits, OffsetInBits, FlagsPOne, Elements, RuntimeLang, 2070 VTableHolder, TemplateParams, Identifier)); 2071 EXPECT_NE(N, DICompositeType::get( 2072 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 2073 AlignInBits, OffsetInBits, Flags, getTuple(), RuntimeLang, 2074 VTableHolder, TemplateParams, Identifier)); 2075 EXPECT_NE(N, DICompositeType::get( 2076 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 2077 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang + 1, 2078 VTableHolder, TemplateParams, Identifier)); 2079 EXPECT_NE(N, DICompositeType::get( 2080 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 2081 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, 2082 getCompositeType(), TemplateParams, Identifier)); 2083 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, 2084 BaseType, SizeInBits, AlignInBits, 2085 OffsetInBits, Flags, Elements, RuntimeLang, 2086 VTableHolder, getTuple(), Identifier)); 2087 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, 2088 BaseType, SizeInBits, AlignInBits, 2089 OffsetInBits, Flags, Elements, RuntimeLang, 2090 VTableHolder, TemplateParams, "other")); 2091 2092 // Be sure that missing identifiers get null pointers. 2093 EXPECT_FALSE(DICompositeType::get(Context, Tag, Name, File, Line, Scope, 2094 BaseType, SizeInBits, AlignInBits, 2095 OffsetInBits, Flags, Elements, RuntimeLang, 2096 VTableHolder, TemplateParams, "") 2097 ->getRawIdentifier()); 2098 EXPECT_FALSE(DICompositeType::get(Context, Tag, Name, File, Line, Scope, 2099 BaseType, SizeInBits, AlignInBits, 2100 OffsetInBits, Flags, Elements, RuntimeLang, 2101 VTableHolder, TemplateParams) 2102 ->getRawIdentifier()); 2103 2104 TempDICompositeType Temp = N->clone(); 2105 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2106 } 2107 2108 TEST_F(DICompositeTypeTest, getWithLargeValues) { 2109 unsigned Tag = dwarf::DW_TAG_structure_type; 2110 StringRef Name = "some name"; 2111 DIFile *File = getFile(); 2112 unsigned Line = 1; 2113 DIScope *Scope = getSubprogram(); 2114 DIType *BaseType = getCompositeType(); 2115 uint64_t SizeInBits = UINT64_MAX; 2116 uint32_t AlignInBits = UINT32_MAX - 1; 2117 uint64_t OffsetInBits = UINT64_MAX - 2; 2118 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5); 2119 MDTuple *Elements = getTuple(); 2120 unsigned RuntimeLang = 6; 2121 DIType *VTableHolder = getCompositeType(); 2122 MDTuple *TemplateParams = getTuple(); 2123 StringRef Identifier = "some id"; 2124 2125 auto *N = DICompositeType::get(Context, Tag, Name, File, Line, Scope, 2126 BaseType, SizeInBits, AlignInBits, 2127 OffsetInBits, Flags, Elements, RuntimeLang, 2128 VTableHolder, TemplateParams, Identifier); 2129 EXPECT_EQ(SizeInBits, N->getSizeInBits()); 2130 EXPECT_EQ(AlignInBits, N->getAlignInBits()); 2131 EXPECT_EQ(OffsetInBits, N->getOffsetInBits()); 2132 } 2133 2134 TEST_F(DICompositeTypeTest, replaceOperands) { 2135 unsigned Tag = dwarf::DW_TAG_structure_type; 2136 StringRef Name = "some name"; 2137 DIFile *File = getFile(); 2138 unsigned Line = 1; 2139 DIScope *Scope = getSubprogram(); 2140 DIType *BaseType = getCompositeType(); 2141 uint64_t SizeInBits = 2; 2142 uint32_t AlignInBits = 3; 2143 uint64_t OffsetInBits = 4; 2144 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5); 2145 unsigned RuntimeLang = 6; 2146 StringRef Identifier = "some id"; 2147 2148 auto *N = DICompositeType::get( 2149 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2150 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier); 2151 2152 auto *Elements = MDTuple::getDistinct(Context, {}); 2153 EXPECT_EQ(nullptr, N->getElements().get()); 2154 N->replaceElements(Elements); 2155 EXPECT_EQ(Elements, N->getElements().get()); 2156 N->replaceElements(nullptr); 2157 EXPECT_EQ(nullptr, N->getElements().get()); 2158 2159 DIType *VTableHolder = getCompositeType(); 2160 EXPECT_EQ(nullptr, N->getVTableHolder()); 2161 N->replaceVTableHolder(VTableHolder); 2162 EXPECT_EQ(VTableHolder, N->getVTableHolder()); 2163 // As an extension, the containing type can be anything. This is 2164 // used by Rust to associate vtables with their concrete type. 2165 DIType *BasicType = getBasicType("basic"); 2166 N->replaceVTableHolder(BasicType); 2167 EXPECT_EQ(BasicType, N->getVTableHolder()); 2168 N->replaceVTableHolder(nullptr); 2169 EXPECT_EQ(nullptr, N->getVTableHolder()); 2170 2171 auto *TemplateParams = MDTuple::getDistinct(Context, {}); 2172 EXPECT_EQ(nullptr, N->getTemplateParams().get()); 2173 N->replaceTemplateParams(TemplateParams); 2174 EXPECT_EQ(TemplateParams, N->getTemplateParams().get()); 2175 N->replaceTemplateParams(nullptr); 2176 EXPECT_EQ(nullptr, N->getTemplateParams().get()); 2177 } 2178 2179 TEST_F(DICompositeTypeTest, variant_part) { 2180 unsigned Tag = dwarf::DW_TAG_variant_part; 2181 StringRef Name = "some name"; 2182 DIFile *File = getFile(); 2183 unsigned Line = 1; 2184 DIScope *Scope = getSubprogram(); 2185 DIType *BaseType = getCompositeType(); 2186 uint64_t SizeInBits = 2; 2187 uint32_t AlignInBits = 3; 2188 uint64_t OffsetInBits = 4; 2189 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5); 2190 unsigned RuntimeLang = 6; 2191 StringRef Identifier = "some id"; 2192 DIDerivedType *Discriminator = cast<DIDerivedType>(getDerivedType()); 2193 DIDerivedType *Discriminator2 = cast<DIDerivedType>(getDerivedType()); 2194 2195 EXPECT_NE(Discriminator, Discriminator2); 2196 2197 auto *N = DICompositeType::get( 2198 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2199 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2200 Discriminator); 2201 2202 // Test the hashing. 2203 auto *Same = DICompositeType::get( 2204 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2205 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2206 Discriminator); 2207 auto *Other = DICompositeType::get( 2208 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2209 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2210 Discriminator2); 2211 auto *NoDisc = DICompositeType::get( 2212 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2213 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2214 nullptr); 2215 2216 EXPECT_EQ(N, Same); 2217 EXPECT_NE(Same, Other); 2218 EXPECT_NE(Same, NoDisc); 2219 EXPECT_NE(Other, NoDisc); 2220 2221 EXPECT_EQ(N->getDiscriminator(), Discriminator); 2222 } 2223 2224 TEST_F(DICompositeTypeTest, dynamicArray) { 2225 unsigned Tag = dwarf::DW_TAG_array_type; 2226 StringRef Name = "some name"; 2227 DIFile *File = getFile(); 2228 unsigned Line = 1; 2229 DILocalScope *Scope = getSubprogram(); 2230 DIType *BaseType = getCompositeType(); 2231 uint64_t SizeInBits = 32; 2232 uint32_t AlignInBits = 32; 2233 uint64_t OffsetInBits = 4; 2234 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(3); 2235 unsigned RuntimeLang = 6; 2236 StringRef Identifier = "some id"; 2237 DIType *Type = getDerivedType(); 2238 Metadata *DlVar1 = DILocalVariable::get(Context, Scope, "dl_var1", File, 8, 2239 Type, 2, Flags, 8, nullptr); 2240 Metadata *DlVar2 = DILocalVariable::get(Context, Scope, "dl_var2", File, 8, 2241 Type, 2, Flags, 8, nullptr); 2242 uint64_t Elements1[] = {dwarf::DW_OP_push_object_address, dwarf::DW_OP_deref}; 2243 Metadata *DataLocation1 = DIExpression::get(Context, Elements1); 2244 2245 uint64_t Elements2[] = {dwarf::DW_OP_constu, 0}; 2246 Metadata *DataLocation2 = DIExpression::get(Context, Elements2); 2247 2248 uint64_t Elements3[] = {dwarf::DW_OP_constu, 3}; 2249 Metadata *Rank1 = DIExpression::get(Context, Elements3); 2250 2251 uint64_t Elements4[] = {dwarf::DW_OP_constu, 4}; 2252 Metadata *Rank2 = DIExpression::get(Context, Elements4); 2253 2254 ConstantInt *RankInt1 = ConstantInt::get(Context, APInt(7, 0)); 2255 ConstantAsMetadata *RankConst1 = ConstantAsMetadata::get(RankInt1); 2256 ConstantInt *RankInt2 = ConstantInt::get(Context, APInt(6, 0)); 2257 ConstantAsMetadata *RankConst2 = ConstantAsMetadata::get(RankInt2); 2258 auto *N1 = DICompositeType::get( 2259 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2260 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2261 nullptr, DlVar1); 2262 2263 auto *Same1 = DICompositeType::get( 2264 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2265 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2266 nullptr, DlVar1); 2267 2268 auto *Other1 = DICompositeType::get( 2269 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2270 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2271 nullptr, DlVar2); 2272 2273 EXPECT_EQ(N1, Same1); 2274 EXPECT_NE(Same1, Other1); 2275 EXPECT_EQ(N1->getDataLocation(), DlVar1); 2276 2277 auto *N2 = DICompositeType::get( 2278 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2279 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2280 nullptr, DataLocation1); 2281 2282 auto *Same2 = DICompositeType::get( 2283 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2284 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2285 nullptr, DataLocation1); 2286 2287 auto *Other2 = DICompositeType::get( 2288 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2289 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2290 nullptr, DataLocation2); 2291 2292 EXPECT_EQ(N2, Same2); 2293 EXPECT_NE(Same2, Other2); 2294 EXPECT_EQ(N2->getDataLocationExp(), DataLocation1); 2295 2296 auto *N3 = DICompositeType::get( 2297 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2298 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2299 nullptr, DataLocation1, nullptr, nullptr, Rank1); 2300 2301 auto *Same3 = DICompositeType::get( 2302 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2303 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2304 nullptr, DataLocation1, nullptr, nullptr, Rank1); 2305 2306 auto *Other3 = DICompositeType::get( 2307 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2308 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2309 nullptr, DataLocation1, nullptr, nullptr, Rank2); 2310 2311 EXPECT_EQ(N3, Same3); 2312 EXPECT_NE(Same3, Other3); 2313 EXPECT_EQ(N3->getRankExp(), Rank1); 2314 2315 auto *N4 = DICompositeType::get( 2316 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2317 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2318 nullptr, DataLocation1, nullptr, nullptr, RankConst1); 2319 2320 auto *Same4 = DICompositeType::get( 2321 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2322 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2323 nullptr, DataLocation1, nullptr, nullptr, RankConst1); 2324 2325 auto *Other4 = DICompositeType::get( 2326 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2327 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2328 nullptr, DataLocation1, nullptr, nullptr, RankConst2); 2329 2330 EXPECT_EQ(N4, Same4); 2331 EXPECT_NE(Same4, Other4); 2332 EXPECT_EQ(N4->getRankConst(), RankInt1); 2333 } 2334 2335 typedef MetadataTest DISubroutineTypeTest; 2336 2337 TEST_F(DISubroutineTypeTest, get) { 2338 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(1); 2339 DINode::DIFlags FlagsPOne = static_cast<DINode::DIFlags>(Flags + 1); 2340 MDTuple *TypeArray = getTuple(); 2341 2342 auto *N = DISubroutineType::get(Context, Flags, 0, TypeArray); 2343 EXPECT_EQ(dwarf::DW_TAG_subroutine_type, N->getTag()); 2344 EXPECT_EQ(Flags, N->getFlags()); 2345 EXPECT_EQ(TypeArray, N->getTypeArray().get()); 2346 EXPECT_EQ(N, DISubroutineType::get(Context, Flags, 0, TypeArray)); 2347 2348 EXPECT_NE(N, DISubroutineType::get(Context, FlagsPOne, 0, TypeArray)); 2349 EXPECT_NE(N, DISubroutineType::get(Context, Flags, 0, getTuple())); 2350 2351 // Test the hashing of calling conventions. 2352 auto *Fast = DISubroutineType::get( 2353 Context, Flags, dwarf::DW_CC_BORLAND_msfastcall, TypeArray); 2354 auto *Std = DISubroutineType::get(Context, Flags, 2355 dwarf::DW_CC_BORLAND_stdcall, TypeArray); 2356 EXPECT_EQ(Fast, 2357 DISubroutineType::get(Context, Flags, 2358 dwarf::DW_CC_BORLAND_msfastcall, TypeArray)); 2359 EXPECT_EQ(Std, DISubroutineType::get( 2360 Context, Flags, dwarf::DW_CC_BORLAND_stdcall, TypeArray)); 2361 2362 EXPECT_NE(N, Fast); 2363 EXPECT_NE(N, Std); 2364 EXPECT_NE(Fast, Std); 2365 2366 TempDISubroutineType Temp = N->clone(); 2367 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2368 2369 // Test always-empty operands. 2370 EXPECT_EQ(nullptr, N->getScope()); 2371 EXPECT_EQ(nullptr, N->getFile()); 2372 EXPECT_EQ("", N->getName()); 2373 } 2374 2375 typedef MetadataTest DIFileTest; 2376 2377 TEST_F(DIFileTest, get) { 2378 StringRef Filename = "file"; 2379 StringRef Directory = "dir"; 2380 DIFile::ChecksumKind CSKind = DIFile::ChecksumKind::CSK_MD5; 2381 StringRef ChecksumString = "000102030405060708090a0b0c0d0e0f"; 2382 DIFile::ChecksumInfo<StringRef> Checksum(CSKind, ChecksumString); 2383 StringRef Source = "source"; 2384 auto *N = DIFile::get(Context, Filename, Directory, Checksum, Source); 2385 2386 EXPECT_EQ(dwarf::DW_TAG_file_type, N->getTag()); 2387 EXPECT_EQ(Filename, N->getFilename()); 2388 EXPECT_EQ(Directory, N->getDirectory()); 2389 EXPECT_EQ(Checksum, N->getChecksum()); 2390 EXPECT_EQ(Source, N->getSource()); 2391 EXPECT_EQ(N, DIFile::get(Context, Filename, Directory, Checksum, Source)); 2392 2393 EXPECT_NE(N, DIFile::get(Context, "other", Directory, Checksum, Source)); 2394 EXPECT_NE(N, DIFile::get(Context, Filename, "other", Checksum, Source)); 2395 DIFile::ChecksumInfo<StringRef> OtherChecksum(DIFile::ChecksumKind::CSK_SHA1, ChecksumString); 2396 EXPECT_NE( 2397 N, DIFile::get(Context, Filename, Directory, OtherChecksum)); 2398 StringRef OtherSource = "other"; 2399 EXPECT_NE(N, DIFile::get(Context, Filename, Directory, Checksum, OtherSource)); 2400 EXPECT_NE(N, DIFile::get(Context, Filename, Directory, Checksum)); 2401 EXPECT_NE(N, DIFile::get(Context, Filename, Directory)); 2402 2403 TempDIFile Temp = N->clone(); 2404 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2405 } 2406 2407 TEST_F(DIFileTest, EmptySource) { 2408 DIFile *N = DIFile::get(Context, "file", "dir"); 2409 EXPECT_EQ(std::nullopt, N->getSource()); 2410 2411 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum; 2412 std::optional<StringRef> Source; 2413 N = DIFile::get(Context, "file", "dir", Checksum, Source); 2414 EXPECT_EQ(Source, N->getSource()); 2415 2416 Source = ""; 2417 N = DIFile::get(Context, "file", "dir", Checksum, Source); 2418 EXPECT_EQ(Source, N->getSource()); 2419 } 2420 2421 TEST_F(DIFileTest, ScopeGetFile) { 2422 // Ensure that DIScope::getFile() returns itself. 2423 DIScope *N = DIFile::get(Context, "file", "dir"); 2424 EXPECT_EQ(N, N->getFile()); 2425 } 2426 2427 typedef MetadataTest DICompileUnitTest; 2428 2429 TEST_F(DICompileUnitTest, get) { 2430 unsigned SourceLanguage = 1; 2431 DIFile *File = getFile(); 2432 StringRef Producer = "some producer"; 2433 bool IsOptimized = false; 2434 StringRef Flags = "flag after flag"; 2435 unsigned RuntimeVersion = 2; 2436 StringRef SplitDebugFilename = "another/file"; 2437 auto EmissionKind = DICompileUnit::FullDebug; 2438 MDTuple *EnumTypes = getTuple(); 2439 MDTuple *RetainedTypes = getTuple(); 2440 MDTuple *GlobalVariables = getTuple(); 2441 MDTuple *ImportedEntities = getTuple(); 2442 uint64_t DWOId = 0x10000000c0ffee; 2443 MDTuple *Macros = getTuple(); 2444 StringRef SysRoot = "/"; 2445 StringRef SDK = "MacOSX.sdk"; 2446 auto *N = DICompileUnit::getDistinct( 2447 Context, SourceLanguage, File, Producer, IsOptimized, Flags, 2448 RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, 2449 RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, true, 2450 false, DICompileUnit::DebugNameTableKind::Default, false, SysRoot, SDK); 2451 2452 EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag()); 2453 EXPECT_EQ(SourceLanguage, N->getSourceLanguage()); 2454 EXPECT_EQ(File, N->getFile()); 2455 EXPECT_EQ(Producer, N->getProducer()); 2456 EXPECT_EQ(IsOptimized, N->isOptimized()); 2457 EXPECT_EQ(Flags, N->getFlags()); 2458 EXPECT_EQ(RuntimeVersion, N->getRuntimeVersion()); 2459 EXPECT_EQ(SplitDebugFilename, N->getSplitDebugFilename()); 2460 EXPECT_EQ(EmissionKind, N->getEmissionKind()); 2461 EXPECT_EQ(EnumTypes, N->getEnumTypes().get()); 2462 EXPECT_EQ(RetainedTypes, N->getRetainedTypes().get()); 2463 EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get()); 2464 EXPECT_EQ(ImportedEntities, N->getImportedEntities().get()); 2465 EXPECT_EQ(Macros, N->getMacros().get()); 2466 EXPECT_EQ(DWOId, N->getDWOId()); 2467 EXPECT_EQ(SysRoot, N->getSysRoot()); 2468 EXPECT_EQ(SDK, N->getSDK()); 2469 2470 TempDICompileUnit Temp = N->clone(); 2471 EXPECT_EQ(dwarf::DW_TAG_compile_unit, Temp->getTag()); 2472 EXPECT_EQ(SourceLanguage, Temp->getSourceLanguage()); 2473 EXPECT_EQ(File, Temp->getFile()); 2474 EXPECT_EQ(Producer, Temp->getProducer()); 2475 EXPECT_EQ(IsOptimized, Temp->isOptimized()); 2476 EXPECT_EQ(Flags, Temp->getFlags()); 2477 EXPECT_EQ(RuntimeVersion, Temp->getRuntimeVersion()); 2478 EXPECT_EQ(SplitDebugFilename, Temp->getSplitDebugFilename()); 2479 EXPECT_EQ(EmissionKind, Temp->getEmissionKind()); 2480 EXPECT_EQ(EnumTypes, Temp->getEnumTypes().get()); 2481 EXPECT_EQ(RetainedTypes, Temp->getRetainedTypes().get()); 2482 EXPECT_EQ(GlobalVariables, Temp->getGlobalVariables().get()); 2483 EXPECT_EQ(ImportedEntities, Temp->getImportedEntities().get()); 2484 EXPECT_EQ(Macros, Temp->getMacros().get()); 2485 EXPECT_EQ(SysRoot, Temp->getSysRoot()); 2486 EXPECT_EQ(SDK, Temp->getSDK()); 2487 2488 auto *TempAddress = Temp.get(); 2489 auto *Clone = MDNode::replaceWithPermanent(std::move(Temp)); 2490 EXPECT_TRUE(Clone->isDistinct()); 2491 EXPECT_EQ(TempAddress, Clone); 2492 } 2493 2494 TEST_F(DICompileUnitTest, replaceArrays) { 2495 unsigned SourceLanguage = 1; 2496 DIFile *File = getFile(); 2497 StringRef Producer = "some producer"; 2498 bool IsOptimized = false; 2499 StringRef Flags = "flag after flag"; 2500 unsigned RuntimeVersion = 2; 2501 StringRef SplitDebugFilename = "another/file"; 2502 auto EmissionKind = DICompileUnit::FullDebug; 2503 MDTuple *EnumTypes = MDTuple::getDistinct(Context, {}); 2504 MDTuple *RetainedTypes = MDTuple::getDistinct(Context, {}); 2505 MDTuple *ImportedEntities = MDTuple::getDistinct(Context, {}); 2506 uint64_t DWOId = 0xc0ffee; 2507 StringRef SysRoot = "/"; 2508 StringRef SDK = "MacOSX.sdk"; 2509 auto *N = DICompileUnit::getDistinct( 2510 Context, SourceLanguage, File, Producer, IsOptimized, Flags, 2511 RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, 2512 RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId, true, false, 2513 DICompileUnit::DebugNameTableKind::Default, false, SysRoot, SDK); 2514 2515 auto *GlobalVariables = MDTuple::getDistinct(Context, {}); 2516 EXPECT_EQ(nullptr, N->getGlobalVariables().get()); 2517 N->replaceGlobalVariables(GlobalVariables); 2518 EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get()); 2519 N->replaceGlobalVariables(nullptr); 2520 EXPECT_EQ(nullptr, N->getGlobalVariables().get()); 2521 2522 auto *Macros = MDTuple::getDistinct(Context, {}); 2523 EXPECT_EQ(nullptr, N->getMacros().get()); 2524 N->replaceMacros(Macros); 2525 EXPECT_EQ(Macros, N->getMacros().get()); 2526 N->replaceMacros(nullptr); 2527 EXPECT_EQ(nullptr, N->getMacros().get()); 2528 } 2529 2530 typedef MetadataTest DISubprogramTest; 2531 2532 TEST_F(DISubprogramTest, get) { 2533 DIScope *Scope = getCompositeType(); 2534 StringRef Name = "name"; 2535 StringRef LinkageName = "linkage"; 2536 DIFile *File = getFile(); 2537 unsigned Line = 2; 2538 DISubroutineType *Type = getSubroutineType(); 2539 bool IsLocalToUnit = false; 2540 bool IsDefinition = true; 2541 unsigned ScopeLine = 3; 2542 DIType *ContainingType = getCompositeType(); 2543 unsigned Virtuality = 2; 2544 unsigned VirtualIndex = 5; 2545 int ThisAdjustment = -3; 2546 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(6); 2547 bool IsOptimized = false; 2548 MDTuple *TemplateParams = getTuple(); 2549 DISubprogram *Declaration = getSubprogram(); 2550 MDTuple *RetainedNodes = getTuple(); 2551 MDTuple *ThrownTypes = getTuple(); 2552 MDTuple *Annotations = getTuple(); 2553 StringRef TargetFuncName = "target"; 2554 DICompileUnit *Unit = getUnit(); 2555 DISubprogram::DISPFlags SPFlags = 2556 static_cast<DISubprogram::DISPFlags>(Virtuality); 2557 assert(!IsLocalToUnit && IsDefinition && !IsOptimized && 2558 "bools and SPFlags have to match"); 2559 SPFlags |= DISubprogram::SPFlagDefinition; 2560 2561 auto *N = DISubprogram::get( 2562 Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, 2563 ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, 2564 TemplateParams, Declaration, RetainedNodes, ThrownTypes, Annotations, 2565 TargetFuncName); 2566 2567 EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag()); 2568 EXPECT_EQ(Scope, N->getScope()); 2569 EXPECT_EQ(Name, N->getName()); 2570 EXPECT_EQ(LinkageName, N->getLinkageName()); 2571 EXPECT_EQ(File, N->getFile()); 2572 EXPECT_EQ(Line, N->getLine()); 2573 EXPECT_EQ(Type, N->getType()); 2574 EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit()); 2575 EXPECT_EQ(IsDefinition, N->isDefinition()); 2576 EXPECT_EQ(ScopeLine, N->getScopeLine()); 2577 EXPECT_EQ(ContainingType, N->getContainingType()); 2578 EXPECT_EQ(Virtuality, N->getVirtuality()); 2579 EXPECT_EQ(VirtualIndex, N->getVirtualIndex()); 2580 EXPECT_EQ(ThisAdjustment, N->getThisAdjustment()); 2581 EXPECT_EQ(Flags, N->getFlags()); 2582 EXPECT_EQ(IsOptimized, N->isOptimized()); 2583 EXPECT_EQ(Unit, N->getUnit()); 2584 EXPECT_EQ(TemplateParams, N->getTemplateParams().get()); 2585 EXPECT_EQ(Declaration, N->getDeclaration()); 2586 EXPECT_EQ(RetainedNodes, N->getRetainedNodes().get()); 2587 EXPECT_EQ(ThrownTypes, N->getThrownTypes().get()); 2588 EXPECT_EQ(Annotations, N->getAnnotations().get()); 2589 EXPECT_EQ(TargetFuncName, N->getTargetFuncName()); 2590 EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2591 Type, ScopeLine, ContainingType, VirtualIndex, 2592 ThisAdjustment, Flags, SPFlags, Unit, 2593 TemplateParams, Declaration, RetainedNodes, 2594 ThrownTypes, Annotations, TargetFuncName)); 2595 2596 EXPECT_NE(N, DISubprogram::get(Context, getCompositeType(), Name, LinkageName, 2597 File, Line, Type, ScopeLine, ContainingType, 2598 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2599 Unit, TemplateParams, Declaration, 2600 RetainedNodes, ThrownTypes, Annotations, 2601 TargetFuncName)); 2602 EXPECT_NE(N, DISubprogram::get(Context, Scope, "other", LinkageName, File, 2603 Line, Type, ScopeLine, ContainingType, 2604 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2605 Unit, TemplateParams, Declaration, 2606 RetainedNodes, ThrownTypes, Annotations, 2607 TargetFuncName)); 2608 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line, 2609 Type, ScopeLine, ContainingType, VirtualIndex, 2610 ThisAdjustment, Flags, SPFlags, Unit, 2611 TemplateParams, Declaration, RetainedNodes, 2612 ThrownTypes, Annotations, TargetFuncName)); 2613 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, getFile(), 2614 Line, Type, ScopeLine, ContainingType, 2615 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2616 Unit, TemplateParams, Declaration, 2617 RetainedNodes, ThrownTypes, Annotations, 2618 TargetFuncName)); 2619 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, 2620 Line + 1, Type, ScopeLine, ContainingType, 2621 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2622 Unit, TemplateParams, Declaration, 2623 RetainedNodes, ThrownTypes, Annotations, 2624 TargetFuncName)); 2625 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2626 getSubroutineType(), ScopeLine, ContainingType, 2627 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2628 Unit, TemplateParams, Declaration, 2629 RetainedNodes, ThrownTypes, Annotations, 2630 TargetFuncName)); 2631 EXPECT_NE(N, DISubprogram::get( 2632 Context, Scope, Name, LinkageName, File, Line, Type, 2633 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, 2634 Flags, SPFlags ^ DISubprogram::SPFlagLocalToUnit, Unit, 2635 TemplateParams, Declaration, RetainedNodes, ThrownTypes, 2636 Annotations, TargetFuncName)); 2637 EXPECT_NE(N, DISubprogram::get( 2638 Context, Scope, Name, LinkageName, File, Line, Type, 2639 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, 2640 Flags, SPFlags ^ DISubprogram::SPFlagDefinition, Unit, 2641 TemplateParams, Declaration, RetainedNodes, ThrownTypes, 2642 Annotations, TargetFuncName)); 2643 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2644 Type, ScopeLine + 1, ContainingType, 2645 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2646 Unit, TemplateParams, Declaration, 2647 RetainedNodes, ThrownTypes, Annotations, 2648 TargetFuncName)); 2649 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2650 Type, ScopeLine, getCompositeType(), 2651 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2652 Unit, TemplateParams, Declaration, 2653 RetainedNodes, ThrownTypes, Annotations, 2654 TargetFuncName)); 2655 EXPECT_NE(N, DISubprogram::get( 2656 Context, Scope, Name, LinkageName, File, Line, Type, 2657 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, 2658 Flags, SPFlags ^ DISubprogram::SPFlagVirtual, Unit, 2659 TemplateParams, Declaration, RetainedNodes, ThrownTypes, 2660 Annotations, TargetFuncName)); 2661 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2662 Type, ScopeLine, ContainingType, 2663 VirtualIndex + 1, ThisAdjustment, Flags, 2664 SPFlags, Unit, TemplateParams, Declaration, 2665 RetainedNodes, ThrownTypes, Annotations, 2666 TargetFuncName)); 2667 EXPECT_NE(N, DISubprogram::get( 2668 Context, Scope, Name, LinkageName, File, Line, Type, 2669 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, 2670 Flags, SPFlags ^ DISubprogram::SPFlagOptimized, Unit, 2671 TemplateParams, Declaration, RetainedNodes, ThrownTypes, 2672 Annotations, TargetFuncName)); 2673 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2674 Type, ScopeLine, ContainingType, VirtualIndex, 2675 ThisAdjustment, Flags, SPFlags, nullptr, 2676 TemplateParams, Declaration, RetainedNodes, 2677 ThrownTypes, Annotations, TargetFuncName)); 2678 EXPECT_NE(N, 2679 DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2680 Type, ScopeLine, ContainingType, VirtualIndex, 2681 ThisAdjustment, Flags, SPFlags, Unit, getTuple(), 2682 Declaration, RetainedNodes, ThrownTypes, 2683 Annotations, TargetFuncName)); 2684 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2685 Type, ScopeLine, ContainingType, VirtualIndex, 2686 ThisAdjustment, Flags, SPFlags, Unit, 2687 TemplateParams, getSubprogram(), RetainedNodes, 2688 ThrownTypes, Annotations, TargetFuncName)); 2689 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2690 Type, ScopeLine, ContainingType, VirtualIndex, 2691 ThisAdjustment, Flags, SPFlags, Unit, 2692 TemplateParams, Declaration, getTuple(), 2693 ThrownTypes, Annotations, TargetFuncName)); 2694 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2695 Type, ScopeLine, ContainingType, VirtualIndex, 2696 ThisAdjustment, Flags, SPFlags, Unit, 2697 TemplateParams, Declaration, RetainedNodes, 2698 getTuple(), Annotations, TargetFuncName)); 2699 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2700 Type, ScopeLine, ContainingType, VirtualIndex, 2701 ThisAdjustment, Flags, SPFlags, Unit, 2702 TemplateParams, Declaration, RetainedNodes, 2703 ThrownTypes, getTuple(), TargetFuncName)); 2704 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2705 Type, ScopeLine, ContainingType, VirtualIndex, 2706 ThisAdjustment, Flags, SPFlags, Unit, 2707 TemplateParams, Declaration, RetainedNodes, 2708 ThrownTypes, Annotations, "other")); 2709 2710 TempDISubprogram Temp = N->clone(); 2711 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2712 } 2713 2714 typedef MetadataTest DILexicalBlockTest; 2715 2716 TEST_F(DILexicalBlockTest, get) { 2717 DILocalScope *Scope = getSubprogram(); 2718 DIFile *File = getFile(); 2719 unsigned Line = 5; 2720 unsigned Column = 8; 2721 2722 auto *N = DILexicalBlock::get(Context, Scope, File, Line, Column); 2723 2724 EXPECT_EQ(dwarf::DW_TAG_lexical_block, N->getTag()); 2725 EXPECT_EQ(Scope, N->getScope()); 2726 EXPECT_EQ(File, N->getFile()); 2727 EXPECT_EQ(Line, N->getLine()); 2728 EXPECT_EQ(Column, N->getColumn()); 2729 EXPECT_EQ(N, DILexicalBlock::get(Context, Scope, File, Line, Column)); 2730 2731 EXPECT_NE(N, 2732 DILexicalBlock::get(Context, getSubprogram(), File, Line, Column)); 2733 EXPECT_NE(N, DILexicalBlock::get(Context, Scope, getFile(), Line, Column)); 2734 EXPECT_NE(N, DILexicalBlock::get(Context, Scope, File, Line + 1, Column)); 2735 EXPECT_NE(N, DILexicalBlock::get(Context, Scope, File, Line, Column + 1)); 2736 2737 TempDILexicalBlock Temp = N->clone(); 2738 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2739 } 2740 2741 TEST_F(DILexicalBlockTest, Overflow) { 2742 DISubprogram *SP = getSubprogram(); 2743 DIFile *F = getFile(); 2744 { 2745 auto *LB = DILexicalBlock::get(Context, SP, F, 2, 7); 2746 EXPECT_EQ(2u, LB->getLine()); 2747 EXPECT_EQ(7u, LB->getColumn()); 2748 } 2749 unsigned U16 = 1u << 16; 2750 { 2751 auto *LB = DILexicalBlock::get(Context, SP, F, UINT32_MAX, U16 - 1); 2752 EXPECT_EQ(UINT32_MAX, LB->getLine()); 2753 EXPECT_EQ(U16 - 1, LB->getColumn()); 2754 } 2755 { 2756 auto *LB = DILexicalBlock::get(Context, SP, F, UINT32_MAX, U16); 2757 EXPECT_EQ(UINT32_MAX, LB->getLine()); 2758 EXPECT_EQ(0u, LB->getColumn()); 2759 } 2760 { 2761 auto *LB = DILexicalBlock::get(Context, SP, F, UINT32_MAX, U16 + 1); 2762 EXPECT_EQ(UINT32_MAX, LB->getLine()); 2763 EXPECT_EQ(0u, LB->getColumn()); 2764 } 2765 } 2766 2767 typedef MetadataTest DILexicalBlockFileTest; 2768 2769 TEST_F(DILexicalBlockFileTest, get) { 2770 DILocalScope *Scope = getSubprogram(); 2771 DIFile *File = getFile(); 2772 unsigned Discriminator = 5; 2773 2774 auto *N = DILexicalBlockFile::get(Context, Scope, File, Discriminator); 2775 2776 EXPECT_EQ(dwarf::DW_TAG_lexical_block, N->getTag()); 2777 EXPECT_EQ(Scope, N->getScope()); 2778 EXPECT_EQ(File, N->getFile()); 2779 EXPECT_EQ(Discriminator, N->getDiscriminator()); 2780 EXPECT_EQ(N, DILexicalBlockFile::get(Context, Scope, File, Discriminator)); 2781 2782 EXPECT_NE(N, DILexicalBlockFile::get(Context, getSubprogram(), File, 2783 Discriminator)); 2784 EXPECT_NE(N, 2785 DILexicalBlockFile::get(Context, Scope, getFile(), Discriminator)); 2786 EXPECT_NE(N, 2787 DILexicalBlockFile::get(Context, Scope, File, Discriminator + 1)); 2788 2789 TempDILexicalBlockFile Temp = N->clone(); 2790 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2791 } 2792 2793 typedef MetadataTest DINamespaceTest; 2794 2795 TEST_F(DINamespaceTest, get) { 2796 DIScope *Scope = getFile(); 2797 StringRef Name = "namespace"; 2798 bool ExportSymbols = true; 2799 2800 auto *N = DINamespace::get(Context, Scope, Name, ExportSymbols); 2801 2802 EXPECT_EQ(dwarf::DW_TAG_namespace, N->getTag()); 2803 EXPECT_EQ(Scope, N->getScope()); 2804 EXPECT_EQ(Name, N->getName()); 2805 EXPECT_EQ(N, DINamespace::get(Context, Scope, Name, ExportSymbols)); 2806 EXPECT_NE(N, DINamespace::get(Context, getFile(), Name, ExportSymbols)); 2807 EXPECT_NE(N, DINamespace::get(Context, Scope, "other", ExportSymbols)); 2808 EXPECT_NE(N, DINamespace::get(Context, Scope, Name, !ExportSymbols)); 2809 2810 TempDINamespace Temp = N->clone(); 2811 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2812 } 2813 2814 typedef MetadataTest DIModuleTest; 2815 2816 TEST_F(DIModuleTest, get) { 2817 DIFile *File = getFile(); 2818 DIScope *Scope = getFile(); 2819 StringRef Name = "module"; 2820 StringRef ConfigMacro = "-DNDEBUG"; 2821 StringRef Includes = "-I."; 2822 StringRef APINotes = "/tmp/m.apinotes"; 2823 unsigned LineNo = 4; 2824 bool IsDecl = true; 2825 2826 auto *N = DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, 2827 APINotes, LineNo, IsDecl); 2828 2829 EXPECT_EQ(dwarf::DW_TAG_module, N->getTag()); 2830 EXPECT_EQ(File, N->getFile()); 2831 EXPECT_EQ(Scope, N->getScope()); 2832 EXPECT_EQ(Name, N->getName()); 2833 EXPECT_EQ(ConfigMacro, N->getConfigurationMacros()); 2834 EXPECT_EQ(Includes, N->getIncludePath()); 2835 EXPECT_EQ(APINotes, N->getAPINotesFile()); 2836 EXPECT_EQ(LineNo, N->getLineNo()); 2837 EXPECT_EQ(IsDecl, N->getIsDecl()); 2838 EXPECT_EQ(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, 2839 APINotes, LineNo, IsDecl)); 2840 EXPECT_NE(N, DIModule::get(Context, getFile(), getFile(), Name, ConfigMacro, 2841 Includes, APINotes, LineNo, IsDecl)); 2842 EXPECT_NE(N, DIModule::get(Context, File, Scope, "other", ConfigMacro, 2843 Includes, APINotes, LineNo, IsDecl)); 2844 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, "other", Includes, 2845 APINotes, LineNo, IsDecl)); 2846 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, "other", 2847 APINotes, LineNo, IsDecl)); 2848 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, 2849 "other", LineNo, IsDecl)); 2850 EXPECT_NE(N, DIModule::get(Context, getFile(), Scope, Name, ConfigMacro, 2851 Includes, APINotes, LineNo, IsDecl)); 2852 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, 2853 APINotes, 5, IsDecl)); 2854 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, 2855 APINotes, LineNo, false)); 2856 2857 TempDIModule Temp = N->clone(); 2858 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2859 } 2860 2861 typedef MetadataTest DITemplateTypeParameterTest; 2862 2863 TEST_F(DITemplateTypeParameterTest, get) { 2864 StringRef Name = "template"; 2865 DIType *Type = getBasicType("basic"); 2866 bool defaulted = false; 2867 2868 auto *N = DITemplateTypeParameter::get(Context, Name, Type, defaulted); 2869 2870 EXPECT_EQ(dwarf::DW_TAG_template_type_parameter, N->getTag()); 2871 EXPECT_EQ(Name, N->getName()); 2872 EXPECT_EQ(Type, N->getType()); 2873 EXPECT_EQ(N, DITemplateTypeParameter::get(Context, Name, Type, defaulted)); 2874 2875 EXPECT_NE(N, DITemplateTypeParameter::get(Context, "other", Type, defaulted)); 2876 EXPECT_NE(N, DITemplateTypeParameter::get(Context, Name, 2877 getBasicType("other"), defaulted)); 2878 EXPECT_NE(N, DITemplateTypeParameter::get(Context, Name, Type, true)); 2879 2880 TempDITemplateTypeParameter Temp = N->clone(); 2881 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2882 } 2883 2884 typedef MetadataTest DITemplateValueParameterTest; 2885 2886 TEST_F(DITemplateValueParameterTest, get) { 2887 unsigned Tag = dwarf::DW_TAG_template_value_parameter; 2888 StringRef Name = "template"; 2889 DIType *Type = getBasicType("basic"); 2890 bool defaulted = false; 2891 Metadata *Value = getConstantAsMetadata(); 2892 2893 auto *N = 2894 DITemplateValueParameter::get(Context, Tag, Name, Type, defaulted, Value); 2895 EXPECT_EQ(Tag, N->getTag()); 2896 EXPECT_EQ(Name, N->getName()); 2897 EXPECT_EQ(Type, N->getType()); 2898 EXPECT_EQ(Value, N->getValue()); 2899 EXPECT_EQ(N, DITemplateValueParameter::get(Context, Tag, Name, Type, 2900 defaulted, Value)); 2901 2902 EXPECT_NE(N, DITemplateValueParameter::get( 2903 Context, dwarf::DW_TAG_GNU_template_template_param, Name, 2904 Type, defaulted, Value)); 2905 EXPECT_NE(N, DITemplateValueParameter::get(Context, Tag, "other", Type, 2906 defaulted, Value)); 2907 EXPECT_NE(N, DITemplateValueParameter::get(Context, Tag, Name, 2908 getBasicType("other"), defaulted, 2909 Value)); 2910 EXPECT_NE(N, 2911 DITemplateValueParameter::get(Context, Tag, Name, Type, defaulted, 2912 getConstantAsMetadata())); 2913 EXPECT_NE( 2914 N, DITemplateValueParameter::get(Context, Tag, Name, Type, true, Value)); 2915 2916 TempDITemplateValueParameter Temp = N->clone(); 2917 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2918 } 2919 2920 typedef MetadataTest DIGlobalVariableTest; 2921 2922 TEST_F(DIGlobalVariableTest, get) { 2923 DIScope *Scope = getSubprogram(); 2924 StringRef Name = "name"; 2925 StringRef LinkageName = "linkage"; 2926 DIFile *File = getFile(); 2927 unsigned Line = 5; 2928 DIType *Type = getDerivedType(); 2929 bool IsLocalToUnit = false; 2930 bool IsDefinition = true; 2931 MDTuple *templateParams = getTuple(); 2932 DIDerivedType *StaticDataMemberDeclaration = 2933 cast<DIDerivedType>(getDerivedType()); 2934 2935 uint32_t AlignInBits = 8; 2936 2937 auto *N = DIGlobalVariable::get( 2938 Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, 2939 IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, 2940 nullptr); 2941 2942 EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag()); 2943 EXPECT_EQ(Scope, N->getScope()); 2944 EXPECT_EQ(Name, N->getName()); 2945 EXPECT_EQ(LinkageName, N->getLinkageName()); 2946 EXPECT_EQ(File, N->getFile()); 2947 EXPECT_EQ(Line, N->getLine()); 2948 EXPECT_EQ(Type, N->getType()); 2949 EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit()); 2950 EXPECT_EQ(IsDefinition, N->isDefinition()); 2951 EXPECT_EQ(StaticDataMemberDeclaration, N->getStaticDataMemberDeclaration()); 2952 EXPECT_EQ(templateParams, N->getTemplateParams()); 2953 EXPECT_EQ(AlignInBits, N->getAlignInBits()); 2954 EXPECT_EQ(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2955 Line, Type, IsLocalToUnit, IsDefinition, 2956 StaticDataMemberDeclaration, 2957 templateParams, AlignInBits, nullptr)); 2958 2959 EXPECT_NE(N, DIGlobalVariable::get( 2960 Context, getSubprogram(), Name, LinkageName, File, Line, 2961 Type, IsLocalToUnit, IsDefinition, 2962 StaticDataMemberDeclaration, templateParams, AlignInBits, 2963 nullptr)); 2964 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, "other", LinkageName, File, 2965 Line, Type, IsLocalToUnit, IsDefinition, 2966 StaticDataMemberDeclaration, 2967 templateParams, AlignInBits, nullptr)); 2968 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, "other", File, Line, 2969 Type, IsLocalToUnit, IsDefinition, 2970 StaticDataMemberDeclaration, 2971 templateParams, AlignInBits, nullptr)); 2972 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, 2973 getFile(), Line, Type, IsLocalToUnit, 2974 IsDefinition, StaticDataMemberDeclaration, 2975 templateParams, AlignInBits, nullptr)); 2976 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2977 Line + 1, Type, IsLocalToUnit, 2978 IsDefinition, StaticDataMemberDeclaration, 2979 templateParams, AlignInBits, nullptr)); 2980 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2981 Line, getDerivedType(), IsLocalToUnit, 2982 IsDefinition, StaticDataMemberDeclaration, 2983 templateParams, AlignInBits, nullptr)); 2984 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2985 Line, Type, !IsLocalToUnit, IsDefinition, 2986 StaticDataMemberDeclaration, 2987 templateParams, AlignInBits, nullptr)); 2988 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2989 Line, Type, IsLocalToUnit, !IsDefinition, 2990 StaticDataMemberDeclaration, 2991 templateParams, AlignInBits, nullptr)); 2992 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2993 Line, Type, IsLocalToUnit, IsDefinition, 2994 cast<DIDerivedType>(getDerivedType()), 2995 templateParams, AlignInBits, nullptr)); 2996 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2997 Line, Type, IsLocalToUnit, IsDefinition, 2998 StaticDataMemberDeclaration, nullptr, 2999 AlignInBits, nullptr)); 3000 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 3001 Line, Type, IsLocalToUnit, IsDefinition, 3002 StaticDataMemberDeclaration, 3003 templateParams, (AlignInBits << 1), 3004 nullptr)); 3005 3006 TempDIGlobalVariable Temp = N->clone(); 3007 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 3008 } 3009 3010 typedef MetadataTest DIGlobalVariableExpressionTest; 3011 3012 TEST_F(DIGlobalVariableExpressionTest, get) { 3013 DIScope *Scope = getSubprogram(); 3014 StringRef Name = "name"; 3015 StringRef LinkageName = "linkage"; 3016 DIFile *File = getFile(); 3017 unsigned Line = 5; 3018 DIType *Type = getDerivedType(); 3019 bool IsLocalToUnit = false; 3020 bool IsDefinition = true; 3021 MDTuple *templateParams = getTuple(); 3022 auto *Expr = DIExpression::get(Context, {1, 2}); 3023 auto *Expr2 = DIExpression::get(Context, {1, 2, 3}); 3024 DIDerivedType *StaticDataMemberDeclaration = 3025 cast<DIDerivedType>(getDerivedType()); 3026 uint32_t AlignInBits = 8; 3027 3028 auto *Var = DIGlobalVariable::get( 3029 Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, 3030 IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, 3031 nullptr); 3032 auto *Var2 = DIGlobalVariable::get( 3033 Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, 3034 IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, 3035 nullptr); 3036 auto *N = DIGlobalVariableExpression::get(Context, Var, Expr); 3037 3038 EXPECT_EQ(Var, N->getVariable()); 3039 EXPECT_EQ(Expr, N->getExpression()); 3040 EXPECT_EQ(N, DIGlobalVariableExpression::get(Context, Var, Expr)); 3041 EXPECT_NE(N, DIGlobalVariableExpression::get(Context, Var2, Expr)); 3042 EXPECT_NE(N, DIGlobalVariableExpression::get(Context, Var, Expr2)); 3043 3044 TempDIGlobalVariableExpression Temp = N->clone(); 3045 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 3046 } 3047 3048 typedef MetadataTest DILocalVariableTest; 3049 3050 TEST_F(DILocalVariableTest, get) { 3051 DILocalScope *Scope = getSubprogram(); 3052 StringRef Name = "name"; 3053 DIFile *File = getFile(); 3054 unsigned Line = 5; 3055 DIType *Type = getDerivedType(); 3056 unsigned Arg = 6; 3057 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 3058 uint32_t AlignInBits = 8; 3059 3060 auto *N = 3061 DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, Flags, 3062 AlignInBits, nullptr); 3063 EXPECT_TRUE(N->isParameter()); 3064 EXPECT_EQ(Scope, N->getScope()); 3065 EXPECT_EQ(Name, N->getName()); 3066 EXPECT_EQ(File, N->getFile()); 3067 EXPECT_EQ(Line, N->getLine()); 3068 EXPECT_EQ(Type, N->getType()); 3069 EXPECT_EQ(Arg, N->getArg()); 3070 EXPECT_EQ(Flags, N->getFlags()); 3071 EXPECT_EQ(AlignInBits, N->getAlignInBits()); 3072 EXPECT_EQ(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, 3073 Flags, AlignInBits, nullptr)); 3074 3075 EXPECT_FALSE( 3076 DILocalVariable::get(Context, Scope, Name, File, Line, Type, 0, Flags, 3077 AlignInBits, nullptr)->isParameter()); 3078 EXPECT_NE(N, DILocalVariable::get(Context, getSubprogram(), Name, File, Line, 3079 Type, Arg, Flags, AlignInBits, nullptr)); 3080 EXPECT_NE(N, DILocalVariable::get(Context, Scope, "other", File, Line, Type, 3081 Arg, Flags, AlignInBits, nullptr)); 3082 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, getFile(), Line, Type, 3083 Arg, Flags, AlignInBits, nullptr)); 3084 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line + 1, Type, 3085 Arg, Flags, AlignInBits, nullptr)); 3086 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, 3087 getDerivedType(), Arg, Flags, AlignInBits, 3088 nullptr)); 3089 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, 3090 Arg + 1, Flags, AlignInBits, nullptr)); 3091 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, 3092 Arg, Flags, (AlignInBits << 1), nullptr)); 3093 3094 TempDILocalVariable Temp = N->clone(); 3095 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 3096 } 3097 3098 TEST_F(DILocalVariableTest, getArg256) { 3099 EXPECT_EQ(255u, DILocalVariable::get(Context, getSubprogram(), "", getFile(), 3100 0, nullptr, 255, DINode::FlagZero, 0, 3101 nullptr) 3102 ->getArg()); 3103 EXPECT_EQ(256u, DILocalVariable::get(Context, getSubprogram(), "", getFile(), 3104 0, nullptr, 256, DINode::FlagZero, 0, 3105 nullptr) 3106 ->getArg()); 3107 EXPECT_EQ(257u, DILocalVariable::get(Context, getSubprogram(), "", getFile(), 3108 0, nullptr, 257, DINode::FlagZero, 0, 3109 nullptr) 3110 ->getArg()); 3111 unsigned Max = UINT16_MAX; 3112 EXPECT_EQ(Max, DILocalVariable::get(Context, getSubprogram(), "", getFile(), 3113 0, nullptr, Max, DINode::FlagZero, 0, 3114 nullptr) 3115 ->getArg()); 3116 } 3117 3118 typedef MetadataTest DIExpressionTest; 3119 3120 TEST_F(DIExpressionTest, get) { 3121 uint64_t Elements[] = {2, 6, 9, 78, 0}; 3122 auto *N = DIExpression::get(Context, Elements); 3123 EXPECT_EQ(ArrayRef(Elements), N->getElements()); 3124 EXPECT_EQ(N, DIExpression::get(Context, Elements)); 3125 3126 EXPECT_EQ(5u, N->getNumElements()); 3127 EXPECT_EQ(2u, N->getElement(0)); 3128 EXPECT_EQ(6u, N->getElement(1)); 3129 EXPECT_EQ(9u, N->getElement(2)); 3130 EXPECT_EQ(78u, N->getElement(3)); 3131 EXPECT_EQ(0u, N->getElement(4)); 3132 3133 TempDIExpression Temp = N->clone(); 3134 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 3135 3136 // Test DIExpression::prepend(). 3137 uint64_t Elts0[] = {dwarf::DW_OP_LLVM_fragment, 0, 32}; 3138 auto *N0 = DIExpression::get(Context, Elts0); 3139 uint8_t DIExprFlags = DIExpression::ApplyOffset; 3140 DIExprFlags |= DIExpression::DerefBefore; 3141 DIExprFlags |= DIExpression::DerefAfter; 3142 DIExprFlags |= DIExpression::StackValue; 3143 auto *N0WithPrependedOps = DIExpression::prepend(N0, DIExprFlags, 64); 3144 uint64_t Elts1[] = {dwarf::DW_OP_deref, 3145 dwarf::DW_OP_plus_uconst, 64, 3146 dwarf::DW_OP_deref, 3147 dwarf::DW_OP_stack_value, 3148 dwarf::DW_OP_LLVM_fragment, 0, 32}; 3149 auto *N1 = DIExpression::get(Context, Elts1); 3150 EXPECT_EQ(N0WithPrependedOps, N1); 3151 3152 // Test DIExpression::append(). 3153 uint64_t Elts2[] = {dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst, 64, 3154 dwarf::DW_OP_deref, dwarf::DW_OP_stack_value}; 3155 auto *N2 = DIExpression::append(N0, Elts2); 3156 EXPECT_EQ(N0WithPrependedOps, N2); 3157 } 3158 3159 TEST_F(DIExpressionTest, Fold) { 3160 3161 // Remove a No-op DW_OP_plus_uconst from an expression. 3162 SmallVector<uint64_t, 8> Ops = {dwarf::DW_OP_plus_uconst, 0}; 3163 auto *Expr = DIExpression::get(Context, Ops); 3164 auto *E = Expr->foldConstantMath(); 3165 SmallVector<uint64_t, 8> ResOps; 3166 auto *EmptyExpr = DIExpression::get(Context, ResOps); 3167 EXPECT_EQ(E, EmptyExpr); 3168 3169 // Remove a No-op add from an expression. 3170 Ops.clear(); 3171 Ops.push_back(dwarf::DW_OP_constu); 3172 Ops.push_back(0); 3173 Ops.push_back(dwarf::DW_OP_plus); 3174 Expr = DIExpression::get(Context, Ops); 3175 E = Expr->foldConstantMath(); 3176 EXPECT_EQ(E, EmptyExpr); 3177 3178 // Remove a No-op subtract from an expression. 3179 Ops.clear(); 3180 Ops.push_back(dwarf::DW_OP_constu); 3181 Ops.push_back(0); 3182 Ops.push_back(dwarf::DW_OP_minus); 3183 Expr = DIExpression::get(Context, Ops); 3184 E = Expr->foldConstantMath(); 3185 EXPECT_EQ(E, EmptyExpr); 3186 3187 // Remove a No-op shift left from an expression. 3188 Ops.clear(); 3189 Ops.push_back(dwarf::DW_OP_constu); 3190 Ops.push_back(0); 3191 Ops.push_back(dwarf::DW_OP_shl); 3192 Expr = DIExpression::get(Context, Ops); 3193 E = Expr->foldConstantMath(); 3194 EXPECT_EQ(E, EmptyExpr); 3195 3196 // Remove a No-op shift right from an expression. 3197 Ops.clear(); 3198 Ops.push_back(dwarf::DW_OP_constu); 3199 Ops.push_back(0); 3200 Ops.push_back(dwarf::DW_OP_shr); 3201 Expr = DIExpression::get(Context, Ops); 3202 E = Expr->foldConstantMath(); 3203 EXPECT_EQ(E, EmptyExpr); 3204 3205 // Remove a No-op multiply from an expression. 3206 Ops.clear(); 3207 Ops.push_back(dwarf::DW_OP_constu); 3208 Ops.push_back(1); 3209 Ops.push_back(dwarf::DW_OP_mul); 3210 Expr = DIExpression::get(Context, Ops); 3211 E = Expr->foldConstantMath(); 3212 EXPECT_EQ(E, EmptyExpr); 3213 3214 // Remove a No-op divide from an expression. 3215 Ops.clear(); 3216 Ops.push_back(dwarf::DW_OP_constu); 3217 Ops.push_back(1); 3218 Ops.push_back(dwarf::DW_OP_div); 3219 Expr = DIExpression::get(Context, Ops); 3220 E = Expr->foldConstantMath(); 3221 EXPECT_EQ(E, EmptyExpr); 3222 3223 // Test fold {DW_OP_plus_uconst, Const1, DW_OP_plus_uconst, Const2} -> 3224 // {DW_OP_plus_uconst, Const1 + Const2} 3225 Ops.clear(); 3226 Ops.push_back(dwarf::DW_OP_plus_uconst); 3227 Ops.push_back(2); 3228 Ops.push_back(dwarf::DW_OP_plus_uconst); 3229 Ops.push_back(3); 3230 Expr = DIExpression::get(Context, Ops); 3231 E = Expr->foldConstantMath(); 3232 ResOps.push_back(dwarf::DW_OP_plus_uconst); 3233 ResOps.push_back(5); 3234 auto *ResExpr = DIExpression::get(Context, ResOps); 3235 EXPECT_EQ(E, ResExpr); 3236 3237 // Test {DW_OP_constu, Const1, DW_OP_plus_uconst, Const2} -> {DW_OP_constu, 3238 // Const1 + Const2} 3239 Ops.clear(); 3240 Ops.push_back(dwarf::DW_OP_constu); 3241 Ops.push_back(2); 3242 Ops.push_back(dwarf::DW_OP_plus_uconst); 3243 Ops.push_back(3); 3244 Expr = DIExpression::get(Context, Ops); 3245 E = Expr->foldConstantMath(); 3246 ResOps.clear(); 3247 ResOps.push_back(dwarf::DW_OP_constu); 3248 ResOps.push_back(5); 3249 ResExpr = DIExpression::get(Context, ResOps); 3250 EXPECT_EQ(E, ResExpr); 3251 3252 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_plus} -> 3253 // {DW_OP_constu, Const1 + Const2} 3254 Ops.clear(); 3255 Ops.push_back(dwarf::DW_OP_constu); 3256 Ops.push_back(8); 3257 Ops.push_back(dwarf::DW_OP_constu); 3258 Ops.push_back(2); 3259 Ops.push_back(dwarf::DW_OP_plus); 3260 Expr = DIExpression::get(Context, Ops); 3261 E = Expr->foldConstantMath(); 3262 ResOps.clear(); 3263 ResOps.push_back(dwarf::DW_OP_constu); 3264 ResOps.push_back(10); 3265 ResExpr = DIExpression::get(Context, ResOps); 3266 EXPECT_EQ(E, ResExpr); 3267 3268 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_minus} -> 3269 // {DW_OP_constu, Const1 - Const2} 3270 Ops.clear(); 3271 Ops.push_back(dwarf::DW_OP_constu); 3272 Ops.push_back(8); 3273 Ops.push_back(dwarf::DW_OP_constu); 3274 Ops.push_back(2); 3275 Ops.push_back(dwarf::DW_OP_minus); 3276 Expr = DIExpression::get(Context, Ops); 3277 E = Expr->foldConstantMath(); 3278 ResOps.clear(); 3279 ResOps.push_back(dwarf::DW_OP_constu); 3280 ResOps.push_back(6); 3281 ResExpr = DIExpression::get(Context, ResOps); 3282 EXPECT_EQ(E, ResExpr); 3283 3284 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_mul} -> 3285 // {DW_OP_constu, Const1 * Const2} 3286 Ops.clear(); 3287 Ops.push_back(dwarf::DW_OP_constu); 3288 Ops.push_back(8); 3289 Ops.push_back(dwarf::DW_OP_constu); 3290 Ops.push_back(2); 3291 Ops.push_back(dwarf::DW_OP_mul); 3292 Expr = DIExpression::get(Context, Ops); 3293 E = Expr->foldConstantMath(); 3294 ResOps.clear(); 3295 ResOps.push_back(dwarf::DW_OP_constu); 3296 ResOps.push_back(16); 3297 ResExpr = DIExpression::get(Context, ResOps); 3298 EXPECT_EQ(E, ResExpr); 3299 3300 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_div} -> 3301 // {DW_OP_constu, Const1 / Const2} 3302 Ops.clear(); 3303 Ops.push_back(dwarf::DW_OP_constu); 3304 Ops.push_back(8); 3305 Ops.push_back(dwarf::DW_OP_constu); 3306 Ops.push_back(2); 3307 Ops.push_back(dwarf::DW_OP_div); 3308 Expr = DIExpression::get(Context, Ops); 3309 E = Expr->foldConstantMath(); 3310 ResOps.clear(); 3311 ResOps.push_back(dwarf::DW_OP_constu); 3312 ResOps.push_back(4); 3313 ResExpr = DIExpression::get(Context, ResOps); 3314 EXPECT_EQ(E, ResExpr); 3315 3316 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_shl} -> 3317 // {DW_OP_constu, Const1 << Const2} 3318 Ops.clear(); 3319 Ops.push_back(dwarf::DW_OP_constu); 3320 Ops.push_back(8); 3321 Ops.push_back(dwarf::DW_OP_constu); 3322 Ops.push_back(2); 3323 Ops.push_back(dwarf::DW_OP_shl); 3324 Expr = DIExpression::get(Context, Ops); 3325 E = Expr->foldConstantMath(); 3326 ResOps.clear(); 3327 ResOps.push_back(dwarf::DW_OP_constu); 3328 ResOps.push_back(32); 3329 ResExpr = DIExpression::get(Context, ResOps); 3330 EXPECT_EQ(E, ResExpr); 3331 3332 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_shr} -> 3333 // {DW_OP_constu, Const1 >> Const2} 3334 Ops.clear(); 3335 Ops.push_back(dwarf::DW_OP_constu); 3336 Ops.push_back(8); 3337 Ops.push_back(dwarf::DW_OP_constu); 3338 Ops.push_back(2); 3339 Ops.push_back(dwarf::DW_OP_shr); 3340 Expr = DIExpression::get(Context, Ops); 3341 E = Expr->foldConstantMath(); 3342 ResOps.clear(); 3343 ResOps.push_back(dwarf::DW_OP_constu); 3344 ResOps.push_back(2); 3345 ResExpr = DIExpression::get(Context, ResOps); 3346 EXPECT_EQ(E, ResExpr); 3347 3348 // Test {DW_OP_plus_uconst, Const1, DW_OP_constu, Const2, DW_OP_plus} -> 3349 // {DW_OP_plus_uconst, Const1 + Const2} 3350 Ops.clear(); 3351 Ops.push_back(dwarf::DW_OP_plus_uconst); 3352 Ops.push_back(8); 3353 Ops.push_back(dwarf::DW_OP_constu); 3354 Ops.push_back(2); 3355 Ops.push_back(dwarf::DW_OP_plus); 3356 Expr = DIExpression::get(Context, Ops); 3357 E = Expr->foldConstantMath(); 3358 ResOps.clear(); 3359 ResOps.push_back(dwarf::DW_OP_plus_uconst); 3360 ResOps.push_back(10); 3361 ResExpr = DIExpression::get(Context, ResOps); 3362 EXPECT_EQ(E, ResExpr); 3363 3364 // Test {DW_OP_constu, Const1, DW_OP_plus, DW_OP_plus_uconst, Const2} -> 3365 // {DW_OP_plus_uconst, Const1 + Const2} 3366 Ops.clear(); 3367 Ops.push_back(dwarf::DW_OP_constu); 3368 Ops.push_back(8); 3369 Ops.push_back(dwarf::DW_OP_plus); 3370 Ops.push_back(dwarf::DW_OP_plus_uconst); 3371 Ops.push_back(2); 3372 Expr = DIExpression::get(Context, Ops); 3373 E = Expr->foldConstantMath(); 3374 ResOps.clear(); 3375 ResOps.push_back(dwarf::DW_OP_plus_uconst); 3376 ResOps.push_back(10); 3377 ResExpr = DIExpression::get(Context, ResOps); 3378 EXPECT_EQ(E, ResExpr); 3379 3380 // Test {DW_OP_constu, Const1, DW_OP_plus, DW_OP_constu, Const2, DW_OP_plus} 3381 // -> {DW_OP_plus_uconst, Const1 + Const2} 3382 Ops.clear(); 3383 Ops.push_back(dwarf::DW_OP_constu); 3384 Ops.push_back(8); 3385 Ops.push_back(dwarf::DW_OP_plus); 3386 Ops.push_back(dwarf::DW_OP_constu); 3387 Ops.push_back(2); 3388 Ops.push_back(dwarf::DW_OP_plus); 3389 Expr = DIExpression::get(Context, Ops); 3390 E = Expr->foldConstantMath(); 3391 ResOps.clear(); 3392 ResOps.push_back(dwarf::DW_OP_plus_uconst); 3393 ResOps.push_back(10); 3394 ResExpr = DIExpression::get(Context, ResOps); 3395 EXPECT_EQ(E, ResExpr); 3396 3397 // Test {DW_OP_constu, Const1, DW_OP_mul, DW_OP_constu, Const2, DW_OP_mul} -> 3398 // {DW_OP_constu, Const1 * Const2, DW_OP_mul} 3399 Ops.clear(); 3400 Ops.push_back(dwarf::DW_OP_constu); 3401 Ops.push_back(8); 3402 Ops.push_back(dwarf::DW_OP_mul); 3403 Ops.push_back(dwarf::DW_OP_constu); 3404 Ops.push_back(2); 3405 Ops.push_back(dwarf::DW_OP_mul); 3406 Expr = DIExpression::get(Context, Ops); 3407 E = Expr->foldConstantMath(); 3408 ResOps.clear(); 3409 ResOps.push_back(dwarf::DW_OP_constu); 3410 ResOps.push_back(16); 3411 ResOps.push_back(dwarf::DW_OP_mul); 3412 ResExpr = DIExpression::get(Context, ResOps); 3413 EXPECT_EQ(E, ResExpr); 3414 3415 // Test {DW_OP_plus_uconst, Const1, DW_OP_plus, DW_OP_LLVM_arg, Arg, 3416 // DW_OP_plus, DW_OP_constu, Const2, DW_OP_plus} -> {DW_OP_plus_uconst, Const1 3417 // + Const2, DW_OP_LLVM_arg, Arg, DW_OP_plus} 3418 Ops.clear(); 3419 Ops.push_back(dwarf::DW_OP_plus_uconst); 3420 Ops.push_back(8); 3421 Ops.push_back(dwarf::DW_OP_LLVM_arg); 3422 Ops.push_back(0); 3423 Ops.push_back(dwarf::DW_OP_plus); 3424 Ops.push_back(dwarf::DW_OP_constu); 3425 Ops.push_back(2); 3426 Ops.push_back(dwarf::DW_OP_plus); 3427 Expr = DIExpression::get(Context, Ops); 3428 E = Expr->foldConstantMath(); 3429 ResOps.clear(); 3430 ResOps.push_back(dwarf::DW_OP_plus_uconst); 3431 ResOps.push_back(10); 3432 ResOps.push_back(dwarf::DW_OP_LLVM_arg); 3433 ResOps.push_back(0); 3434 ResOps.push_back(dwarf::DW_OP_plus); 3435 ResExpr = DIExpression::get(Context, ResOps); 3436 EXPECT_EQ(E, ResExpr); 3437 3438 // Test {DW_OP_constu, Const1, DW_OP_plus, DW_OP_LLVM_arg, Arg, DW_OP_plus, 3439 // DW_OP_plus_uconst, Const2} -> {DW_OP_constu, Const1 + Const2, DW_OP_plus, 3440 // DW_OP_LLVM_arg, Arg, DW_OP_plus} 3441 Ops.clear(); 3442 Ops.push_back(dwarf::DW_OP_constu); 3443 Ops.push_back(8); 3444 Ops.push_back(dwarf::DW_OP_plus); 3445 Ops.push_back(dwarf::DW_OP_LLVM_arg); 3446 Ops.push_back(0); 3447 Ops.push_back(dwarf::DW_OP_plus); 3448 Ops.push_back(dwarf::DW_OP_plus_uconst); 3449 Ops.push_back(2); 3450 Expr = DIExpression::get(Context, Ops); 3451 E = Expr->foldConstantMath(); 3452 ResOps.clear(); 3453 ResOps.push_back(dwarf::DW_OP_plus_uconst); 3454 ResOps.push_back(10); 3455 ResOps.push_back(dwarf::DW_OP_LLVM_arg); 3456 ResOps.push_back(0); 3457 ResOps.push_back(dwarf::DW_OP_plus); 3458 ResExpr = DIExpression::get(Context, ResOps); 3459 EXPECT_EQ(E, ResExpr); 3460 3461 // Test {DW_OP_constu, Const1, DW_OP_plus, DW_OP_LLVM_arg, Arg, DW_OP_plus, 3462 // DW_OP_constu, Const2, DW_OP_plus} -> {DW_OP_constu, Const1 + Const2, 3463 // DW_OP_plus, DW_OP_LLVM_arg, Arg, DW_OP_plus} 3464 Ops.clear(); 3465 Ops.push_back(dwarf::DW_OP_constu); 3466 Ops.push_back(8); 3467 Ops.push_back(dwarf::DW_OP_plus); 3468 Ops.push_back(dwarf::DW_OP_LLVM_arg); 3469 Ops.push_back(0); 3470 Ops.push_back(dwarf::DW_OP_plus); 3471 Ops.push_back(dwarf::DW_OP_constu); 3472 Ops.push_back(2); 3473 Ops.push_back(dwarf::DW_OP_plus); 3474 Expr = DIExpression::get(Context, Ops); 3475 E = Expr->foldConstantMath(); 3476 ResOps.clear(); 3477 ResOps.push_back(dwarf::DW_OP_plus_uconst); 3478 ResOps.push_back(10); 3479 ResOps.push_back(dwarf::DW_OP_LLVM_arg); 3480 ResOps.push_back(0); 3481 ResOps.push_back(dwarf::DW_OP_plus); 3482 ResExpr = DIExpression::get(Context, ResOps); 3483 EXPECT_EQ(E, ResExpr); 3484 3485 // Test {DW_OP_constu, Const1, DW_OP_mul, DW_OP_LLVM_arg, Arg, DW_OP_mul, 3486 // DW_OP_constu, Const2, DW_OP_mul} -> {DW_OP_constu, Const1 * Const2, 3487 // DW_OP_mul, DW_OP_LLVM_arg, Arg, DW_OP_mul} 3488 Ops.clear(); 3489 Ops.push_back(dwarf::DW_OP_constu); 3490 Ops.push_back(8); 3491 Ops.push_back(dwarf::DW_OP_mul); 3492 Ops.push_back(dwarf::DW_OP_LLVM_arg); 3493 Ops.push_back(0); 3494 Ops.push_back(dwarf::DW_OP_mul); 3495 Ops.push_back(dwarf::DW_OP_constu); 3496 Ops.push_back(2); 3497 Ops.push_back(dwarf::DW_OP_mul); 3498 Expr = DIExpression::get(Context, Ops); 3499 E = Expr->foldConstantMath(); 3500 ResOps.clear(); 3501 ResOps.push_back(dwarf::DW_OP_constu); 3502 ResOps.push_back(16); 3503 ResOps.push_back(dwarf::DW_OP_mul); 3504 ResOps.push_back(dwarf::DW_OP_LLVM_arg); 3505 ResOps.push_back(0); 3506 ResOps.push_back(dwarf::DW_OP_mul); 3507 ResExpr = DIExpression::get(Context, ResOps); 3508 EXPECT_EQ(E, ResExpr); 3509 3510 // Test an overflow addition. 3511 Ops.clear(); 3512 Ops.push_back(dwarf::DW_OP_plus_uconst); 3513 Ops.push_back(UINT64_MAX); 3514 Ops.push_back(dwarf::DW_OP_plus_uconst); 3515 Ops.push_back(2); 3516 Expr = DIExpression::get(Context, Ops); 3517 E = Expr->foldConstantMath(); 3518 ResOps.clear(); 3519 ResOps.push_back(dwarf::DW_OP_plus_uconst); 3520 ResOps.push_back(UINT64_MAX); 3521 ResOps.push_back(dwarf::DW_OP_plus_uconst); 3522 ResOps.push_back(2); 3523 ResExpr = DIExpression::get(Context, ResOps); 3524 EXPECT_EQ(E, ResExpr); 3525 3526 // Test an underflow subtraction. 3527 Ops.clear(); 3528 Ops.push_back(dwarf::DW_OP_constu); 3529 Ops.push_back(1); 3530 Ops.push_back(dwarf::DW_OP_constu); 3531 Ops.push_back(2); 3532 Ops.push_back(dwarf::DW_OP_minus); 3533 Expr = DIExpression::get(Context, Ops); 3534 E = Expr->foldConstantMath(); 3535 ResOps.clear(); 3536 ResOps.push_back(dwarf::DW_OP_constu); 3537 ResOps.push_back(1); 3538 ResOps.push_back(dwarf::DW_OP_constu); 3539 ResOps.push_back(2); 3540 ResOps.push_back(dwarf::DW_OP_minus); 3541 ResExpr = DIExpression::get(Context, ResOps); 3542 EXPECT_EQ(E, ResExpr); 3543 3544 // Test a left shift greater than 63. 3545 Ops.clear(); 3546 Ops.push_back(dwarf::DW_OP_constu); 3547 Ops.push_back(1); 3548 Ops.push_back(dwarf::DW_OP_constu); 3549 Ops.push_back(64); 3550 Ops.push_back(dwarf::DW_OP_shl); 3551 Expr = DIExpression::get(Context, Ops); 3552 E = Expr->foldConstantMath(); 3553 ResOps.clear(); 3554 ResOps.push_back(dwarf::DW_OP_constu); 3555 ResOps.push_back(1); 3556 ResOps.push_back(dwarf::DW_OP_constu); 3557 ResOps.push_back(64); 3558 ResOps.push_back(dwarf::DW_OP_shl); 3559 ResExpr = DIExpression::get(Context, ResOps); 3560 EXPECT_EQ(E, ResExpr); 3561 3562 // Test a right shift greater than 63. 3563 Ops.clear(); 3564 Ops.push_back(dwarf::DW_OP_constu); 3565 Ops.push_back(1); 3566 Ops.push_back(dwarf::DW_OP_constu); 3567 Ops.push_back(64); 3568 Ops.push_back(dwarf::DW_OP_shr); 3569 Expr = DIExpression::get(Context, Ops); 3570 E = Expr->foldConstantMath(); 3571 ResOps.clear(); 3572 ResOps.push_back(dwarf::DW_OP_constu); 3573 ResOps.push_back(1); 3574 ResOps.push_back(dwarf::DW_OP_constu); 3575 ResOps.push_back(64); 3576 ResOps.push_back(dwarf::DW_OP_shr); 3577 ResExpr = DIExpression::get(Context, ResOps); 3578 EXPECT_EQ(E, ResExpr); 3579 3580 // Test an overflow multiplication. 3581 Ops.clear(); 3582 Ops.push_back(dwarf::DW_OP_constu); 3583 Ops.push_back(UINT64_MAX); 3584 Ops.push_back(dwarf::DW_OP_constu); 3585 Ops.push_back(2); 3586 Ops.push_back(dwarf::DW_OP_mul); 3587 Expr = DIExpression::get(Context, Ops); 3588 E = Expr->foldConstantMath(); 3589 ResOps.clear(); 3590 ResOps.push_back(dwarf::DW_OP_constu); 3591 ResOps.push_back(UINT64_MAX); 3592 ResOps.push_back(dwarf::DW_OP_constu); 3593 ResOps.push_back(2); 3594 ResOps.push_back(dwarf::DW_OP_mul); 3595 ResExpr = DIExpression::get(Context, ResOps); 3596 EXPECT_EQ(E, ResExpr); 3597 3598 // Test a divide by 0. 3599 Ops.clear(); 3600 Ops.push_back(dwarf::DW_OP_constu); 3601 Ops.push_back(2); 3602 Ops.push_back(dwarf::DW_OP_constu); 3603 Ops.push_back(0); 3604 Ops.push_back(dwarf::DW_OP_div); 3605 Expr = DIExpression::get(Context, Ops); 3606 E = Expr->foldConstantMath(); 3607 ResOps.clear(); 3608 ResOps.push_back(dwarf::DW_OP_constu); 3609 ResOps.push_back(2); 3610 ResOps.push_back(dwarf::DW_OP_lit0); 3611 ResOps.push_back(dwarf::DW_OP_div); 3612 ResExpr = DIExpression::get(Context, ResOps); 3613 EXPECT_EQ(E, ResExpr); 3614 } 3615 3616 TEST_F(DIExpressionTest, Append) { 3617 // Test appending a {dwarf::DW_OP_constu, <const>, DW_OP_plus} to a DW_OP_plus 3618 // expression 3619 SmallVector<uint64_t, 8> Ops = {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_constu, 3620 2, dwarf::DW_OP_plus}; 3621 auto *Expr = DIExpression::get(Context, Ops); 3622 SmallVector<uint64_t, 8> AppendOps = {dwarf::DW_OP_constu, 3, 3623 dwarf::DW_OP_plus}; 3624 auto *AppendExpr = DIExpression::append(Expr, AppendOps); 3625 SmallVector<uint64_t, 8> OpsRes = {dwarf::DW_OP_LLVM_arg, 0, 3626 dwarf::DW_OP_plus_uconst, 5}; 3627 auto *ResExpr = DIExpression::get(Context, OpsRes); 3628 EXPECT_EQ(ResExpr, AppendExpr); 3629 3630 // Test appending a {dwarf::DW_OP_plus_uconst, <const>} to a DW_OP_plus 3631 // expression uint64_t PlusUConstOps[] = {dwarf::DW_OP_plus_uconst, 3}; 3632 AppendOps.clear(); 3633 AppendOps.push_back(dwarf::DW_OP_plus_uconst); 3634 AppendOps.push_back(3); 3635 AppendExpr = DIExpression::append(Expr, AppendOps); 3636 OpsRes.clear(); 3637 OpsRes.push_back(dwarf::DW_OP_LLVM_arg); 3638 OpsRes.push_back(0); 3639 OpsRes.push_back(dwarf::DW_OP_plus_uconst); 3640 OpsRes.push_back(5); 3641 ResExpr = DIExpression::get(Context, OpsRes); 3642 EXPECT_EQ(ResExpr, AppendExpr); 3643 3644 // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_plus} to an expression 3645 AppendOps.clear(); 3646 AppendOps.push_back(dwarf::DW_OP_constu); 3647 AppendOps.push_back(0); 3648 AppendOps.push_back(dwarf::DW_OP_plus); 3649 AppendExpr = DIExpression::append(Expr, AppendOps); 3650 OpsRes.clear(); 3651 OpsRes.push_back(dwarf::DW_OP_LLVM_arg); 3652 OpsRes.push_back(0); 3653 OpsRes.push_back(dwarf::DW_OP_plus_uconst); 3654 OpsRes.push_back(2); 3655 ResExpr = DIExpression::get(Context, OpsRes); 3656 EXPECT_EQ(ResExpr, AppendExpr); 3657 3658 // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_minus} to an expression 3659 AppendOps.clear(); 3660 AppendOps.push_back(dwarf::DW_OP_constu); 3661 AppendOps.push_back(0); 3662 AppendOps.push_back(dwarf::DW_OP_minus); 3663 AppendExpr = DIExpression::append(Expr, AppendOps); 3664 OpsRes.clear(); 3665 OpsRes.push_back(dwarf::DW_OP_LLVM_arg); 3666 OpsRes.push_back(0); 3667 OpsRes.push_back(dwarf::DW_OP_plus_uconst); 3668 OpsRes.push_back(2); 3669 ResExpr = DIExpression::get(Context, OpsRes); 3670 EXPECT_EQ(ResExpr, AppendExpr); 3671 3672 // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_shl} to an expression 3673 AppendOps.clear(); 3674 AppendOps.push_back(dwarf::DW_OP_constu); 3675 AppendOps.push_back(0); 3676 AppendOps.push_back(dwarf::DW_OP_shl); 3677 AppendExpr = DIExpression::append(Expr, AppendOps); 3678 OpsRes.clear(); 3679 OpsRes.push_back(dwarf::DW_OP_LLVM_arg); 3680 OpsRes.push_back(0); 3681 OpsRes.push_back(dwarf::DW_OP_plus_uconst); 3682 OpsRes.push_back(2); 3683 ResExpr = DIExpression::get(Context, OpsRes); 3684 EXPECT_EQ(ResExpr, AppendExpr); 3685 3686 // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_shr} to an expression 3687 AppendOps.clear(); 3688 AppendOps.push_back(dwarf::DW_OP_constu); 3689 AppendOps.push_back(0); 3690 AppendOps.push_back(dwarf::DW_OP_shr); 3691 AppendExpr = DIExpression::append(Expr, AppendOps); 3692 OpsRes.clear(); 3693 OpsRes.push_back(dwarf::DW_OP_LLVM_arg); 3694 OpsRes.push_back(0); 3695 OpsRes.push_back(dwarf::DW_OP_plus_uconst); 3696 OpsRes.push_back(2); 3697 ResExpr = DIExpression::get(Context, OpsRes); 3698 EXPECT_EQ(ResExpr, AppendExpr); 3699 3700 // Test appending a {dwarf::DW_OP_constu, <const>, DW_OP_mul} to a DW_OP_mul 3701 // expression 3702 Ops.clear(); 3703 Ops.push_back(dwarf::DW_OP_LLVM_arg); 3704 Ops.push_back(0); 3705 Ops.push_back(dwarf::DW_OP_constu); 3706 Ops.push_back(2); 3707 Ops.push_back(dwarf::DW_OP_mul); 3708 Expr = DIExpression::get(Context, Ops); 3709 AppendOps.clear(); 3710 AppendOps.push_back(dwarf::DW_OP_constu); 3711 AppendOps.push_back(3); 3712 AppendOps.push_back(dwarf::DW_OP_mul); 3713 AppendExpr = DIExpression::append(Expr, AppendOps); 3714 OpsRes.clear(); 3715 OpsRes.push_back(dwarf::DW_OP_LLVM_arg); 3716 OpsRes.push_back(0); 3717 OpsRes.push_back(dwarf::DW_OP_constu); 3718 OpsRes.push_back(6); 3719 OpsRes.push_back(dwarf::DW_OP_mul); 3720 ResExpr = DIExpression::get(Context, OpsRes); 3721 EXPECT_EQ(ResExpr, AppendExpr); 3722 3723 // Test appending a {dwarf::DW_OP_constu, 1, DW_OP_mul} to an expression 3724 AppendOps.clear(); 3725 AppendOps.push_back(dwarf::DW_OP_constu); 3726 AppendOps.push_back(1); 3727 AppendOps.push_back(dwarf::DW_OP_mul); 3728 AppendExpr = DIExpression::append(Expr, AppendOps); 3729 OpsRes.clear(); 3730 OpsRes.push_back(dwarf::DW_OP_LLVM_arg); 3731 OpsRes.push_back(0); 3732 OpsRes.push_back(dwarf::DW_OP_constu); 3733 OpsRes.push_back(2); 3734 OpsRes.push_back(dwarf::DW_OP_mul); 3735 ResExpr = DIExpression::get(Context, OpsRes); 3736 EXPECT_EQ(ResExpr, AppendExpr); 3737 3738 // Test appending a {dwarf::DW_OP_constu, 1, DW_OP_div} to an expression 3739 AppendOps.clear(); 3740 AppendOps.push_back(dwarf::DW_OP_constu); 3741 AppendOps.push_back(1); 3742 AppendOps.push_back(dwarf::DW_OP_div); 3743 AppendExpr = DIExpression::append(Expr, AppendOps); 3744 OpsRes.clear(); 3745 OpsRes.push_back(dwarf::DW_OP_LLVM_arg); 3746 OpsRes.push_back(0); 3747 OpsRes.push_back(dwarf::DW_OP_constu); 3748 OpsRes.push_back(2); 3749 OpsRes.push_back(dwarf::DW_OP_mul); 3750 ResExpr = DIExpression::get(Context, OpsRes); 3751 EXPECT_EQ(ResExpr, AppendExpr); 3752 } 3753 3754 TEST_F(DIExpressionTest, isValid) { 3755 #define EXPECT_VALID(...) \ 3756 do { \ 3757 uint64_t Elements[] = {__VA_ARGS__}; \ 3758 EXPECT_TRUE(DIExpression::get(Context, Elements)->isValid()); \ 3759 } while (false) 3760 #define EXPECT_INVALID(...) \ 3761 do { \ 3762 uint64_t Elements[] = {__VA_ARGS__}; \ 3763 EXPECT_FALSE(DIExpression::get(Context, Elements)->isValid()); \ 3764 } while (false) 3765 3766 // Empty expression should be valid. 3767 EXPECT_TRUE(DIExpression::get(Context, {})->isValid()); 3768 3769 // Valid constructions. 3770 EXPECT_VALID(dwarf::DW_OP_plus_uconst, 6); 3771 EXPECT_VALID(dwarf::DW_OP_constu, 6, dwarf::DW_OP_plus); 3772 EXPECT_VALID(dwarf::DW_OP_deref); 3773 EXPECT_VALID(dwarf::DW_OP_LLVM_fragment, 3, 7); 3774 EXPECT_VALID(dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_deref); 3775 EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst, 6); 3776 EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_LLVM_fragment, 3, 7); 3777 EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst, 6, 3778 dwarf::DW_OP_LLVM_fragment, 3, 7); 3779 EXPECT_VALID(dwarf::DW_OP_LLVM_entry_value, 1); 3780 EXPECT_VALID(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_entry_value, 1); 3781 3782 // Invalid constructions. 3783 EXPECT_INVALID(~0u); 3784 EXPECT_INVALID(dwarf::DW_OP_plus, 0); 3785 EXPECT_INVALID(dwarf::DW_OP_plus_uconst); 3786 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment); 3787 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3); 3788 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3, 7, dwarf::DW_OP_plus_uconst, 3); 3789 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3, 7, dwarf::DW_OP_deref); 3790 EXPECT_INVALID(dwarf::DW_OP_LLVM_entry_value, 2); 3791 EXPECT_INVALID(dwarf::DW_OP_plus_uconst, 5, dwarf::DW_OP_LLVM_entry_value, 1); 3792 EXPECT_INVALID(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 5, 3793 dwarf::DW_OP_LLVM_entry_value, 1); 3794 EXPECT_INVALID(dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_LLVM_entry_value, 1); 3795 3796 #undef EXPECT_VALID 3797 #undef EXPECT_INVALID 3798 } 3799 3800 TEST_F(DIExpressionTest, createFragmentExpression) { 3801 #define EXPECT_VALID_FRAGMENT(Offset, Size, ...) \ 3802 do { \ 3803 uint64_t Elements[] = {__VA_ARGS__}; \ 3804 DIExpression *Expression = DIExpression::get(Context, Elements); \ 3805 EXPECT_TRUE( \ 3806 DIExpression::createFragmentExpression(Expression, Offset, Size) \ 3807 .has_value()); \ 3808 } while (false) 3809 #define EXPECT_INVALID_FRAGMENT(Offset, Size, ...) \ 3810 do { \ 3811 uint64_t Elements[] = {__VA_ARGS__}; \ 3812 DIExpression *Expression = DIExpression::get(Context, Elements); \ 3813 EXPECT_FALSE( \ 3814 DIExpression::createFragmentExpression(Expression, Offset, Size) \ 3815 .has_value()); \ 3816 } while (false) 3817 3818 // createFragmentExpression adds correct ops. 3819 std::optional<DIExpression*> R = DIExpression::createFragmentExpression( 3820 DIExpression::get(Context, {}), 0, 32); 3821 EXPECT_EQ(R.has_value(), true); 3822 EXPECT_EQ(3u, (*R)->getNumElements()); 3823 EXPECT_EQ(dwarf::DW_OP_LLVM_fragment, (*R)->getElement(0)); 3824 EXPECT_EQ(0u, (*R)->getElement(1)); 3825 EXPECT_EQ(32u, (*R)->getElement(2)); 3826 3827 // Valid fragment expressions. 3828 EXPECT_VALID_FRAGMENT(0, 32, {}); 3829 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_deref); 3830 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_LLVM_fragment, 0, 32); 3831 EXPECT_VALID_FRAGMENT(16, 16, dwarf::DW_OP_LLVM_fragment, 0, 32); 3832 3833 // Invalid fragment expressions (incompatible ops). 3834 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 6, dwarf::DW_OP_plus, 3835 dwarf::DW_OP_stack_value); 3836 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 14, dwarf::DW_OP_minus, 3837 dwarf::DW_OP_stack_value); 3838 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 16, dwarf::DW_OP_shr, 3839 dwarf::DW_OP_stack_value); 3840 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 16, dwarf::DW_OP_shl, 3841 dwarf::DW_OP_stack_value); 3842 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 16, dwarf::DW_OP_shra, 3843 dwarf::DW_OP_stack_value); 3844 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6, 3845 dwarf::DW_OP_stack_value); 3846 3847 // Fragments can be created for expressions using DW_OP_plus to compute an 3848 // address. 3849 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 6, dwarf::DW_OP_plus); 3850 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_deref); 3851 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_deref, 3852 dwarf::DW_OP_stack_value); 3853 3854 // Check the other deref operations work in the same way. 3855 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6, 3856 dwarf::DW_OP_deref_size, 1); 3857 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6, 3858 dwarf::DW_OP_deref_type, 1, 1); 3859 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6, 3860 dwarf::DW_OP_xderef); 3861 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6, 3862 dwarf::DW_OP_xderef_size, 1); 3863 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6, 3864 dwarf::DW_OP_xderef_type, 1, 1); 3865 3866 // Fragments cannot be created for expressions using DW_OP_plus to compute an 3867 // implicit value (check that this correctly fails even though there is a 3868 // deref in the expression). 3869 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst, 3870 2, dwarf::DW_OP_stack_value); 3871 3872 #undef EXPECT_VALID_FRAGMENT 3873 #undef EXPECT_INVALID_FRAGMENT 3874 } 3875 3876 TEST_F(DIExpressionTest, extractLeadingOffset) { 3877 int64_t Offset; 3878 SmallVector<uint64_t> Remaining; 3879 using namespace dwarf; 3880 #define OPS(...) SmallVector<uint64_t>(ArrayRef<uint64_t>{__VA_ARGS__}) 3881 #define EXTRACT_FROM(...) \ 3882 DIExpression::get(Context, {__VA_ARGS__}) \ 3883 ->extractLeadingOffset(Offset, Remaining) 3884 // Test the number of expression inputs 3885 // ------------------------------------ 3886 // 3887 // Single location expressions are permitted. 3888 EXPECT_TRUE(EXTRACT_FROM(DW_OP_plus_uconst, 2)); 3889 EXPECT_EQ(Offset, 2); 3890 EXPECT_EQ(Remaining.size(), 0u); 3891 // This is also a single-location. 3892 EXPECT_TRUE(EXTRACT_FROM(DW_OP_LLVM_arg, 0, DW_OP_plus_uconst, 2)); 3893 EXPECT_EQ(Offset, 2); 3894 EXPECT_EQ(Remaining.size(), 0u); 3895 // Variadic locations are not permitted. A non-zero arg is assumed to 3896 // indicate multiple inputs. 3897 EXPECT_FALSE(EXTRACT_FROM(DW_OP_LLVM_arg, 1)); 3898 EXPECT_FALSE(EXTRACT_FROM(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)); 3899 3900 // Test offsets expressions 3901 // ------------------------ 3902 EXPECT_TRUE(EXTRACT_FROM()); 3903 EXPECT_EQ(Offset, 0); 3904 EXPECT_EQ(Remaining.size(), 0u); 3905 3906 EXPECT_TRUE(EXTRACT_FROM(DW_OP_constu, 4, DW_OP_plus)); 3907 EXPECT_EQ(Offset, 4); 3908 EXPECT_EQ(Remaining.size(), 0u); 3909 3910 EXPECT_TRUE(EXTRACT_FROM(DW_OP_constu, 2, DW_OP_minus)); 3911 EXPECT_EQ(Offset, -2); 3912 EXPECT_EQ(Remaining.size(), 0u); 3913 3914 EXPECT_TRUE(EXTRACT_FROM(DW_OP_plus_uconst, 8)); 3915 EXPECT_EQ(Offset, 8); 3916 EXPECT_EQ(Remaining.size(), 0u); 3917 3918 EXPECT_TRUE(EXTRACT_FROM(DW_OP_plus_uconst, 4, DW_OP_constu, 2, DW_OP_minus)); 3919 EXPECT_EQ(Offset, 2); 3920 EXPECT_EQ(Remaining.size(), 0u); 3921 3922 // Not all operations are permitted for simplicity. Can be added 3923 // if needed in future. 3924 EXPECT_FALSE(EXTRACT_FROM(DW_OP_constu, 2, DW_OP_mul)); 3925 3926 // Test "remaining ops" 3927 // -------------------- 3928 EXPECT_TRUE(EXTRACT_FROM(DW_OP_plus_uconst, 4, DW_OP_constu, 8, DW_OP_minus, 3929 DW_OP_LLVM_fragment, 0, 32)); 3930 EXPECT_EQ(Remaining, OPS(DW_OP_LLVM_fragment, 0, 32)); 3931 EXPECT_EQ(Offset, -4); 3932 3933 EXPECT_TRUE(EXTRACT_FROM(DW_OP_deref)); 3934 EXPECT_EQ(Remaining, OPS(DW_OP_deref)); 3935 EXPECT_EQ(Offset, 0); 3936 3937 // Check things after the non-offset ops are added too. 3938 EXPECT_TRUE(EXTRACT_FROM(DW_OP_plus_uconst, 2, DW_OP_deref_size, 4, 3939 DW_OP_stack_value)); 3940 EXPECT_EQ(Remaining, OPS(DW_OP_deref_size, 4, DW_OP_stack_value)); 3941 EXPECT_EQ(Offset, 2); 3942 3943 // DW_OP_deref_type isn't supported in LLVM so this currently fails. 3944 EXPECT_FALSE(EXTRACT_FROM(DW_OP_deref_type, 0)); 3945 3946 EXPECT_TRUE(EXTRACT_FROM(DW_OP_LLVM_extract_bits_zext, 0, 8)); 3947 EXPECT_EQ(Remaining, OPS(DW_OP_LLVM_extract_bits_zext, 0, 8)); 3948 3949 EXPECT_TRUE(EXTRACT_FROM(DW_OP_LLVM_extract_bits_sext, 4, 4)); 3950 EXPECT_EQ(Remaining, OPS(DW_OP_LLVM_extract_bits_sext, 4, 4)); 3951 #undef EXTRACT_FROM 3952 #undef OPS 3953 } 3954 3955 TEST_F(DIExpressionTest, convertToUndefExpression) { 3956 #define EXPECT_UNDEF_OPS_EQUAL(TestExpr, Expected) \ 3957 do { \ 3958 const DIExpression *Undef = \ 3959 DIExpression::convertToUndefExpression(TestExpr); \ 3960 EXPECT_EQ(Undef, Expected); \ 3961 } while (false) 3962 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__}) 3963 3964 // Expressions which are single-location and non-complex should be unchanged. 3965 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(), GET_EXPR()); 3966 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_fragment, 0, 32), 3967 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 0, 32)); 3968 3969 // Variadic expressions should become single-location. 3970 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0), GET_EXPR()); 3971 EXPECT_UNDEF_OPS_EQUAL( 3972 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_fragment, 32, 32), 3973 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 32, 32)); 3974 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, 3975 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul), 3976 GET_EXPR()); 3977 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, 3978 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul, 3979 dwarf::DW_OP_LLVM_fragment, 64, 32), 3980 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 64, 32)); 3981 3982 // Any stack-computing ops should be removed. 3983 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_plus_uconst, 8), GET_EXPR()); 3984 EXPECT_UNDEF_OPS_EQUAL( 3985 GET_EXPR(dwarf::DW_OP_plus_uconst, 8, dwarf::DW_OP_LLVM_fragment, 0, 16), 3986 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 0, 16)); 3987 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu, 24, dwarf::DW_OP_shra), 3988 GET_EXPR()); 3989 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu, 24, dwarf::DW_OP_shra, 3990 dwarf::DW_OP_LLVM_fragment, 8, 16), 3991 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 8, 16)); 3992 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_deref), GET_EXPR()); 3993 EXPECT_UNDEF_OPS_EQUAL( 3994 GET_EXPR(dwarf::DW_OP_deref, dwarf::DW_OP_LLVM_fragment, 16, 16), 3995 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 16, 16)); 3996 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu, 4, dwarf::DW_OP_minus), 3997 GET_EXPR()); 3998 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu, 4, dwarf::DW_OP_minus, 3999 dwarf::DW_OP_LLVM_fragment, 24, 16), 4000 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 24, 16)); 4001 4002 // Stack-value operators are also not preserved. 4003 EXPECT_UNDEF_OPS_EQUAL( 4004 GET_EXPR(dwarf::DW_OP_plus_uconst, 8, dwarf::DW_OP_stack_value), 4005 GET_EXPR()); 4006 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_plus_uconst, 8, 4007 dwarf::DW_OP_stack_value, 4008 dwarf::DW_OP_LLVM_fragment, 32, 16), 4009 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 32, 16)); 4010 4011 #undef EXPECT_UNDEF_OPS_EQUAL 4012 #undef GET_EXPR 4013 } 4014 4015 TEST_F(DIExpressionTest, convertToVariadicExpression) { 4016 #define EXPECT_CONVERT_IS_NOOP(TestExpr) \ 4017 do { \ 4018 const DIExpression *Variadic = \ 4019 DIExpression::convertToVariadicExpression(TestExpr); \ 4020 EXPECT_EQ(Variadic, TestExpr); \ 4021 } while (false) 4022 #define EXPECT_VARIADIC_OPS_EQUAL(TestExpr, Expected) \ 4023 do { \ 4024 const DIExpression *Variadic = \ 4025 DIExpression::convertToVariadicExpression(TestExpr); \ 4026 EXPECT_EQ(Variadic, Expected); \ 4027 } while (false) 4028 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__}) 4029 4030 // Expressions which are already variadic should be unaffected. 4031 EXPECT_CONVERT_IS_NOOP( 4032 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_stack_value)); 4033 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, 4034 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_plus, 4035 dwarf::DW_OP_stack_value)); 4036 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_constu, 5, dwarf::DW_OP_LLVM_arg, 4037 0, dwarf::DW_OP_plus, 4038 dwarf::DW_OP_stack_value)); 4039 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, 4040 dwarf::DW_OP_stack_value, 4041 dwarf::DW_OP_LLVM_fragment, 0, 32)); 4042 4043 // Other expressions should receive a leading `LLVM_arg 0`. 4044 EXPECT_VARIADIC_OPS_EQUAL(GET_EXPR(), GET_EXPR(dwarf::DW_OP_LLVM_arg, 0)); 4045 EXPECT_VARIADIC_OPS_EQUAL( 4046 GET_EXPR(dwarf::DW_OP_plus_uconst, 4), 4047 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 4)); 4048 EXPECT_VARIADIC_OPS_EQUAL( 4049 GET_EXPR(dwarf::DW_OP_plus_uconst, 4, dwarf::DW_OP_stack_value), 4050 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 4, 4051 dwarf::DW_OP_stack_value)); 4052 EXPECT_VARIADIC_OPS_EQUAL( 4053 GET_EXPR(dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_stack_value, 4054 dwarf::DW_OP_LLVM_fragment, 32, 32), 4055 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 6, 4056 dwarf::DW_OP_stack_value, dwarf::DW_OP_LLVM_fragment, 32, 32)); 4057 EXPECT_VARIADIC_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_plus_uconst, 14, 4058 dwarf::DW_OP_LLVM_fragment, 32, 32), 4059 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, 4060 dwarf::DW_OP_plus_uconst, 14, 4061 dwarf::DW_OP_LLVM_fragment, 32, 32)); 4062 4063 #undef EXPECT_CONVERT_IS_NOOP 4064 #undef EXPECT_VARIADIC_OPS_EQUAL 4065 #undef GET_EXPR 4066 } 4067 4068 TEST_F(DIExpressionTest, convertToNonVariadicExpression) { 4069 #define EXPECT_CONVERT_IS_NOOP(TestExpr) \ 4070 do { \ 4071 std::optional<const DIExpression *> NonVariadic = \ 4072 DIExpression::convertToNonVariadicExpression(TestExpr); \ 4073 EXPECT_TRUE(NonVariadic.has_value()); \ 4074 EXPECT_EQ(*NonVariadic, TestExpr); \ 4075 } while (false) 4076 #define EXPECT_NON_VARIADIC_OPS_EQUAL(TestExpr, Expected) \ 4077 do { \ 4078 std::optional<const DIExpression *> NonVariadic = \ 4079 DIExpression::convertToNonVariadicExpression(TestExpr); \ 4080 EXPECT_TRUE(NonVariadic.has_value()); \ 4081 EXPECT_EQ(*NonVariadic, Expected); \ 4082 } while (false) 4083 #define EXPECT_INVALID_CONVERSION(TestExpr) \ 4084 do { \ 4085 std::optional<const DIExpression *> NonVariadic = \ 4086 DIExpression::convertToNonVariadicExpression(TestExpr); \ 4087 EXPECT_FALSE(NonVariadic.has_value()); \ 4088 } while (false) 4089 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__}) 4090 4091 // Expressions which are already non-variadic should be unaffected. 4092 EXPECT_CONVERT_IS_NOOP(GET_EXPR()); 4093 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_plus_uconst, 4)); 4094 EXPECT_CONVERT_IS_NOOP( 4095 GET_EXPR(dwarf::DW_OP_plus_uconst, 4, dwarf::DW_OP_stack_value)); 4096 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_plus_uconst, 6, 4097 dwarf::DW_OP_stack_value, 4098 dwarf::DW_OP_LLVM_fragment, 32, 32)); 4099 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_plus_uconst, 14, 4100 dwarf::DW_OP_LLVM_fragment, 32, 32)); 4101 4102 // Variadic expressions with a single leading `LLVM_arg 0` and no other 4103 // LLVM_args should have the leading arg removed. 4104 EXPECT_NON_VARIADIC_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0), GET_EXPR()); 4105 EXPECT_NON_VARIADIC_OPS_EQUAL( 4106 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_stack_value), 4107 GET_EXPR(dwarf::DW_OP_stack_value)); 4108 EXPECT_NON_VARIADIC_OPS_EQUAL( 4109 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_fragment, 16, 32), 4110 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 16, 32)); 4111 EXPECT_NON_VARIADIC_OPS_EQUAL( 4112 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_stack_value, 4113 dwarf::DW_OP_LLVM_fragment, 24, 32), 4114 GET_EXPR(dwarf::DW_OP_stack_value, dwarf::DW_OP_LLVM_fragment, 24, 32)); 4115 EXPECT_NON_VARIADIC_OPS_EQUAL( 4116 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 4), 4117 GET_EXPR(dwarf::DW_OP_plus_uconst, 4)); 4118 EXPECT_NON_VARIADIC_OPS_EQUAL( 4119 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 4, 4120 dwarf::DW_OP_stack_value), 4121 GET_EXPR(dwarf::DW_OP_plus_uconst, 4, dwarf::DW_OP_stack_value)); 4122 EXPECT_NON_VARIADIC_OPS_EQUAL( 4123 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 6, 4124 dwarf::DW_OP_stack_value, dwarf::DW_OP_LLVM_fragment, 32, 32), 4125 GET_EXPR(dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_stack_value, 4126 dwarf::DW_OP_LLVM_fragment, 32, 32)); 4127 EXPECT_NON_VARIADIC_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, 4128 dwarf::DW_OP_plus_uconst, 14, 4129 dwarf::DW_OP_LLVM_fragment, 32, 32), 4130 GET_EXPR(dwarf::DW_OP_plus_uconst, 14, 4131 dwarf::DW_OP_LLVM_fragment, 32, 32)); 4132 4133 // Variadic expressions that have any LLVM_args other than a leading 4134 // `LLVM_arg 0` cannot be converted and so should return std::nullopt. 4135 EXPECT_INVALID_CONVERSION(GET_EXPR( 4136 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul)); 4137 EXPECT_INVALID_CONVERSION( 4138 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg, 1, 4139 dwarf::DW_OP_plus, dwarf::DW_OP_stack_value)); 4140 EXPECT_INVALID_CONVERSION( 4141 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg, 0, 4142 dwarf::DW_OP_minus, dwarf::DW_OP_stack_value)); 4143 EXPECT_INVALID_CONVERSION(GET_EXPR(dwarf::DW_OP_constu, 5, 4144 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_div, 4145 dwarf::DW_OP_stack_value)); 4146 4147 #undef EXPECT_CONVERT_IS_NOOP 4148 #undef EXPECT_NON_VARIADIC_OPS_EQUAL 4149 #undef EXPECT_INVALID_CONVERSION 4150 #undef GET_EXPR 4151 } 4152 4153 TEST_F(DIExpressionTest, replaceArg) { 4154 #define EXPECT_REPLACE_ARG_EQ(Expr, OldArg, NewArg, ...) \ 4155 do { \ 4156 uint64_t Elements[] = {__VA_ARGS__}; \ 4157 ArrayRef<uint64_t> Expected = Elements; \ 4158 DIExpression *Expression = DIExpression::replaceArg(Expr, OldArg, NewArg); \ 4159 EXPECT_EQ(Expression->getElements(), Expected); \ 4160 } while (false) 4161 4162 auto N = DIExpression::get( 4163 Context, {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg, 1, 4164 dwarf::DW_OP_plus, dwarf::DW_OP_LLVM_arg, 2, dwarf::DW_OP_mul}); 4165 EXPECT_REPLACE_ARG_EQ(N, 0, 1, dwarf::DW_OP_LLVM_arg, 0, 4166 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus, 4167 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul); 4168 EXPECT_REPLACE_ARG_EQ(N, 0, 2, dwarf::DW_OP_LLVM_arg, 1, 4169 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus, 4170 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul); 4171 EXPECT_REPLACE_ARG_EQ(N, 2, 0, dwarf::DW_OP_LLVM_arg, 0, 4172 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_plus, 4173 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_mul); 4174 EXPECT_REPLACE_ARG_EQ(N, 2, 1, dwarf::DW_OP_LLVM_arg, 0, 4175 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_plus, 4176 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul); 4177 4178 #undef EXPECT_REPLACE_ARG_EQ 4179 } 4180 4181 TEST_F(DIExpressionTest, isEqualExpression) { 4182 #define EXPECT_EQ_DEBUG_VALUE(ExprA, DirectA, ExprB, DirectB) \ 4183 EXPECT_TRUE(DIExpression::isEqualExpression(ExprA, DirectA, ExprB, DirectB)) 4184 #define EXPECT_NE_DEBUG_VALUE(ExprA, DirectA, ExprB, DirectB) \ 4185 EXPECT_FALSE(DIExpression::isEqualExpression(ExprA, DirectA, ExprB, DirectB)) 4186 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__}) 4187 4188 EXPECT_EQ_DEBUG_VALUE(GET_EXPR(), false, GET_EXPR(), false); 4189 EXPECT_NE_DEBUG_VALUE(GET_EXPR(), false, GET_EXPR(), true); 4190 EXPECT_EQ_DEBUG_VALUE( 4191 GET_EXPR(dwarf::DW_OP_plus_uconst, 32), true, 4192 GET_EXPR(dwarf::DW_OP_plus_uconst, 32, dwarf::DW_OP_deref), false); 4193 EXPECT_NE_DEBUG_VALUE( 4194 GET_EXPR(dwarf::DW_OP_plus_uconst, 16, dwarf::DW_OP_deref), true, 4195 GET_EXPR(dwarf::DW_OP_plus_uconst, 16, dwarf::DW_OP_deref), false); 4196 EXPECT_EQ_DEBUG_VALUE( 4197 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 5), false, 4198 GET_EXPR(dwarf::DW_OP_plus_uconst, 5), false); 4199 EXPECT_NE_DEBUG_VALUE(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus), 4200 false, 4201 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, 4202 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus), 4203 false); 4204 EXPECT_NE_DEBUG_VALUE(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_constu, 4205 8, dwarf::DW_OP_minus), 4206 false, 4207 GET_EXPR(dwarf::DW_OP_constu, 8, dwarf::DW_OP_LLVM_arg, 4208 0, dwarf::DW_OP_minus), 4209 false); 4210 // These expressions are actually equivalent, but we do not currently identify 4211 // commutative operations with different operand orders as being equivalent. 4212 EXPECT_NE_DEBUG_VALUE(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_constu, 4213 8, dwarf::DW_OP_plus), 4214 false, 4215 GET_EXPR(dwarf::DW_OP_constu, 8, dwarf::DW_OP_LLVM_arg, 4216 0, dwarf::DW_OP_plus), 4217 false); 4218 4219 #undef EXPECT_EQ_DEBUG_VALUE 4220 #undef EXPECT_NE_DEBUG_VALUE 4221 #undef GET_EXPR 4222 } 4223 4224 TEST_F(DIExpressionTest, foldConstant) { 4225 const ConstantInt *Int; 4226 const ConstantInt *NewInt; 4227 DIExpression *Expr; 4228 DIExpression *NewExpr; 4229 4230 #define EXPECT_FOLD_CONST(StartWidth, StartValue, StartIsSigned, EndWidth, \ 4231 EndValue, EndIsSigned, NumElts) \ 4232 Int = \ 4233 ConstantInt::get(Context, APInt(StartWidth, StartValue, StartIsSigned)); \ 4234 std::tie(NewExpr, NewInt) = Expr->constantFold(Int); \ 4235 ASSERT_EQ(NewInt->getBitWidth(), EndWidth##u); \ 4236 EXPECT_EQ(NewInt->getValue(), APInt(EndWidth, EndValue, EndIsSigned)); \ 4237 EXPECT_EQ(NewExpr->getNumElements(), NumElts##u) 4238 4239 // Unfoldable expression should return the original unmodified Int/Expr. 4240 Expr = DIExpression::get(Context, {dwarf::DW_OP_deref}); 4241 EXPECT_FOLD_CONST(32, 117, false, 32, 117, false, 1); 4242 EXPECT_EQ(NewExpr, Expr); 4243 EXPECT_EQ(NewInt, Int); 4244 EXPECT_TRUE(NewExpr->startsWithDeref()); 4245 4246 // One unsigned bit-width conversion. 4247 Expr = DIExpression::get( 4248 Context, {dwarf::DW_OP_LLVM_convert, 72, dwarf::DW_ATE_unsigned}); 4249 EXPECT_FOLD_CONST(8, 12, false, 72, 12, false, 0); 4250 4251 // Two unsigned bit-width conversions (mask truncation). 4252 Expr = DIExpression::get( 4253 Context, {dwarf::DW_OP_LLVM_convert, 8, dwarf::DW_ATE_unsigned, 4254 dwarf::DW_OP_LLVM_convert, 16, dwarf::DW_ATE_unsigned}); 4255 EXPECT_FOLD_CONST(32, -1, true, 16, 0xff, false, 0); 4256 4257 // Sign extension. 4258 Expr = DIExpression::get( 4259 Context, {dwarf::DW_OP_LLVM_convert, 32, dwarf::DW_ATE_signed}); 4260 EXPECT_FOLD_CONST(16, -1, true, 32, -1, true, 0); 4261 4262 // Get non-foldable operations back in the new Expr. 4263 uint64_t Elements[] = {dwarf::DW_OP_deref, dwarf::DW_OP_stack_value}; 4264 ArrayRef<uint64_t> Expected = Elements; 4265 Expr = DIExpression::get( 4266 Context, {dwarf::DW_OP_LLVM_convert, 32, dwarf::DW_ATE_signed}); 4267 Expr = DIExpression::append(Expr, Expected); 4268 ASSERT_EQ(Expr->getNumElements(), 5u); 4269 EXPECT_FOLD_CONST(16, -1, true, 32, -1, true, 2); 4270 EXPECT_EQ(NewExpr->getElements(), Expected); 4271 4272 #undef EXPECT_FOLD_CONST 4273 } 4274 4275 TEST_F(DIExpressionTest, appendToStackAssert) { 4276 DIExpression *Expr = DIExpression::get(Context, {}); 4277 4278 // Verify that the DW_OP_LLVM_convert operands, which have the same values as 4279 // DW_OP_stack_value and DW_OP_LLVM_fragment, do not get interpreted as such 4280 // operations. This previously triggered an assert. 4281 uint64_t FromSize = dwarf::DW_OP_stack_value; 4282 uint64_t ToSize = dwarf::DW_OP_LLVM_fragment; 4283 uint64_t Ops[] = { 4284 dwarf::DW_OP_LLVM_convert, FromSize, dwarf::DW_ATE_signed, 4285 dwarf::DW_OP_LLVM_convert, ToSize, dwarf::DW_ATE_signed, 4286 }; 4287 Expr = DIExpression::appendToStack(Expr, Ops); 4288 4289 uint64_t Expected[] = { 4290 dwarf::DW_OP_LLVM_convert, FromSize, dwarf::DW_ATE_signed, 4291 dwarf::DW_OP_LLVM_convert, ToSize, dwarf::DW_ATE_signed, 4292 dwarf::DW_OP_stack_value}; 4293 EXPECT_EQ(Expr->getElements(), ArrayRef<uint64_t>(Expected)); 4294 } 4295 4296 typedef MetadataTest DIObjCPropertyTest; 4297 4298 TEST_F(DIObjCPropertyTest, get) { 4299 StringRef Name = "name"; 4300 DIFile *File = getFile(); 4301 unsigned Line = 5; 4302 StringRef GetterName = "getter"; 4303 StringRef SetterName = "setter"; 4304 unsigned Attributes = 7; 4305 DIType *Type = getBasicType("basic"); 4306 4307 auto *N = DIObjCProperty::get(Context, Name, File, Line, GetterName, 4308 SetterName, Attributes, Type); 4309 4310 EXPECT_EQ(dwarf::DW_TAG_APPLE_property, N->getTag()); 4311 EXPECT_EQ(Name, N->getName()); 4312 EXPECT_EQ(File, N->getFile()); 4313 EXPECT_EQ(Line, N->getLine()); 4314 EXPECT_EQ(GetterName, N->getGetterName()); 4315 EXPECT_EQ(SetterName, N->getSetterName()); 4316 EXPECT_EQ(Attributes, N->getAttributes()); 4317 EXPECT_EQ(Type, N->getType()); 4318 EXPECT_EQ(N, DIObjCProperty::get(Context, Name, File, Line, GetterName, 4319 SetterName, Attributes, Type)); 4320 4321 EXPECT_NE(N, DIObjCProperty::get(Context, "other", File, Line, GetterName, 4322 SetterName, Attributes, Type)); 4323 EXPECT_NE(N, DIObjCProperty::get(Context, Name, getFile(), Line, GetterName, 4324 SetterName, Attributes, Type)); 4325 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line + 1, GetterName, 4326 SetterName, Attributes, Type)); 4327 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, "other", 4328 SetterName, Attributes, Type)); 4329 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName, 4330 "other", Attributes, Type)); 4331 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName, 4332 SetterName, Attributes + 1, Type)); 4333 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName, 4334 SetterName, Attributes, 4335 getBasicType("other"))); 4336 4337 TempDIObjCProperty Temp = N->clone(); 4338 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 4339 } 4340 4341 typedef MetadataTest DIImportedEntityTest; 4342 4343 TEST_F(DIImportedEntityTest, get) { 4344 unsigned Tag = dwarf::DW_TAG_imported_module; 4345 DIScope *Scope = getSubprogram(); 4346 DINode *Entity = getCompositeType(); 4347 DIFile *File = getFile(); 4348 unsigned Line = 5; 4349 StringRef Name = "name"; 4350 4351 auto *N = 4352 DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, Name); 4353 4354 EXPECT_EQ(Tag, N->getTag()); 4355 EXPECT_EQ(Scope, N->getScope()); 4356 EXPECT_EQ(Entity, N->getEntity()); 4357 EXPECT_EQ(File, N->getFile()); 4358 EXPECT_EQ(Line, N->getLine()); 4359 EXPECT_EQ(Name, N->getName()); 4360 EXPECT_EQ( 4361 N, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, Name)); 4362 4363 EXPECT_NE(N, 4364 DIImportedEntity::get(Context, dwarf::DW_TAG_imported_declaration, 4365 Scope, Entity, File, Line, Name)); 4366 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, getSubprogram(), Entity, 4367 File, Line, Name)); 4368 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, getCompositeType(), 4369 File, Line, Name)); 4370 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, Entity, nullptr, Line, 4371 Name)); 4372 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, Entity, File, 4373 Line + 1, Name)); 4374 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, 4375 "other")); 4376 4377 TempDIImportedEntity Temp = N->clone(); 4378 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 4379 4380 MDTuple *Elements1 = getTuple(); 4381 MDTuple *Elements2 = getTuple(); 4382 auto *Ne = DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, 4383 Name, Elements1); 4384 4385 EXPECT_EQ(Elements1, Ne->getElements().get()); 4386 4387 EXPECT_EQ(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, 4388 Name, Elements1)); 4389 EXPECT_NE(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, 4390 "ModOther", Elements1)); 4391 EXPECT_NE(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, 4392 Name, Elements2)); 4393 EXPECT_NE( 4394 Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, Name)); 4395 4396 TempDIImportedEntity Tempe = Ne->clone(); 4397 EXPECT_EQ(Ne, MDNode::replaceWithUniqued(std::move(Tempe))); 4398 } 4399 4400 typedef MetadataTest MetadataAsValueTest; 4401 4402 TEST_F(MetadataAsValueTest, MDNode) { 4403 MDNode *N = MDNode::get(Context, {}); 4404 auto *V = MetadataAsValue::get(Context, N); 4405 EXPECT_TRUE(V->getType()->isMetadataTy()); 4406 EXPECT_EQ(N, V->getMetadata()); 4407 4408 auto *V2 = MetadataAsValue::get(Context, N); 4409 EXPECT_EQ(V, V2); 4410 } 4411 4412 TEST_F(MetadataAsValueTest, MDNodeMDNode) { 4413 MDNode *N = MDNode::get(Context, {}); 4414 Metadata *Ops[] = {N}; 4415 MDNode *N2 = MDNode::get(Context, Ops); 4416 auto *V = MetadataAsValue::get(Context, N2); 4417 EXPECT_TRUE(V->getType()->isMetadataTy()); 4418 EXPECT_EQ(N2, V->getMetadata()); 4419 4420 auto *V2 = MetadataAsValue::get(Context, N2); 4421 EXPECT_EQ(V, V2); 4422 4423 auto *V3 = MetadataAsValue::get(Context, N); 4424 EXPECT_TRUE(V3->getType()->isMetadataTy()); 4425 EXPECT_NE(V, V3); 4426 EXPECT_EQ(N, V3->getMetadata()); 4427 } 4428 4429 TEST_F(MetadataAsValueTest, MDNodeConstant) { 4430 auto *C = ConstantInt::getTrue(Context); 4431 auto *MD = ConstantAsMetadata::get(C); 4432 Metadata *Ops[] = {MD}; 4433 auto *N = MDNode::get(Context, Ops); 4434 4435 auto *V = MetadataAsValue::get(Context, MD); 4436 EXPECT_TRUE(V->getType()->isMetadataTy()); 4437 EXPECT_EQ(MD, V->getMetadata()); 4438 4439 auto *V2 = MetadataAsValue::get(Context, N); 4440 EXPECT_EQ(MD, V2->getMetadata()); 4441 EXPECT_EQ(V, V2); 4442 } 4443 4444 typedef MetadataTest ValueAsMetadataTest; 4445 4446 TEST_F(ValueAsMetadataTest, UpdatesOnRAUW) { 4447 Type *Ty = PointerType::getUnqual(Context); 4448 std::unique_ptr<GlobalVariable> GV0( 4449 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 4450 auto *MD = ValueAsMetadata::get(GV0.get()); 4451 EXPECT_TRUE(MD->getValue() == GV0.get()); 4452 ASSERT_TRUE(GV0->use_empty()); 4453 4454 std::unique_ptr<GlobalVariable> GV1( 4455 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 4456 GV0->replaceAllUsesWith(GV1.get()); 4457 EXPECT_TRUE(MD->getValue() == GV1.get()); 4458 } 4459 4460 TEST_F(ValueAsMetadataTest, handleRAUWWithTypeChange) { 4461 // Test that handleRAUW supports type changes. 4462 // This is helpful in cases where poison values are used to encode 4463 // types in metadata, e.g. in type annotations. 4464 // Changing the type stored in metadata requires to change the type of 4465 // the stored poison value. 4466 auto *I32Poison = PoisonValue::get(Type::getInt32Ty(Context)); 4467 auto *I64Poison = PoisonValue::get(Type::getInt64Ty(Context)); 4468 auto *MD = ConstantAsMetadata::get(I32Poison); 4469 4470 EXPECT_EQ(MD->getValue(), I32Poison); 4471 EXPECT_NE(MD->getValue(), I64Poison); 4472 4473 ValueAsMetadata::handleRAUW(I32Poison, I64Poison); 4474 4475 EXPECT_NE(MD->getValue(), I32Poison); 4476 EXPECT_EQ(MD->getValue(), I64Poison); 4477 } 4478 4479 TEST_F(ValueAsMetadataTest, TempTempReplacement) { 4480 // Create a constant. 4481 ConstantAsMetadata *CI = 4482 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); 4483 4484 auto Temp1 = MDTuple::getTemporary(Context, {}); 4485 auto Temp2 = MDTuple::getTemporary(Context, {CI}); 4486 auto *N = MDTuple::get(Context, {Temp1.get()}); 4487 4488 // Test replacing a temporary node with another temporary node. 4489 Temp1->replaceAllUsesWith(Temp2.get()); 4490 EXPECT_EQ(N->getOperand(0), Temp2.get()); 4491 4492 // Clean up Temp2 for teardown. 4493 Temp2->replaceAllUsesWith(nullptr); 4494 } 4495 4496 TEST_F(ValueAsMetadataTest, CollidingDoubleUpdates) { 4497 // Create a constant. 4498 ConstantAsMetadata *CI = 4499 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); 4500 4501 // Create a temporary to prevent nodes from resolving. 4502 auto Temp = MDTuple::getTemporary(Context, {}); 4503 4504 // When the first operand of N1 gets reset to nullptr, it'll collide with N2. 4505 Metadata *Ops1[] = {CI, CI, Temp.get()}; 4506 Metadata *Ops2[] = {nullptr, CI, Temp.get()}; 4507 4508 auto *N1 = MDTuple::get(Context, Ops1); 4509 auto *N2 = MDTuple::get(Context, Ops2); 4510 ASSERT_NE(N1, N2); 4511 4512 // Tell metadata that the constant is getting deleted. 4513 // 4514 // After this, N1 will be invalid, so don't touch it. 4515 ValueAsMetadata::handleDeletion(CI->getValue()); 4516 EXPECT_EQ(nullptr, N2->getOperand(0)); 4517 EXPECT_EQ(nullptr, N2->getOperand(1)); 4518 EXPECT_EQ(Temp.get(), N2->getOperand(2)); 4519 4520 // Clean up Temp for teardown. 4521 Temp->replaceAllUsesWith(nullptr); 4522 } 4523 4524 typedef MetadataTest DIArgListTest; 4525 4526 TEST_F(DIArgListTest, get) { 4527 SmallVector<ValueAsMetadata *, 2> VMs; 4528 VMs.push_back( 4529 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0)))); 4530 VMs.push_back( 4531 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(2, 0)))); 4532 DIArgList *DV0 = DIArgList::get(Context, VMs); 4533 DIArgList *DV1 = DIArgList::get(Context, VMs); 4534 EXPECT_EQ(DV0, DV1); 4535 } 4536 4537 TEST_F(DIArgListTest, UpdatesOnRAUW) { 4538 Type *Ty = PointerType::getUnqual(Context); 4539 ConstantAsMetadata *CI = 4540 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); 4541 std::unique_ptr<GlobalVariable> GV0( 4542 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 4543 auto *MD0 = ValueAsMetadata::get(GV0.get()); 4544 4545 SmallVector<ValueAsMetadata *, 2> VMs; 4546 VMs.push_back(CI); 4547 VMs.push_back(MD0); 4548 auto *AL = DIArgList::get(Context, VMs); 4549 EXPECT_EQ(AL->getArgs()[0], CI); 4550 EXPECT_EQ(AL->getArgs()[1], MD0); 4551 4552 std::unique_ptr<GlobalVariable> GV1( 4553 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 4554 auto *MD1 = ValueAsMetadata::get(GV1.get()); 4555 GV0->replaceAllUsesWith(GV1.get()); 4556 EXPECT_EQ(AL->getArgs()[0], CI); 4557 EXPECT_EQ(AL->getArgs()[1], MD1); 4558 } 4559 4560 typedef MetadataTest TrackingMDRefTest; 4561 4562 TEST_F(TrackingMDRefTest, UpdatesOnRAUW) { 4563 Type *Ty = PointerType::getUnqual(Context); 4564 std::unique_ptr<GlobalVariable> GV0( 4565 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 4566 TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV0.get())); 4567 EXPECT_TRUE(MD->getValue() == GV0.get()); 4568 ASSERT_TRUE(GV0->use_empty()); 4569 4570 std::unique_ptr<GlobalVariable> GV1( 4571 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 4572 GV0->replaceAllUsesWith(GV1.get()); 4573 EXPECT_TRUE(MD->getValue() == GV1.get()); 4574 4575 // Reset it, so we don't inadvertently test deletion. 4576 MD.reset(); 4577 } 4578 4579 TEST_F(TrackingMDRefTest, UpdatesOnDeletion) { 4580 Type *Ty = PointerType::getUnqual(Context); 4581 std::unique_ptr<GlobalVariable> GV( 4582 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 4583 TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV.get())); 4584 EXPECT_TRUE(MD->getValue() == GV.get()); 4585 ASSERT_TRUE(GV->use_empty()); 4586 4587 GV.reset(); 4588 EXPECT_TRUE(!MD); 4589 } 4590 4591 TEST(NamedMDNodeTest, Search) { 4592 LLVMContext Context; 4593 ConstantAsMetadata *C = 4594 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 1)); 4595 ConstantAsMetadata *C2 = 4596 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 2)); 4597 4598 Metadata *const V = C; 4599 Metadata *const V2 = C2; 4600 MDNode *n = MDNode::get(Context, V); 4601 MDNode *n2 = MDNode::get(Context, V2); 4602 4603 Module M("MyModule", Context); 4604 const char *Name = "llvm.NMD1"; 4605 NamedMDNode *NMD = M.getOrInsertNamedMetadata(Name); 4606 NMD->addOperand(n); 4607 NMD->addOperand(n2); 4608 4609 std::string Str; 4610 raw_string_ostream oss(Str); 4611 NMD->print(oss); 4612 EXPECT_STREQ("!llvm.NMD1 = !{!0, !1}\n", Str.c_str()); 4613 } 4614 4615 typedef MetadataTest FunctionAttachmentTest; 4616 TEST_F(FunctionAttachmentTest, setMetadata) { 4617 Function *F = getFunction("foo"); 4618 ASSERT_FALSE(F->hasMetadata()); 4619 EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg)); 4620 EXPECT_EQ(nullptr, F->getMetadata("dbg")); 4621 EXPECT_EQ(nullptr, F->getMetadata("other")); 4622 4623 DISubprogram *SP1 = getSubprogram(); 4624 DISubprogram *SP2 = getSubprogram(); 4625 ASSERT_NE(SP1, SP2); 4626 4627 F->setMetadata("dbg", SP1); 4628 EXPECT_TRUE(F->hasMetadata()); 4629 EXPECT_EQ(SP1, F->getMetadata(LLVMContext::MD_dbg)); 4630 EXPECT_EQ(SP1, F->getMetadata("dbg")); 4631 EXPECT_EQ(nullptr, F->getMetadata("other")); 4632 4633 F->setMetadata(LLVMContext::MD_dbg, SP2); 4634 EXPECT_TRUE(F->hasMetadata()); 4635 EXPECT_EQ(SP2, F->getMetadata(LLVMContext::MD_dbg)); 4636 EXPECT_EQ(SP2, F->getMetadata("dbg")); 4637 EXPECT_EQ(nullptr, F->getMetadata("other")); 4638 4639 F->setMetadata("dbg", nullptr); 4640 EXPECT_FALSE(F->hasMetadata()); 4641 EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg)); 4642 EXPECT_EQ(nullptr, F->getMetadata("dbg")); 4643 EXPECT_EQ(nullptr, F->getMetadata("other")); 4644 4645 MDTuple *T1 = getTuple(); 4646 MDTuple *T2 = getTuple(); 4647 ASSERT_NE(T1, T2); 4648 4649 F->setMetadata("other1", T1); 4650 F->setMetadata("other2", T2); 4651 EXPECT_TRUE(F->hasMetadata()); 4652 EXPECT_EQ(T1, F->getMetadata("other1")); 4653 EXPECT_EQ(T2, F->getMetadata("other2")); 4654 EXPECT_EQ(nullptr, F->getMetadata("dbg")); 4655 4656 F->setMetadata("other1", T2); 4657 F->setMetadata("other2", T1); 4658 EXPECT_EQ(T2, F->getMetadata("other1")); 4659 EXPECT_EQ(T1, F->getMetadata("other2")); 4660 4661 F->setMetadata("other1", nullptr); 4662 F->setMetadata("other2", nullptr); 4663 EXPECT_FALSE(F->hasMetadata()); 4664 EXPECT_EQ(nullptr, F->getMetadata("other1")); 4665 EXPECT_EQ(nullptr, F->getMetadata("other2")); 4666 } 4667 4668 TEST_F(FunctionAttachmentTest, getAll) { 4669 Function *F = getFunction("foo"); 4670 4671 MDTuple *T1 = getTuple(); 4672 MDTuple *T2 = getTuple(); 4673 MDTuple *P = getTuple(); 4674 DISubprogram *SP = getSubprogram(); 4675 4676 F->setMetadata("other1", T2); 4677 F->setMetadata(LLVMContext::MD_dbg, SP); 4678 F->setMetadata("other2", T1); 4679 F->setMetadata(LLVMContext::MD_prof, P); 4680 F->setMetadata("other2", T2); 4681 F->setMetadata("other1", T1); 4682 4683 SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; 4684 F->getAllMetadata(MDs); 4685 ASSERT_EQ(4u, MDs.size()); 4686 EXPECT_EQ(LLVMContext::MD_dbg, MDs[0].first); 4687 EXPECT_EQ(LLVMContext::MD_prof, MDs[1].first); 4688 EXPECT_EQ(Context.getMDKindID("other1"), MDs[2].first); 4689 EXPECT_EQ(Context.getMDKindID("other2"), MDs[3].first); 4690 EXPECT_EQ(SP, MDs[0].second); 4691 EXPECT_EQ(P, MDs[1].second); 4692 EXPECT_EQ(T1, MDs[2].second); 4693 EXPECT_EQ(T2, MDs[3].second); 4694 } 4695 4696 TEST_F(FunctionAttachmentTest, Verifier) { 4697 Function *F = getFunction("foo"); 4698 F->setMetadata("attach", getTuple()); 4699 F->setIsMaterializable(true); 4700 4701 // Confirm this is materializable. 4702 ASSERT_TRUE(F->isMaterializable()); 4703 4704 // Materializable functions cannot have metadata attachments. 4705 EXPECT_TRUE(verifyFunction(*F)); 4706 4707 // Function declarations can. 4708 F->setIsMaterializable(false); 4709 EXPECT_FALSE(verifyModule(*F->getParent())); 4710 EXPECT_FALSE(verifyFunction(*F)); 4711 4712 // So can definitions. 4713 (void)new UnreachableInst(Context, BasicBlock::Create(Context, "bb", F)); 4714 EXPECT_FALSE(verifyModule(*F->getParent())); 4715 EXPECT_FALSE(verifyFunction(*F)); 4716 } 4717 4718 TEST_F(FunctionAttachmentTest, RealEntryCount) { 4719 Function *F = getFunction("foo"); 4720 EXPECT_FALSE(F->getEntryCount().has_value()); 4721 F->setEntryCount(12304, Function::PCT_Real); 4722 auto Count = F->getEntryCount(); 4723 EXPECT_TRUE(Count.has_value()); 4724 EXPECT_EQ(12304u, Count->getCount()); 4725 EXPECT_EQ(Function::PCT_Real, Count->getType()); 4726 } 4727 4728 TEST_F(FunctionAttachmentTest, SyntheticEntryCount) { 4729 Function *F = getFunction("bar"); 4730 EXPECT_FALSE(F->getEntryCount().has_value()); 4731 F->setEntryCount(123, Function::PCT_Synthetic); 4732 auto Count = F->getEntryCount(true /*allow synthetic*/); 4733 EXPECT_TRUE(Count.has_value()); 4734 EXPECT_EQ(123u, Count->getCount()); 4735 EXPECT_EQ(Function::PCT_Synthetic, Count->getType()); 4736 } 4737 4738 TEST_F(FunctionAttachmentTest, SubprogramAttachment) { 4739 Function *F = getFunction("foo"); 4740 DISubprogram *SP = getSubprogram(); 4741 F->setSubprogram(SP); 4742 4743 // Note that the static_cast confirms that F->getSubprogram() actually 4744 // returns an DISubprogram. 4745 EXPECT_EQ(SP, static_cast<DISubprogram *>(F->getSubprogram())); 4746 EXPECT_EQ(SP, F->getMetadata("dbg")); 4747 EXPECT_EQ(SP, F->getMetadata(LLVMContext::MD_dbg)); 4748 } 4749 4750 typedef MetadataTest DistinctMDOperandPlaceholderTest; 4751 TEST_F(DistinctMDOperandPlaceholderTest, getID) { 4752 EXPECT_EQ(7u, DistinctMDOperandPlaceholder(7).getID()); 4753 } 4754 4755 TEST_F(DistinctMDOperandPlaceholderTest, replaceUseWith) { 4756 // Set up some placeholders. 4757 DistinctMDOperandPlaceholder PH0(7); 4758 DistinctMDOperandPlaceholder PH1(3); 4759 DistinctMDOperandPlaceholder PH2(0); 4760 Metadata *Ops[] = {&PH0, &PH1, &PH2}; 4761 auto *D = MDTuple::getDistinct(Context, Ops); 4762 ASSERT_EQ(&PH0, D->getOperand(0)); 4763 ASSERT_EQ(&PH1, D->getOperand(1)); 4764 ASSERT_EQ(&PH2, D->getOperand(2)); 4765 4766 // Replace them. 4767 auto *N0 = MDTuple::get(Context, {}); 4768 auto *N1 = MDTuple::get(Context, N0); 4769 PH0.replaceUseWith(N0); 4770 PH1.replaceUseWith(N1); 4771 PH2.replaceUseWith(nullptr); 4772 EXPECT_EQ(N0, D->getOperand(0)); 4773 EXPECT_EQ(N1, D->getOperand(1)); 4774 EXPECT_EQ(nullptr, D->getOperand(2)); 4775 } 4776 4777 TEST_F(DistinctMDOperandPlaceholderTest, replaceUseWithNoUser) { 4778 // There is no user, but we can still call replace. 4779 DistinctMDOperandPlaceholder(7).replaceUseWith(MDTuple::get(Context, {})); 4780 } 4781 4782 // Test various assertions in metadata tracking. Don't run these tests if gtest 4783 // will use SEH to recover from them. Two of these tests get halfway through 4784 // inserting metadata into DenseMaps for tracking purposes, and then they 4785 // assert, and we attempt to destroy an LLVMContext with broken invariants, 4786 // leading to infinite loops. 4787 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) && !defined(GTEST_HAS_SEH) 4788 TEST_F(DistinctMDOperandPlaceholderTest, MetadataAsValue) { 4789 // This shouldn't crash. 4790 DistinctMDOperandPlaceholder PH(7); 4791 EXPECT_DEATH(MetadataAsValue::get(Context, &PH), 4792 "Unexpected callback to owner"); 4793 } 4794 4795 TEST_F(DistinctMDOperandPlaceholderTest, UniquedMDNode) { 4796 // This shouldn't crash. 4797 DistinctMDOperandPlaceholder PH(7); 4798 EXPECT_DEATH(MDTuple::get(Context, &PH), "Unexpected callback to owner"); 4799 } 4800 4801 TEST_F(DistinctMDOperandPlaceholderTest, SecondDistinctMDNode) { 4802 // This shouldn't crash. 4803 DistinctMDOperandPlaceholder PH(7); 4804 MDTuple::getDistinct(Context, &PH); 4805 EXPECT_DEATH(MDTuple::getDistinct(Context, &PH), 4806 "Placeholders can only be used once"); 4807 } 4808 4809 TEST_F(DistinctMDOperandPlaceholderTest, TrackingMDRefAndDistinctMDNode) { 4810 // TrackingMDRef doesn't install an owner callback, so it can't be detected 4811 // as an invalid use. However, using a placeholder in a TrackingMDRef *and* 4812 // a distinct node isn't possible and we should assert. 4813 // 4814 // (There's no positive test for using TrackingMDRef because it's not a 4815 // useful thing to do.) 4816 { 4817 DistinctMDOperandPlaceholder PH(7); 4818 MDTuple::getDistinct(Context, &PH); 4819 EXPECT_DEATH(TrackingMDRef Ref(&PH), "Placeholders can only be used once"); 4820 } 4821 { 4822 DistinctMDOperandPlaceholder PH(7); 4823 TrackingMDRef Ref(&PH); 4824 EXPECT_DEATH(MDTuple::getDistinct(Context, &PH), 4825 "Placeholders can only be used once"); 4826 } 4827 } 4828 #endif 4829 4830 typedef MetadataTest DebugVariableTest; 4831 TEST_F(DebugVariableTest, DenseMap) { 4832 DenseMap<DebugVariable, uint64_t> DebugVariableMap; 4833 4834 DILocalScope *Scope = getSubprogram(); 4835 DIFile *File = getFile(); 4836 DIType *Type = getDerivedType(); 4837 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 4838 4839 DILocation *InlinedLoc = DILocation::get(Context, 2, 7, Scope); 4840 4841 DILocalVariable *VarA = 4842 DILocalVariable::get(Context, Scope, "A", File, 5, Type, 2, Flags, 8, nullptr); 4843 DILocalVariable *VarB = 4844 DILocalVariable::get(Context, Scope, "B", File, 7, Type, 3, Flags, 8, nullptr); 4845 4846 DebugVariable DebugVariableA(VarA, std::nullopt, nullptr); 4847 DebugVariable DebugVariableInlineA(VarA, std::nullopt, InlinedLoc); 4848 DebugVariable DebugVariableB(VarB, std::nullopt, nullptr); 4849 DebugVariable DebugVariableFragB(VarB, {{16, 16}}, nullptr); 4850 4851 DebugVariableMap.insert({DebugVariableA, 2}); 4852 DebugVariableMap.insert({DebugVariableInlineA, 3}); 4853 DebugVariableMap.insert({DebugVariableB, 6}); 4854 DebugVariableMap.insert({DebugVariableFragB, 12}); 4855 4856 EXPECT_EQ(DebugVariableMap.count(DebugVariableA), 1u); 4857 EXPECT_EQ(DebugVariableMap.count(DebugVariableInlineA), 1u); 4858 EXPECT_EQ(DebugVariableMap.count(DebugVariableB), 1u); 4859 EXPECT_EQ(DebugVariableMap.count(DebugVariableFragB), 1u); 4860 4861 EXPECT_EQ(DebugVariableMap.find(DebugVariableA)->second, 2u); 4862 EXPECT_EQ(DebugVariableMap.find(DebugVariableInlineA)->second, 3u); 4863 EXPECT_EQ(DebugVariableMap.find(DebugVariableB)->second, 6u); 4864 EXPECT_EQ(DebugVariableMap.find(DebugVariableFragB)->second, 12u); 4865 } 4866 4867 typedef MetadataTest MDTupleAllocationTest; 4868 TEST_F(MDTupleAllocationTest, Tracking) { 4869 // Make sure that the move constructor and move assignment op 4870 // for MDOperand correctly adjust tracking information. 4871 auto *Value1 = getConstantAsMetadata(); 4872 MDTuple *A = MDTuple::getDistinct(Context, {Value1, Value1}); 4873 EXPECT_EQ(A->getOperand(0), Value1); 4874 EXPECT_EQ(A->getOperand(1), Value1); 4875 4876 MDNode::op_range Ops = A->operands(); 4877 4878 MDOperand NewOps1; 4879 // Move assignment operator. 4880 NewOps1 = std::move(*const_cast<MDOperand *>(Ops.begin())); 4881 // Move constructor. 4882 MDOperand NewOps2(std::move(*const_cast<MDOperand *>(Ops.begin() + 1))); 4883 4884 EXPECT_EQ(NewOps1.get(), static_cast<Metadata *>(Value1)); 4885 EXPECT_EQ(NewOps2.get(), static_cast<Metadata *>(Value1)); 4886 4887 auto *Value2 = getConstantAsMetadata(); 4888 Value *V1 = Value1->getValue(); 4889 Value *V2 = Value2->getValue(); 4890 ValueAsMetadata::handleRAUW(V1, V2); 4891 4892 EXPECT_EQ(NewOps1.get(), static_cast<Metadata *>(Value2)); 4893 EXPECT_EQ(NewOps2.get(), static_cast<Metadata *>(Value2)); 4894 } 4895 4896 TEST_F(MDTupleAllocationTest, Resize) { 4897 MDTuple *A = getTuple(); 4898 Metadata *Value1 = getConstantAsMetadata(); 4899 Metadata *Value2 = getConstantAsMetadata(); 4900 Metadata *Value3 = getConstantAsMetadata(); 4901 4902 EXPECT_EQ(A->getNumOperands(), 0u); 4903 4904 // Add a couple of elements to it, which resizes the node. 4905 A->push_back(Value1); 4906 EXPECT_EQ(A->getNumOperands(), 1u); 4907 EXPECT_EQ(A->getOperand(0), Value1); 4908 4909 A->push_back(Value2); 4910 EXPECT_EQ(A->getNumOperands(), 2u); 4911 EXPECT_EQ(A->getOperand(0), Value1); 4912 EXPECT_EQ(A->getOperand(1), Value2); 4913 4914 // Append another element, which should resize the node 4915 // to a "large" node, though not detectable by the user. 4916 A->push_back(Value3); 4917 EXPECT_EQ(A->getNumOperands(), 3u); 4918 EXPECT_EQ(A->getOperand(0), Value1); 4919 EXPECT_EQ(A->getOperand(1), Value2); 4920 EXPECT_EQ(A->getOperand(2), Value3); 4921 4922 // Remove the last element 4923 A->pop_back(); 4924 EXPECT_EQ(A->getNumOperands(), 2u); 4925 EXPECT_EQ(A->getOperand(1), Value2); 4926 4927 // Allocate a node with 4 operands. 4928 Metadata *Value4 = getConstantAsMetadata(); 4929 Metadata *Value5 = getConstantAsMetadata(); 4930 4931 Metadata *Ops[] = {Value1, Value2, Value3, Value4}; 4932 MDTuple *B = MDTuple::getDistinct(Context, Ops); 4933 4934 EXPECT_EQ(B->getNumOperands(), 4u); 4935 B->pop_back(); 4936 EXPECT_EQ(B->getNumOperands(), 3u); 4937 B->push_back(Value5); 4938 EXPECT_EQ(B->getNumOperands(), 4u); 4939 EXPECT_EQ(B->getOperand(0), Value1); 4940 EXPECT_EQ(B->getOperand(1), Value2); 4941 EXPECT_EQ(B->getOperand(2), Value3); 4942 EXPECT_EQ(B->getOperand(3), Value5); 4943 4944 // Check that we can resize temporary nodes as well. 4945 auto Temp1 = MDTuple::getTemporary(Context, {}); 4946 EXPECT_EQ(Temp1->getNumOperands(), 0u); 4947 4948 Temp1->push_back(Value1); 4949 EXPECT_EQ(Temp1->getNumOperands(), 1u); 4950 EXPECT_EQ(Temp1->getOperand(0), Value1); 4951 4952 for (int i = 0; i < 11; i++) 4953 Temp1->push_back(Value2); 4954 EXPECT_EQ(Temp1->getNumOperands(), 12u); 4955 EXPECT_EQ(Temp1->getOperand(2), Value2); 4956 EXPECT_EQ(Temp1->getOperand(11), Value2); 4957 4958 // Allocate a node that starts off as a large one. 4959 Metadata *OpsLarge[] = {Value1, Value2, Value3, Value4, 4960 Value1, Value2, Value3, Value4, 4961 Value1, Value2, Value3, Value4, 4962 Value1, Value2, Value3, Value4, 4963 Value1, Value2, Value3, Value4}; 4964 MDTuple *C = MDTuple::getDistinct(Context, OpsLarge); 4965 EXPECT_EQ(C->getNumOperands(), 20u); 4966 EXPECT_EQ(C->getOperand(7), Value4); 4967 EXPECT_EQ(C->getOperand(13), Value2); 4968 4969 C->push_back(Value1); 4970 C->push_back(Value2); 4971 EXPECT_EQ(C->getNumOperands(), 22u); 4972 EXPECT_EQ(C->getOperand(21), Value2); 4973 C->pop_back(); 4974 EXPECT_EQ(C->getNumOperands(), 21u); 4975 EXPECT_EQ(C->getOperand(20), Value1); 4976 } 4977 4978 TEST_F(MDTupleAllocationTest, Tracking2) { 4979 // Resize a tuple and check that we can still RAUW one of its operands. 4980 auto *Value1 = getConstantAsMetadata(); 4981 MDTuple *A = getTuple(); 4982 A->push_back(Value1); 4983 A->push_back(Value1); 4984 A->push_back(Value1); // Causes a resize to large. 4985 EXPECT_EQ(A->getOperand(0), Value1); 4986 EXPECT_EQ(A->getOperand(1), Value1); 4987 EXPECT_EQ(A->getOperand(2), Value1); 4988 4989 auto *Value2 = getConstantAsMetadata(); 4990 Value *V1 = Value1->getValue(); 4991 Value *V2 = Value2->getValue(); 4992 ValueAsMetadata::handleRAUW(V1, V2); 4993 4994 EXPECT_EQ(A->getOperand(0), Value2); 4995 EXPECT_EQ(A->getOperand(1), Value2); 4996 EXPECT_EQ(A->getOperand(2), Value2); 4997 } 4998 4999 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) && !defined(GTEST_HAS_SEH) 5000 typedef MetadataTest MDTupleAllocationDeathTest; 5001 TEST_F(MDTupleAllocationDeathTest, ResizeRejected) { 5002 MDTuple *A = MDTuple::get(Context, std::nullopt); 5003 auto *Value1 = getConstantAsMetadata(); 5004 EXPECT_DEATH(A->push_back(Value1), 5005 "Resizing is not supported for uniqued nodes"); 5006 5007 // Check that a node, which has been allocated as a temporary, 5008 // cannot be resized after it has been uniqued. 5009 auto *Value2 = getConstantAsMetadata(); 5010 auto B = MDTuple::getTemporary(Context, {Value2}); 5011 B->push_back(Value2); 5012 MDTuple *BUniqued = MDNode::replaceWithUniqued(std::move(B)); 5013 EXPECT_EQ(BUniqued->getNumOperands(), 2u); 5014 EXPECT_EQ(BUniqued->getOperand(1), Value2); 5015 EXPECT_DEATH(BUniqued->push_back(Value2), 5016 "Resizing is not supported for uniqued nodes"); 5017 } 5018 #endif 5019 5020 } // end namespace 5021