brintos

brintos / llvm-project-archived public Read only

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