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 using namespace llvm; 26 27 namespace { 28 29 TEST(ContextAndReplaceableUsesTest, FromContext) { 30 LLVMContext Context; 31 ContextAndReplaceableUses CRU(Context); 32 EXPECT_EQ(&Context, &CRU.getContext()); 33 EXPECT_FALSE(CRU.hasReplaceableUses()); 34 EXPECT_FALSE(CRU.getReplaceableUses()); 35 } 36 37 TEST(ContextAndReplaceableUsesTest, FromReplaceableUses) { 38 LLVMContext Context; 39 ContextAndReplaceableUses CRU(std::make_unique<ReplaceableMetadataImpl>(Context)); 40 EXPECT_EQ(&Context, &CRU.getContext()); 41 EXPECT_TRUE(CRU.hasReplaceableUses()); 42 EXPECT_TRUE(CRU.getReplaceableUses()); 43 } 44 45 TEST(ContextAndReplaceableUsesTest, makeReplaceable) { 46 LLVMContext Context; 47 ContextAndReplaceableUses CRU(Context); 48 CRU.makeReplaceable(std::make_unique<ReplaceableMetadataImpl>(Context)); 49 EXPECT_EQ(&Context, &CRU.getContext()); 50 EXPECT_TRUE(CRU.hasReplaceableUses()); 51 EXPECT_TRUE(CRU.getReplaceableUses()); 52 } 53 54 TEST(ContextAndReplaceableUsesTest, takeReplaceableUses) { 55 LLVMContext Context; 56 auto ReplaceableUses = std::make_unique<ReplaceableMetadataImpl>(Context); 57 auto *Ptr = ReplaceableUses.get(); 58 ContextAndReplaceableUses CRU(std::move(ReplaceableUses)); 59 ReplaceableUses = CRU.takeReplaceableUses(); 60 EXPECT_EQ(&Context, &CRU.getContext()); 61 EXPECT_FALSE(CRU.hasReplaceableUses()); 62 EXPECT_FALSE(CRU.getReplaceableUses()); 63 EXPECT_EQ(Ptr, ReplaceableUses.get()); 64 } 65 66 class MetadataTest : public testing::Test { 67 public: 68 MetadataTest() : M("test", Context), Counter(0) {} 69 70 protected: 71 LLVMContext Context; 72 Module M; 73 int Counter; 74 75 MDNode *getNode() { return MDNode::get(Context, None); } 76 MDNode *getNode(Metadata *MD) { return MDNode::get(Context, MD); } 77 MDNode *getNode(Metadata *MD1, Metadata *MD2) { 78 Metadata *MDs[] = {MD1, MD2}; 79 return MDNode::get(Context, MDs); 80 } 81 82 MDTuple *getTuple() { return MDTuple::getDistinct(Context, None); } 83 DISubroutineType *getSubroutineType() { 84 return DISubroutineType::getDistinct(Context, DINode::FlagZero, 0, 85 getNode(nullptr)); 86 } 87 DISubprogram *getSubprogram() { 88 return DISubprogram::getDistinct( 89 Context, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0, 90 DINode::FlagZero, DISubprogram::SPFlagZero, nullptr); 91 } 92 DIFile *getFile() { 93 return DIFile::getDistinct(Context, "file.c", "/path/to/dir"); 94 } 95 DICompileUnit *getUnit() { 96 return DICompileUnit::getDistinct( 97 Context, 1, getFile(), "clang", false, "-g", 2, "", 98 DICompileUnit::FullDebug, getTuple(), getTuple(), getTuple(), 99 getTuple(), getTuple(), 0, true, false, 100 DICompileUnit::DebugNameTableKind::Default, false, "/", ""); 101 } 102 DIType *getBasicType(StringRef Name) { 103 return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name); 104 } 105 DIType *getDerivedType() { 106 return DIDerivedType::getDistinct( 107 Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, 108 getBasicType("basictype"), 1, 2, 0, None, DINode::FlagZero); 109 } 110 Constant *getConstant() { 111 return ConstantInt::get(Type::getInt32Ty(Context), Counter++); 112 } 113 ConstantAsMetadata *getConstantAsMetadata() { 114 return ConstantAsMetadata::get(getConstant()); 115 } 116 DIType *getCompositeType() { 117 return DICompositeType::getDistinct( 118 Context, dwarf::DW_TAG_structure_type, "", nullptr, 0, nullptr, nullptr, 119 32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, ""); 120 } 121 Function *getFunction(StringRef Name) { 122 return Function::Create( 123 FunctionType::get(Type::getVoidTy(Context), None, false), 124 Function::ExternalLinkage, Name, M); 125 } 126 }; 127 typedef MetadataTest MDStringTest; 128 129 // Test that construction of MDString with different value produces different 130 // MDString objects, even with the same string pointer and nulls in the string. 131 TEST_F(MDStringTest, CreateDifferent) { 132 char x[3] = { 'f', 0, 'A' }; 133 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); 134 x[2] = 'B'; 135 MDString *s2 = MDString::get(Context, StringRef(&x[0], 3)); 136 EXPECT_NE(s1, s2); 137 } 138 139 // Test that creation of MDStrings with the same string contents produces the 140 // same MDString object, even with different pointers. 141 TEST_F(MDStringTest, CreateSame) { 142 char x[4] = { 'a', 'b', 'c', 'X' }; 143 char y[4] = { 'a', 'b', 'c', 'Y' }; 144 145 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); 146 MDString *s2 = MDString::get(Context, StringRef(&y[0], 3)); 147 EXPECT_EQ(s1, s2); 148 } 149 150 // Test that MDString prints out the string we fed it. 151 TEST_F(MDStringTest, PrintingSimple) { 152 char str[14] = "testing 1 2 3"; 153 MDString *s = MDString::get(Context, StringRef(&str[0], 13)); 154 strncpy(str, "aaaaaaaaaaaaa", 14); 155 156 std::string Str; 157 raw_string_ostream oss(Str); 158 s->print(oss); 159 EXPECT_STREQ("!\"testing 1 2 3\"", oss.str().c_str()); 160 } 161 162 // Test printing of MDString with non-printable characters. 163 TEST_F(MDStringTest, PrintingComplex) { 164 char str[5] = {0, '\n', '"', '\\', (char)-1}; 165 MDString *s = MDString::get(Context, StringRef(str+0, 5)); 166 std::string Str; 167 raw_string_ostream oss(Str); 168 s->print(oss); 169 EXPECT_STREQ("!\"\\00\\0A\\22\\\\\\FF\"", oss.str().c_str()); 170 } 171 172 typedef MetadataTest MDNodeTest; 173 174 // Test the two constructors, and containing other Constants. 175 TEST_F(MDNodeTest, Simple) { 176 char x[3] = { 'a', 'b', 'c' }; 177 char y[3] = { '1', '2', '3' }; 178 179 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); 180 MDString *s2 = MDString::get(Context, StringRef(&y[0], 3)); 181 ConstantAsMetadata *CI = 182 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); 183 184 std::vector<Metadata *> V; 185 V.push_back(s1); 186 V.push_back(CI); 187 V.push_back(s2); 188 189 MDNode *n1 = MDNode::get(Context, V); 190 Metadata *const c1 = n1; 191 MDNode *n2 = MDNode::get(Context, c1); 192 Metadata *const c2 = n2; 193 MDNode *n3 = MDNode::get(Context, V); 194 MDNode *n4 = MDNode::getIfExists(Context, V); 195 MDNode *n5 = MDNode::getIfExists(Context, c1); 196 MDNode *n6 = MDNode::getIfExists(Context, c2); 197 EXPECT_NE(n1, n2); 198 EXPECT_EQ(n1, n3); 199 EXPECT_EQ(n4, n1); 200 EXPECT_EQ(n5, n2); 201 EXPECT_EQ(n6, (Metadata *)nullptr); 202 203 EXPECT_EQ(3u, n1->getNumOperands()); 204 EXPECT_EQ(s1, n1->getOperand(0)); 205 EXPECT_EQ(CI, n1->getOperand(1)); 206 EXPECT_EQ(s2, n1->getOperand(2)); 207 208 EXPECT_EQ(1u, n2->getNumOperands()); 209 EXPECT_EQ(n1, n2->getOperand(0)); 210 } 211 212 TEST_F(MDNodeTest, Delete) { 213 Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 1); 214 Instruction *I = new BitCastInst(C, Type::getInt32Ty(Context)); 215 216 Metadata *const V = LocalAsMetadata::get(I); 217 MDNode *n = MDNode::get(Context, V); 218 TrackingMDRef wvh(n); 219 220 EXPECT_EQ(n, wvh); 221 222 I->deleteValue(); 223 } 224 225 TEST_F(MDNodeTest, SelfReference) { 226 // !0 = !{!0} 227 // !1 = !{!0} 228 { 229 auto Temp = MDNode::getTemporary(Context, None); 230 Metadata *Args[] = {Temp.get()}; 231 MDNode *Self = MDNode::get(Context, Args); 232 Self->replaceOperandWith(0, Self); 233 ASSERT_EQ(Self, Self->getOperand(0)); 234 235 // Self-references should be distinct, so MDNode::get() should grab a 236 // uniqued node that references Self, not Self. 237 Args[0] = Self; 238 MDNode *Ref1 = MDNode::get(Context, Args); 239 MDNode *Ref2 = MDNode::get(Context, Args); 240 EXPECT_NE(Self, Ref1); 241 EXPECT_EQ(Ref1, Ref2); 242 } 243 244 // !0 = !{!0, !{}} 245 // !1 = !{!0, !{}} 246 { 247 auto Temp = MDNode::getTemporary(Context, None); 248 Metadata *Args[] = {Temp.get(), MDNode::get(Context, None)}; 249 MDNode *Self = MDNode::get(Context, Args); 250 Self->replaceOperandWith(0, Self); 251 ASSERT_EQ(Self, Self->getOperand(0)); 252 253 // Self-references should be distinct, so MDNode::get() should grab a 254 // uniqued node that references Self, not Self itself. 255 Args[0] = Self; 256 MDNode *Ref1 = MDNode::get(Context, Args); 257 MDNode *Ref2 = MDNode::get(Context, Args); 258 EXPECT_NE(Self, Ref1); 259 EXPECT_EQ(Ref1, Ref2); 260 } 261 } 262 263 TEST_F(MDNodeTest, Print) { 264 Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 7); 265 MDString *S = MDString::get(Context, "foo"); 266 MDNode *N0 = getNode(); 267 MDNode *N1 = getNode(N0); 268 MDNode *N2 = getNode(N0, N1); 269 270 Metadata *Args[] = {ConstantAsMetadata::get(C), S, nullptr, N0, N1, N2}; 271 MDNode *N = MDNode::get(Context, Args); 272 273 std::string Expected; 274 { 275 raw_string_ostream OS(Expected); 276 OS << "<" << (void *)N << "> = !{"; 277 C->printAsOperand(OS); 278 OS << ", "; 279 S->printAsOperand(OS); 280 OS << ", null"; 281 MDNode *Nodes[] = {N0, N1, N2}; 282 for (auto *Node : Nodes) 283 OS << ", <" << (void *)Node << ">"; 284 OS << "}"; 285 } 286 287 std::string Actual; 288 { 289 raw_string_ostream OS(Actual); 290 N->print(OS); 291 } 292 293 EXPECT_EQ(Expected, Actual); 294 } 295 296 #define EXPECT_PRINTER_EQ(EXPECTED, PRINT) \ 297 do { \ 298 std::string Actual_; \ 299 raw_string_ostream OS(Actual_); \ 300 PRINT; \ 301 OS.flush(); \ 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, None); 358 auto *N1 = MDNode::getDistinct(Context, None); 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, None); 384 auto *N1 = MDNode::getDistinct(Context, None); 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, None); 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, None, 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, None); 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, None); 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, None); 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 = Type::getInt1PtrTy(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, None); 573 ASSERT_TRUE(Empty->isResolved()); 574 ASSERT_FALSE(Empty->isDistinct()); 575 ASSERT_EQ(Empty, MDNode::get(Context, None)); 576 577 // distinct !{} 578 MDNode *Distinct1 = MDNode::getDistinct(Context, None); 579 MDNode *Distinct2 = MDNode::getDistinct(Context, None); 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, None)); 588 } 589 590 TEST_F(MDNodeTest, isUniqued) { 591 MDNode *U = MDTuple::get(Context, None); 592 MDNode *D = MDTuple::getDistinct(Context, None); 593 auto T = MDTuple::getTemporary(Context, None); 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, None); 601 MDNode *D = MDTuple::getDistinct(Context, None); 602 auto T = MDTuple::getTemporary(Context, None); 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, None); 610 MDNode *D = MDTuple::getDistinct(Context, None); 611 auto T = MDTuple::getTemporary(Context, None); 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, None); 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, None); 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, None); 637 638 // !1 = !{!3, null} 639 auto Temp3 = MDTuple::getTemporary(Context, None); 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, None); 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, None); 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, None); 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, None).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 = Type::getInt1PtrTy(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 = Type::getInt1PtrTy(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, None); 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, None); 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, None); 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, Overflow) { 921 DISubprogram *N = getSubprogram(); 922 { 923 DILocation *L = DILocation::get(Context, 2, 7, N); 924 EXPECT_EQ(2u, L->getLine()); 925 EXPECT_EQ(7u, L->getColumn()); 926 } 927 unsigned U16 = 1u << 16; 928 { 929 DILocation *L = DILocation::get(Context, UINT32_MAX, U16 - 1, N); 930 EXPECT_EQ(UINT32_MAX, L->getLine()); 931 EXPECT_EQ(U16 - 1, L->getColumn()); 932 } 933 { 934 DILocation *L = DILocation::get(Context, UINT32_MAX, U16, N); 935 EXPECT_EQ(UINT32_MAX, L->getLine()); 936 EXPECT_EQ(0u, L->getColumn()); 937 } 938 { 939 DILocation *L = DILocation::get(Context, UINT32_MAX, U16 + 1, N); 940 EXPECT_EQ(UINT32_MAX, L->getLine()); 941 EXPECT_EQ(0u, L->getColumn()); 942 } 943 } 944 945 TEST_F(DILocationTest, Merge) { 946 DISubprogram *N = getSubprogram(); 947 DIScope *S = DILexicalBlock::get(Context, N, getFile(), 3, 4); 948 949 { 950 // Identical. 951 auto *A = DILocation::get(Context, 2, 7, N); 952 auto *B = DILocation::get(Context, 2, 7, N); 953 auto *M = DILocation::getMergedLocation(A, B); 954 EXPECT_EQ(2u, M->getLine()); 955 EXPECT_EQ(7u, M->getColumn()); 956 EXPECT_EQ(N, M->getScope()); 957 } 958 959 { 960 // Identical, different scopes. 961 auto *A = DILocation::get(Context, 2, 7, N); 962 auto *B = DILocation::get(Context, 2, 7, S); 963 auto *M = DILocation::getMergedLocation(A, B); 964 EXPECT_EQ(0u, M->getLine()); // FIXME: Should this be 2? 965 EXPECT_EQ(0u, M->getColumn()); // FIXME: Should this be 7? 966 EXPECT_EQ(N, M->getScope()); 967 } 968 969 { 970 // Different lines, same scopes. 971 auto *A = DILocation::get(Context, 1, 6, N); 972 auto *B = DILocation::get(Context, 2, 7, N); 973 auto *M = DILocation::getMergedLocation(A, B); 974 EXPECT_EQ(0u, M->getLine()); 975 EXPECT_EQ(0u, M->getColumn()); 976 EXPECT_EQ(N, M->getScope()); 977 } 978 979 { 980 // Twisty locations, all different, same function. 981 auto *A = DILocation::get(Context, 1, 6, N); 982 auto *B = DILocation::get(Context, 2, 7, S); 983 auto *M = DILocation::getMergedLocation(A, B); 984 EXPECT_EQ(0u, M->getLine()); 985 EXPECT_EQ(0u, M->getColumn()); 986 EXPECT_EQ(N, M->getScope()); 987 } 988 989 { 990 // Different function, same inlined-at. 991 auto *F = getFile(); 992 auto *SP1 = DISubprogram::getDistinct(Context, F, "a", "a", F, 0, nullptr, 993 0, nullptr, 0, 0, DINode::FlagZero, 994 DISubprogram::SPFlagZero, nullptr); 995 auto *SP2 = DISubprogram::getDistinct(Context, F, "b", "b", F, 0, nullptr, 996 0, nullptr, 0, 0, DINode::FlagZero, 997 DISubprogram::SPFlagZero, nullptr); 998 999 auto *I = DILocation::get(Context, 2, 7, N); 1000 auto *A = DILocation::get(Context, 1, 6, SP1, I); 1001 auto *B = DILocation::get(Context, 2, 7, SP2, I); 1002 auto *M = DILocation::getMergedLocation(A, B); 1003 EXPECT_EQ(0u, M->getLine()); 1004 EXPECT_EQ(0u, M->getColumn()); 1005 EXPECT_TRUE(isa<DILocalScope>(M->getScope())); 1006 EXPECT_EQ(I, M->getInlinedAt()); 1007 } 1008 1009 { 1010 // Completely different. 1011 auto *I = DILocation::get(Context, 2, 7, N); 1012 auto *A = DILocation::get(Context, 1, 6, S, I); 1013 auto *B = DILocation::get(Context, 2, 7, getSubprogram()); 1014 auto *M = DILocation::getMergedLocation(A, B); 1015 EXPECT_EQ(0u, M->getLine()); 1016 EXPECT_EQ(0u, M->getColumn()); 1017 EXPECT_TRUE(isa<DILocalScope>(M->getScope())); 1018 EXPECT_EQ(S, M->getScope()); 1019 EXPECT_EQ(nullptr, M->getInlinedAt()); 1020 } 1021 } 1022 1023 TEST_F(DILocationTest, getDistinct) { 1024 MDNode *N = getSubprogram(); 1025 DILocation *L0 = DILocation::getDistinct(Context, 2, 7, N); 1026 EXPECT_TRUE(L0->isDistinct()); 1027 DILocation *L1 = DILocation::get(Context, 2, 7, N); 1028 EXPECT_FALSE(L1->isDistinct()); 1029 EXPECT_EQ(L1, DILocation::get(Context, 2, 7, N)); 1030 } 1031 1032 TEST_F(DILocationTest, getTemporary) { 1033 MDNode *N = MDNode::get(Context, None); 1034 auto L = DILocation::getTemporary(Context, 2, 7, N); 1035 EXPECT_TRUE(L->isTemporary()); 1036 EXPECT_FALSE(L->isResolved()); 1037 } 1038 1039 TEST_F(DILocationTest, cloneTemporary) { 1040 MDNode *N = MDNode::get(Context, None); 1041 auto L = DILocation::getTemporary(Context, 2, 7, N); 1042 EXPECT_TRUE(L->isTemporary()); 1043 auto L2 = L->clone(); 1044 EXPECT_TRUE(L2->isTemporary()); 1045 } 1046 1047 TEST_F(DILocationTest, discriminatorEncoding) { 1048 EXPECT_EQ(0U, DILocation::encodeDiscriminator(0, 0, 0).getValue()); 1049 1050 // Encode base discriminator as a component: lsb is 0, then the value. 1051 // The other components are all absent, so we leave all the other bits 0. 1052 EXPECT_EQ(2U, DILocation::encodeDiscriminator(1, 0, 0).getValue()); 1053 1054 // Base discriminator component is empty, so lsb is 1. Next component is not 1055 // empty, so its lsb is 0, then its value (1). Next component is empty. 1056 // So the bit pattern is 101. 1057 EXPECT_EQ(5U, DILocation::encodeDiscriminator(0, 1, 0).getValue()); 1058 1059 // First 2 components are empty, so the bit pattern is 11. Then the 1060 // next component - ending up with 1011. 1061 EXPECT_EQ(0xbU, DILocation::encodeDiscriminator(0, 0, 1).getValue()); 1062 1063 // The bit pattern for the first 2 components is 11. The next bit is 0, 1064 // because the last component is not empty. We have 29 bits usable for 1065 // encoding, but we cap it at 12 bits uniformously for all components. We 1066 // encode the last component over 14 bits. 1067 EXPECT_EQ(0xfffbU, DILocation::encodeDiscriminator(0, 0, 0xfff).getValue()); 1068 1069 EXPECT_EQ(0x102U, DILocation::encodeDiscriminator(1, 1, 0).getValue()); 1070 1071 EXPECT_EQ(0x13eU, DILocation::encodeDiscriminator(0x1f, 1, 0).getValue()); 1072 1073 EXPECT_EQ(0x87feU, DILocation::encodeDiscriminator(0x1ff, 1, 0).getValue()); 1074 1075 EXPECT_EQ(0x1f3eU, DILocation::encodeDiscriminator(0x1f, 0x1f, 0).getValue()); 1076 1077 EXPECT_EQ(0x3ff3eU, 1078 DILocation::encodeDiscriminator(0x1f, 0x1ff, 0).getValue()); 1079 1080 EXPECT_EQ(0x1ff87feU, 1081 DILocation::encodeDiscriminator(0x1ff, 0x1ff, 0).getValue()); 1082 1083 EXPECT_EQ(0xfff9f3eU, 1084 DILocation::encodeDiscriminator(0x1f, 0x1f, 0xfff).getValue()); 1085 1086 EXPECT_EQ(0xffc3ff3eU, 1087 DILocation::encodeDiscriminator(0x1f, 0x1ff, 0x1ff).getValue()); 1088 1089 EXPECT_EQ(0xffcf87feU, 1090 DILocation::encodeDiscriminator(0x1ff, 0x1f, 0x1ff).getValue()); 1091 1092 EXPECT_EQ(0xe1ff87feU, 1093 DILocation::encodeDiscriminator(0x1ff, 0x1ff, 7).getValue()); 1094 } 1095 1096 TEST_F(DILocationTest, discriminatorEncodingNegativeTests) { 1097 EXPECT_EQ(None, DILocation::encodeDiscriminator(0, 0, 0x1000)); 1098 EXPECT_EQ(None, DILocation::encodeDiscriminator(0x1000, 0, 0)); 1099 EXPECT_EQ(None, DILocation::encodeDiscriminator(0, 0x1000, 0)); 1100 EXPECT_EQ(None, DILocation::encodeDiscriminator(0, 0, 0x1000)); 1101 EXPECT_EQ(None, DILocation::encodeDiscriminator(0x1ff, 0x1ff, 8)); 1102 EXPECT_EQ(None, 1103 DILocation::encodeDiscriminator(std::numeric_limits<uint32_t>::max(), 1104 std::numeric_limits<uint32_t>::max(), 1105 0)); 1106 } 1107 1108 TEST_F(DILocationTest, discriminatorSpecialCases) { 1109 // We don't test getCopyIdentifier here because the only way 1110 // to set it is by constructing an encoded discriminator using 1111 // encodeDiscriminator, which is already tested. 1112 auto L1 = DILocation::get(Context, 1, 2, getSubprogram()); 1113 EXPECT_EQ(0U, L1->getBaseDiscriminator()); 1114 EXPECT_EQ(1U, L1->getDuplicationFactor()); 1115 1116 EXPECT_EQ(L1, L1->cloneWithBaseDiscriminator(0).getValue()); 1117 EXPECT_EQ(L1, L1->cloneByMultiplyingDuplicationFactor(0).getValue()); 1118 EXPECT_EQ(L1, L1->cloneByMultiplyingDuplicationFactor(1).getValue()); 1119 1120 auto L2 = L1->cloneWithBaseDiscriminator(1).getValue(); 1121 EXPECT_EQ(0U, L1->getBaseDiscriminator()); 1122 EXPECT_EQ(1U, L1->getDuplicationFactor()); 1123 1124 EXPECT_EQ(1U, L2->getBaseDiscriminator()); 1125 EXPECT_EQ(1U, L2->getDuplicationFactor()); 1126 1127 auto L3 = L2->cloneByMultiplyingDuplicationFactor(2).getValue(); 1128 EXPECT_EQ(1U, L3->getBaseDiscriminator()); 1129 EXPECT_EQ(2U, L3->getDuplicationFactor()); 1130 1131 EXPECT_EQ(L2, L2->cloneByMultiplyingDuplicationFactor(1).getValue()); 1132 1133 auto L4 = L3->cloneByMultiplyingDuplicationFactor(4).getValue(); 1134 EXPECT_EQ(1U, L4->getBaseDiscriminator()); 1135 EXPECT_EQ(8U, L4->getDuplicationFactor()); 1136 1137 auto L5 = L4->cloneWithBaseDiscriminator(2).getValue(); 1138 EXPECT_EQ(2U, L5->getBaseDiscriminator()); 1139 EXPECT_EQ(8U, L5->getDuplicationFactor()); 1140 1141 // Check extreme cases 1142 auto L6 = L1->cloneWithBaseDiscriminator(0xfff).getValue(); 1143 EXPECT_EQ(0xfffU, L6->getBaseDiscriminator()); 1144 EXPECT_EQ(0xfffU, L6->cloneByMultiplyingDuplicationFactor(0xfff) 1145 .getValue() 1146 ->getDuplicationFactor()); 1147 1148 // Check we return None for unencodable cases. 1149 EXPECT_EQ(None, L4->cloneWithBaseDiscriminator(0x1000)); 1150 EXPECT_EQ(None, L4->cloneByMultiplyingDuplicationFactor(0x1000)); 1151 } 1152 1153 1154 typedef MetadataTest GenericDINodeTest; 1155 1156 TEST_F(GenericDINodeTest, get) { 1157 StringRef Header = "header"; 1158 auto *Empty = MDNode::get(Context, None); 1159 Metadata *Ops1[] = {Empty}; 1160 auto *N = GenericDINode::get(Context, 15, Header, Ops1); 1161 EXPECT_EQ(15u, N->getTag()); 1162 EXPECT_EQ(2u, N->getNumOperands()); 1163 EXPECT_EQ(Header, N->getHeader()); 1164 EXPECT_EQ(MDString::get(Context, Header), N->getOperand(0)); 1165 EXPECT_EQ(1u, N->getNumDwarfOperands()); 1166 EXPECT_EQ(Empty, N->getDwarfOperand(0)); 1167 EXPECT_EQ(Empty, N->getOperand(1)); 1168 ASSERT_TRUE(N->isUniqued()); 1169 1170 EXPECT_EQ(N, GenericDINode::get(Context, 15, Header, Ops1)); 1171 1172 N->replaceOperandWith(1, nullptr); 1173 EXPECT_EQ(15u, N->getTag()); 1174 EXPECT_EQ(Header, N->getHeader()); 1175 EXPECT_EQ(nullptr, N->getDwarfOperand(0)); 1176 ASSERT_TRUE(N->isUniqued()); 1177 1178 Metadata *Ops2[] = {nullptr}; 1179 EXPECT_EQ(N, GenericDINode::get(Context, 15, Header, Ops2)); 1180 1181 N->replaceDwarfOperandWith(0, Empty); 1182 EXPECT_EQ(15u, N->getTag()); 1183 EXPECT_EQ(Header, N->getHeader()); 1184 EXPECT_EQ(Empty, N->getDwarfOperand(0)); 1185 ASSERT_TRUE(N->isUniqued()); 1186 EXPECT_EQ(N, GenericDINode::get(Context, 15, Header, Ops1)); 1187 1188 TempGenericDINode Temp = N->clone(); 1189 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1190 } 1191 1192 TEST_F(GenericDINodeTest, getEmptyHeader) { 1193 // Canonicalize !"" to null. 1194 auto *N = GenericDINode::get(Context, 15, StringRef(), None); 1195 EXPECT_EQ(StringRef(), N->getHeader()); 1196 EXPECT_EQ(nullptr, N->getOperand(0)); 1197 } 1198 1199 typedef MetadataTest DISubrangeTest; 1200 1201 TEST_F(DISubrangeTest, get) { 1202 auto *N = DISubrange::get(Context, 5, 7); 1203 auto Count = N->getCount(); 1204 auto Lower = N->getLowerBound(); 1205 EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag()); 1206 ASSERT_TRUE(Count); 1207 ASSERT_TRUE(Count.is<ConstantInt*>()); 1208 EXPECT_EQ(5, Count.get<ConstantInt*>()->getSExtValue()); 1209 EXPECT_EQ(7, Lower.get<ConstantInt *>()->getSExtValue()); 1210 EXPECT_EQ(N, DISubrange::get(Context, 5, 7)); 1211 EXPECT_EQ(DISubrange::get(Context, 5, 0), DISubrange::get(Context, 5)); 1212 1213 TempDISubrange Temp = N->clone(); 1214 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1215 } 1216 1217 TEST_F(DISubrangeTest, getEmptyArray) { 1218 auto *N = DISubrange::get(Context, -1, 0); 1219 auto Count = N->getCount(); 1220 auto Lower = N->getLowerBound(); 1221 EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag()); 1222 ASSERT_TRUE(Count); 1223 ASSERT_TRUE(Count.is<ConstantInt*>()); 1224 EXPECT_EQ(-1, Count.get<ConstantInt*>()->getSExtValue()); 1225 EXPECT_EQ(0, Lower.get<ConstantInt *>()->getSExtValue()); 1226 EXPECT_EQ(N, DISubrange::get(Context, -1, 0)); 1227 } 1228 1229 TEST_F(DISubrangeTest, getVariableCount) { 1230 DILocalScope *Scope = getSubprogram(); 1231 DIFile *File = getFile(); 1232 DIType *Type = getDerivedType(); 1233 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1234 auto *VlaExpr = DILocalVariable::get(Context, Scope, "vla_expr", File, 8, 1235 Type, 2, Flags, 8, nullptr); 1236 1237 auto *N = DISubrange::get(Context, VlaExpr, 0); 1238 auto Count = N->getCount(); 1239 auto Lower = N->getLowerBound(); 1240 ASSERT_TRUE(Count); 1241 ASSERT_TRUE(Count.is<DIVariable*>()); 1242 EXPECT_EQ(VlaExpr, Count.get<DIVariable*>()); 1243 ASSERT_TRUE(isa<DIVariable>(N->getRawCountNode())); 1244 EXPECT_EQ(0, Lower.get<ConstantInt *>()->getSExtValue()); 1245 EXPECT_EQ("vla_expr", Count.get<DIVariable*>()->getName()); 1246 EXPECT_EQ(N, DISubrange::get(Context, VlaExpr, 0)); 1247 } 1248 1249 TEST_F(DISubrangeTest, fortranAllocatableInt) { 1250 DILocalScope *Scope = getSubprogram(); 1251 DIFile *File = getFile(); 1252 DIType *Type = getDerivedType(); 1253 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1254 auto *LI = ConstantAsMetadata::get( 1255 ConstantInt::getSigned(Type::getInt64Ty(Context), -10)); 1256 auto *UI = ConstantAsMetadata::get( 1257 ConstantInt::getSigned(Type::getInt64Ty(Context), 10)); 1258 auto *SI = ConstantAsMetadata::get( 1259 ConstantInt::getSigned(Type::getInt64Ty(Context), 4)); 1260 auto *UIother = ConstantAsMetadata::get( 1261 ConstantInt::getSigned(Type::getInt64Ty(Context), 20)); 1262 auto *UVother = DILocalVariable::get(Context, Scope, "ubother", File, 8, Type, 1263 2, Flags, 8, nullptr); 1264 auto *UEother = DIExpression::get(Context, {5, 6}); 1265 auto *LIZero = ConstantAsMetadata::get( 1266 ConstantInt::getSigned(Type::getInt64Ty(Context), 0)); 1267 auto *UIZero = ConstantAsMetadata::get( 1268 ConstantInt::getSigned(Type::getInt64Ty(Context), 0)); 1269 1270 auto *N = DISubrange::get(Context, nullptr, LI, UI, SI); 1271 1272 auto Lower = N->getLowerBound(); 1273 ASSERT_TRUE(Lower); 1274 ASSERT_TRUE(Lower.is<ConstantInt *>()); 1275 EXPECT_EQ(cast<ConstantInt>(LI->getValue()), Lower.get<ConstantInt *>()); 1276 1277 auto Upper = N->getUpperBound(); 1278 ASSERT_TRUE(Upper); 1279 ASSERT_TRUE(Upper.is<ConstantInt *>()); 1280 EXPECT_EQ(cast<ConstantInt>(UI->getValue()), Upper.get<ConstantInt *>()); 1281 1282 auto Stride = N->getStride(); 1283 ASSERT_TRUE(Stride); 1284 ASSERT_TRUE(Stride.is<ConstantInt *>()); 1285 EXPECT_EQ(cast<ConstantInt>(SI->getValue()), Stride.get<ConstantInt *>()); 1286 1287 EXPECT_EQ(N, DISubrange::get(Context, nullptr, LI, UI, SI)); 1288 1289 EXPECT_NE(N, DISubrange::get(Context, nullptr, LI, UIother, SI)); 1290 EXPECT_NE(N, DISubrange::get(Context, nullptr, LI, UEother, SI)); 1291 EXPECT_NE(N, DISubrange::get(Context, nullptr, LI, UVother, SI)); 1292 1293 auto *NZeroLower = DISubrange::get(Context, nullptr, LIZero, UI, SI); 1294 EXPECT_NE(NZeroLower, DISubrange::get(Context, nullptr, nullptr, UI, SI)); 1295 1296 auto *NZeroUpper = DISubrange::get(Context, nullptr, LI, UIZero, SI); 1297 EXPECT_NE(NZeroUpper, DISubrange::get(Context, nullptr, LI, nullptr, SI)); 1298 } 1299 1300 TEST_F(DISubrangeTest, fortranAllocatableVar) { 1301 DILocalScope *Scope = getSubprogram(); 1302 DIFile *File = getFile(); 1303 DIType *Type = getDerivedType(); 1304 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1305 auto *LV = 1306 DILocalVariable::get(Context, Scope, "lb", File, 8, Type, 2, Flags, 8, 1307 nullptr); 1308 auto *UV = 1309 DILocalVariable::get(Context, Scope, "ub", File, 8, Type, 2, Flags, 8, 1310 nullptr); 1311 auto *SV = 1312 DILocalVariable::get(Context, Scope, "st", File, 8, Type, 2, Flags, 8, 1313 nullptr); 1314 auto *SVother = DILocalVariable::get(Context, Scope, "stother", File, 8, Type, 1315 2, Flags, 8, nullptr); 1316 auto *SIother = ConstantAsMetadata::get( 1317 ConstantInt::getSigned(Type::getInt64Ty(Context), 20)); 1318 auto *SEother = DIExpression::get(Context, {5, 6}); 1319 1320 auto *N = DISubrange::get(Context, nullptr, LV, UV, SV); 1321 1322 auto Lower = N->getLowerBound(); 1323 ASSERT_TRUE(Lower); 1324 ASSERT_TRUE(Lower.is<DIVariable *>()); 1325 EXPECT_EQ(LV, Lower.get<DIVariable *>()); 1326 1327 auto Upper = N->getUpperBound(); 1328 ASSERT_TRUE(Upper); 1329 ASSERT_TRUE(Upper.is<DIVariable *>()); 1330 EXPECT_EQ(UV, Upper.get<DIVariable *>()); 1331 1332 auto Stride = N->getStride(); 1333 ASSERT_TRUE(Stride); 1334 ASSERT_TRUE(Stride.is<DIVariable *>()); 1335 EXPECT_EQ(SV, Stride.get<DIVariable *>()); 1336 1337 EXPECT_EQ(N, DISubrange::get(Context, nullptr, LV, UV, SV)); 1338 1339 EXPECT_NE(N, DISubrange::get(Context, nullptr, LV, UV, SVother)); 1340 EXPECT_NE(N, DISubrange::get(Context, nullptr, LV, UV, SEother)); 1341 EXPECT_NE(N, DISubrange::get(Context, nullptr, LV, UV, SIother)); 1342 } 1343 1344 TEST_F(DISubrangeTest, fortranAllocatableExpr) { 1345 DILocalScope *Scope = getSubprogram(); 1346 DIFile *File = getFile(); 1347 DIType *Type = getDerivedType(); 1348 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1349 auto *LE = DIExpression::get(Context, {1, 2}); 1350 auto *UE = DIExpression::get(Context, {2, 3}); 1351 auto *SE = DIExpression::get(Context, {3, 4}); 1352 auto *LEother = DIExpression::get(Context, {5, 6}); 1353 auto *LIother = ConstantAsMetadata::get( 1354 ConstantInt::getSigned(Type::getInt64Ty(Context), 20)); 1355 auto *LVother = DILocalVariable::get(Context, Scope, "lbother", File, 8, Type, 1356 2, Flags, 8, nullptr); 1357 1358 auto *N = DISubrange::get(Context, nullptr, LE, UE, SE); 1359 1360 auto Lower = N->getLowerBound(); 1361 ASSERT_TRUE(Lower); 1362 ASSERT_TRUE(Lower.is<DIExpression *>()); 1363 EXPECT_EQ(LE, Lower.get<DIExpression *>()); 1364 1365 auto Upper = N->getUpperBound(); 1366 ASSERT_TRUE(Upper); 1367 ASSERT_TRUE(Upper.is<DIExpression *>()); 1368 EXPECT_EQ(UE, Upper.get<DIExpression *>()); 1369 1370 auto Stride = N->getStride(); 1371 ASSERT_TRUE(Stride); 1372 ASSERT_TRUE(Stride.is<DIExpression *>()); 1373 EXPECT_EQ(SE, Stride.get<DIExpression *>()); 1374 1375 EXPECT_EQ(N, DISubrange::get(Context, nullptr, LE, UE, SE)); 1376 1377 EXPECT_NE(N, DISubrange::get(Context, nullptr, LEother, UE, SE)); 1378 EXPECT_NE(N, DISubrange::get(Context, nullptr, LIother, UE, SE)); 1379 EXPECT_NE(N, DISubrange::get(Context, nullptr, LVother, UE, SE)); 1380 } 1381 1382 typedef MetadataTest DIGenericSubrangeTest; 1383 1384 TEST_F(DIGenericSubrangeTest, fortranAssumedRankInt) { 1385 DILocalScope *Scope = getSubprogram(); 1386 DIFile *File = getFile(); 1387 DIType *Type = getDerivedType(); 1388 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1389 auto *LI = DIExpression::get( 1390 Context, {dwarf::DW_OP_consts, static_cast<uint64_t>(-10)}); 1391 auto *UI = DIExpression::get(Context, {dwarf::DW_OP_consts, 10}); 1392 auto *SI = DIExpression::get(Context, {dwarf::DW_OP_consts, 4}); 1393 auto *UIother = DIExpression::get(Context, {dwarf::DW_OP_consts, 20}); 1394 auto *UVother = DILocalVariable::get(Context, Scope, "ubother", File, 8, Type, 1395 2, Flags, 8, nullptr); 1396 auto *UEother = DIExpression::get(Context, {5, 6}); 1397 auto *LIZero = DIExpression::get(Context, {dwarf::DW_OP_consts, 0}); 1398 auto *UIZero = DIExpression::get(Context, {dwarf::DW_OP_consts, 0}); 1399 1400 auto *N = DIGenericSubrange::get(Context, nullptr, LI, UI, SI); 1401 1402 auto Lower = N->getLowerBound(); 1403 ASSERT_TRUE(Lower); 1404 ASSERT_TRUE(Lower.is<DIExpression *>()); 1405 EXPECT_EQ(dyn_cast_or_null<DIExpression>(LI), Lower.get<DIExpression *>()); 1406 1407 auto Upper = N->getUpperBound(); 1408 ASSERT_TRUE(Upper); 1409 ASSERT_TRUE(Upper.is<DIExpression *>()); 1410 EXPECT_EQ(dyn_cast_or_null<DIExpression>(UI), Upper.get<DIExpression *>()); 1411 1412 auto Stride = N->getStride(); 1413 ASSERT_TRUE(Stride); 1414 ASSERT_TRUE(Stride.is<DIExpression *>()); 1415 EXPECT_EQ(dyn_cast_or_null<DIExpression>(SI), Stride.get<DIExpression *>()); 1416 1417 EXPECT_EQ(N, DIGenericSubrange::get(Context, nullptr, LI, UI, SI)); 1418 1419 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LI, UIother, SI)); 1420 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LI, UEother, SI)); 1421 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LI, UVother, SI)); 1422 1423 auto *NZeroLower = DIGenericSubrange::get(Context, nullptr, LIZero, UI, SI); 1424 EXPECT_NE(NZeroLower, 1425 DIGenericSubrange::get(Context, nullptr, nullptr, UI, SI)); 1426 1427 auto *NZeroUpper = DIGenericSubrange::get(Context, nullptr, LI, UIZero, SI); 1428 EXPECT_NE(NZeroUpper, 1429 DIGenericSubrange::get(Context, nullptr, LI, nullptr, SI)); 1430 } 1431 1432 TEST_F(DIGenericSubrangeTest, fortranAssumedRankVar) { 1433 DILocalScope *Scope = getSubprogram(); 1434 DIFile *File = getFile(); 1435 DIType *Type = getDerivedType(); 1436 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1437 auto *LV = 1438 DILocalVariable::get(Context, Scope, "lb", File, 8, Type, 2, Flags, 8, 1439 nullptr); 1440 auto *UV = 1441 DILocalVariable::get(Context, Scope, "ub", File, 8, Type, 2, Flags, 8, 1442 nullptr); 1443 auto *SV = 1444 DILocalVariable::get(Context, Scope, "st", File, 8, Type, 2, Flags, 8, 1445 nullptr); 1446 auto *SVother = DILocalVariable::get(Context, Scope, "stother", File, 8, Type, 1447 2, Flags, 8, nullptr); 1448 auto *SIother = DIExpression::get( 1449 Context, {dwarf::DW_OP_consts, static_cast<uint64_t>(-1)}); 1450 auto *SEother = DIExpression::get(Context, {5, 6}); 1451 1452 auto *N = DIGenericSubrange::get(Context, nullptr, LV, UV, SV); 1453 1454 auto Lower = N->getLowerBound(); 1455 ASSERT_TRUE(Lower); 1456 ASSERT_TRUE(Lower.is<DIVariable *>()); 1457 EXPECT_EQ(LV, Lower.get<DIVariable *>()); 1458 1459 auto Upper = N->getUpperBound(); 1460 ASSERT_TRUE(Upper); 1461 ASSERT_TRUE(Upper.is<DIVariable *>()); 1462 EXPECT_EQ(UV, Upper.get<DIVariable *>()); 1463 1464 auto Stride = N->getStride(); 1465 ASSERT_TRUE(Stride); 1466 ASSERT_TRUE(Stride.is<DIVariable *>()); 1467 EXPECT_EQ(SV, Stride.get<DIVariable *>()); 1468 1469 EXPECT_EQ(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SV)); 1470 1471 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SVother)); 1472 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SEother)); 1473 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SIother)); 1474 } 1475 1476 TEST_F(DIGenericSubrangeTest, useDIBuilder) { 1477 DILocalScope *Scope = getSubprogram(); 1478 DIFile *File = getFile(); 1479 DIType *Type = getDerivedType(); 1480 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 1481 auto *LV = 1482 DILocalVariable::get(Context, Scope, "lb", File, 8, Type, 2, Flags, 8, nullptr); 1483 auto *UE = DIExpression::get(Context, {2, 3}); 1484 auto *SE = DIExpression::get(Context, {3, 4}); 1485 1486 auto *LVother = DILocalVariable::get(Context, Scope, "lbother", File, 8, Type, 1487 2, Flags, 8, nullptr); 1488 auto *LIother = DIExpression::get( 1489 Context, {dwarf::DW_OP_consts, static_cast<uint64_t>(-1)}); 1490 1491 Module M("M", Context); 1492 DIBuilder DIB(M); 1493 1494 auto *N = DIB.getOrCreateGenericSubrange( 1495 DIGenericSubrange::BoundType(nullptr), DIGenericSubrange::BoundType(LV), 1496 DIGenericSubrange::BoundType(UE), DIGenericSubrange::BoundType(SE)); 1497 1498 auto Lower = N->getLowerBound(); 1499 ASSERT_TRUE(Lower); 1500 ASSERT_TRUE(Lower.is<DIVariable *>()); 1501 EXPECT_EQ(LV, Lower.get<DIVariable *>()); 1502 1503 auto Upper = N->getUpperBound(); 1504 ASSERT_TRUE(Upper); 1505 ASSERT_TRUE(Upper.is<DIExpression *>()); 1506 EXPECT_EQ(UE, Upper.get<DIExpression *>()); 1507 1508 auto Stride = N->getStride(); 1509 ASSERT_TRUE(Stride); 1510 ASSERT_TRUE(Stride.is<DIExpression *>()); 1511 EXPECT_EQ(SE, Stride.get<DIExpression *>()); 1512 1513 EXPECT_EQ( 1514 N, DIB.getOrCreateGenericSubrange(DIGenericSubrange::BoundType(nullptr), 1515 DIGenericSubrange::BoundType(LV), 1516 DIGenericSubrange::BoundType(UE), 1517 DIGenericSubrange::BoundType(SE))); 1518 1519 EXPECT_NE( 1520 N, DIB.getOrCreateGenericSubrange(DIGenericSubrange::BoundType(nullptr), 1521 DIGenericSubrange::BoundType(LVother), 1522 DIGenericSubrange::BoundType(UE), 1523 DIGenericSubrange::BoundType(SE))); 1524 EXPECT_NE( 1525 N, DIB.getOrCreateGenericSubrange(DIGenericSubrange::BoundType(nullptr), 1526 DIGenericSubrange::BoundType(LIother), 1527 DIGenericSubrange::BoundType(UE), 1528 DIGenericSubrange::BoundType(SE))); 1529 } 1530 typedef MetadataTest DIEnumeratorTest; 1531 1532 TEST_F(DIEnumeratorTest, get) { 1533 auto *N = DIEnumerator::get(Context, 7, false, "name"); 1534 EXPECT_EQ(dwarf::DW_TAG_enumerator, N->getTag()); 1535 EXPECT_EQ(7, N->getValue().getSExtValue()); 1536 EXPECT_FALSE(N->isUnsigned()); 1537 EXPECT_EQ("name", N->getName()); 1538 EXPECT_EQ(N, DIEnumerator::get(Context, 7, false, "name")); 1539 1540 EXPECT_NE(N, DIEnumerator::get(Context, 7, true, "name")); 1541 EXPECT_NE(N, DIEnumerator::get(Context, 8, false, "name")); 1542 EXPECT_NE(N, DIEnumerator::get(Context, 7, false, "nam")); 1543 1544 TempDIEnumerator Temp = N->clone(); 1545 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1546 } 1547 1548 TEST_F(DIEnumeratorTest, getWithLargeValues) { 1549 auto *N = DIEnumerator::get(Context, APInt::getMaxValue(128), false, "val"); 1550 EXPECT_EQ(128U, N->getValue().countPopulation()); 1551 EXPECT_EQ(N, 1552 DIEnumerator::get(Context, APInt::getMaxValue(128), false, "val")); 1553 EXPECT_NE(N, 1554 DIEnumerator::get(Context, APInt::getMinValue(128), false, "val")); 1555 } 1556 1557 typedef MetadataTest DIBasicTypeTest; 1558 1559 TEST_F(DIBasicTypeTest, get) { 1560 auto *N = 1561 DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 26, 7, 1562 DINode::FlagZero); 1563 EXPECT_EQ(dwarf::DW_TAG_base_type, N->getTag()); 1564 EXPECT_EQ("special", N->getName()); 1565 EXPECT_EQ(33u, N->getSizeInBits()); 1566 EXPECT_EQ(26u, N->getAlignInBits()); 1567 EXPECT_EQ(7u, N->getEncoding()); 1568 EXPECT_EQ(0u, N->getLine()); 1569 EXPECT_EQ(DINode::FlagZero, N->getFlags()); 1570 EXPECT_EQ(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1571 26, 7, DINode::FlagZero)); 1572 1573 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, 1574 "special", 33, 26, 7, DINode::FlagZero)); 1575 EXPECT_NE(N, 1576 DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 7, 1577 DINode::FlagZero)); 1578 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 32, 1579 26, 7, DINode::FlagZero)); 1580 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1581 25, 7, DINode::FlagZero)); 1582 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1583 26, 6, DINode::FlagZero)); 1584 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1585 26, 7, DINode::FlagBigEndian)); 1586 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 1587 26, 7, DINode::FlagLittleEndian)); 1588 1589 TempDIBasicType Temp = N->clone(); 1590 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1591 } 1592 1593 TEST_F(DIBasicTypeTest, getWithLargeValues) { 1594 auto *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 1595 UINT64_MAX, UINT32_MAX - 1, 7, DINode::FlagZero); 1596 EXPECT_EQ(UINT64_MAX, N->getSizeInBits()); 1597 EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits()); 1598 } 1599 1600 TEST_F(DIBasicTypeTest, getUnspecified) { 1601 auto *N = 1602 DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, "unspecified"); 1603 EXPECT_EQ(dwarf::DW_TAG_unspecified_type, N->getTag()); 1604 EXPECT_EQ("unspecified", N->getName()); 1605 EXPECT_EQ(0u, N->getSizeInBits()); 1606 EXPECT_EQ(0u, N->getAlignInBits()); 1607 EXPECT_EQ(0u, N->getEncoding()); 1608 EXPECT_EQ(0u, N->getLine()); 1609 EXPECT_EQ(DINode::FlagZero, N->getFlags()); 1610 } 1611 1612 typedef MetadataTest DITypeTest; 1613 1614 TEST_F(DITypeTest, clone) { 1615 // Check that DIType has a specialized clone that returns TempDIType. 1616 DIType *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "int", 32, 32, 1617 dwarf::DW_ATE_signed, DINode::FlagZero); 1618 1619 TempDIType Temp = N->clone(); 1620 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1621 } 1622 1623 TEST_F(DITypeTest, cloneWithFlags) { 1624 // void (void) 1625 Metadata *TypesOps[] = {nullptr}; 1626 Metadata *Types = MDTuple::get(Context, TypesOps); 1627 1628 DIType *D = 1629 DISubroutineType::getDistinct(Context, DINode::FlagZero, 0, Types); 1630 EXPECT_EQ(DINode::FlagZero, D->getFlags()); 1631 TempDIType D2 = D->cloneWithFlags(DINode::FlagRValueReference); 1632 EXPECT_EQ(DINode::FlagRValueReference, D2->getFlags()); 1633 EXPECT_EQ(DINode::FlagZero, D->getFlags()); 1634 1635 TempDIType T = 1636 DISubroutineType::getTemporary(Context, DINode::FlagZero, 0, Types); 1637 EXPECT_EQ(DINode::FlagZero, T->getFlags()); 1638 TempDIType T2 = T->cloneWithFlags(DINode::FlagRValueReference); 1639 EXPECT_EQ(DINode::FlagRValueReference, T2->getFlags()); 1640 EXPECT_EQ(DINode::FlagZero, T->getFlags()); 1641 } 1642 1643 typedef MetadataTest DIDerivedTypeTest; 1644 1645 TEST_F(DIDerivedTypeTest, get) { 1646 DIFile *File = getFile(); 1647 DIScope *Scope = getSubprogram(); 1648 DIType *BaseType = getBasicType("basic"); 1649 MDTuple *ExtraData = getTuple(); 1650 unsigned DWARFAddressSpace = 8; 1651 DINode::DIFlags Flags5 = static_cast<DINode::DIFlags>(5); 1652 DINode::DIFlags Flags4 = static_cast<DINode::DIFlags>(4); 1653 1654 auto *N = 1655 DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1656 1, Scope, BaseType, 2, 3, 4, DWARFAddressSpace, Flags5, 1657 ExtraData); 1658 EXPECT_EQ(dwarf::DW_TAG_pointer_type, N->getTag()); 1659 EXPECT_EQ("something", N->getName()); 1660 EXPECT_EQ(File, N->getFile()); 1661 EXPECT_EQ(1u, N->getLine()); 1662 EXPECT_EQ(Scope, N->getScope()); 1663 EXPECT_EQ(BaseType, N->getBaseType()); 1664 EXPECT_EQ(2u, N->getSizeInBits()); 1665 EXPECT_EQ(3u, N->getAlignInBits()); 1666 EXPECT_EQ(4u, N->getOffsetInBits()); 1667 EXPECT_EQ(DWARFAddressSpace, N->getDWARFAddressSpace().getValue()); 1668 EXPECT_EQ(5u, N->getFlags()); 1669 EXPECT_EQ(ExtraData, N->getExtraData()); 1670 EXPECT_EQ(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1671 "something", File, 1, Scope, BaseType, 2, 3, 1672 4, DWARFAddressSpace, Flags5, ExtraData)); 1673 1674 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_reference_type, 1675 "something", File, 1, Scope, BaseType, 2, 3, 1676 4, DWARFAddressSpace, Flags5, ExtraData)); 1677 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "else", 1678 File, 1, Scope, BaseType, 2, 3, 1679 4, DWARFAddressSpace, Flags5, ExtraData)); 1680 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1681 "something", getFile(), 1, Scope, BaseType, 2, 1682 3, 4, DWARFAddressSpace, Flags5, ExtraData)); 1683 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1684 "something", File, 2, Scope, BaseType, 2, 3, 1685 4, DWARFAddressSpace, Flags5, ExtraData)); 1686 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1687 "something", File, 1, getSubprogram(), 1688 BaseType, 2, 3, 4, DWARFAddressSpace, Flags5, 1689 ExtraData)); 1690 EXPECT_NE(N, DIDerivedType::get( 1691 Context, dwarf::DW_TAG_pointer_type, "something", File, 1, 1692 Scope, getBasicType("basic2"), 2, 3, 4, DWARFAddressSpace, 1693 Flags5, ExtraData)); 1694 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1695 "something", File, 1, Scope, BaseType, 3, 3, 1696 4, DWARFAddressSpace, Flags5, ExtraData)); 1697 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1698 "something", File, 1, Scope, BaseType, 2, 2, 1699 4, DWARFAddressSpace, Flags5, ExtraData)); 1700 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1701 "something", File, 1, Scope, BaseType, 2, 3, 1702 5, DWARFAddressSpace, Flags5, ExtraData)); 1703 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1704 "something", File, 1, Scope, BaseType, 2, 3, 1705 4, DWARFAddressSpace + 1, Flags5, ExtraData)); 1706 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1707 "something", File, 1, Scope, BaseType, 2, 3, 1708 4, DWARFAddressSpace, Flags4, ExtraData)); 1709 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, 1710 "something", File, 1, Scope, BaseType, 2, 3, 1711 4, DWARFAddressSpace, Flags5, getTuple())); 1712 1713 TempDIDerivedType Temp = N->clone(); 1714 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1715 } 1716 1717 TEST_F(DIDerivedTypeTest, getWithLargeValues) { 1718 DIFile *File = getFile(); 1719 DIScope *Scope = getSubprogram(); 1720 DIType *BaseType = getBasicType("basic"); 1721 MDTuple *ExtraData = getTuple(); 1722 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5); 1723 1724 auto *N = DIDerivedType::get( 1725 Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, 1726 BaseType, UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, 1727 Flags, ExtraData); 1728 EXPECT_EQ(UINT64_MAX, N->getSizeInBits()); 1729 EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits()); 1730 EXPECT_EQ(UINT64_MAX - 2, N->getOffsetInBits()); 1731 EXPECT_EQ(UINT32_MAX - 3, N->getDWARFAddressSpace().getValue()); 1732 } 1733 1734 typedef MetadataTest DICompositeTypeTest; 1735 1736 TEST_F(DICompositeTypeTest, get) { 1737 unsigned Tag = dwarf::DW_TAG_structure_type; 1738 StringRef Name = "some name"; 1739 DIFile *File = getFile(); 1740 unsigned Line = 1; 1741 DIScope *Scope = getSubprogram(); 1742 DIType *BaseType = getCompositeType(); 1743 uint64_t SizeInBits = 2; 1744 uint32_t AlignInBits = 3; 1745 uint64_t OffsetInBits = 4; 1746 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5); 1747 MDTuple *Elements = getTuple(); 1748 unsigned RuntimeLang = 6; 1749 DIType *VTableHolder = getCompositeType(); 1750 MDTuple *TemplateParams = getTuple(); 1751 StringRef Identifier = "some id"; 1752 1753 auto *N = DICompositeType::get(Context, Tag, Name, File, Line, Scope, 1754 BaseType, SizeInBits, AlignInBits, 1755 OffsetInBits, Flags, Elements, RuntimeLang, 1756 VTableHolder, TemplateParams, Identifier); 1757 EXPECT_EQ(Tag, N->getTag()); 1758 EXPECT_EQ(Name, N->getName()); 1759 EXPECT_EQ(File, N->getFile()); 1760 EXPECT_EQ(Line, N->getLine()); 1761 EXPECT_EQ(Scope, N->getScope()); 1762 EXPECT_EQ(BaseType, N->getBaseType()); 1763 EXPECT_EQ(SizeInBits, N->getSizeInBits()); 1764 EXPECT_EQ(AlignInBits, N->getAlignInBits()); 1765 EXPECT_EQ(OffsetInBits, N->getOffsetInBits()); 1766 EXPECT_EQ(Flags, N->getFlags()); 1767 EXPECT_EQ(Elements, N->getElements().get()); 1768 EXPECT_EQ(RuntimeLang, N->getRuntimeLang()); 1769 EXPECT_EQ(VTableHolder, N->getVTableHolder()); 1770 EXPECT_EQ(TemplateParams, N->getTemplateParams().get()); 1771 EXPECT_EQ(Identifier, N->getIdentifier()); 1772 1773 EXPECT_EQ(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, 1774 BaseType, SizeInBits, AlignInBits, 1775 OffsetInBits, Flags, Elements, RuntimeLang, 1776 VTableHolder, TemplateParams, Identifier)); 1777 1778 EXPECT_NE(N, DICompositeType::get(Context, Tag + 1, Name, File, Line, Scope, 1779 BaseType, SizeInBits, AlignInBits, 1780 OffsetInBits, Flags, Elements, RuntimeLang, 1781 VTableHolder, TemplateParams, Identifier)); 1782 EXPECT_NE(N, DICompositeType::get(Context, Tag, "abc", File, Line, Scope, 1783 BaseType, SizeInBits, AlignInBits, 1784 OffsetInBits, Flags, Elements, RuntimeLang, 1785 VTableHolder, TemplateParams, Identifier)); 1786 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, getFile(), Line, Scope, 1787 BaseType, SizeInBits, AlignInBits, 1788 OffsetInBits, Flags, Elements, RuntimeLang, 1789 VTableHolder, TemplateParams, Identifier)); 1790 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line + 1, Scope, 1791 BaseType, SizeInBits, AlignInBits, 1792 OffsetInBits, Flags, Elements, RuntimeLang, 1793 VTableHolder, TemplateParams, Identifier)); 1794 EXPECT_NE(N, DICompositeType::get( 1795 Context, Tag, Name, File, Line, getSubprogram(), BaseType, 1796 SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, 1797 RuntimeLang, VTableHolder, TemplateParams, Identifier)); 1798 EXPECT_NE(N, DICompositeType::get( 1799 Context, Tag, Name, File, Line, Scope, getBasicType("other"), 1800 SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, 1801 RuntimeLang, VTableHolder, TemplateParams, Identifier)); 1802 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, 1803 BaseType, SizeInBits + 1, AlignInBits, 1804 OffsetInBits, Flags, Elements, RuntimeLang, 1805 VTableHolder, TemplateParams, Identifier)); 1806 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, 1807 BaseType, SizeInBits, AlignInBits + 1, 1808 OffsetInBits, Flags, Elements, RuntimeLang, 1809 VTableHolder, TemplateParams, Identifier)); 1810 EXPECT_NE(N, DICompositeType::get( 1811 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 1812 AlignInBits, OffsetInBits + 1, Flags, Elements, RuntimeLang, 1813 VTableHolder, TemplateParams, Identifier)); 1814 DINode::DIFlags FlagsPOne = static_cast<DINode::DIFlags>(Flags + 1); 1815 EXPECT_NE(N, DICompositeType::get( 1816 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 1817 AlignInBits, OffsetInBits, FlagsPOne, Elements, RuntimeLang, 1818 VTableHolder, TemplateParams, Identifier)); 1819 EXPECT_NE(N, DICompositeType::get( 1820 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 1821 AlignInBits, OffsetInBits, Flags, getTuple(), RuntimeLang, 1822 VTableHolder, TemplateParams, Identifier)); 1823 EXPECT_NE(N, DICompositeType::get( 1824 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 1825 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang + 1, 1826 VTableHolder, TemplateParams, Identifier)); 1827 EXPECT_NE(N, DICompositeType::get( 1828 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, 1829 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, 1830 getCompositeType(), TemplateParams, Identifier)); 1831 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, 1832 BaseType, SizeInBits, AlignInBits, 1833 OffsetInBits, Flags, Elements, RuntimeLang, 1834 VTableHolder, getTuple(), Identifier)); 1835 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, 1836 BaseType, SizeInBits, AlignInBits, 1837 OffsetInBits, Flags, Elements, RuntimeLang, 1838 VTableHolder, TemplateParams, "other")); 1839 1840 // Be sure that missing identifiers get null pointers. 1841 EXPECT_FALSE(DICompositeType::get(Context, Tag, Name, File, Line, Scope, 1842 BaseType, SizeInBits, AlignInBits, 1843 OffsetInBits, Flags, Elements, RuntimeLang, 1844 VTableHolder, TemplateParams, "") 1845 ->getRawIdentifier()); 1846 EXPECT_FALSE(DICompositeType::get(Context, Tag, Name, File, Line, Scope, 1847 BaseType, SizeInBits, AlignInBits, 1848 OffsetInBits, Flags, Elements, RuntimeLang, 1849 VTableHolder, TemplateParams) 1850 ->getRawIdentifier()); 1851 1852 TempDICompositeType Temp = N->clone(); 1853 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 1854 } 1855 1856 TEST_F(DICompositeTypeTest, getWithLargeValues) { 1857 unsigned Tag = dwarf::DW_TAG_structure_type; 1858 StringRef Name = "some name"; 1859 DIFile *File = getFile(); 1860 unsigned Line = 1; 1861 DIScope *Scope = getSubprogram(); 1862 DIType *BaseType = getCompositeType(); 1863 uint64_t SizeInBits = UINT64_MAX; 1864 uint32_t AlignInBits = UINT32_MAX - 1; 1865 uint64_t OffsetInBits = UINT64_MAX - 2; 1866 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5); 1867 MDTuple *Elements = getTuple(); 1868 unsigned RuntimeLang = 6; 1869 DIType *VTableHolder = getCompositeType(); 1870 MDTuple *TemplateParams = getTuple(); 1871 StringRef Identifier = "some id"; 1872 1873 auto *N = DICompositeType::get(Context, Tag, Name, File, Line, Scope, 1874 BaseType, SizeInBits, AlignInBits, 1875 OffsetInBits, Flags, Elements, RuntimeLang, 1876 VTableHolder, TemplateParams, Identifier); 1877 EXPECT_EQ(SizeInBits, N->getSizeInBits()); 1878 EXPECT_EQ(AlignInBits, N->getAlignInBits()); 1879 EXPECT_EQ(OffsetInBits, N->getOffsetInBits()); 1880 } 1881 1882 TEST_F(DICompositeTypeTest, replaceOperands) { 1883 unsigned Tag = dwarf::DW_TAG_structure_type; 1884 StringRef Name = "some name"; 1885 DIFile *File = getFile(); 1886 unsigned Line = 1; 1887 DIScope *Scope = getSubprogram(); 1888 DIType *BaseType = getCompositeType(); 1889 uint64_t SizeInBits = 2; 1890 uint32_t AlignInBits = 3; 1891 uint64_t OffsetInBits = 4; 1892 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5); 1893 unsigned RuntimeLang = 6; 1894 StringRef Identifier = "some id"; 1895 1896 auto *N = DICompositeType::get( 1897 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 1898 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier); 1899 1900 auto *Elements = MDTuple::getDistinct(Context, None); 1901 EXPECT_EQ(nullptr, N->getElements().get()); 1902 N->replaceElements(Elements); 1903 EXPECT_EQ(Elements, N->getElements().get()); 1904 N->replaceElements(nullptr); 1905 EXPECT_EQ(nullptr, N->getElements().get()); 1906 1907 DIType *VTableHolder = getCompositeType(); 1908 EXPECT_EQ(nullptr, N->getVTableHolder()); 1909 N->replaceVTableHolder(VTableHolder); 1910 EXPECT_EQ(VTableHolder, N->getVTableHolder()); 1911 // As an extension, the containing type can be anything. This is 1912 // used by Rust to associate vtables with their concrete type. 1913 DIType *BasicType = getBasicType("basic"); 1914 N->replaceVTableHolder(BasicType); 1915 EXPECT_EQ(BasicType, N->getVTableHolder()); 1916 N->replaceVTableHolder(nullptr); 1917 EXPECT_EQ(nullptr, N->getVTableHolder()); 1918 1919 auto *TemplateParams = MDTuple::getDistinct(Context, None); 1920 EXPECT_EQ(nullptr, N->getTemplateParams().get()); 1921 N->replaceTemplateParams(TemplateParams); 1922 EXPECT_EQ(TemplateParams, N->getTemplateParams().get()); 1923 N->replaceTemplateParams(nullptr); 1924 EXPECT_EQ(nullptr, N->getTemplateParams().get()); 1925 } 1926 1927 TEST_F(DICompositeTypeTest, variant_part) { 1928 unsigned Tag = dwarf::DW_TAG_variant_part; 1929 StringRef Name = "some name"; 1930 DIFile *File = getFile(); 1931 unsigned Line = 1; 1932 DIScope *Scope = getSubprogram(); 1933 DIType *BaseType = getCompositeType(); 1934 uint64_t SizeInBits = 2; 1935 uint32_t AlignInBits = 3; 1936 uint64_t OffsetInBits = 4; 1937 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5); 1938 unsigned RuntimeLang = 6; 1939 StringRef Identifier = "some id"; 1940 DIDerivedType *Discriminator = cast<DIDerivedType>(getDerivedType()); 1941 DIDerivedType *Discriminator2 = cast<DIDerivedType>(getDerivedType()); 1942 1943 EXPECT_NE(Discriminator, Discriminator2); 1944 1945 auto *N = DICompositeType::get( 1946 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 1947 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 1948 Discriminator); 1949 1950 // Test the hashing. 1951 auto *Same = DICompositeType::get( 1952 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 1953 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 1954 Discriminator); 1955 auto *Other = DICompositeType::get( 1956 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 1957 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 1958 Discriminator2); 1959 auto *NoDisc = DICompositeType::get( 1960 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 1961 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 1962 nullptr); 1963 1964 EXPECT_EQ(N, Same); 1965 EXPECT_NE(Same, Other); 1966 EXPECT_NE(Same, NoDisc); 1967 EXPECT_NE(Other, NoDisc); 1968 1969 EXPECT_EQ(N->getDiscriminator(), Discriminator); 1970 } 1971 1972 TEST_F(DICompositeTypeTest, dynamicArray) { 1973 unsigned Tag = dwarf::DW_TAG_array_type; 1974 StringRef Name = "some name"; 1975 DIFile *File = getFile(); 1976 unsigned Line = 1; 1977 DILocalScope *Scope = getSubprogram(); 1978 DIType *BaseType = getCompositeType(); 1979 uint64_t SizeInBits = 32; 1980 uint32_t AlignInBits = 32; 1981 uint64_t OffsetInBits = 4; 1982 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(3); 1983 unsigned RuntimeLang = 6; 1984 StringRef Identifier = "some id"; 1985 DIType *Type = getDerivedType(); 1986 Metadata *DlVar1 = DILocalVariable::get(Context, Scope, "dl_var1", File, 8, 1987 Type, 2, Flags, 8, nullptr); 1988 Metadata *DlVar2 = DILocalVariable::get(Context, Scope, "dl_var2", File, 8, 1989 Type, 2, Flags, 8, nullptr); 1990 uint64_t Elements1[] = {dwarf::DW_OP_push_object_address, dwarf::DW_OP_deref}; 1991 Metadata *DataLocation1 = DIExpression::get(Context, Elements1); 1992 1993 uint64_t Elements2[] = {dwarf::DW_OP_constu, 0}; 1994 Metadata *DataLocation2 = DIExpression::get(Context, Elements2); 1995 1996 uint64_t Elements3[] = {dwarf::DW_OP_constu, 3}; 1997 Metadata *Rank1 = DIExpression::get(Context, Elements3); 1998 1999 uint64_t Elements4[] = {dwarf::DW_OP_constu, 4}; 2000 Metadata *Rank2 = DIExpression::get(Context, Elements4); 2001 2002 ConstantInt *RankInt1 = ConstantInt::get(Context, APInt(7, 0)); 2003 ConstantAsMetadata *RankConst1 = ConstantAsMetadata::get(RankInt1); 2004 ConstantInt *RankInt2 = ConstantInt::get(Context, APInt(6, 0)); 2005 ConstantAsMetadata *RankConst2 = ConstantAsMetadata::get(RankInt2); 2006 auto *N1 = DICompositeType::get( 2007 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2008 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2009 nullptr, DlVar1); 2010 2011 auto *Same1 = DICompositeType::get( 2012 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2013 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2014 nullptr, DlVar1); 2015 2016 auto *Other1 = DICompositeType::get( 2017 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2018 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2019 nullptr, DlVar2); 2020 2021 EXPECT_EQ(N1, Same1); 2022 EXPECT_NE(Same1, Other1); 2023 EXPECT_EQ(N1->getDataLocation(), DlVar1); 2024 2025 auto *N2 = DICompositeType::get( 2026 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2027 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2028 nullptr, DataLocation1); 2029 2030 auto *Same2 = DICompositeType::get( 2031 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2032 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2033 nullptr, DataLocation1); 2034 2035 auto *Other2 = DICompositeType::get( 2036 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2037 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2038 nullptr, DataLocation2); 2039 2040 EXPECT_EQ(N2, Same2); 2041 EXPECT_NE(Same2, Other2); 2042 EXPECT_EQ(N2->getDataLocationExp(), DataLocation1); 2043 2044 auto *N3 = DICompositeType::get( 2045 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2046 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2047 nullptr, DataLocation1, nullptr, nullptr, Rank1); 2048 2049 auto *Same3 = DICompositeType::get( 2050 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2051 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2052 nullptr, DataLocation1, nullptr, nullptr, Rank1); 2053 2054 auto *Other3 = DICompositeType::get( 2055 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2056 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2057 nullptr, DataLocation1, nullptr, nullptr, Rank2); 2058 2059 EXPECT_EQ(N3, Same3); 2060 EXPECT_NE(Same3, Other3); 2061 EXPECT_EQ(N3->getRankExp(), Rank1); 2062 2063 auto *N4 = DICompositeType::get( 2064 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2065 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2066 nullptr, DataLocation1, nullptr, nullptr, RankConst1); 2067 2068 auto *Same4 = DICompositeType::get( 2069 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2070 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2071 nullptr, DataLocation1, nullptr, nullptr, RankConst1); 2072 2073 auto *Other4 = DICompositeType::get( 2074 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, 2075 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, 2076 nullptr, DataLocation1, nullptr, nullptr, RankConst2); 2077 2078 EXPECT_EQ(N4, Same4); 2079 EXPECT_NE(Same4, Other4); 2080 EXPECT_EQ(N4->getRankConst(), RankInt1); 2081 } 2082 2083 typedef MetadataTest DISubroutineTypeTest; 2084 2085 TEST_F(DISubroutineTypeTest, get) { 2086 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(1); 2087 DINode::DIFlags FlagsPOne = static_cast<DINode::DIFlags>(Flags + 1); 2088 MDTuple *TypeArray = getTuple(); 2089 2090 auto *N = DISubroutineType::get(Context, Flags, 0, TypeArray); 2091 EXPECT_EQ(dwarf::DW_TAG_subroutine_type, N->getTag()); 2092 EXPECT_EQ(Flags, N->getFlags()); 2093 EXPECT_EQ(TypeArray, N->getTypeArray().get()); 2094 EXPECT_EQ(N, DISubroutineType::get(Context, Flags, 0, TypeArray)); 2095 2096 EXPECT_NE(N, DISubroutineType::get(Context, FlagsPOne, 0, TypeArray)); 2097 EXPECT_NE(N, DISubroutineType::get(Context, Flags, 0, getTuple())); 2098 2099 // Test the hashing of calling conventions. 2100 auto *Fast = DISubroutineType::get( 2101 Context, Flags, dwarf::DW_CC_BORLAND_msfastcall, TypeArray); 2102 auto *Std = DISubroutineType::get(Context, Flags, 2103 dwarf::DW_CC_BORLAND_stdcall, TypeArray); 2104 EXPECT_EQ(Fast, 2105 DISubroutineType::get(Context, Flags, 2106 dwarf::DW_CC_BORLAND_msfastcall, TypeArray)); 2107 EXPECT_EQ(Std, DISubroutineType::get( 2108 Context, Flags, dwarf::DW_CC_BORLAND_stdcall, TypeArray)); 2109 2110 EXPECT_NE(N, Fast); 2111 EXPECT_NE(N, Std); 2112 EXPECT_NE(Fast, Std); 2113 2114 TempDISubroutineType Temp = N->clone(); 2115 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2116 2117 // Test always-empty operands. 2118 EXPECT_EQ(nullptr, N->getScope()); 2119 EXPECT_EQ(nullptr, N->getFile()); 2120 EXPECT_EQ("", N->getName()); 2121 } 2122 2123 typedef MetadataTest DIFileTest; 2124 2125 TEST_F(DIFileTest, get) { 2126 StringRef Filename = "file"; 2127 StringRef Directory = "dir"; 2128 DIFile::ChecksumKind CSKind = DIFile::ChecksumKind::CSK_MD5; 2129 StringRef ChecksumString = "000102030405060708090a0b0c0d0e0f"; 2130 DIFile::ChecksumInfo<StringRef> Checksum(CSKind, ChecksumString); 2131 StringRef Source = "source"; 2132 auto *N = DIFile::get(Context, Filename, Directory, Checksum, Source); 2133 2134 EXPECT_EQ(dwarf::DW_TAG_file_type, N->getTag()); 2135 EXPECT_EQ(Filename, N->getFilename()); 2136 EXPECT_EQ(Directory, N->getDirectory()); 2137 EXPECT_EQ(Checksum, N->getChecksum()); 2138 EXPECT_EQ(Source, N->getSource()); 2139 EXPECT_EQ(N, DIFile::get(Context, Filename, Directory, Checksum, Source)); 2140 2141 EXPECT_NE(N, DIFile::get(Context, "other", Directory, Checksum, Source)); 2142 EXPECT_NE(N, DIFile::get(Context, Filename, "other", Checksum, Source)); 2143 DIFile::ChecksumInfo<StringRef> OtherChecksum(DIFile::ChecksumKind::CSK_SHA1, ChecksumString); 2144 EXPECT_NE( 2145 N, DIFile::get(Context, Filename, Directory, OtherChecksum)); 2146 StringRef OtherSource = "other"; 2147 EXPECT_NE(N, DIFile::get(Context, Filename, Directory, Checksum, OtherSource)); 2148 EXPECT_NE(N, DIFile::get(Context, Filename, Directory, Checksum)); 2149 EXPECT_NE(N, DIFile::get(Context, Filename, Directory)); 2150 2151 TempDIFile Temp = N->clone(); 2152 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2153 } 2154 2155 TEST_F(DIFileTest, ScopeGetFile) { 2156 // Ensure that DIScope::getFile() returns itself. 2157 DIScope *N = DIFile::get(Context, "file", "dir"); 2158 EXPECT_EQ(N, N->getFile()); 2159 } 2160 2161 typedef MetadataTest DICompileUnitTest; 2162 2163 TEST_F(DICompileUnitTest, get) { 2164 unsigned SourceLanguage = 1; 2165 DIFile *File = getFile(); 2166 StringRef Producer = "some producer"; 2167 bool IsOptimized = false; 2168 StringRef Flags = "flag after flag"; 2169 unsigned RuntimeVersion = 2; 2170 StringRef SplitDebugFilename = "another/file"; 2171 auto EmissionKind = DICompileUnit::FullDebug; 2172 MDTuple *EnumTypes = getTuple(); 2173 MDTuple *RetainedTypes = getTuple(); 2174 MDTuple *GlobalVariables = getTuple(); 2175 MDTuple *ImportedEntities = getTuple(); 2176 uint64_t DWOId = 0x10000000c0ffee; 2177 MDTuple *Macros = getTuple(); 2178 StringRef SysRoot = "/"; 2179 StringRef SDK = "MacOSX.sdk"; 2180 auto *N = DICompileUnit::getDistinct( 2181 Context, SourceLanguage, File, Producer, IsOptimized, Flags, 2182 RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, 2183 RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, true, 2184 false, DICompileUnit::DebugNameTableKind::Default, false, SysRoot, SDK); 2185 2186 EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag()); 2187 EXPECT_EQ(SourceLanguage, N->getSourceLanguage()); 2188 EXPECT_EQ(File, N->getFile()); 2189 EXPECT_EQ(Producer, N->getProducer()); 2190 EXPECT_EQ(IsOptimized, N->isOptimized()); 2191 EXPECT_EQ(Flags, N->getFlags()); 2192 EXPECT_EQ(RuntimeVersion, N->getRuntimeVersion()); 2193 EXPECT_EQ(SplitDebugFilename, N->getSplitDebugFilename()); 2194 EXPECT_EQ(EmissionKind, N->getEmissionKind()); 2195 EXPECT_EQ(EnumTypes, N->getEnumTypes().get()); 2196 EXPECT_EQ(RetainedTypes, N->getRetainedTypes().get()); 2197 EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get()); 2198 EXPECT_EQ(ImportedEntities, N->getImportedEntities().get()); 2199 EXPECT_EQ(Macros, N->getMacros().get()); 2200 EXPECT_EQ(DWOId, N->getDWOId()); 2201 EXPECT_EQ(SysRoot, N->getSysRoot()); 2202 EXPECT_EQ(SDK, N->getSDK()); 2203 2204 TempDICompileUnit Temp = N->clone(); 2205 EXPECT_EQ(dwarf::DW_TAG_compile_unit, Temp->getTag()); 2206 EXPECT_EQ(SourceLanguage, Temp->getSourceLanguage()); 2207 EXPECT_EQ(File, Temp->getFile()); 2208 EXPECT_EQ(Producer, Temp->getProducer()); 2209 EXPECT_EQ(IsOptimized, Temp->isOptimized()); 2210 EXPECT_EQ(Flags, Temp->getFlags()); 2211 EXPECT_EQ(RuntimeVersion, Temp->getRuntimeVersion()); 2212 EXPECT_EQ(SplitDebugFilename, Temp->getSplitDebugFilename()); 2213 EXPECT_EQ(EmissionKind, Temp->getEmissionKind()); 2214 EXPECT_EQ(EnumTypes, Temp->getEnumTypes().get()); 2215 EXPECT_EQ(RetainedTypes, Temp->getRetainedTypes().get()); 2216 EXPECT_EQ(GlobalVariables, Temp->getGlobalVariables().get()); 2217 EXPECT_EQ(ImportedEntities, Temp->getImportedEntities().get()); 2218 EXPECT_EQ(Macros, Temp->getMacros().get()); 2219 EXPECT_EQ(SysRoot, Temp->getSysRoot()); 2220 EXPECT_EQ(SDK, Temp->getSDK()); 2221 2222 auto *TempAddress = Temp.get(); 2223 auto *Clone = MDNode::replaceWithPermanent(std::move(Temp)); 2224 EXPECT_TRUE(Clone->isDistinct()); 2225 EXPECT_EQ(TempAddress, Clone); 2226 } 2227 2228 TEST_F(DICompileUnitTest, replaceArrays) { 2229 unsigned SourceLanguage = 1; 2230 DIFile *File = getFile(); 2231 StringRef Producer = "some producer"; 2232 bool IsOptimized = false; 2233 StringRef Flags = "flag after flag"; 2234 unsigned RuntimeVersion = 2; 2235 StringRef SplitDebugFilename = "another/file"; 2236 auto EmissionKind = DICompileUnit::FullDebug; 2237 MDTuple *EnumTypes = MDTuple::getDistinct(Context, None); 2238 MDTuple *RetainedTypes = MDTuple::getDistinct(Context, None); 2239 MDTuple *ImportedEntities = MDTuple::getDistinct(Context, None); 2240 uint64_t DWOId = 0xc0ffee; 2241 StringRef SysRoot = "/"; 2242 StringRef SDK = "MacOSX.sdk"; 2243 auto *N = DICompileUnit::getDistinct( 2244 Context, SourceLanguage, File, Producer, IsOptimized, Flags, 2245 RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, 2246 RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId, true, false, 2247 DICompileUnit::DebugNameTableKind::Default, false, SysRoot, SDK); 2248 2249 auto *GlobalVariables = MDTuple::getDistinct(Context, None); 2250 EXPECT_EQ(nullptr, N->getGlobalVariables().get()); 2251 N->replaceGlobalVariables(GlobalVariables); 2252 EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get()); 2253 N->replaceGlobalVariables(nullptr); 2254 EXPECT_EQ(nullptr, N->getGlobalVariables().get()); 2255 2256 auto *Macros = MDTuple::getDistinct(Context, None); 2257 EXPECT_EQ(nullptr, N->getMacros().get()); 2258 N->replaceMacros(Macros); 2259 EXPECT_EQ(Macros, N->getMacros().get()); 2260 N->replaceMacros(nullptr); 2261 EXPECT_EQ(nullptr, N->getMacros().get()); 2262 } 2263 2264 typedef MetadataTest DISubprogramTest; 2265 2266 TEST_F(DISubprogramTest, get) { 2267 DIScope *Scope = getCompositeType(); 2268 StringRef Name = "name"; 2269 StringRef LinkageName = "linkage"; 2270 DIFile *File = getFile(); 2271 unsigned Line = 2; 2272 DISubroutineType *Type = getSubroutineType(); 2273 bool IsLocalToUnit = false; 2274 bool IsDefinition = true; 2275 unsigned ScopeLine = 3; 2276 DIType *ContainingType = getCompositeType(); 2277 unsigned Virtuality = 2; 2278 unsigned VirtualIndex = 5; 2279 int ThisAdjustment = -3; 2280 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(6); 2281 bool IsOptimized = false; 2282 MDTuple *TemplateParams = getTuple(); 2283 DISubprogram *Declaration = getSubprogram(); 2284 MDTuple *RetainedNodes = getTuple(); 2285 MDTuple *ThrownTypes = getTuple(); 2286 MDTuple *Annotations = getTuple(); 2287 StringRef TargetFuncName = "target"; 2288 DICompileUnit *Unit = getUnit(); 2289 DISubprogram::DISPFlags SPFlags = 2290 static_cast<DISubprogram::DISPFlags>(Virtuality); 2291 assert(!IsLocalToUnit && IsDefinition && !IsOptimized && 2292 "bools and SPFlags have to match"); 2293 SPFlags |= DISubprogram::SPFlagDefinition; 2294 2295 auto *N = DISubprogram::get( 2296 Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, 2297 ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, 2298 TemplateParams, Declaration, RetainedNodes, ThrownTypes, Annotations, 2299 TargetFuncName); 2300 2301 EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag()); 2302 EXPECT_EQ(Scope, N->getScope()); 2303 EXPECT_EQ(Name, N->getName()); 2304 EXPECT_EQ(LinkageName, N->getLinkageName()); 2305 EXPECT_EQ(File, N->getFile()); 2306 EXPECT_EQ(Line, N->getLine()); 2307 EXPECT_EQ(Type, N->getType()); 2308 EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit()); 2309 EXPECT_EQ(IsDefinition, N->isDefinition()); 2310 EXPECT_EQ(ScopeLine, N->getScopeLine()); 2311 EXPECT_EQ(ContainingType, N->getContainingType()); 2312 EXPECT_EQ(Virtuality, N->getVirtuality()); 2313 EXPECT_EQ(VirtualIndex, N->getVirtualIndex()); 2314 EXPECT_EQ(ThisAdjustment, N->getThisAdjustment()); 2315 EXPECT_EQ(Flags, N->getFlags()); 2316 EXPECT_EQ(IsOptimized, N->isOptimized()); 2317 EXPECT_EQ(Unit, N->getUnit()); 2318 EXPECT_EQ(TemplateParams, N->getTemplateParams().get()); 2319 EXPECT_EQ(Declaration, N->getDeclaration()); 2320 EXPECT_EQ(RetainedNodes, N->getRetainedNodes().get()); 2321 EXPECT_EQ(ThrownTypes, N->getThrownTypes().get()); 2322 EXPECT_EQ(Annotations, N->getAnnotations().get()); 2323 EXPECT_EQ(TargetFuncName, N->getTargetFuncName()); 2324 EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2325 Type, ScopeLine, ContainingType, VirtualIndex, 2326 ThisAdjustment, Flags, SPFlags, Unit, 2327 TemplateParams, Declaration, RetainedNodes, 2328 ThrownTypes, Annotations, TargetFuncName)); 2329 2330 EXPECT_NE(N, DISubprogram::get(Context, getCompositeType(), Name, LinkageName, 2331 File, Line, Type, ScopeLine, ContainingType, 2332 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2333 Unit, TemplateParams, Declaration, 2334 RetainedNodes, ThrownTypes, Annotations, 2335 TargetFuncName)); 2336 EXPECT_NE(N, DISubprogram::get(Context, Scope, "other", LinkageName, File, 2337 Line, Type, ScopeLine, ContainingType, 2338 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2339 Unit, TemplateParams, Declaration, 2340 RetainedNodes, ThrownTypes, Annotations, 2341 TargetFuncName)); 2342 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line, 2343 Type, ScopeLine, ContainingType, VirtualIndex, 2344 ThisAdjustment, Flags, SPFlags, Unit, 2345 TemplateParams, Declaration, RetainedNodes, 2346 ThrownTypes, Annotations, TargetFuncName)); 2347 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, getFile(), 2348 Line, Type, ScopeLine, ContainingType, 2349 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2350 Unit, TemplateParams, Declaration, 2351 RetainedNodes, ThrownTypes, Annotations, 2352 TargetFuncName)); 2353 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, 2354 Line + 1, Type, ScopeLine, ContainingType, 2355 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2356 Unit, TemplateParams, Declaration, 2357 RetainedNodes, ThrownTypes, Annotations, 2358 TargetFuncName)); 2359 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2360 getSubroutineType(), ScopeLine, ContainingType, 2361 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2362 Unit, TemplateParams, Declaration, 2363 RetainedNodes, ThrownTypes, Annotations, 2364 TargetFuncName)); 2365 EXPECT_NE(N, DISubprogram::get( 2366 Context, Scope, Name, LinkageName, File, Line, Type, 2367 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, 2368 Flags, SPFlags ^ DISubprogram::SPFlagLocalToUnit, Unit, 2369 TemplateParams, Declaration, RetainedNodes, ThrownTypes, 2370 Annotations, TargetFuncName)); 2371 EXPECT_NE(N, DISubprogram::get( 2372 Context, Scope, Name, LinkageName, File, Line, Type, 2373 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, 2374 Flags, SPFlags ^ DISubprogram::SPFlagDefinition, Unit, 2375 TemplateParams, Declaration, RetainedNodes, ThrownTypes, 2376 Annotations, TargetFuncName)); 2377 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2378 Type, ScopeLine + 1, ContainingType, 2379 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2380 Unit, TemplateParams, Declaration, 2381 RetainedNodes, ThrownTypes, Annotations, 2382 TargetFuncName)); 2383 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2384 Type, ScopeLine, getCompositeType(), 2385 VirtualIndex, ThisAdjustment, Flags, SPFlags, 2386 Unit, TemplateParams, Declaration, 2387 RetainedNodes, ThrownTypes, Annotations, 2388 TargetFuncName)); 2389 EXPECT_NE(N, DISubprogram::get( 2390 Context, Scope, Name, LinkageName, File, Line, Type, 2391 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, 2392 Flags, SPFlags ^ DISubprogram::SPFlagVirtual, Unit, 2393 TemplateParams, Declaration, RetainedNodes, ThrownTypes, 2394 Annotations, TargetFuncName)); 2395 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2396 Type, ScopeLine, ContainingType, 2397 VirtualIndex + 1, ThisAdjustment, Flags, 2398 SPFlags, Unit, TemplateParams, Declaration, 2399 RetainedNodes, ThrownTypes, Annotations, 2400 TargetFuncName)); 2401 EXPECT_NE(N, DISubprogram::get( 2402 Context, Scope, Name, LinkageName, File, Line, Type, 2403 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, 2404 Flags, SPFlags ^ DISubprogram::SPFlagOptimized, Unit, 2405 TemplateParams, Declaration, RetainedNodes, ThrownTypes, 2406 Annotations, TargetFuncName)); 2407 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2408 Type, ScopeLine, ContainingType, VirtualIndex, 2409 ThisAdjustment, Flags, SPFlags, nullptr, 2410 TemplateParams, Declaration, RetainedNodes, 2411 ThrownTypes, Annotations, TargetFuncName)); 2412 EXPECT_NE(N, 2413 DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2414 Type, ScopeLine, ContainingType, VirtualIndex, 2415 ThisAdjustment, Flags, SPFlags, Unit, getTuple(), 2416 Declaration, RetainedNodes, ThrownTypes, 2417 Annotations, TargetFuncName)); 2418 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2419 Type, ScopeLine, ContainingType, VirtualIndex, 2420 ThisAdjustment, Flags, SPFlags, Unit, 2421 TemplateParams, getSubprogram(), RetainedNodes, 2422 ThrownTypes, Annotations, TargetFuncName)); 2423 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2424 Type, ScopeLine, ContainingType, VirtualIndex, 2425 ThisAdjustment, Flags, SPFlags, Unit, 2426 TemplateParams, Declaration, getTuple(), 2427 ThrownTypes, Annotations, TargetFuncName)); 2428 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2429 Type, ScopeLine, ContainingType, VirtualIndex, 2430 ThisAdjustment, Flags, SPFlags, Unit, 2431 TemplateParams, Declaration, RetainedNodes, 2432 getTuple(), Annotations, TargetFuncName)); 2433 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2434 Type, ScopeLine, ContainingType, VirtualIndex, 2435 ThisAdjustment, Flags, SPFlags, Unit, 2436 TemplateParams, Declaration, RetainedNodes, 2437 ThrownTypes, getTuple(), TargetFuncName)); 2438 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, 2439 Type, ScopeLine, ContainingType, VirtualIndex, 2440 ThisAdjustment, Flags, SPFlags, Unit, 2441 TemplateParams, Declaration, RetainedNodes, 2442 ThrownTypes, Annotations, "other")); 2443 2444 TempDISubprogram Temp = N->clone(); 2445 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2446 } 2447 2448 typedef MetadataTest DILexicalBlockTest; 2449 2450 TEST_F(DILexicalBlockTest, get) { 2451 DILocalScope *Scope = getSubprogram(); 2452 DIFile *File = getFile(); 2453 unsigned Line = 5; 2454 unsigned Column = 8; 2455 2456 auto *N = DILexicalBlock::get(Context, Scope, File, Line, Column); 2457 2458 EXPECT_EQ(dwarf::DW_TAG_lexical_block, N->getTag()); 2459 EXPECT_EQ(Scope, N->getScope()); 2460 EXPECT_EQ(File, N->getFile()); 2461 EXPECT_EQ(Line, N->getLine()); 2462 EXPECT_EQ(Column, N->getColumn()); 2463 EXPECT_EQ(N, DILexicalBlock::get(Context, Scope, File, Line, Column)); 2464 2465 EXPECT_NE(N, 2466 DILexicalBlock::get(Context, getSubprogram(), File, Line, Column)); 2467 EXPECT_NE(N, DILexicalBlock::get(Context, Scope, getFile(), Line, Column)); 2468 EXPECT_NE(N, DILexicalBlock::get(Context, Scope, File, Line + 1, Column)); 2469 EXPECT_NE(N, DILexicalBlock::get(Context, Scope, File, Line, Column + 1)); 2470 2471 TempDILexicalBlock Temp = N->clone(); 2472 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2473 } 2474 2475 TEST_F(DILexicalBlockTest, Overflow) { 2476 DISubprogram *SP = getSubprogram(); 2477 DIFile *F = getFile(); 2478 { 2479 auto *LB = DILexicalBlock::get(Context, SP, F, 2, 7); 2480 EXPECT_EQ(2u, LB->getLine()); 2481 EXPECT_EQ(7u, LB->getColumn()); 2482 } 2483 unsigned U16 = 1u << 16; 2484 { 2485 auto *LB = DILexicalBlock::get(Context, SP, F, UINT32_MAX, U16 - 1); 2486 EXPECT_EQ(UINT32_MAX, LB->getLine()); 2487 EXPECT_EQ(U16 - 1, LB->getColumn()); 2488 } 2489 { 2490 auto *LB = DILexicalBlock::get(Context, SP, F, UINT32_MAX, U16); 2491 EXPECT_EQ(UINT32_MAX, LB->getLine()); 2492 EXPECT_EQ(0u, LB->getColumn()); 2493 } 2494 { 2495 auto *LB = DILexicalBlock::get(Context, SP, F, UINT32_MAX, U16 + 1); 2496 EXPECT_EQ(UINT32_MAX, LB->getLine()); 2497 EXPECT_EQ(0u, LB->getColumn()); 2498 } 2499 } 2500 2501 typedef MetadataTest DILexicalBlockFileTest; 2502 2503 TEST_F(DILexicalBlockFileTest, get) { 2504 DILocalScope *Scope = getSubprogram(); 2505 DIFile *File = getFile(); 2506 unsigned Discriminator = 5; 2507 2508 auto *N = DILexicalBlockFile::get(Context, Scope, File, Discriminator); 2509 2510 EXPECT_EQ(dwarf::DW_TAG_lexical_block, N->getTag()); 2511 EXPECT_EQ(Scope, N->getScope()); 2512 EXPECT_EQ(File, N->getFile()); 2513 EXPECT_EQ(Discriminator, N->getDiscriminator()); 2514 EXPECT_EQ(N, DILexicalBlockFile::get(Context, Scope, File, Discriminator)); 2515 2516 EXPECT_NE(N, DILexicalBlockFile::get(Context, getSubprogram(), File, 2517 Discriminator)); 2518 EXPECT_NE(N, 2519 DILexicalBlockFile::get(Context, Scope, getFile(), Discriminator)); 2520 EXPECT_NE(N, 2521 DILexicalBlockFile::get(Context, Scope, File, Discriminator + 1)); 2522 2523 TempDILexicalBlockFile Temp = N->clone(); 2524 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2525 } 2526 2527 typedef MetadataTest DINamespaceTest; 2528 2529 TEST_F(DINamespaceTest, get) { 2530 DIScope *Scope = getFile(); 2531 StringRef Name = "namespace"; 2532 bool ExportSymbols = true; 2533 2534 auto *N = DINamespace::get(Context, Scope, Name, ExportSymbols); 2535 2536 EXPECT_EQ(dwarf::DW_TAG_namespace, N->getTag()); 2537 EXPECT_EQ(Scope, N->getScope()); 2538 EXPECT_EQ(Name, N->getName()); 2539 EXPECT_EQ(N, DINamespace::get(Context, Scope, Name, ExportSymbols)); 2540 EXPECT_NE(N, DINamespace::get(Context, getFile(), Name, ExportSymbols)); 2541 EXPECT_NE(N, DINamespace::get(Context, Scope, "other", ExportSymbols)); 2542 EXPECT_NE(N, DINamespace::get(Context, Scope, Name, !ExportSymbols)); 2543 2544 TempDINamespace Temp = N->clone(); 2545 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2546 } 2547 2548 typedef MetadataTest DIModuleTest; 2549 2550 TEST_F(DIModuleTest, get) { 2551 DIFile *File = getFile(); 2552 DIScope *Scope = getFile(); 2553 StringRef Name = "module"; 2554 StringRef ConfigMacro = "-DNDEBUG"; 2555 StringRef Includes = "-I."; 2556 StringRef APINotes = "/tmp/m.apinotes"; 2557 unsigned LineNo = 4; 2558 bool IsDecl = true; 2559 2560 auto *N = DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, 2561 APINotes, LineNo, IsDecl); 2562 2563 EXPECT_EQ(dwarf::DW_TAG_module, N->getTag()); 2564 EXPECT_EQ(File, N->getFile()); 2565 EXPECT_EQ(Scope, N->getScope()); 2566 EXPECT_EQ(Name, N->getName()); 2567 EXPECT_EQ(ConfigMacro, N->getConfigurationMacros()); 2568 EXPECT_EQ(Includes, N->getIncludePath()); 2569 EXPECT_EQ(APINotes, N->getAPINotesFile()); 2570 EXPECT_EQ(LineNo, N->getLineNo()); 2571 EXPECT_EQ(IsDecl, N->getIsDecl()); 2572 EXPECT_EQ(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, 2573 APINotes, LineNo, IsDecl)); 2574 EXPECT_NE(N, DIModule::get(Context, getFile(), getFile(), Name, ConfigMacro, 2575 Includes, APINotes, LineNo, IsDecl)); 2576 EXPECT_NE(N, DIModule::get(Context, File, Scope, "other", ConfigMacro, 2577 Includes, APINotes, LineNo, IsDecl)); 2578 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, "other", Includes, 2579 APINotes, LineNo, IsDecl)); 2580 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, "other", 2581 APINotes, LineNo, IsDecl)); 2582 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, 2583 "other", LineNo, IsDecl)); 2584 EXPECT_NE(N, DIModule::get(Context, getFile(), Scope, Name, ConfigMacro, 2585 Includes, APINotes, LineNo, IsDecl)); 2586 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, 2587 APINotes, 5, IsDecl)); 2588 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes, 2589 APINotes, LineNo, false)); 2590 2591 TempDIModule Temp = N->clone(); 2592 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2593 } 2594 2595 typedef MetadataTest DITemplateTypeParameterTest; 2596 2597 TEST_F(DITemplateTypeParameterTest, get) { 2598 StringRef Name = "template"; 2599 DIType *Type = getBasicType("basic"); 2600 bool defaulted = false; 2601 2602 auto *N = DITemplateTypeParameter::get(Context, Name, Type, defaulted); 2603 2604 EXPECT_EQ(dwarf::DW_TAG_template_type_parameter, N->getTag()); 2605 EXPECT_EQ(Name, N->getName()); 2606 EXPECT_EQ(Type, N->getType()); 2607 EXPECT_EQ(N, DITemplateTypeParameter::get(Context, Name, Type, defaulted)); 2608 2609 EXPECT_NE(N, DITemplateTypeParameter::get(Context, "other", Type, defaulted)); 2610 EXPECT_NE(N, DITemplateTypeParameter::get(Context, Name, 2611 getBasicType("other"), defaulted)); 2612 EXPECT_NE(N, DITemplateTypeParameter::get(Context, Name, Type, true)); 2613 2614 TempDITemplateTypeParameter Temp = N->clone(); 2615 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2616 } 2617 2618 typedef MetadataTest DITemplateValueParameterTest; 2619 2620 TEST_F(DITemplateValueParameterTest, get) { 2621 unsigned Tag = dwarf::DW_TAG_template_value_parameter; 2622 StringRef Name = "template"; 2623 DIType *Type = getBasicType("basic"); 2624 bool defaulted = false; 2625 Metadata *Value = getConstantAsMetadata(); 2626 2627 auto *N = 2628 DITemplateValueParameter::get(Context, Tag, Name, Type, defaulted, Value); 2629 EXPECT_EQ(Tag, N->getTag()); 2630 EXPECT_EQ(Name, N->getName()); 2631 EXPECT_EQ(Type, N->getType()); 2632 EXPECT_EQ(Value, N->getValue()); 2633 EXPECT_EQ(N, DITemplateValueParameter::get(Context, Tag, Name, Type, 2634 defaulted, Value)); 2635 2636 EXPECT_NE(N, DITemplateValueParameter::get( 2637 Context, dwarf::DW_TAG_GNU_template_template_param, Name, 2638 Type, defaulted, Value)); 2639 EXPECT_NE(N, DITemplateValueParameter::get(Context, Tag, "other", Type, 2640 defaulted, Value)); 2641 EXPECT_NE(N, DITemplateValueParameter::get(Context, Tag, Name, 2642 getBasicType("other"), defaulted, 2643 Value)); 2644 EXPECT_NE(N, 2645 DITemplateValueParameter::get(Context, Tag, Name, Type, defaulted, 2646 getConstantAsMetadata())); 2647 EXPECT_NE( 2648 N, DITemplateValueParameter::get(Context, Tag, Name, Type, true, Value)); 2649 2650 TempDITemplateValueParameter Temp = N->clone(); 2651 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2652 } 2653 2654 typedef MetadataTest DIGlobalVariableTest; 2655 2656 TEST_F(DIGlobalVariableTest, get) { 2657 DIScope *Scope = getSubprogram(); 2658 StringRef Name = "name"; 2659 StringRef LinkageName = "linkage"; 2660 DIFile *File = getFile(); 2661 unsigned Line = 5; 2662 DIType *Type = getDerivedType(); 2663 bool IsLocalToUnit = false; 2664 bool IsDefinition = true; 2665 MDTuple *templateParams = getTuple(); 2666 DIDerivedType *StaticDataMemberDeclaration = 2667 cast<DIDerivedType>(getDerivedType()); 2668 2669 uint32_t AlignInBits = 8; 2670 2671 auto *N = DIGlobalVariable::get( 2672 Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, 2673 IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, 2674 nullptr); 2675 2676 EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag()); 2677 EXPECT_EQ(Scope, N->getScope()); 2678 EXPECT_EQ(Name, N->getName()); 2679 EXPECT_EQ(LinkageName, N->getLinkageName()); 2680 EXPECT_EQ(File, N->getFile()); 2681 EXPECT_EQ(Line, N->getLine()); 2682 EXPECT_EQ(Type, N->getType()); 2683 EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit()); 2684 EXPECT_EQ(IsDefinition, N->isDefinition()); 2685 EXPECT_EQ(StaticDataMemberDeclaration, N->getStaticDataMemberDeclaration()); 2686 EXPECT_EQ(templateParams, N->getTemplateParams()); 2687 EXPECT_EQ(AlignInBits, N->getAlignInBits()); 2688 EXPECT_EQ(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2689 Line, Type, IsLocalToUnit, IsDefinition, 2690 StaticDataMemberDeclaration, 2691 templateParams, AlignInBits, nullptr)); 2692 2693 EXPECT_NE(N, DIGlobalVariable::get( 2694 Context, getSubprogram(), Name, LinkageName, File, Line, 2695 Type, IsLocalToUnit, IsDefinition, 2696 StaticDataMemberDeclaration, templateParams, AlignInBits, 2697 nullptr)); 2698 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, "other", LinkageName, File, 2699 Line, Type, IsLocalToUnit, IsDefinition, 2700 StaticDataMemberDeclaration, 2701 templateParams, AlignInBits, nullptr)); 2702 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, "other", File, Line, 2703 Type, IsLocalToUnit, IsDefinition, 2704 StaticDataMemberDeclaration, 2705 templateParams, AlignInBits, nullptr)); 2706 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, 2707 getFile(), Line, Type, IsLocalToUnit, 2708 IsDefinition, StaticDataMemberDeclaration, 2709 templateParams, AlignInBits, nullptr)); 2710 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2711 Line + 1, Type, IsLocalToUnit, 2712 IsDefinition, StaticDataMemberDeclaration, 2713 templateParams, AlignInBits, nullptr)); 2714 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2715 Line, getDerivedType(), IsLocalToUnit, 2716 IsDefinition, StaticDataMemberDeclaration, 2717 templateParams, AlignInBits, nullptr)); 2718 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2719 Line, Type, !IsLocalToUnit, IsDefinition, 2720 StaticDataMemberDeclaration, 2721 templateParams, AlignInBits, nullptr)); 2722 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2723 Line, Type, IsLocalToUnit, !IsDefinition, 2724 StaticDataMemberDeclaration, 2725 templateParams, AlignInBits, nullptr)); 2726 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2727 Line, Type, IsLocalToUnit, IsDefinition, 2728 cast<DIDerivedType>(getDerivedType()), 2729 templateParams, AlignInBits, nullptr)); 2730 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2731 Line, Type, IsLocalToUnit, IsDefinition, 2732 StaticDataMemberDeclaration, nullptr, 2733 AlignInBits, nullptr)); 2734 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, 2735 Line, Type, IsLocalToUnit, IsDefinition, 2736 StaticDataMemberDeclaration, 2737 templateParams, (AlignInBits << 1), 2738 nullptr)); 2739 2740 TempDIGlobalVariable Temp = N->clone(); 2741 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2742 } 2743 2744 typedef MetadataTest DIGlobalVariableExpressionTest; 2745 2746 TEST_F(DIGlobalVariableExpressionTest, get) { 2747 DIScope *Scope = getSubprogram(); 2748 StringRef Name = "name"; 2749 StringRef LinkageName = "linkage"; 2750 DIFile *File = getFile(); 2751 unsigned Line = 5; 2752 DIType *Type = getDerivedType(); 2753 bool IsLocalToUnit = false; 2754 bool IsDefinition = true; 2755 MDTuple *templateParams = getTuple(); 2756 auto *Expr = DIExpression::get(Context, {1, 2}); 2757 auto *Expr2 = DIExpression::get(Context, {1, 2, 3}); 2758 DIDerivedType *StaticDataMemberDeclaration = 2759 cast<DIDerivedType>(getDerivedType()); 2760 uint32_t AlignInBits = 8; 2761 2762 auto *Var = DIGlobalVariable::get( 2763 Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, 2764 IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, 2765 nullptr); 2766 auto *Var2 = DIGlobalVariable::get( 2767 Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, 2768 IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, 2769 nullptr); 2770 auto *N = DIGlobalVariableExpression::get(Context, Var, Expr); 2771 2772 EXPECT_EQ(Var, N->getVariable()); 2773 EXPECT_EQ(Expr, N->getExpression()); 2774 EXPECT_EQ(N, DIGlobalVariableExpression::get(Context, Var, Expr)); 2775 EXPECT_NE(N, DIGlobalVariableExpression::get(Context, Var2, Expr)); 2776 EXPECT_NE(N, DIGlobalVariableExpression::get(Context, Var, Expr2)); 2777 2778 TempDIGlobalVariableExpression Temp = N->clone(); 2779 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2780 } 2781 2782 typedef MetadataTest DILocalVariableTest; 2783 2784 TEST_F(DILocalVariableTest, get) { 2785 DILocalScope *Scope = getSubprogram(); 2786 StringRef Name = "name"; 2787 DIFile *File = getFile(); 2788 unsigned Line = 5; 2789 DIType *Type = getDerivedType(); 2790 unsigned Arg = 6; 2791 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 2792 uint32_t AlignInBits = 8; 2793 2794 auto *N = 2795 DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, Flags, 2796 AlignInBits, nullptr); 2797 EXPECT_TRUE(N->isParameter()); 2798 EXPECT_EQ(Scope, N->getScope()); 2799 EXPECT_EQ(Name, N->getName()); 2800 EXPECT_EQ(File, N->getFile()); 2801 EXPECT_EQ(Line, N->getLine()); 2802 EXPECT_EQ(Type, N->getType()); 2803 EXPECT_EQ(Arg, N->getArg()); 2804 EXPECT_EQ(Flags, N->getFlags()); 2805 EXPECT_EQ(AlignInBits, N->getAlignInBits()); 2806 EXPECT_EQ(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, 2807 Flags, AlignInBits, nullptr)); 2808 2809 EXPECT_FALSE( 2810 DILocalVariable::get(Context, Scope, Name, File, Line, Type, 0, Flags, 2811 AlignInBits, nullptr)->isParameter()); 2812 EXPECT_NE(N, DILocalVariable::get(Context, getSubprogram(), Name, File, Line, 2813 Type, Arg, Flags, AlignInBits, nullptr)); 2814 EXPECT_NE(N, DILocalVariable::get(Context, Scope, "other", File, Line, Type, 2815 Arg, Flags, AlignInBits, nullptr)); 2816 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, getFile(), Line, Type, 2817 Arg, Flags, AlignInBits, nullptr)); 2818 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line + 1, Type, 2819 Arg, Flags, AlignInBits, nullptr)); 2820 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, 2821 getDerivedType(), Arg, Flags, AlignInBits, 2822 nullptr)); 2823 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, 2824 Arg + 1, Flags, AlignInBits, nullptr)); 2825 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, 2826 Arg, Flags, (AlignInBits << 1), nullptr)); 2827 2828 TempDILocalVariable Temp = N->clone(); 2829 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2830 } 2831 2832 TEST_F(DILocalVariableTest, getArg256) { 2833 EXPECT_EQ(255u, DILocalVariable::get(Context, getSubprogram(), "", getFile(), 2834 0, nullptr, 255, DINode::FlagZero, 0, 2835 nullptr) 2836 ->getArg()); 2837 EXPECT_EQ(256u, DILocalVariable::get(Context, getSubprogram(), "", getFile(), 2838 0, nullptr, 256, DINode::FlagZero, 0, 2839 nullptr) 2840 ->getArg()); 2841 EXPECT_EQ(257u, DILocalVariable::get(Context, getSubprogram(), "", getFile(), 2842 0, nullptr, 257, DINode::FlagZero, 0, 2843 nullptr) 2844 ->getArg()); 2845 unsigned Max = UINT16_MAX; 2846 EXPECT_EQ(Max, DILocalVariable::get(Context, getSubprogram(), "", getFile(), 2847 0, nullptr, Max, DINode::FlagZero, 0, 2848 nullptr) 2849 ->getArg()); 2850 } 2851 2852 typedef MetadataTest DIExpressionTest; 2853 2854 TEST_F(DIExpressionTest, get) { 2855 uint64_t Elements[] = {2, 6, 9, 78, 0}; 2856 auto *N = DIExpression::get(Context, Elements); 2857 EXPECT_EQ(makeArrayRef(Elements), N->getElements()); 2858 EXPECT_EQ(N, DIExpression::get(Context, Elements)); 2859 2860 EXPECT_EQ(5u, N->getNumElements()); 2861 EXPECT_EQ(2u, N->getElement(0)); 2862 EXPECT_EQ(6u, N->getElement(1)); 2863 EXPECT_EQ(9u, N->getElement(2)); 2864 EXPECT_EQ(78u, N->getElement(3)); 2865 EXPECT_EQ(0u, N->getElement(4)); 2866 2867 TempDIExpression Temp = N->clone(); 2868 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 2869 2870 // Test DIExpression::prepend(). 2871 uint64_t Elts0[] = {dwarf::DW_OP_LLVM_fragment, 0, 32}; 2872 auto *N0 = DIExpression::get(Context, Elts0); 2873 uint8_t DIExprFlags = DIExpression::ApplyOffset; 2874 DIExprFlags |= DIExpression::DerefBefore; 2875 DIExprFlags |= DIExpression::DerefAfter; 2876 DIExprFlags |= DIExpression::StackValue; 2877 auto *N0WithPrependedOps = DIExpression::prepend(N0, DIExprFlags, 64); 2878 uint64_t Elts1[] = {dwarf::DW_OP_deref, 2879 dwarf::DW_OP_plus_uconst, 64, 2880 dwarf::DW_OP_deref, 2881 dwarf::DW_OP_stack_value, 2882 dwarf::DW_OP_LLVM_fragment, 0, 32}; 2883 auto *N1 = DIExpression::get(Context, Elts1); 2884 EXPECT_EQ(N0WithPrependedOps, N1); 2885 2886 // Test DIExpression::append(). 2887 uint64_t Elts2[] = {dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst, 64, 2888 dwarf::DW_OP_deref, dwarf::DW_OP_stack_value}; 2889 auto *N2 = DIExpression::append(N0, Elts2); 2890 EXPECT_EQ(N0WithPrependedOps, N2); 2891 } 2892 2893 TEST_F(DIExpressionTest, isValid) { 2894 #define EXPECT_VALID(...) \ 2895 do { \ 2896 uint64_t Elements[] = {__VA_ARGS__}; \ 2897 EXPECT_TRUE(DIExpression::get(Context, Elements)->isValid()); \ 2898 } while (false) 2899 #define EXPECT_INVALID(...) \ 2900 do { \ 2901 uint64_t Elements[] = {__VA_ARGS__}; \ 2902 EXPECT_FALSE(DIExpression::get(Context, Elements)->isValid()); \ 2903 } while (false) 2904 2905 // Empty expression should be valid. 2906 EXPECT_TRUE(DIExpression::get(Context, None)); 2907 2908 // Valid constructions. 2909 EXPECT_VALID(dwarf::DW_OP_plus_uconst, 6); 2910 EXPECT_VALID(dwarf::DW_OP_constu, 6, dwarf::DW_OP_plus); 2911 EXPECT_VALID(dwarf::DW_OP_deref); 2912 EXPECT_VALID(dwarf::DW_OP_LLVM_fragment, 3, 7); 2913 EXPECT_VALID(dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_deref); 2914 EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst, 6); 2915 EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_LLVM_fragment, 3, 7); 2916 EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst, 6, 2917 dwarf::DW_OP_LLVM_fragment, 3, 7); 2918 2919 // Invalid constructions. 2920 EXPECT_INVALID(~0u); 2921 EXPECT_INVALID(dwarf::DW_OP_plus, 0); 2922 EXPECT_INVALID(dwarf::DW_OP_plus_uconst); 2923 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment); 2924 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3); 2925 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3, 7, dwarf::DW_OP_plus_uconst, 3); 2926 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3, 7, dwarf::DW_OP_deref); 2927 2928 #undef EXPECT_VALID 2929 #undef EXPECT_INVALID 2930 } 2931 2932 TEST_F(DIExpressionTest, createFragmentExpression) { 2933 #define EXPECT_VALID_FRAGMENT(Offset, Size, ...) \ 2934 do { \ 2935 uint64_t Elements[] = {__VA_ARGS__}; \ 2936 DIExpression* Expression = DIExpression::get(Context, Elements); \ 2937 EXPECT_TRUE(DIExpression::createFragmentExpression( \ 2938 Expression, Offset, Size).hasValue()); \ 2939 } while (false) 2940 #define EXPECT_INVALID_FRAGMENT(Offset, Size, ...) \ 2941 do { \ 2942 uint64_t Elements[] = {__VA_ARGS__}; \ 2943 DIExpression* Expression = DIExpression::get(Context, Elements); \ 2944 EXPECT_FALSE(DIExpression::createFragmentExpression( \ 2945 Expression, Offset, Size).hasValue()); \ 2946 } while (false) 2947 2948 // createFragmentExpression adds correct ops. 2949 Optional<DIExpression*> R = DIExpression::createFragmentExpression( 2950 DIExpression::get(Context, {}), 0, 32); 2951 EXPECT_EQ(R.hasValue(), true); 2952 EXPECT_EQ(3u, (*R)->getNumElements()); 2953 EXPECT_EQ(dwarf::DW_OP_LLVM_fragment, (*R)->getElement(0)); 2954 EXPECT_EQ(0u, (*R)->getElement(1)); 2955 EXPECT_EQ(32u, (*R)->getElement(2)); 2956 2957 // Valid fragment expressions. 2958 EXPECT_VALID_FRAGMENT(0, 32, {}); 2959 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_deref); 2960 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_LLVM_fragment, 0, 32); 2961 EXPECT_VALID_FRAGMENT(16, 16, dwarf::DW_OP_LLVM_fragment, 0, 32); 2962 2963 // Invalid fragment expressions (incompatible ops). 2964 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 6, dwarf::DW_OP_plus); 2965 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 14, dwarf::DW_OP_minus); 2966 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 16, dwarf::DW_OP_shr); 2967 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 16, dwarf::DW_OP_shl); 2968 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 16, dwarf::DW_OP_shra); 2969 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6); 2970 2971 #undef EXPECT_VALID_FRAGMENT 2972 #undef EXPECT_INVALID_FRAGMENT 2973 } 2974 2975 TEST_F(DIExpressionTest, replaceArg) { 2976 #define EXPECT_REPLACE_ARG_EQ(Expr, OldArg, NewArg, ...) \ 2977 do { \ 2978 uint64_t Elements[] = {__VA_ARGS__}; \ 2979 ArrayRef<uint64_t> Expected = Elements; \ 2980 DIExpression *Expression = DIExpression::replaceArg(Expr, OldArg, NewArg); \ 2981 EXPECT_EQ(Expression->getElements(), Expected); \ 2982 } while (false) 2983 2984 auto N = DIExpression::get( 2985 Context, {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg, 1, 2986 dwarf::DW_OP_plus, dwarf::DW_OP_LLVM_arg, 2, dwarf::DW_OP_mul}); 2987 EXPECT_REPLACE_ARG_EQ(N, 0, 1, dwarf::DW_OP_LLVM_arg, 0, 2988 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus, 2989 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul); 2990 EXPECT_REPLACE_ARG_EQ(N, 0, 2, dwarf::DW_OP_LLVM_arg, 1, 2991 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus, 2992 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul); 2993 EXPECT_REPLACE_ARG_EQ(N, 2, 0, dwarf::DW_OP_LLVM_arg, 0, 2994 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_plus, 2995 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_mul); 2996 EXPECT_REPLACE_ARG_EQ(N, 2, 1, dwarf::DW_OP_LLVM_arg, 0, 2997 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_plus, 2998 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul); 2999 3000 #undef EXPECT_REPLACE_ARG_EQ 3001 } 3002 3003 TEST_F(DIExpressionTest, foldConstant) { 3004 const ConstantInt *Int; 3005 const ConstantInt *NewInt; 3006 DIExpression *Expr; 3007 DIExpression *NewExpr; 3008 3009 #define EXPECT_FOLD_CONST(StartWidth, StartValue, EndWidth, EndValue, NumElts) \ 3010 Int = ConstantInt::get(Context, APInt(StartWidth, StartValue)); \ 3011 std::tie(NewExpr, NewInt) = Expr->constantFold(Int); \ 3012 ASSERT_EQ(NewInt->getBitWidth(), EndWidth##u); \ 3013 EXPECT_EQ(NewInt->getValue(), APInt(EndWidth, EndValue)); \ 3014 EXPECT_EQ(NewExpr->getNumElements(), NumElts##u) 3015 3016 // Unfoldable expression should return the original unmodified Int/Expr. 3017 Expr = DIExpression::get(Context, {dwarf::DW_OP_deref}); 3018 EXPECT_FOLD_CONST(32, 117, 32, 117, 1); 3019 EXPECT_EQ(NewExpr, Expr); 3020 EXPECT_EQ(NewInt, Int); 3021 EXPECT_TRUE(NewExpr->startsWithDeref()); 3022 3023 // One unsigned bit-width conversion. 3024 Expr = DIExpression::get( 3025 Context, {dwarf::DW_OP_LLVM_convert, 72, dwarf::DW_ATE_unsigned}); 3026 EXPECT_FOLD_CONST(8, 12, 72, 12, 0); 3027 3028 // Two unsigned bit-width conversions (mask truncation). 3029 Expr = DIExpression::get( 3030 Context, {dwarf::DW_OP_LLVM_convert, 8, dwarf::DW_ATE_unsigned, 3031 dwarf::DW_OP_LLVM_convert, 16, dwarf::DW_ATE_unsigned}); 3032 EXPECT_FOLD_CONST(32, -1, 16, 0xff, 0); 3033 3034 // Sign extension. 3035 Expr = DIExpression::get( 3036 Context, {dwarf::DW_OP_LLVM_convert, 32, dwarf::DW_ATE_signed}); 3037 EXPECT_FOLD_CONST(16, -1, 32, -1, 0); 3038 3039 // Get non-foldable operations back in the new Expr. 3040 uint64_t Elements[] = {dwarf::DW_OP_deref, dwarf::DW_OP_stack_value}; 3041 ArrayRef<uint64_t> Expected = Elements; 3042 Expr = DIExpression::get( 3043 Context, {dwarf::DW_OP_LLVM_convert, 32, dwarf::DW_ATE_signed}); 3044 Expr = DIExpression::append(Expr, Expected); 3045 ASSERT_EQ(Expr->getNumElements(), 5u); 3046 EXPECT_FOLD_CONST(16, -1, 32, -1, 2); 3047 EXPECT_EQ(NewExpr->getElements(), Expected); 3048 3049 #undef EXPECT_FOLD_CONST 3050 } 3051 3052 typedef MetadataTest DIObjCPropertyTest; 3053 3054 TEST_F(DIObjCPropertyTest, get) { 3055 StringRef Name = "name"; 3056 DIFile *File = getFile(); 3057 unsigned Line = 5; 3058 StringRef GetterName = "getter"; 3059 StringRef SetterName = "setter"; 3060 unsigned Attributes = 7; 3061 DIType *Type = getBasicType("basic"); 3062 3063 auto *N = DIObjCProperty::get(Context, Name, File, Line, GetterName, 3064 SetterName, Attributes, Type); 3065 3066 EXPECT_EQ(dwarf::DW_TAG_APPLE_property, N->getTag()); 3067 EXPECT_EQ(Name, N->getName()); 3068 EXPECT_EQ(File, N->getFile()); 3069 EXPECT_EQ(Line, N->getLine()); 3070 EXPECT_EQ(GetterName, N->getGetterName()); 3071 EXPECT_EQ(SetterName, N->getSetterName()); 3072 EXPECT_EQ(Attributes, N->getAttributes()); 3073 EXPECT_EQ(Type, N->getType()); 3074 EXPECT_EQ(N, DIObjCProperty::get(Context, Name, File, Line, GetterName, 3075 SetterName, Attributes, Type)); 3076 3077 EXPECT_NE(N, DIObjCProperty::get(Context, "other", File, Line, GetterName, 3078 SetterName, Attributes, Type)); 3079 EXPECT_NE(N, DIObjCProperty::get(Context, Name, getFile(), Line, GetterName, 3080 SetterName, Attributes, Type)); 3081 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line + 1, GetterName, 3082 SetterName, Attributes, Type)); 3083 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, "other", 3084 SetterName, Attributes, Type)); 3085 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName, 3086 "other", Attributes, Type)); 3087 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName, 3088 SetterName, Attributes + 1, Type)); 3089 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName, 3090 SetterName, Attributes, 3091 getBasicType("other"))); 3092 3093 TempDIObjCProperty Temp = N->clone(); 3094 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 3095 } 3096 3097 typedef MetadataTest DIImportedEntityTest; 3098 3099 TEST_F(DIImportedEntityTest, get) { 3100 unsigned Tag = dwarf::DW_TAG_imported_module; 3101 DIScope *Scope = getSubprogram(); 3102 DINode *Entity = getCompositeType(); 3103 DIFile *File = getFile(); 3104 unsigned Line = 5; 3105 StringRef Name = "name"; 3106 3107 auto *N = 3108 DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, Name); 3109 3110 EXPECT_EQ(Tag, N->getTag()); 3111 EXPECT_EQ(Scope, N->getScope()); 3112 EXPECT_EQ(Entity, N->getEntity()); 3113 EXPECT_EQ(File, N->getFile()); 3114 EXPECT_EQ(Line, N->getLine()); 3115 EXPECT_EQ(Name, N->getName()); 3116 EXPECT_EQ( 3117 N, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, Name)); 3118 3119 EXPECT_NE(N, 3120 DIImportedEntity::get(Context, dwarf::DW_TAG_imported_declaration, 3121 Scope, Entity, File, Line, Name)); 3122 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, getSubprogram(), Entity, 3123 File, Line, Name)); 3124 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, getCompositeType(), 3125 File, Line, Name)); 3126 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, Entity, nullptr, Line, 3127 Name)); 3128 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, Entity, File, 3129 Line + 1, Name)); 3130 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, 3131 "other")); 3132 3133 TempDIImportedEntity Temp = N->clone(); 3134 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); 3135 3136 MDTuple *Elements1 = getTuple(); 3137 MDTuple *Elements2 = getTuple(); 3138 auto *Ne = DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, 3139 Name, Elements1); 3140 3141 EXPECT_EQ(Elements1, Ne->getElements().get()); 3142 3143 EXPECT_EQ(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, 3144 Name, Elements1)); 3145 EXPECT_NE(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, 3146 "ModOther", Elements1)); 3147 EXPECT_NE(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, 3148 Name, Elements2)); 3149 EXPECT_NE( 3150 Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, Name)); 3151 3152 TempDIImportedEntity Tempe = Ne->clone(); 3153 EXPECT_EQ(Ne, MDNode::replaceWithUniqued(std::move(Tempe))); 3154 } 3155 3156 typedef MetadataTest MetadataAsValueTest; 3157 3158 TEST_F(MetadataAsValueTest, MDNode) { 3159 MDNode *N = MDNode::get(Context, None); 3160 auto *V = MetadataAsValue::get(Context, N); 3161 EXPECT_TRUE(V->getType()->isMetadataTy()); 3162 EXPECT_EQ(N, V->getMetadata()); 3163 3164 auto *V2 = MetadataAsValue::get(Context, N); 3165 EXPECT_EQ(V, V2); 3166 } 3167 3168 TEST_F(MetadataAsValueTest, MDNodeMDNode) { 3169 MDNode *N = MDNode::get(Context, None); 3170 Metadata *Ops[] = {N}; 3171 MDNode *N2 = MDNode::get(Context, Ops); 3172 auto *V = MetadataAsValue::get(Context, N2); 3173 EXPECT_TRUE(V->getType()->isMetadataTy()); 3174 EXPECT_EQ(N2, V->getMetadata()); 3175 3176 auto *V2 = MetadataAsValue::get(Context, N2); 3177 EXPECT_EQ(V, V2); 3178 3179 auto *V3 = MetadataAsValue::get(Context, N); 3180 EXPECT_TRUE(V3->getType()->isMetadataTy()); 3181 EXPECT_NE(V, V3); 3182 EXPECT_EQ(N, V3->getMetadata()); 3183 } 3184 3185 TEST_F(MetadataAsValueTest, MDNodeConstant) { 3186 auto *C = ConstantInt::getTrue(Context); 3187 auto *MD = ConstantAsMetadata::get(C); 3188 Metadata *Ops[] = {MD}; 3189 auto *N = MDNode::get(Context, Ops); 3190 3191 auto *V = MetadataAsValue::get(Context, MD); 3192 EXPECT_TRUE(V->getType()->isMetadataTy()); 3193 EXPECT_EQ(MD, V->getMetadata()); 3194 3195 auto *V2 = MetadataAsValue::get(Context, N); 3196 EXPECT_EQ(MD, V2->getMetadata()); 3197 EXPECT_EQ(V, V2); 3198 } 3199 3200 typedef MetadataTest ValueAsMetadataTest; 3201 3202 TEST_F(ValueAsMetadataTest, UpdatesOnRAUW) { 3203 Type *Ty = Type::getInt1PtrTy(Context); 3204 std::unique_ptr<GlobalVariable> GV0( 3205 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 3206 auto *MD = ValueAsMetadata::get(GV0.get()); 3207 EXPECT_TRUE(MD->getValue() == GV0.get()); 3208 ASSERT_TRUE(GV0->use_empty()); 3209 3210 std::unique_ptr<GlobalVariable> GV1( 3211 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 3212 GV0->replaceAllUsesWith(GV1.get()); 3213 EXPECT_TRUE(MD->getValue() == GV1.get()); 3214 } 3215 3216 TEST_F(ValueAsMetadataTest, TempTempReplacement) { 3217 // Create a constant. 3218 ConstantAsMetadata *CI = 3219 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); 3220 3221 auto Temp1 = MDTuple::getTemporary(Context, None); 3222 auto Temp2 = MDTuple::getTemporary(Context, {CI}); 3223 auto *N = MDTuple::get(Context, {Temp1.get()}); 3224 3225 // Test replacing a temporary node with another temporary node. 3226 Temp1->replaceAllUsesWith(Temp2.get()); 3227 EXPECT_EQ(N->getOperand(0), Temp2.get()); 3228 3229 // Clean up Temp2 for teardown. 3230 Temp2->replaceAllUsesWith(nullptr); 3231 } 3232 3233 TEST_F(ValueAsMetadataTest, CollidingDoubleUpdates) { 3234 // Create a constant. 3235 ConstantAsMetadata *CI = 3236 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); 3237 3238 // Create a temporary to prevent nodes from resolving. 3239 auto Temp = MDTuple::getTemporary(Context, None); 3240 3241 // When the first operand of N1 gets reset to nullptr, it'll collide with N2. 3242 Metadata *Ops1[] = {CI, CI, Temp.get()}; 3243 Metadata *Ops2[] = {nullptr, CI, Temp.get()}; 3244 3245 auto *N1 = MDTuple::get(Context, Ops1); 3246 auto *N2 = MDTuple::get(Context, Ops2); 3247 ASSERT_NE(N1, N2); 3248 3249 // Tell metadata that the constant is getting deleted. 3250 // 3251 // After this, N1 will be invalid, so don't touch it. 3252 ValueAsMetadata::handleDeletion(CI->getValue()); 3253 EXPECT_EQ(nullptr, N2->getOperand(0)); 3254 EXPECT_EQ(nullptr, N2->getOperand(1)); 3255 EXPECT_EQ(Temp.get(), N2->getOperand(2)); 3256 3257 // Clean up Temp for teardown. 3258 Temp->replaceAllUsesWith(nullptr); 3259 } 3260 3261 typedef MetadataTest DIArgListTest; 3262 3263 TEST_F(DIArgListTest, get) { 3264 SmallVector<ValueAsMetadata *, 2> VMs; 3265 VMs.push_back( 3266 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0)))); 3267 VMs.push_back( 3268 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(2, 0)))); 3269 DIArgList *DV0 = DIArgList::get(Context, VMs); 3270 DIArgList *DV1 = DIArgList::get(Context, VMs); 3271 EXPECT_EQ(DV0, DV1); 3272 } 3273 3274 TEST_F(DIArgListTest, UpdatesOnRAUW) { 3275 Type *Ty = Type::getInt1PtrTy(Context); 3276 ConstantAsMetadata *CI = 3277 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))); 3278 std::unique_ptr<GlobalVariable> GV0( 3279 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 3280 auto *MD0 = ValueAsMetadata::get(GV0.get()); 3281 3282 SmallVector<ValueAsMetadata *, 2> VMs; 3283 VMs.push_back(CI); 3284 VMs.push_back(MD0); 3285 auto *AL = DIArgList::get(Context, VMs); 3286 EXPECT_EQ(AL->getArgs()[0], CI); 3287 EXPECT_EQ(AL->getArgs()[1], MD0); 3288 3289 std::unique_ptr<GlobalVariable> GV1( 3290 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 3291 auto *MD1 = ValueAsMetadata::get(GV1.get()); 3292 GV0->replaceAllUsesWith(GV1.get()); 3293 EXPECT_EQ(AL->getArgs()[0], CI); 3294 EXPECT_EQ(AL->getArgs()[1], MD1); 3295 } 3296 3297 typedef MetadataTest TrackingMDRefTest; 3298 3299 TEST_F(TrackingMDRefTest, UpdatesOnRAUW) { 3300 Type *Ty = Type::getInt1PtrTy(Context); 3301 std::unique_ptr<GlobalVariable> GV0( 3302 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 3303 TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV0.get())); 3304 EXPECT_TRUE(MD->getValue() == GV0.get()); 3305 ASSERT_TRUE(GV0->use_empty()); 3306 3307 std::unique_ptr<GlobalVariable> GV1( 3308 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 3309 GV0->replaceAllUsesWith(GV1.get()); 3310 EXPECT_TRUE(MD->getValue() == GV1.get()); 3311 3312 // Reset it, so we don't inadvertently test deletion. 3313 MD.reset(); 3314 } 3315 3316 TEST_F(TrackingMDRefTest, UpdatesOnDeletion) { 3317 Type *Ty = Type::getInt1PtrTy(Context); 3318 std::unique_ptr<GlobalVariable> GV( 3319 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage)); 3320 TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV.get())); 3321 EXPECT_TRUE(MD->getValue() == GV.get()); 3322 ASSERT_TRUE(GV->use_empty()); 3323 3324 GV.reset(); 3325 EXPECT_TRUE(!MD); 3326 } 3327 3328 TEST(NamedMDNodeTest, Search) { 3329 LLVMContext Context; 3330 ConstantAsMetadata *C = 3331 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 1)); 3332 ConstantAsMetadata *C2 = 3333 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 2)); 3334 3335 Metadata *const V = C; 3336 Metadata *const V2 = C2; 3337 MDNode *n = MDNode::get(Context, V); 3338 MDNode *n2 = MDNode::get(Context, V2); 3339 3340 Module M("MyModule", Context); 3341 const char *Name = "llvm.NMD1"; 3342 NamedMDNode *NMD = M.getOrInsertNamedMetadata(Name); 3343 NMD->addOperand(n); 3344 NMD->addOperand(n2); 3345 3346 std::string Str; 3347 raw_string_ostream oss(Str); 3348 NMD->print(oss); 3349 EXPECT_STREQ("!llvm.NMD1 = !{!0, !1}\n", 3350 oss.str().c_str()); 3351 } 3352 3353 typedef MetadataTest FunctionAttachmentTest; 3354 TEST_F(FunctionAttachmentTest, setMetadata) { 3355 Function *F = getFunction("foo"); 3356 ASSERT_FALSE(F->hasMetadata()); 3357 EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg)); 3358 EXPECT_EQ(nullptr, F->getMetadata("dbg")); 3359 EXPECT_EQ(nullptr, F->getMetadata("other")); 3360 3361 DISubprogram *SP1 = getSubprogram(); 3362 DISubprogram *SP2 = getSubprogram(); 3363 ASSERT_NE(SP1, SP2); 3364 3365 F->setMetadata("dbg", SP1); 3366 EXPECT_TRUE(F->hasMetadata()); 3367 EXPECT_EQ(SP1, F->getMetadata(LLVMContext::MD_dbg)); 3368 EXPECT_EQ(SP1, F->getMetadata("dbg")); 3369 EXPECT_EQ(nullptr, F->getMetadata("other")); 3370 3371 F->setMetadata(LLVMContext::MD_dbg, SP2); 3372 EXPECT_TRUE(F->hasMetadata()); 3373 EXPECT_EQ(SP2, F->getMetadata(LLVMContext::MD_dbg)); 3374 EXPECT_EQ(SP2, F->getMetadata("dbg")); 3375 EXPECT_EQ(nullptr, F->getMetadata("other")); 3376 3377 F->setMetadata("dbg", nullptr); 3378 EXPECT_FALSE(F->hasMetadata()); 3379 EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg)); 3380 EXPECT_EQ(nullptr, F->getMetadata("dbg")); 3381 EXPECT_EQ(nullptr, F->getMetadata("other")); 3382 3383 MDTuple *T1 = getTuple(); 3384 MDTuple *T2 = getTuple(); 3385 ASSERT_NE(T1, T2); 3386 3387 F->setMetadata("other1", T1); 3388 F->setMetadata("other2", T2); 3389 EXPECT_TRUE(F->hasMetadata()); 3390 EXPECT_EQ(T1, F->getMetadata("other1")); 3391 EXPECT_EQ(T2, F->getMetadata("other2")); 3392 EXPECT_EQ(nullptr, F->getMetadata("dbg")); 3393 3394 F->setMetadata("other1", T2); 3395 F->setMetadata("other2", T1); 3396 EXPECT_EQ(T2, F->getMetadata("other1")); 3397 EXPECT_EQ(T1, F->getMetadata("other2")); 3398 3399 F->setMetadata("other1", nullptr); 3400 F->setMetadata("other2", nullptr); 3401 EXPECT_FALSE(F->hasMetadata()); 3402 EXPECT_EQ(nullptr, F->getMetadata("other1")); 3403 EXPECT_EQ(nullptr, F->getMetadata("other2")); 3404 } 3405 3406 TEST_F(FunctionAttachmentTest, getAll) { 3407 Function *F = getFunction("foo"); 3408 3409 MDTuple *T1 = getTuple(); 3410 MDTuple *T2 = getTuple(); 3411 MDTuple *P = getTuple(); 3412 DISubprogram *SP = getSubprogram(); 3413 3414 F->setMetadata("other1", T2); 3415 F->setMetadata(LLVMContext::MD_dbg, SP); 3416 F->setMetadata("other2", T1); 3417 F->setMetadata(LLVMContext::MD_prof, P); 3418 F->setMetadata("other2", T2); 3419 F->setMetadata("other1", T1); 3420 3421 SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; 3422 F->getAllMetadata(MDs); 3423 ASSERT_EQ(4u, MDs.size()); 3424 EXPECT_EQ(LLVMContext::MD_dbg, MDs[0].first); 3425 EXPECT_EQ(LLVMContext::MD_prof, MDs[1].first); 3426 EXPECT_EQ(Context.getMDKindID("other1"), MDs[2].first); 3427 EXPECT_EQ(Context.getMDKindID("other2"), MDs[3].first); 3428 EXPECT_EQ(SP, MDs[0].second); 3429 EXPECT_EQ(P, MDs[1].second); 3430 EXPECT_EQ(T1, MDs[2].second); 3431 EXPECT_EQ(T2, MDs[3].second); 3432 } 3433 3434 TEST_F(FunctionAttachmentTest, Verifier) { 3435 Function *F = getFunction("foo"); 3436 F->setMetadata("attach", getTuple()); 3437 F->setIsMaterializable(true); 3438 3439 // Confirm this is materializable. 3440 ASSERT_TRUE(F->isMaterializable()); 3441 3442 // Materializable functions cannot have metadata attachments. 3443 EXPECT_TRUE(verifyFunction(*F)); 3444 3445 // Function declarations can. 3446 F->setIsMaterializable(false); 3447 EXPECT_FALSE(verifyModule(*F->getParent())); 3448 EXPECT_FALSE(verifyFunction(*F)); 3449 3450 // So can definitions. 3451 (void)new UnreachableInst(Context, BasicBlock::Create(Context, "bb", F)); 3452 EXPECT_FALSE(verifyModule(*F->getParent())); 3453 EXPECT_FALSE(verifyFunction(*F)); 3454 } 3455 3456 TEST_F(FunctionAttachmentTest, RealEntryCount) { 3457 Function *F = getFunction("foo"); 3458 EXPECT_FALSE(F->getEntryCount().hasValue()); 3459 F->setEntryCount(12304, Function::PCT_Real); 3460 auto Count = F->getEntryCount(); 3461 EXPECT_TRUE(Count.hasValue()); 3462 EXPECT_EQ(12304u, Count->getCount()); 3463 EXPECT_EQ(Function::PCT_Real, Count->getType()); 3464 } 3465 3466 TEST_F(FunctionAttachmentTest, SyntheticEntryCount) { 3467 Function *F = getFunction("bar"); 3468 EXPECT_FALSE(F->getEntryCount().hasValue()); 3469 F->setEntryCount(123, Function::PCT_Synthetic); 3470 auto Count = F->getEntryCount(true /*allow synthetic*/); 3471 EXPECT_TRUE(Count.hasValue()); 3472 EXPECT_EQ(123u, Count->getCount()); 3473 EXPECT_EQ(Function::PCT_Synthetic, Count->getType()); 3474 } 3475 3476 TEST_F(FunctionAttachmentTest, SubprogramAttachment) { 3477 Function *F = getFunction("foo"); 3478 DISubprogram *SP = getSubprogram(); 3479 F->setSubprogram(SP); 3480 3481 // Note that the static_cast confirms that F->getSubprogram() actually 3482 // returns an DISubprogram. 3483 EXPECT_EQ(SP, static_cast<DISubprogram *>(F->getSubprogram())); 3484 EXPECT_EQ(SP, F->getMetadata("dbg")); 3485 EXPECT_EQ(SP, F->getMetadata(LLVMContext::MD_dbg)); 3486 } 3487 3488 typedef MetadataTest DistinctMDOperandPlaceholderTest; 3489 TEST_F(DistinctMDOperandPlaceholderTest, getID) { 3490 EXPECT_EQ(7u, DistinctMDOperandPlaceholder(7).getID()); 3491 } 3492 3493 TEST_F(DistinctMDOperandPlaceholderTest, replaceUseWith) { 3494 // Set up some placeholders. 3495 DistinctMDOperandPlaceholder PH0(7); 3496 DistinctMDOperandPlaceholder PH1(3); 3497 DistinctMDOperandPlaceholder PH2(0); 3498 Metadata *Ops[] = {&PH0, &PH1, &PH2}; 3499 auto *D = MDTuple::getDistinct(Context, Ops); 3500 ASSERT_EQ(&PH0, D->getOperand(0)); 3501 ASSERT_EQ(&PH1, D->getOperand(1)); 3502 ASSERT_EQ(&PH2, D->getOperand(2)); 3503 3504 // Replace them. 3505 auto *N0 = MDTuple::get(Context, None); 3506 auto *N1 = MDTuple::get(Context, N0); 3507 PH0.replaceUseWith(N0); 3508 PH1.replaceUseWith(N1); 3509 PH2.replaceUseWith(nullptr); 3510 EXPECT_EQ(N0, D->getOperand(0)); 3511 EXPECT_EQ(N1, D->getOperand(1)); 3512 EXPECT_EQ(nullptr, D->getOperand(2)); 3513 } 3514 3515 TEST_F(DistinctMDOperandPlaceholderTest, replaceUseWithNoUser) { 3516 // There is no user, but we can still call replace. 3517 DistinctMDOperandPlaceholder(7).replaceUseWith(MDTuple::get(Context, None)); 3518 } 3519 3520 // Test various assertions in metadata tracking. Don't run these tests if gtest 3521 // will use SEH to recover from them. Two of these tests get halfway through 3522 // inserting metadata into DenseMaps for tracking purposes, and then they 3523 // assert, and we attempt to destroy an LLVMContext with broken invariants, 3524 // leading to infinite loops. 3525 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) && !defined(GTEST_HAS_SEH) 3526 TEST_F(DistinctMDOperandPlaceholderTest, MetadataAsValue) { 3527 // This shouldn't crash. 3528 DistinctMDOperandPlaceholder PH(7); 3529 EXPECT_DEATH(MetadataAsValue::get(Context, &PH), 3530 "Unexpected callback to owner"); 3531 } 3532 3533 TEST_F(DistinctMDOperandPlaceholderTest, UniquedMDNode) { 3534 // This shouldn't crash. 3535 DistinctMDOperandPlaceholder PH(7); 3536 EXPECT_DEATH(MDTuple::get(Context, &PH), "Unexpected callback to owner"); 3537 } 3538 3539 TEST_F(DistinctMDOperandPlaceholderTest, SecondDistinctMDNode) { 3540 // This shouldn't crash. 3541 DistinctMDOperandPlaceholder PH(7); 3542 MDTuple::getDistinct(Context, &PH); 3543 EXPECT_DEATH(MDTuple::getDistinct(Context, &PH), 3544 "Placeholders can only be used once"); 3545 } 3546 3547 TEST_F(DistinctMDOperandPlaceholderTest, TrackingMDRefAndDistinctMDNode) { 3548 // TrackingMDRef doesn't install an owner callback, so it can't be detected 3549 // as an invalid use. However, using a placeholder in a TrackingMDRef *and* 3550 // a distinct node isn't possible and we should assert. 3551 // 3552 // (There's no positive test for using TrackingMDRef because it's not a 3553 // useful thing to do.) 3554 { 3555 DistinctMDOperandPlaceholder PH(7); 3556 MDTuple::getDistinct(Context, &PH); 3557 EXPECT_DEATH(TrackingMDRef Ref(&PH), "Placeholders can only be used once"); 3558 } 3559 { 3560 DistinctMDOperandPlaceholder PH(7); 3561 TrackingMDRef Ref(&PH); 3562 EXPECT_DEATH(MDTuple::getDistinct(Context, &PH), 3563 "Placeholders can only be used once"); 3564 } 3565 } 3566 #endif 3567 3568 typedef MetadataTest DebugVariableTest; 3569 TEST_F(DebugVariableTest, DenseMap) { 3570 DenseMap<DebugVariable, uint64_t> DebugVariableMap; 3571 3572 DILocalScope *Scope = getSubprogram(); 3573 DIFile *File = getFile(); 3574 DIType *Type = getDerivedType(); 3575 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7); 3576 3577 DILocation *InlinedLoc = DILocation::get(Context, 2, 7, Scope); 3578 3579 DILocalVariable *VarA = 3580 DILocalVariable::get(Context, Scope, "A", File, 5, Type, 2, Flags, 8, nullptr); 3581 DILocalVariable *VarB = 3582 DILocalVariable::get(Context, Scope, "B", File, 7, Type, 3, Flags, 8, nullptr); 3583 3584 DebugVariable DebugVariableA(VarA, NoneType(), nullptr); 3585 DebugVariable DebugVariableInlineA(VarA, NoneType(), InlinedLoc); 3586 DebugVariable DebugVariableB(VarB, NoneType(), nullptr); 3587 DebugVariable DebugVariableFragB(VarB, {{16, 16}}, nullptr); 3588 3589 DebugVariableMap.insert({DebugVariableA, 2}); 3590 DebugVariableMap.insert({DebugVariableInlineA, 3}); 3591 DebugVariableMap.insert({DebugVariableB, 6}); 3592 DebugVariableMap.insert({DebugVariableFragB, 12}); 3593 3594 EXPECT_EQ(DebugVariableMap.count(DebugVariableA), 1u); 3595 EXPECT_EQ(DebugVariableMap.count(DebugVariableInlineA), 1u); 3596 EXPECT_EQ(DebugVariableMap.count(DebugVariableB), 1u); 3597 EXPECT_EQ(DebugVariableMap.count(DebugVariableFragB), 1u); 3598 3599 EXPECT_EQ(DebugVariableMap.find(DebugVariableA)->second, 2u); 3600 EXPECT_EQ(DebugVariableMap.find(DebugVariableInlineA)->second, 3u); 3601 EXPECT_EQ(DebugVariableMap.find(DebugVariableB)->second, 6u); 3602 EXPECT_EQ(DebugVariableMap.find(DebugVariableFragB)->second, 12u); 3603 } 3604 3605 typedef MetadataTest MDTupleAllocationTest; 3606 TEST_F(MDTupleAllocationTest, Tracking) { 3607 // Make sure that the move constructor and move assignment op 3608 // for MDOperand correctly adjust tracking information. 3609 auto *Value1 = getConstantAsMetadata(); 3610 MDTuple *A = MDTuple::getDistinct(Context, {Value1, Value1}); 3611 EXPECT_EQ(A->getOperand(0), Value1); 3612 EXPECT_EQ(A->getOperand(1), Value1); 3613 3614 MDNode::op_range Ops = A->operands(); 3615 3616 MDOperand NewOps1; 3617 // Move assignment operator. 3618 NewOps1 = std::move(*const_cast<MDOperand *>(Ops.begin())); 3619 // Move constructor. 3620 MDOperand NewOps2(std::move(*const_cast<MDOperand *>(Ops.begin() + 1))); 3621 3622 EXPECT_EQ(NewOps1.get(), static_cast<Metadata *>(Value1)); 3623 EXPECT_EQ(NewOps2.get(), static_cast<Metadata *>(Value1)); 3624 3625 auto *Value2 = getConstantAsMetadata(); 3626 Value *V1 = Value1->getValue(); 3627 Value *V2 = Value2->getValue(); 3628 ValueAsMetadata::handleRAUW(V1, V2); 3629 3630 EXPECT_EQ(NewOps1.get(), static_cast<Metadata *>(Value2)); 3631 EXPECT_EQ(NewOps2.get(), static_cast<Metadata *>(Value2)); 3632 } 3633 3634 } // end namespace 3635