//===- llvm/unittest/IR/DebugInfo.cpp - DebugInfo tests -------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/DebugInfo.h"
#include "../lib/IR/LLVMContextImpl.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugProgramInstruction.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Transforms/Utils/Local.h"

#include "gtest/gtest.h"

using namespace llvm;

static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
  SMDiagnostic Err;
  std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
  if (!Mod)
    Err.print("DebugInfoTest", errs());
  return Mod;
}

namespace {

TEST(DINodeTest, getFlag) {
  // Some valid flags.
  EXPECT_EQ(DINode::FlagPublic, DINode::getFlag("DIFlagPublic"));
  EXPECT_EQ(DINode::FlagProtected, DINode::getFlag("DIFlagProtected"));
  EXPECT_EQ(DINode::FlagPrivate, DINode::getFlag("DIFlagPrivate"));
  EXPECT_EQ(DINode::FlagVector, DINode::getFlag("DIFlagVector"));
  EXPECT_EQ(DINode::FlagRValueReference,
            DINode::getFlag("DIFlagRValueReference"));

  // FlagAccessibility shouldn't work.
  EXPECT_EQ(0u, DINode::getFlag("DIFlagAccessibility"));

  // Some other invalid strings.
  EXPECT_EQ(0u, DINode::getFlag("FlagVector"));
  EXPECT_EQ(0u, DINode::getFlag("Vector"));
  EXPECT_EQ(0u, DINode::getFlag("other things"));
  EXPECT_EQ(0u, DINode::getFlag("DIFlagOther"));
}

TEST(DINodeTest, getFlagString) {
  // Some valid flags.
  EXPECT_EQ(StringRef("DIFlagPublic"),
            DINode::getFlagString(DINode::FlagPublic));
  EXPECT_EQ(StringRef("DIFlagProtected"),
            DINode::getFlagString(DINode::FlagProtected));
  EXPECT_EQ(StringRef("DIFlagPrivate"),
            DINode::getFlagString(DINode::FlagPrivate));
  EXPECT_EQ(StringRef("DIFlagVector"),
            DINode::getFlagString(DINode::FlagVector));
  EXPECT_EQ(StringRef("DIFlagRValueReference"),
            DINode::getFlagString(DINode::FlagRValueReference));

  // FlagAccessibility actually equals FlagPublic.
  EXPECT_EQ(StringRef("DIFlagPublic"),
            DINode::getFlagString(DINode::FlagAccessibility));

  // Some other invalid flags.
  EXPECT_EQ(StringRef(),
            DINode::getFlagString(DINode::FlagPublic | DINode::FlagVector));
  EXPECT_EQ(StringRef(), DINode::getFlagString(DINode::FlagFwdDecl |
                                               DINode::FlagArtificial));
  EXPECT_EQ(StringRef(),
            DINode::getFlagString(static_cast<DINode::DIFlags>(0xffff)));
}

TEST(DINodeTest, splitFlags) {
// Some valid flags.
#define CHECK_SPLIT(FLAGS, VECTOR, REMAINDER)                                  \
  {                                                                            \
    SmallVector<DINode::DIFlags, 8> V;                                         \
    EXPECT_EQ(REMAINDER, DINode::splitFlags(FLAGS, V));                        \
    EXPECT_TRUE(ArrayRef(V).equals(VECTOR));                                   \
  }
  CHECK_SPLIT(DINode::FlagPublic, {DINode::FlagPublic}, DINode::FlagZero);
  CHECK_SPLIT(DINode::FlagProtected, {DINode::FlagProtected}, DINode::FlagZero);
  CHECK_SPLIT(DINode::FlagPrivate, {DINode::FlagPrivate}, DINode::FlagZero);
  CHECK_SPLIT(DINode::FlagVector, {DINode::FlagVector}, DINode::FlagZero);
  CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference},
              DINode::FlagZero);
  DINode::DIFlags Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector};
  CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags,
              DINode::FlagZero);
  CHECK_SPLIT(DINode::FlagZero, {}, DINode::FlagZero);
#undef CHECK_SPLIT
}

TEST(StripTest, LoopMetadata) {
  LLVMContext C;
  std::unique_ptr<Module> M = parseIR(C, R"(
    define void @f() !dbg !5 {
      ret void, !dbg !10, !llvm.loop !11
    }

    !llvm.dbg.cu = !{!0}
    !llvm.debugify = !{!3, !3}
    !llvm.module.flags = !{!4}

    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
    !1 = !DIFile(filename: "loop.ll", directory: "/")
    !2 = !{}
    !3 = !{i32 1}
    !4 = !{i32 2, !"Debug Info Version", i32 3}
    !5 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !7)
    !6 = !DISubroutineType(types: !2)
    !7 = !{!8}
    !8 = !DILocalVariable(name: "1", scope: !5, file: !1, line: 1, type: !9)
    !9 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_unsigned)
    !10 = !DILocation(line: 1, column: 1, scope: !5)
    !11 = distinct !{!11, !10, !10}
)");

  // Look up the debug info emission kind for the CU via the loop metadata
  // attached to the terminator. If, when stripping non-line table debug info,
  // we update the terminator's metadata correctly, we should be able to
  // observe the change in emission kind for the CU.
  auto getEmissionKind = [&]() {
    Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHIIt();
    MDNode *LoopMD = I.getMetadata(LLVMContext::MD_loop);
    return cast<DILocation>(LoopMD->getOperand(1))
        ->getScope()
        ->getSubprogram()
        ->getUnit()
        ->getEmissionKind();
  };

  EXPECT_EQ(getEmissionKind(), DICompileUnit::FullDebug);

  bool Changed = stripNonLineTableDebugInfo(*M);
  EXPECT_TRUE(Changed);

  EXPECT_EQ(getEmissionKind(), DICompileUnit::LineTablesOnly);

  bool BrokenDebugInfo = false;
  bool HardError = verifyModule(*M, &errs(), &BrokenDebugInfo);
  EXPECT_FALSE(HardError);
  EXPECT_FALSE(BrokenDebugInfo);
}

TEST(MetadataTest, DeleteInstUsedByDbgRecord) {
  LLVMContext C;
  std::unique_ptr<Module> M = parseIR(C, R"(
    define i16 @f(i16 %a) !dbg !6 {
      %b = add i16 %a, 1, !dbg !11
      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
      ret i16 0, !dbg !11
    }
    declare void @llvm.dbg.value(metadata, metadata, metadata) #0
    attributes #0 = { nounwind readnone speculatable willreturn }

    !llvm.dbg.cu = !{!0}
    !llvm.module.flags = !{!5}

    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
    !1 = !DIFile(filename: "t.ll", directory: "/")
    !2 = !{}
    !5 = !{i32 2, !"Debug Info Version", i32 3}
    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
    !7 = !DISubroutineType(types: !2)
    !8 = !{!9}
    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
    !11 = !DILocation(line: 1, column: 1, scope: !6)
)");

  // Find %b = add ...
  Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHIIt();

  // Find the dbg.value using %b.
  SmallVector<DbgVariableRecord *, 1> DVRs;
  findDbgValues(&I, DVRs);

  // Delete %b. The dbg.value should now point to undef.
  I.eraseFromParent();
  EXPECT_EQ(DVRs[0]->getNumVariableLocationOps(), 1u);
  EXPECT_TRUE(isa<UndefValue>(DVRs[0]->getValue(0)));
}

TEST(MetadataTest, GlobalConstantMetadataUsedByDbgRecord) {
  LLVMContext C;
  std::unique_ptr<Module> M = parseIR(C, R"(
    @x = dso_local global i32 0, align 4
    declare void @llvm.dbg.value(metadata, metadata, metadata) #0

    define i16 @f(i16 %a) !dbg !6 {
      %b = add i16 %a, 1, !dbg !11
      call void @llvm.dbg.declare(metadata ptr @x, metadata !9, metadata !DIExpression()), !dbg !11
      call void @llvm.dbg.value(metadata ptr @x, metadata !9, metadata !DIExpression()), !dbg !11
      ret i16 0, !dbg !11
    }

    attributes #0 = { nounwind readnone speculatable willreturn }

    !llvm.dbg.cu = !{!0}
    !llvm.module.flags = !{!5}

    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
    !1 = !DIFile(filename: "t.ll", directory: "/")
    !2 = !{}
    !5 = !{i32 2, !"Debug Info Version", i32 3}
    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
    !7 = !DISubroutineType(types: !2)
    !8 = !{!9}
    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
    !11 = !DILocation(line: 1, column: 1, scope: !6)
)");

  // Find the global @x
  Value *V = M->getNamedValue("x");

  // Find the dbg.value
  auto DVRs = findDVRDeclares(V);
  auto DVRVs = findDVRValues(V);

  EXPECT_EQ(DVRs[0]->getNumVariableLocationOps(), 1u);
  EXPECT_TRUE(DVRVs.size() == 1);
  EXPECT_FALSE(isa<UndefValue>(DVRs[0]->getValue(0)));
}

TEST(DbgVariableIntrinsic, EmptyMDIsKillLocation) {
  LLVMContext Ctx;
  std::unique_ptr<Module> M = parseIR(Ctx, R"(
    define dso_local void @fun() local_unnamed_addr #0 !dbg !9 {
    entry:
      call void @llvm.dbg.declare(metadata !{}, metadata !13, metadata !DIExpression()), !dbg !16
      ret void, !dbg !16
    }

    declare void @llvm.dbg.declare(metadata, metadata, metadata)

    !llvm.dbg.cu = !{!0}
    !llvm.module.flags = !{!2, !3}
    !llvm.ident = !{!8}

    !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 16.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
    !1 = !DIFile(filename: "test.c", directory: "/")
    !2 = !{i32 7, !"Dwarf Version", i32 5}
    !3 = !{i32 2, !"Debug Info Version", i32 3}
    !8 = !{!"clang version 16.0.0"}
    !9 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
    !10 = !DISubroutineType(types: !11)
    !11 = !{null}
    !12 = !{!13}
    !13 = !DILocalVariable(name: "a", scope: !9, file: !1, line: 1, type: !14)
    !14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
    !16 = !DILocation(line: 1, column: 21, scope: !9)
    )");

  bool BrokenDebugInfo = true;
  verifyModule(*M, &errs(), &BrokenDebugInfo);
  ASSERT_FALSE(BrokenDebugInfo);

  // Get the dbg.declare.
  Function &F = *cast<Function>(M->getNamedValue("fun"));
  DbgVariableRecord *DbgDeclare =
      cast<DbgVariableRecord>(&*F.front().front().getDbgRecordRange().begin());
  // Check that this form counts as a "no location" marker.
  EXPECT_TRUE(DbgDeclare->isKillLocation());
}

// Duplicate of above test, but in DbgVariableRecord representation.
TEST(MetadataTest, DeleteInstUsedByDbgVariableRecord) {
  LLVMContext C;

  std::unique_ptr<Module> M = parseIR(C, R"(
    define i16 @f(i16 %a) !dbg !6 {
      %b = add i16 %a, 1, !dbg !11
      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
      call void @llvm.dbg.value(metadata !DIArgList(i16 %a, i16 %b), metadata !9, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg !11
      ret i16 0, !dbg !11
    }
    declare void @llvm.dbg.value(metadata, metadata, metadata) #0
    attributes #0 = { nounwind readnone speculatable willreturn }

    !llvm.dbg.cu = !{!0}
    !llvm.module.flags = !{!5}

    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
    !1 = !DIFile(filename: "t.ll", directory: "/")
    !2 = !{}
    !5 = !{i32 2, !"Debug Info Version", i32 3}
    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
    !7 = !DISubroutineType(types: !2)
    !8 = !{!9}
    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
    !11 = !DILocation(line: 1, column: 1, scope: !6)
)");

  Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHIIt();

  // Find the DbgVariableRecords using %b.
  SmallVector<DbgVariableRecord *, 2> DVRs;
  findDbgValues(&I, DVRs);
  ASSERT_EQ(DVRs.size(), 2u);

  // Delete %b. The DbgVariableRecord should now point to undef.
  I.eraseFromParent();
  EXPECT_EQ(DVRs[0]->getNumVariableLocationOps(), 1u);
  EXPECT_TRUE(isa<UndefValue>(DVRs[0]->getVariableLocationOp(0)));
  EXPECT_TRUE(DVRs[0]->isKillLocation());
  EXPECT_EQ(DVRs[1]->getNumVariableLocationOps(), 2u);
  EXPECT_TRUE(isa<UndefValue>(DVRs[1]->getVariableLocationOp(1)));
  EXPECT_TRUE(DVRs[1]->isKillLocation());
}

// Ensure that the order of dbg.value intrinsics returned by findDbgValues, and
// their corresponding DbgVariableRecord representation, are consistent.
TEST(MetadataTest, OrderingOfDbgVariableRecords) {
  LLVMContext C;
  std::unique_ptr<Module> M = parseIR(C, R"(
    define i16 @f(i16 %a) !dbg !6 {
      %b = add i16 %a, 1, !dbg !11
        #dbg_value(i16 %b, !9, !DIExpression(), !11)
        #dbg_value(i16 %b, !12, !DIExpression(), !11)
      ret i16 0, !dbg !11
    }
    attributes #0 = { nounwind readnone speculatable willreturn }

    !llvm.dbg.cu = !{!0}
    !llvm.module.flags = !{!5}

    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
    !1 = !DIFile(filename: "t.ll", directory: "/")
    !2 = !{}
    !5 = !{i32 2, !"Debug Info Version", i32 3}
    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
    !7 = !DISubroutineType(types: !2)
    !8 = !{!9}
    !9 = !DILocalVariable(name: "foo", scope: !6, file: !1, line: 1, type: !10)
    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
    !11 = !DILocation(line: 1, column: 1, scope: !6)
    !12 = !DILocalVariable(name: "bar", scope: !6, file: !1, line: 1, type: !10)
)");

  Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHIIt();

  SmallVector<DbgVariableRecord *, 2> DVRs;

  findDbgValues(&I, DVRs);
  ASSERT_EQ(DVRs.size(), 2u);

  // The correct order of dbg.values is given by their use-list, which becomes
  // the reverse order of creation. Thus the dbg.values should come out as
  // "bar" and then "foo".
  const DILocalVariable *Var0 = DVRs[0]->getVariable();
  EXPECT_TRUE(Var0->getName() == "bar");
  const DILocalVariable *Var1 = DVRs[1]->getVariable();
  EXPECT_TRUE(Var1->getName() == "foo");

  M->convertFromNewDbgValues();
}

TEST(DIBuilder, CreateFile) {
  LLVMContext Ctx;
  std::unique_ptr<Module> M(new Module("MyModule", Ctx));
  DIBuilder DIB(*M);

  DIFile *F = DIB.createFile("main.c", "/");
  EXPECT_EQ(std::nullopt, F->getSource());

  std::optional<DIFile::ChecksumInfo<StringRef>> Checksum;
  std::optional<StringRef> Source;
  F = DIB.createFile("main.c", "/", Checksum, Source);
  EXPECT_EQ(Source, F->getSource());

  Source = "";
  F = DIB.createFile("main.c", "/", Checksum, Source);
  EXPECT_EQ(Source, F->getSource());
}

TEST(DIBuilder, CreateFortranArrayTypeWithAttributes) {
  LLVMContext Ctx;
  std::unique_ptr<Module> M(new Module("MyModule", Ctx));
  DIBuilder DIB(*M);

  DISubrange *Subrange = DIB.getOrCreateSubrange(1,1);
  SmallVector<Metadata*, 4> Subranges;
  Subranges.push_back(Subrange);
  DINodeArray Subscripts = DIB.getOrCreateArray(Subranges);

  auto getDIExpression = [&DIB](int offset) {
    SmallVector<uint64_t, 4> ops;
    ops.push_back(llvm::dwarf::DW_OP_push_object_address);
    DIExpression::appendOffset(ops, offset);
    ops.push_back(llvm::dwarf::DW_OP_deref);

    return DIB.createExpression(ops);
  };

  DIFile *F = DIB.createFile("main.c", "/");
  DICompileUnit *CU = DIB.createCompileUnit(
      dwarf::DW_LANG_C, DIB.createFile("main.c", "/"), "llvm-c", true, "", 0);

  DIVariable *DataLocation =
      DIB.createTempGlobalVariableFwdDecl(CU, "dl", "_dl", F, 1, nullptr, true);
  DIExpression *Associated = getDIExpression(1);
  DIExpression *Allocated = getDIExpression(2);
  DIExpression *Rank = DIB.createConstantValueExpression(3);

  DICompositeType *ArrayType = DIB.createArrayType(0, 0, nullptr, Subscripts,
                                                   DataLocation, Associated,
                                                   Allocated, Rank);

  EXPECT_TRUE(isa_and_nonnull<DICompositeType>(ArrayType));
  EXPECT_EQ(ArrayType->getRawDataLocation(), DataLocation);
  EXPECT_EQ(ArrayType->getRawAssociated(), Associated);
  EXPECT_EQ(ArrayType->getRawAllocated(), Allocated);
  EXPECT_EQ(ArrayType->getRawRank(), Rank);

  // Avoid memory leak.
  DIVariable::deleteTemporary(DataLocation);
}

TEST(DIBuilder, CreateArrayWithBitStride) {
  LLVMContext Ctx;
  std::unique_ptr<Module> M(new Module("MyModule", Ctx));
  DIBuilder DIB(*M);

  Type *Int32Ty = Type::getInt32Ty(Ctx);
  Constant *Ci = ConstantInt::get(Int32Ty, 7);
  Metadata *CM = ConstantAsMetadata::get(Ci);

  StringRef ArrayNameExp = "AnArray";
  DICompositeType *NamedArray =
      DIB.createArrayType(nullptr, ArrayNameExp, nullptr, 0, 8, 8, nullptr, {},
                          nullptr, nullptr, nullptr, nullptr, CM);
  EXPECT_EQ(NamedArray->getTag(), dwarf::DW_TAG_array_type);
  EXPECT_EQ(NamedArray->getRawBitStride(), CM);
  EXPECT_EQ(NamedArray->getBitStrideConst(), Ci);
}

TEST(DIBuilder, CreateSetType) {
  LLVMContext Ctx;
  std::unique_ptr<Module> M(new Module("MyModule", Ctx));
  DIBuilder DIB(*M);
  DIScope *Scope = DISubprogram::getDistinct(
      Ctx, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0,
      DINode::FlagZero, DISubprogram::SPFlagZero, nullptr);
  DIType *Type = DIB.createBasicType("Int", 64, dwarf::DW_ATE_signed);
  DIFile *F = DIB.createFile("main.c", "/");

  DIDerivedType *SetType = DIB.createSetType(Scope, "set1", F, 1, 64, 64, Type);
  EXPECT_TRUE(isa_and_nonnull<DIDerivedType>(SetType));
}

TEST(DIBuilder, CreateStringType) {
  LLVMContext Ctx;
  std::unique_ptr<Module> M(new Module("MyModule", Ctx));
  DIBuilder DIB(*M);
  DIScope *Scope = DISubprogram::getDistinct(
      Ctx, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0,
      DINode::FlagZero, DISubprogram::SPFlagZero, nullptr);
  DIFile *F = DIB.createFile("main.c", "/");
  StringRef StrName = "string";
  DIVariable *StringLen = DIB.createAutoVariable(Scope, StrName, F, 0, nullptr,
                                                 false, DINode::FlagZero, 0);
  auto getDIExpression = [&DIB](int offset) {
    SmallVector<uint64_t, 4> ops;
    ops.push_back(llvm::dwarf::DW_OP_push_object_address);
    DIExpression::appendOffset(ops, offset);
    ops.push_back(llvm::dwarf::DW_OP_deref);

    return DIB.createExpression(ops);
  };
  DIExpression *StringLocationExp = getDIExpression(1);
  DIStringType *StringType =
      DIB.createStringType(StrName, StringLen, StringLocationExp);

  EXPECT_TRUE(isa_and_nonnull<DIStringType>(StringType));
  EXPECT_EQ(StringType->getName(), StrName);
  EXPECT_EQ(StringType->getStringLength(), StringLen);
  EXPECT_EQ(StringType->getStringLocationExp(), StringLocationExp);

  StringRef StrNameExp = "stringexp";
  DIExpression *StringLengthExp = getDIExpression(2);
  DIStringType *StringTypeExp =
      DIB.createStringType(StrNameExp, StringLengthExp, StringLocationExp);

  EXPECT_TRUE(isa_and_nonnull<DIStringType>(StringTypeExp));
  EXPECT_EQ(StringTypeExp->getName(), StrNameExp);
  EXPECT_EQ(StringTypeExp->getStringLocationExp(), StringLocationExp);
  EXPECT_EQ(StringTypeExp->getStringLengthExp(), StringLengthExp);
}

TEST(DIBuilder, DIEnumerator) {
  LLVMContext Ctx;
  std::unique_ptr<Module> M(new Module("MyModule", Ctx));
  DIBuilder DIB(*M);
  APSInt I1(APInt(32, 1));
  APSInt I2(APInt(33, 1));

  auto *E = DIEnumerator::get(Ctx, I1, I1.isSigned(), "name");
  EXPECT_TRUE(E);

  auto *E1 = DIEnumerator::getIfExists(Ctx, I1, I1.isSigned(), "name");
  EXPECT_TRUE(E1);

  auto *E2 = DIEnumerator::getIfExists(Ctx, I2, I1.isSigned(), "name");
  EXPECT_FALSE(E2);
}

TEST(DIBuilder, FixedPointType) {
  LLVMContext Ctx;
  std::unique_ptr<Module> M(new Module("MyModule", Ctx));
  DIBuilder DIB(*M);

  DIFixedPointType *Ty = DIB.createBinaryFixedPointType(
      {}, 32, 0, dwarf::DW_ATE_signed_fixed, DINode::FlagZero, -4);
  EXPECT_TRUE(Ty);
  EXPECT_TRUE(Ty->getKind() == DIFixedPointType::FixedPointBinary);
  EXPECT_TRUE(Ty->getFactor() == -4);
  EXPECT_TRUE(Ty->getEncoding() == dwarf::DW_ATE_signed_fixed);
  EXPECT_TRUE(Ty->getTag() == dwarf::DW_TAG_base_type);

  Ty = DIB.createDecimalFixedPointType({}, 32, 0, dwarf::DW_ATE_unsigned_fixed,
                                       DINode::FlagZero, -7);
  EXPECT_TRUE(Ty);
  EXPECT_TRUE(Ty->getKind() == DIFixedPointType::FixedPointDecimal);
  EXPECT_TRUE(Ty->getFactor() == -7);
  EXPECT_TRUE(Ty->getEncoding() == dwarf::DW_ATE_unsigned_fixed);
  EXPECT_TRUE(Ty->getTag() == dwarf::DW_TAG_base_type);

  APSInt Num(APInt(32, 1));
  APSInt Denom(APInt(33, 72));
  Ty = DIB.createRationalFixedPointType({}, 32, 0, dwarf::DW_ATE_unsigned_fixed,
                                        DINode::FlagZero, Num, Denom);
  EXPECT_TRUE(Ty);
  EXPECT_TRUE(Ty->getKind() == DIFixedPointType::FixedPointRational);
  EXPECT_TRUE(Ty->getFactorRaw() == 0);
  EXPECT_TRUE(Ty->getNumerator() == Num);
  EXPECT_TRUE(Ty->getDenominator() == Denom);
  EXPECT_TRUE(Ty->getEncoding() == dwarf::DW_ATE_unsigned_fixed);
  EXPECT_TRUE(Ty->getTag() == dwarf::DW_TAG_base_type);
}

TEST(DbgAssignRecordTest, replaceVariableLocationOp) {
  LLVMContext C;
  std::unique_ptr<Module> M = parseIR(C, R"(
    define dso_local void @fun(i32 %v1, ptr %p1, ptr %p2) !dbg !7 {
    entry:
        #dbg_assign(i32 %v1, !14, !DIExpression(), !17, ptr %p1, !DIExpression(), !16)
      ret void
    }

    !llvm.dbg.cu = !{!0}
    !llvm.module.flags = !{!3}

    !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 14.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
    !1 = !DIFile(filename: "test.cpp", directory: "/")
    !3 = !{i32 2, !"Debug Info Version", i32 3}
    !7 = distinct !DISubprogram(name: "fun", linkageName: "fun", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
    !8 = !DISubroutineType(types: !9)
    !9 = !{null}
    !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
    !11 = !{}
    !14 = !DILocalVariable(name: "Local", scope: !7, file: !1, line: 3, type: !10)
    !16 = !DILocation(line: 0, scope: !7)
    !17 = distinct !DIAssignID()
    )");
  // Check the test IR isn't malformed.
  ASSERT_TRUE(M);

  Function &Fun = *M->getFunction("fun");
  Value *V1 = Fun.getArg(0);
  Value *P1 = Fun.getArg(1);
  Value *P2 = Fun.getArg(2);
  DbgVariableRecord *DbgAssign = cast<DbgVariableRecord>(
      &*Fun.front().front().getDbgRecordRange().begin());
  ASSERT_TRUE(V1 == DbgAssign->getVariableLocationOp(0));
  ASSERT_TRUE(P1 == DbgAssign->getAddress());

#define TEST_REPLACE(Old, New, ExpectedValue, ExpectedAddr)                    \
  DbgAssign->replaceVariableLocationOp(Old, New);                              \
  EXPECT_EQ(DbgAssign->getVariableLocationOp(0), ExpectedValue);               \
  EXPECT_EQ(DbgAssign->getAddress(), ExpectedAddr);

  // Replace address only.
  TEST_REPLACE(/*Old*/ P1, /*New*/ P2, /*Value*/ V1, /*Address*/ P2);
  // Replace value only.
  TEST_REPLACE(/*Old*/ V1, /*New*/ P2, /*Value*/ P2, /*Address*/ P2);
  // Replace both.
  TEST_REPLACE(/*Old*/ P2, /*New*/ P1, /*Value*/ P1, /*Address*/ P1);

  // Replace address only, value uses a DIArgList.
  // Value = {DIArgList(V1)}, Addr = P1.
  DbgAssign->setRawLocation(DIArgList::get(C, ValueAsMetadata::get(V1)));
  DbgAssign->setExpression(DIExpression::get(
      C, {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_stack_value}));
  TEST_REPLACE(/*Old*/ P1, /*New*/ P2, /*Value*/ V1, /*Address*/ P2);
#undef TEST_REPLACE
}

TEST(AssignmentTrackingTest, Utils) {
  // Test the assignment tracking utils defined in DebugInfo.h namespace at {}.
  // This includes:
  //     getAssignmentInsts
  //     getAssignmentMarkers
  //     RAUW
  //     deleteAll
  //
  // The input IR includes two functions, fun1 and fun2. Both contain an alloca
  // with a DIAssignID tag. fun1's alloca is linked to two llvm.dbg.assign
  // intrinsics, one of which is for an inlined variable and appears before the
  // alloca.

  LLVMContext C;
  std::unique_ptr<Module> M = parseIR(C, R"(
    define dso_local void @fun1() !dbg !7 {
    entry:
        #dbg_assign(i32 undef, !10, !DIExpression(), !12, i32 undef, !DIExpression(), !13)
      %local = alloca i32, align 4, !DIAssignID !12
        #dbg_assign(i32 undef, !16, !DIExpression(), !12, i32 undef, !DIExpression(), !15)
        #dbg_assign(i32 undef, !16, !DIExpression(), !25, i32 undef, !DIExpression(), !15)
        #dbg_assign(i32 undef, !16, !DIExpression(), !25, i32 undef, !DIExpression(), !15)
      ret void, !dbg !15
    }

    define dso_local void @fun2() !dbg !17 {
    entry:
      %local = alloca i32, align 4, !DIAssignID !20
        #dbg_assign(i32 undef, !18, !DIExpression(), !20, i32 undef, !DIExpression(), !19)
      ret void, !dbg !19
    }

    define dso_local void @fun3() !dbg !21 {
    entry:
      %local = alloca i32, align 4, !DIAssignID !24
        #dbg_assign(i32 undef, !22, !DIExpression(), !24, i32* undef, !DIExpression(), !23)
      ret void
    }

    !llvm.dbg.cu = !{!0}
    !llvm.module.flags = !{!3, !4, !5}
    !llvm.ident = !{!6}

    !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
    !1 = !DIFile(filename: "test.c", directory: "/")
    !2 = !{}
    !3 = !{i32 7, !"Dwarf Version", i32 4}
    !4 = !{i32 2, !"Debug Info Version", i32 3}
    !5 = !{i32 1, !"wchar_size", i32 4}
    !6 = !{!"clang version 14.0.0"}
    !7 = distinct !DISubprogram(name: "fun1", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
    !8 = !DISubroutineType(types: !9)
    !9 = !{null}
    !10 = !DILocalVariable(name: "local3", scope: !14, file: !1, line: 2, type: !11)
    !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
    !12 = distinct !DIAssignID()
    !13 = !DILocation(line: 5, column: 1, scope: !14, inlinedAt: !15)
    !14 = distinct !DISubprogram(name: "inline", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
    !15 = !DILocation(line: 3, column: 1, scope: !7)
    !16 = !DILocalVariable(name: "local1", scope: !7, file: !1, line: 2, type: !11)
    !17 = distinct !DISubprogram(name: "fun2", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
    !18 = !DILocalVariable(name: "local2", scope: !17, file: !1, line: 2, type: !11)
    !19 = !DILocation(line: 4, column: 1, scope: !17)
    !20 = distinct !DIAssignID()
    !21 = distinct !DISubprogram(name: "fun3", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
    !22 = !DILocalVariable(name: "local4", scope: !21, file: !1, line: 2, type: !11)
    !23 = !DILocation(line: 4, column: 1, scope: !21)
    !24 = distinct !DIAssignID()
    !25 = distinct !DIAssignID()
    )");

  // Check the test IR isn't malformed.
  ASSERT_TRUE(M);

  Function &Fun1 = *M->getFunction("fun1");
  Instruction &Alloca = *Fun1.getEntryBlock().getFirstNonPHIOrDbg();

  // 1. Check the Instruction <-> Intrinsic mappings work in fun1.
  //
  // Check there are two llvm.dbg.assign intrinsics linked to Alloca.
  auto CheckFun1Mapping = [&Alloca]() {
    auto Markers = at::getDVRAssignmentMarkers(&Alloca);
    EXPECT_TRUE(std::distance(Markers.begin(), Markers.end()) == 2);
    // Check those two entries are distinct.
    DbgVariableRecord *First = *Markers.begin();
    DbgVariableRecord *Second = *std::next(Markers.begin());
    EXPECT_NE(First, Second);

    // Check that we can get back to Alloca from each llvm.dbg.assign.
    for (auto *DAI : Markers) {
      auto Insts = at::getAssignmentInsts(DAI);
      // Check there is exactly one instruction linked to each intrinsic. Use
      // ASSERT_TRUE because we're going to dereference the begin iterator.
      ASSERT_TRUE(std::distance(Insts.begin(), Insts.end()) == 1);
      EXPECT_FALSE(Insts.empty());
      // Check the linked instruction is Alloca.
      Instruction *LinkedInst = *Insts.begin();
      EXPECT_EQ(LinkedInst, &Alloca);
    }
  };
  CheckFun1Mapping();

  // 2. Check DIAssignID RAUW replaces attachments and uses.
  //
  DIAssignID *Old =
      cast_or_null<DIAssignID>(Alloca.getMetadata(LLVMContext::MD_DIAssignID));
  DIAssignID *New = DIAssignID::getDistinct(C);
  ASSERT_TRUE(Old && New && New != Old);
  at::RAUW(Old, New);
  // Check fun1's alloca and intrinsics have been updated and the mapping still
  // works.
  EXPECT_EQ(New, cast_or_null<DIAssignID>(
                     Alloca.getMetadata(LLVMContext::MD_DIAssignID)));
  CheckFun1Mapping();

  // Check that fun2's alloca and intrinsic have not not been updated.
  Instruction &Fun2Alloca =
      *M->getFunction("fun2")->getEntryBlock().getFirstNonPHIOrDbg();
  DIAssignID *Fun2ID = cast_or_null<DIAssignID>(
      Fun2Alloca.getMetadata(LLVMContext::MD_DIAssignID));
  EXPECT_NE(New, Fun2ID);
  auto Fun2Markers = at::getDVRAssignmentMarkers(&Fun2Alloca);
  ASSERT_TRUE(std::distance(Fun2Markers.begin(), Fun2Markers.end()) == 1);
  auto Fun2Insts = at::getAssignmentInsts(*Fun2Markers.begin());
  ASSERT_TRUE(std::distance(Fun2Insts.begin(), Fun2Insts.end()) == 1);
  EXPECT_EQ(*Fun2Insts.begin(), &Fun2Alloca);

  // 3. Check that deleting dbg.assigns from a specific instruction works.
  Instruction &Fun3Alloca =
      *M->getFunction("fun3")->getEntryBlock().getFirstNonPHIOrDbg();
  auto Fun3Markers = at::getDVRAssignmentMarkers(&Fun3Alloca);
  ASSERT_TRUE(std::distance(Fun3Markers.begin(), Fun3Markers.end()) == 1);
  at::deleteAssignmentMarkers(&Fun3Alloca);
  Fun3Markers = at::getDVRAssignmentMarkers(&Fun3Alloca);
  EXPECT_EQ(Fun3Markers.empty(), true);

  // 4. Check that deleting works and applies only to the target function.
  at::deleteAll(&Fun1);
  // There should now only be the alloca and ret in fun1.
  EXPECT_EQ(Fun1.begin()->size(), 2u);
  // fun2's alloca should have the same DIAssignID and remain linked to its
  // llvm.dbg.assign.
  EXPECT_EQ(Fun2ID, cast_or_null<DIAssignID>(
                        Fun2Alloca.getMetadata(LLVMContext::MD_DIAssignID)));
  EXPECT_FALSE(at::getDVRAssignmentMarkers(&Fun2Alloca).empty());
}

TEST(IRBuilder, GetSetInsertionPointWithEmptyBasicBlock) {
  LLVMContext C;
  std::unique_ptr<BasicBlock> BB(BasicBlock::Create(C, "start"));
  Module *M = new Module("module", C);
  IRBuilder<> Builder(BB.get());
  Function *DbgDeclare =
      Intrinsic::getOrInsertDeclaration(M, Intrinsic::dbg_declare);
  Value *DIV = MetadataAsValue::get(C, (Metadata *)nullptr);
  SmallVector<Value *, 3> Args = {DIV, DIV, DIV};
  Builder.CreateCall(DbgDeclare, Args);
  auto IP = BB->getFirstInsertionPt();
  Builder.SetInsertPoint(BB.get(), IP);
}

TEST(AssignmentTrackingTest, InstrMethods) {
  // Test the assignment tracking Instruction methods.
  // This includes:
  //     Instruction::mergeDIAssignID

  LLVMContext C;
  std::unique_ptr<Module> M = parseIR(C, R"(
    define dso_local void @fun() #0 !dbg !8 {
    entry:
      %Local = alloca [2 x i32], align 4, !DIAssignID !12
      call void @llvm.dbg.assign(metadata i1 undef, metadata !13, metadata !DIExpression(), metadata !12, metadata [2 x i32]* %Local, metadata !DIExpression()), !dbg !18
      %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %Local, i64 0, i64 0, !dbg !19
      store i32 5, i32* %arrayidx, align 4, !dbg !20, !DIAssignID !21
      call void @llvm.dbg.assign(metadata i32 5, metadata !13, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32), metadata !21, metadata i32* %arrayidx, metadata !DIExpression()), !dbg !18
      %arrayidx1 = getelementptr inbounds [2 x i32], [2 x i32]* %Local, i64 0, i64 1, !dbg !22
      store i32 6, i32* %arrayidx1, align 4, !dbg !23, !DIAssignID !24
      call void @llvm.dbg.assign(metadata i32 6, metadata !13, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32), metadata !24, metadata i32* %arrayidx1, metadata !DIExpression()), !dbg !18
      ret void, !dbg !25
    }

    declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata) #1

    !llvm.dbg.cu = !{!0}
    !llvm.module.flags = !{!2, !3, !4, !5, !6}
    !llvm.ident = !{!7}

    !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
    !1 = !DIFile(filename: "test.cpp", directory: "/")
    !2 = !{i32 7, !"Dwarf Version", i32 5}
    !3 = !{i32 2, !"Debug Info Version", i32 3}
    !4 = !{i32 1, !"wchar_size", i32 4}
    !5 = !{i32 7, !"uwtable", i32 1}
    !6 = !{i32 7, !"frame-pointer", i32 2}
    !7 = !{!"clang version 14.0.0"}
    !8 = distinct !DISubprogram(name: "fun", linkageName: "fun", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !11)
    !9 = !DISubroutineType(types: !10)
    !10 = !{null}
    !11 = !{}
    !12 = distinct !DIAssignID()
    !13 = !DILocalVariable(name: "Local", scope: !8, file: !1, line: 2, type: !14)
    !14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !15, size: 64, elements: !16)
    !15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
    !16 = !{!17}
    !17 = !DISubrange(count: 2)
    !18 = !DILocation(line: 0, scope: !8)
    !19 = !DILocation(line: 3, column: 3, scope: !8)
    !20 = !DILocation(line: 3, column: 12, scope: !8)
    !21 = distinct !DIAssignID()
    !22 = !DILocation(line: 4, column: 3, scope: !8)
    !23 = !DILocation(line: 4, column: 12, scope: !8)
    !24 = distinct !DIAssignID()
    !25 = !DILocation(line: 5, column: 1, scope: !8)
  )");

  // Check the test IR isn't malformed.
  ASSERT_TRUE(M);
  Function &Fun = *M->getFunction("fun");
  SmallVector<Instruction *> Stores;
  for (auto &BB : Fun) {
    for (auto &I : BB) {
      if (isa<StoreInst>(&I))
        Stores.push_back(&I);
    }
  }

  // The test requires (at least) 2 stores.
  ASSERT_TRUE(Stores.size() == 2);
  // Use SetVectors to check that the attachments and markers are unique
  // (another test requirement).
  SetVector<Metadata *> OrigIDs;
  SetVector<DbgVariableRecord *> Markers;
  for (const Instruction *SI : Stores) {
    Metadata *ID = SI->getMetadata(LLVMContext::MD_DIAssignID);
    ASSERT_TRUE(OrigIDs.insert(ID));
    ASSERT_TRUE(ID != nullptr);
    auto Range = at::getDVRAssignmentMarkers(SI);
    ASSERT_TRUE(std::distance(Range.begin(), Range.end()) == 1);
    ASSERT_TRUE(Markers.insert(*Range.begin()));
  }

  // Test 1 - mergeDIAssignID.
  //
  // Input            store0->mergeDIAssignID(store1)
  // -----            -------------------------
  // store0 !x        store0 !x
  // dbg.assign0 !x   dbg.assign !x
  // store1 !y        store1 !x
  // dbg.assign1 !y   dbg.assign1 !x
  {
    Stores[0]->mergeDIAssignID(Stores[1]);
    // Check that the stores share the same ID.
    Metadata *NewID0 = Stores[0]->getMetadata(LLVMContext::MD_DIAssignID);
    Metadata *NewID1 = Stores[1]->getMetadata(LLVMContext::MD_DIAssignID);
    EXPECT_NE(NewID0, nullptr);
    EXPECT_EQ(NewID0, NewID1);
    EXPECT_EQ(Markers[0]->getAssignID(), NewID0);
    EXPECT_EQ(Markers[1]->getAssignID(), NewID0);
  }

  // Test 2 - mergeDIAssignID.
  //
  // Input            store0->mergeDIAssignID(store1)
  // -----            -------------------------
  // store0 !x        store0 !x
  // dbg.assign0 !x   dbg.assign !x
  // store1           store1
  {
    Stores[1]->setMetadata(LLVMContext::MD_DIAssignID, nullptr);
    Stores[0]->mergeDIAssignID(Stores[1]);
    // Check that store1 doesn't get a new ID.
    Metadata *NewID0 = Stores[0]->getMetadata(LLVMContext::MD_DIAssignID);
    Metadata *NewID1 = Stores[1]->getMetadata(LLVMContext::MD_DIAssignID);
    EXPECT_NE(NewID0, nullptr);
    EXPECT_EQ(NewID1, nullptr);
    EXPECT_EQ(Markers[0]->getAssignID(), NewID0);
  }

  // Test 3 - mergeDIAssignID.
  //
  // Input            store1->mergeDIAssignID(store0)
  // -----            -------------------------
  // store0 !x        store0 !x
  // dbg.assign0 !x   dbg.assign !x
  // store1           store1 !x
  {
    Stores[1]->setMetadata(LLVMContext::MD_DIAssignID, nullptr);
    Stores[1]->mergeDIAssignID(Stores[0]);
    // Check that the stores share the same ID (note store1 starts with none).
    Metadata *NewID0 = Stores[0]->getMetadata(LLVMContext::MD_DIAssignID);
    Metadata *NewID1 = Stores[1]->getMetadata(LLVMContext::MD_DIAssignID);
    EXPECT_NE(NewID0, nullptr);
    EXPECT_EQ(NewID0, NewID1);
    EXPECT_EQ(Markers[0]->getAssignID(), NewID0);
  }

  // Test 4 - mergeDIAssignID.
  //
  // Input            store1->mergeDIAssignID(store0)
  // -----            -------------------------
  // store0 !x        store0 !x
  // dbg.assign0 !x   dbg.assign !x
  // store1 !x        store1 !x
  {
    Stores[0]->mergeDIAssignID(Stores[1]);
    // Check that the stores share the same ID.
    Metadata *NewID0 = Stores[0]->getMetadata(LLVMContext::MD_DIAssignID);
    Metadata *NewID1 = Stores[1]->getMetadata(LLVMContext::MD_DIAssignID);
    EXPECT_NE(NewID0, nullptr);
    EXPECT_EQ(NewID0, NewID1);
    EXPECT_EQ(Markers[0]->getAssignID(), NewID0);
  }

  // Test 5 - dropUnknownNonDebugMetadata.
  //
  // Input            store0->dropUnknownNonDebugMetadata()
  // -----            -------------------------
  // store0 !x        store0 !x
  {
    Stores[0]->dropUnknownNonDebugMetadata();
    Metadata *NewID0 = Stores[0]->getMetadata(LLVMContext::MD_DIAssignID);
    EXPECT_NE(NewID0, nullptr);
  }
}

// Test some very straight-forward operations on DbgVariableRecords -- these are
// dbg.values that have been converted to a non-instruction format.
TEST(MetadataTest, ConvertDbgToDbgVariableRecord) {
  LLVMContext C;
  std::unique_ptr<Module> M = parseIR(C, R"(
    define i16 @f(i16 %a) !dbg !6 {
      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11
      %b = add i16 %a, 1, !dbg !11
      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
      ret i16 0, !dbg !11

    exit:
      %c = add i16 %b, 1, !dbg !11
      ret i16 0, !dbg !11
    }
    declare void @llvm.dbg.value(metadata, metadata, metadata) #0
    attributes #0 = { nounwind readnone speculatable willreturn }

    !llvm.dbg.cu = !{!0}
    !llvm.module.flags = !{!5}

    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
    !1 = !DIFile(filename: "t.ll", directory: "/")
    !2 = !{}
    !5 = !{i32 2, !"Debug Info Version", i32 3}
    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
    !7 = !DISubroutineType(types: !2)
    !8 = !{!9}
    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
    !11 = !DILocation(line: 1, column: 1, scope: !6)
)");

  // The IR above will be autoupgraded to debug records: but this test is about
  // the conversion routines, so convert it back. This test will have value
  // going forwards for the purpose of testing the conversion routine, which
  // some compatibility tools (DXIL?) wish to use.
  M->convertFromNewDbgValues();

  // Find the first dbg.value,
  Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHIIt();
  const DILocalVariable *Var = nullptr;
  const DIExpression *Expr = nullptr;
  const DILocation *Loc = nullptr;
  const Metadata *MLoc = nullptr;
  DbgVariableRecord *DVR1 = nullptr;
  {
    DbgValueInst *DPI = dyn_cast<DbgValueInst>(&I);
    ASSERT_TRUE(DPI);
    Var = DPI->getVariable();
    Expr = DPI->getExpression();
    Loc = DPI->getDebugLoc().get();
    MLoc = DPI->getRawLocation();

    // Test the creation of a DbgVariableRecord and it's conversion back to a
    // dbg.value.
    DVR1 = new DbgVariableRecord(DPI);
    EXPECT_EQ(DVR1->getVariable(), Var);
    EXPECT_EQ(DVR1->getExpression(), Expr);
    EXPECT_EQ(DVR1->getDebugLoc().get(), Loc);
    EXPECT_EQ(DVR1->getRawLocation(), MLoc);

    // Erase dbg.value,
    DPI->eraseFromParent();
    // Re-create from DVR1, inserting at front.
    DVR1->createDebugIntrinsic(&*M,
                               &M->getFunction("f")->getEntryBlock().front());

    Instruction *NewDPI = &M->getFunction("f")->getEntryBlock().front();
    DbgValueInst *DPI2 = dyn_cast<DbgValueInst>(NewDPI);
    ASSERT_TRUE(DPI2);
    EXPECT_EQ(DPI2->getVariable(), Var);
    EXPECT_EQ(DPI2->getExpression(), Expr);
    EXPECT_EQ(DPI2->getDebugLoc().get(), Loc);
    EXPECT_EQ(DPI2->getRawLocation(), MLoc);
  }

  // Fetch the second dbg.value, convert it to a DbgVariableRecord,
  BasicBlock::iterator It = M->getFunction("f")->getEntryBlock().begin();
  It = std::next(std::next(It));
  DbgValueInst *DPI3 = dyn_cast<DbgValueInst>(It);
  ASSERT_TRUE(DPI3);
  DbgVariableRecord *DVR2 = new DbgVariableRecord(DPI3);

  // These dbg.values are supposed to refer to different values.
  EXPECT_NE(DVR1->getRawLocation(), DVR2->getRawLocation());

  // Try manipulating DbgVariableRecords and markers in the exit block.
  BasicBlock *ExitBlock = &*std::next(M->getFunction("f")->getEntryBlock().getIterator());
  Instruction *FirstInst = &ExitBlock->front();
  Instruction *RetInst = &*std::next(FirstInst->getIterator());

  // Set-up DbgMarkers in this block.
  ExitBlock->createMarker(FirstInst);
  ExitBlock->createMarker(RetInst);

  // Insert DbgRecords into markers, order should come out DVR2, DVR1.
  FirstInst->DebugMarker->insertDbgRecord(DVR1, false);
  FirstInst->DebugMarker->insertDbgRecord(DVR2, true);
  unsigned int ItCount = 0;
  for (DbgRecord &Item : FirstInst->DebugMarker->getDbgRecordRange()) {
    EXPECT_TRUE((&Item == DVR2 && ItCount == 0) ||
                (&Item == DVR1 && ItCount == 1));
    EXPECT_EQ(Item.getMarker(), FirstInst->DebugMarker);
    ++ItCount;
  }

  // Clone them onto the second marker -- should allocate new DVRs.
  RetInst->DebugMarker->cloneDebugInfoFrom(FirstInst->DebugMarker, std::nullopt,
                                           false);
  EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 2u);
  ItCount = 0;
  // Check these things store the same information; but that they're not the same
  // objects.
  for (DbgVariableRecord &Item :
       filterDbgVars(RetInst->DebugMarker->getDbgRecordRange())) {
    EXPECT_TRUE(
        (Item.getRawLocation() == DVR2->getRawLocation() && ItCount == 0) ||
        (Item.getRawLocation() == DVR1->getRawLocation() && ItCount == 1));

    EXPECT_EQ(Item.getMarker(), RetInst->DebugMarker);
    EXPECT_NE(&Item, DVR1);
    EXPECT_NE(&Item, DVR2);
    ++ItCount;
  }

  RetInst->DebugMarker->dropDbgRecords();
  EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 0u);

  // Try cloning one single DbgVariableRecord.
  auto DIIt = std::next(FirstInst->DebugMarker->getDbgRecordRange().begin());
  RetInst->DebugMarker->cloneDebugInfoFrom(FirstInst->DebugMarker, DIIt, false);
  EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 1u);
  // The second DbgVariableRecord should have been cloned; it should have the
  // same values as DVR1.
  EXPECT_EQ(
      cast<DbgVariableRecord>(RetInst->DebugMarker->StoredDbgRecords.begin())
          ->getRawLocation(),
      DVR1->getRawLocation());
  // We should be able to drop individual DbgRecords.
  RetInst->DebugMarker->dropOneDbgRecord(
      &*RetInst->DebugMarker->StoredDbgRecords.begin());

  // "Aborb" a DbgMarker: this means pretend that the instruction it's attached
  // to is disappearing so it needs to be transferred into "this" marker.
  RetInst->DebugMarker->absorbDebugValues(*FirstInst->DebugMarker, true);
  EXPECT_EQ(RetInst->DebugMarker->StoredDbgRecords.size(), 2u);
  // Should be the DVR1 and DVR2 objects.
  ItCount = 0;
  for (DbgRecord &Item : RetInst->DebugMarker->getDbgRecordRange()) {
    EXPECT_TRUE((&Item == DVR2 && ItCount == 0) ||
                (&Item == DVR1 && ItCount == 1));
    EXPECT_EQ(Item.getMarker(), RetInst->DebugMarker);
    ++ItCount;
  }

  // Finally -- there are two DbgVariableRecords left over. If we remove
  // evrything in the basic block, then they should sink down into the
  // "TrailingDbgRecords" container for dangling debug-info. Future facilities
  // will restore them back when a terminator is inserted.
  FirstInst->DebugMarker->removeMarker();
  FirstInst->eraseFromParent();
  RetInst->DebugMarker->removeMarker();
  RetInst->eraseFromParent();

  DbgMarker *EndMarker = ExitBlock->getTrailingDbgRecords();
  ASSERT_NE(EndMarker, nullptr);
  EXPECT_EQ(EndMarker->StoredDbgRecords.size(), 2u);
  // Test again that it's those two DbgVariableRecords, DVR1 and DVR2.
  ItCount = 0;
  for (DbgRecord &Item : EndMarker->getDbgRecordRange()) {
    EXPECT_TRUE((&Item == DVR2 && ItCount == 0) ||
                (&Item == DVR1 && ItCount == 1));
    EXPECT_EQ(Item.getMarker(), EndMarker);
    ++ItCount;
  }

  // Cleanup the trailing DbgVariableRecord records and marker.
  EndMarker->eraseFromParent();

  // The record of those trailing DbgVariableRecords would dangle and cause an
  // assertion failure if it lived until the end of the LLVMContext.
  ExitBlock->deleteTrailingDbgRecords();
}

TEST(MetadataTest, DbgVariableRecordConversionRoutines) {
  LLVMContext C;

  std::unique_ptr<Module> M = parseIR(C, R"(
    define i16 @f(i16 %a) !dbg !6 {
      call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11
      %b = add i16 %a, 1, !dbg !11
      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
      ret i16 0, !dbg !11

    exit:
      %c = add i16 %b, 1, !dbg !11
      ret i16 0, !dbg !11
    }
    declare void @llvm.dbg.value(metadata, metadata, metadata) #0
    attributes #0 = { nounwind readnone speculatable willreturn }

    !llvm.dbg.cu = !{!0}
    !llvm.module.flags = !{!5}

    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
    !1 = !DIFile(filename: "t.ll", directory: "/")
    !2 = !{}
    !5 = !{i32 2, !"Debug Info Version", i32 3}
    !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
    !7 = !DISubroutineType(types: !2)
    !8 = !{!9}
    !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
    !11 = !DILocation(line: 1, column: 1, scope: !6)
)");

  // This test exists to check we can convert back and forth between old and new
  // debug info formats (dbg.value intrinsics versus #dbg_value records).
  // We're ripping out support for debug intrinsics, but the conversions will
  // live on in bitcode autoupgrade and possibly DXIL autodowngrade. Thus, this
  // test is still valuable. Begin by starting in the intrinsic format:
  M->convertFromNewDbgValues();

  Function *F = M->getFunction("f");
  BasicBlock *BB1 = &F->getEntryBlock();
  // First instruction should be a dbg.value.
  EXPECT_TRUE(isa<DbgValueInst>(BB1->front()));
  // Validating the block for DbgVariableRecords / DbgMarkers shouldn't fail --
  // there's no data stored right now.
  bool BrokenDebugInfo = false;
  bool Error = verifyModule(*M, &errs(), &BrokenDebugInfo);
  EXPECT_FALSE(Error);
  EXPECT_FALSE(BrokenDebugInfo);

  // Now convert.
  M->convertToNewDbgValues();

  // There should now be no dbg.value instructions!
  // Ensure the first instruction exists, the test all of them.
  EXPECT_FALSE(isa<DbgValueInst>(BB1->front()));
  for (auto &BB : *F)
    for (auto &I : BB)
      EXPECT_FALSE(isa<DbgValueInst>(I));

  // There should be a DbgMarker on each of the two instructions in the entry
  // block, each containing one DbgVariableRecord.
  EXPECT_EQ(BB1->size(), 2u);
  Instruction *FirstInst = &BB1->front();
  Instruction *SecondInst = FirstInst->getNextNode();
  ASSERT_TRUE(FirstInst->DebugMarker);
  ASSERT_TRUE(SecondInst->DebugMarker);
  EXPECT_NE(FirstInst->DebugMarker, SecondInst->DebugMarker);
  EXPECT_EQ(FirstInst, FirstInst->DebugMarker->MarkedInstr);
  EXPECT_EQ(SecondInst, SecondInst->DebugMarker->MarkedInstr);

  EXPECT_EQ(FirstInst->DebugMarker->StoredDbgRecords.size(), 1u);
  DbgVariableRecord *DVR1 = cast<DbgVariableRecord>(
      &*FirstInst->DebugMarker->getDbgRecordRange().begin());
  EXPECT_EQ(DVR1->getMarker(), FirstInst->DebugMarker);
  // Should point at %a, an argument.
  EXPECT_TRUE(isa<Argument>(DVR1->getVariableLocationOp(0)));

  EXPECT_EQ(SecondInst->DebugMarker->StoredDbgRecords.size(), 1u);
  DbgVariableRecord *DVR2 = cast<DbgVariableRecord>(
      &*SecondInst->DebugMarker->getDbgRecordRange().begin());
  EXPECT_EQ(DVR2->getMarker(), SecondInst->DebugMarker);
  // Should point at FirstInst.
  EXPECT_EQ(DVR2->getVariableLocationOp(0), FirstInst);

  // There should be no DbgVariableRecords / DbgMarkers in the second block, but
  // it should be marked as being in the new format.
  BasicBlock *BB2 = BB1->getNextNode();
  for (auto &Inst : *BB2)
    // Either there should be no marker, or it should be empty.
    EXPECT_TRUE(!Inst.DebugMarker ||
                Inst.DebugMarker->StoredDbgRecords.empty());

  // Validating the first block should continue to not be a problem,
  Error = verifyModule(*M, &errs(), &BrokenDebugInfo);
  EXPECT_FALSE(Error);
  EXPECT_FALSE(BrokenDebugInfo);
  // But if we were to break something, it should be able to fire. Don't attempt
  // to comprehensively test the validator, it's a smoke-test rather than a
  // "proper" verification pass.
  DVR1->setMarker(nullptr);
  // A marker pointing the wrong way should be an error.
  Error = verifyModule(*M, &errs(), &BrokenDebugInfo);
  EXPECT_FALSE(Error);
  EXPECT_TRUE(BrokenDebugInfo);
  DVR1->setMarker(FirstInst->DebugMarker);

  DILocalVariable *DLV1 = DVR1->getVariable();
  DIExpression *Expr1 = DVR1->getExpression();
  DILocalVariable *DLV2 = DVR2->getVariable();
  DIExpression *Expr2 = DVR2->getExpression();

  // Convert everything back to the "old" format and ensure it's right.
  M->convertFromNewDbgValues();

  EXPECT_EQ(BB1->size(), 4u);
  ASSERT_TRUE(isa<DbgValueInst>(BB1->front()));
  DbgValueInst *DVI1 = cast<DbgValueInst>(&BB1->front());
  // These dbg.values should still point at the same places.
  EXPECT_TRUE(isa<Argument>(DVI1->getVariableLocationOp(0)));
  DbgValueInst *DVI2 = cast<DbgValueInst>(DVI1->getNextNode()->getNextNode());
  EXPECT_EQ(DVI2->getVariableLocationOp(0), FirstInst);

  // Check a few fields too,
  EXPECT_EQ(DVI1->getVariable(), DLV1);
  EXPECT_EQ(DVI1->getExpression(), Expr1);
  EXPECT_EQ(DVI2->getVariable(), DLV2);
  EXPECT_EQ(DVI2->getExpression(), Expr2);
}

// Test that the hashing function for DISubprograms representing methods produce
// the same result after replacing their scope (the type containing the
// subprogram) from a temporary DIType with the permanent one.
TEST(DIBuilder, HashingDISubprogram) {
  LLVMContext Ctx;
  std::unique_ptr<Module> M = std::make_unique<Module>("MyModule", Ctx);
  DIBuilder DIB(*M);

  DIFile *F = DIB.createFile("main.c", "/");
  DICompileUnit *CU =
      DIB.createCompileUnit(dwarf::DW_LANG_C, F, "Test", false, "", 0);

  llvm::TempDIType ForwardDeclaredType =
      llvm::TempDIType(DIB.createReplaceableCompositeType(
          llvm::dwarf::DW_TAG_structure_type, "MyType", CU, F, 0, 0, 8, 8, {},
          "UniqueIdentifier"));

  // The hashing function is different for declarations and definitions, so
  // create one of each.
  DISubprogram *Declaration =
      DIB.createMethod(ForwardDeclaredType.get(), "MethodName", "LinkageName",
                       F, 0, DIB.createSubroutineType({}));

  DISubprogram *Definition = DIB.createFunction(
      ForwardDeclaredType.get(), "MethodName", "LinkageName", F, 0,
      DIB.createSubroutineType({}), 0, DINode::FlagZero,
      llvm::DISubprogram::SPFlagDefinition, nullptr, Declaration);

  // Produce the hash with the temporary scope.
  unsigned HashDeclaration =
      MDNodeKeyImpl<DISubprogram>(Declaration).getHashValue();
  unsigned HashDefinition =
      MDNodeKeyImpl<DISubprogram>(Definition).getHashValue();

  // Instantiate the real scope and replace the temporary one with it.
  DICompositeType *Type = DIB.createStructType(CU, "MyType", F, 0, 8, 8, {}, {},
                                               {}, 0, {}, "UniqueIdentifier");
  DIB.replaceTemporary(std::move(ForwardDeclaredType), Type);

  // Now make sure the hashing is consistent.
  unsigned HashDeclarationAfter =
      MDNodeKeyImpl<DISubprogram>(Declaration).getHashValue();
  unsigned HashDefinitionAfter =
      MDNodeKeyImpl<DISubprogram>(Definition).getHashValue();

  EXPECT_EQ(HashDeclaration, HashDeclarationAfter);
  EXPECT_EQ(HashDefinition, HashDefinitionAfter);
}

TEST(DIBuilder, CompositeTypes) {
  LLVMContext Ctx;
  std::unique_ptr<Module> M = std::make_unique<Module>("MyModule", Ctx);
  DIBuilder DIB(*M);

  DIFile *F = DIB.createFile("main.c", "/");
  DICompileUnit *CU =
      DIB.createCompileUnit(dwarf::DW_LANG_C, F, "Test", false, "", 0);

  DICompositeType *Class =
      DIB.createClassType(CU, "MyClass", F, 0, 8, 8, 0, {}, nullptr, {}, 0,
                          nullptr, nullptr, "ClassUniqueIdentifier");
  EXPECT_EQ(Class->getTag(), dwarf::DW_TAG_class_type);

  DICompositeType *Struct = DIB.createStructType(
      CU, "MyStruct", F, 0, 8, 8, {}, {}, {}, 0, {}, "StructUniqueIdentifier");
  EXPECT_EQ(Struct->getTag(), dwarf::DW_TAG_structure_type);

  DICompositeType *Union = DIB.createUnionType(CU, "MyUnion", F, 0, 8, 8, {},
                                               {}, 0, "UnionUniqueIdentifier");
  EXPECT_EQ(Union->getTag(), dwarf::DW_TAG_union_type);

  DICompositeType *Array = DIB.createArrayType(8, 8, nullptr, {});
  EXPECT_EQ(Array->getTag(), dwarf::DW_TAG_array_type);

  StringRef ArrayNameExp = "AnArray";
  DICompositeType *NamedArray =
      DIB.createArrayType(nullptr, ArrayNameExp, nullptr, 0, 8, 8, nullptr, {});
  EXPECT_EQ(NamedArray->getTag(), dwarf::DW_TAG_array_type);
  EXPECT_EQ(NamedArray->getName(), ArrayNameExp);

  DICompositeType *Vector = DIB.createVectorType(8, 8, nullptr, {});
  EXPECT_EQ(Vector->getTag(), dwarf::DW_TAG_array_type);

  DICompositeType *Enum = DIB.createEnumerationType(
      CU, "MyEnum", F, 0, 8, 8, {}, nullptr, 0, "EnumUniqueIdentifier");
  EXPECT_EQ(Enum->getTag(), dwarf::DW_TAG_enumeration_type);
}

TEST(DIBuilder, DynamicOffsetAndSize) {
  LLVMContext Ctx;
  auto M = std::make_unique<Module>("MyModule", Ctx);
  DIBuilder DIB(*M);
  DIScope *Scope = DISubprogram::getDistinct(
      Ctx, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0,
      DINode::FlagZero, DISubprogram::SPFlagZero, nullptr);
  DIFile *F = DIB.createFile("main.adb", "/");

  DIVariable *Len = DIB.createAutoVariable(Scope, "length", F, 0, nullptr,
                                           false, DINode::FlagZero, 0);

  DICompositeType *Struct = DIB.createStructType(
      Scope, "some_record", F, 18, Len, 8, DINode::FlagZero, nullptr, {});
  EXPECT_EQ(Struct->getTag(), dwarf::DW_TAG_structure_type);

  SmallVector<uint64_t, 4> ops;
  ops.push_back(llvm::dwarf::DW_OP_push_object_address);
  DIExpression::appendOffset(ops, 3);
  ops.push_back(llvm::dwarf::DW_OP_deref);
  DIExpression *Expr = DIB.createExpression(ops);

  DIDerivedType *Field = DIB.createMemberType(Scope, "field", F, 23, Len, 0,
                                              Expr, DINode::FlagZero, Struct);

  EXPECT_EQ(Field->getRawOffsetInBits(), Expr);
  EXPECT_EQ(Field->getRawSizeInBits(), Len);
}

} // end namespace
