//===- 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/SourceMgr.h"
#include "llvm/Transforms/Utils/Local.h"

#include "gtest/gtest.h"

using namespace llvm;

extern cl::opt<bool> UseNewDbgInfoFormat;

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<DbgValueInst *, 1> DVIs;
  SmallVector<DbgVariableRecord *, 1> DVRs;
  findDbgValues(DVIs, &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(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;
  bool OldDbgValueMode = UseNewDbgInfoFormat;
  UseNewDbgInfoFormat = true;

  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<DbgValueInst *, 2> DVIs;
  SmallVector<DbgVariableRecord *, 2> DVRs;
  findDbgValues(DVIs, &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());
  UseNewDbgInfoFormat = OldDbgValueMode;
}

// Ensure that the order of dbg.value intrinsics returned by findDbgValues, and
// their corresponding DbgVariableRecord representation, are consistent.
TEST(MetadataTest, OrderingOfDbgVariableRecords) {
  bool OldDbgValueMode = UseNewDbgInfoFormat;
  UseNewDbgInfoFormat = false;
  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 i16 %b, metadata !12, 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: "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<DbgValueInst *, 2> DVIs;
  SmallVector<DbgVariableRecord *, 2> DVRs;
  findDbgValues(DVIs, &I, &DVRs);
  ASSERT_EQ(DVIs.size(), 2u);
  ASSERT_EQ(DVRs.size(), 0u);

  // 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".
  DILocalVariable *Var0 = DVIs[0]->getVariable();
  EXPECT_TRUE(Var0->getName() == "bar");
  DILocalVariable *Var1 = DVIs[1]->getVariable();
  EXPECT_TRUE(Var1->getName() == "foo");

  // Now try again, but in DbgVariableRecord form.
  DVIs.clear();

  M->convertToNewDbgValues();
  findDbgValues(DVIs, &I, &DVRs);
  ASSERT_EQ(DVIs.size(), 0u);
  ASSERT_EQ(DVRs.size(), 2u);

  Var0 = DVRs[0]->getVariable();
  EXPECT_TRUE(Var0->getName() == "bar");
  Var1 = DVRs[1]->getVariable();
  EXPECT_TRUE(Var1->getName() == "foo");

  M->convertFromNewDbgValues();
  UseNewDbgInfoFormat = OldDbgValueMode;
}

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(DbgAssignIntrinsicTest, 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:
      call void @llvm.dbg.assign(metadata i32 %v1, metadata !14, metadata !DIExpression(), metadata !17, metadata ptr %p1, metadata !DIExpression()), !dbg !16
      ret void
    }

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

    !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:
      call void @llvm.dbg.assign(metadata i32 undef, metadata !10, metadata !DIExpression(), metadata !12, metadata i32 undef, metadata !DIExpression()), !dbg !13
      %local = alloca i32, align 4, !DIAssignID !12
      call void @llvm.dbg.assign(metadata i32 undef, metadata !16, metadata !DIExpression(), metadata !12, metadata i32 undef, metadata !DIExpression()), !dbg !15
      ret void, !dbg !15
    }

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

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

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

    !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()
    )");

  // 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;
  bool OldDbgValueMode = UseNewDbgInfoFormat;
  UseNewDbgInfoFormat = false;
  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)
)");

  // 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->IsNewDbgInfoFormat = true;
  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();
  UseNewDbgInfoFormat = OldDbgValueMode;
}

TEST(MetadataTest, DbgVariableRecordConversionRoutines) {
  LLVMContext C;

  bool OldDbgValueMode = UseNewDbgInfoFormat;
  UseNewDbgInfoFormat = false;

  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)
)");

  // For the purpose of this test, set and un-set the command line option
  // corresponding to UseNewDbgInfoFormat, but only after parsing, to ensure
  // that the IR starts off in the old format.
  UseNewDbgInfoFormat = true;

  // Check that the conversion routines and utilities between dbg.value
  // debug-info format and DbgVariableRecords works.
  Function *F = M->getFunction("f");
  BasicBlock *BB1 = &F->getEntryBlock();
  // First instruction should be a dbg.value.
  EXPECT_TRUE(isa<DbgValueInst>(BB1->front()));
  EXPECT_FALSE(BB1->IsNewDbgInfoFormat);
  // 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);

  // Function and module should be marked as not having the new format too.
  EXPECT_FALSE(F->IsNewDbgInfoFormat);
  EXPECT_FALSE(M->IsNewDbgInfoFormat);

  // Now convert.
  M->convertToNewDbgValues();
  EXPECT_TRUE(M->IsNewDbgInfoFormat);
  EXPECT_TRUE(F->IsNewDbgInfoFormat);
  EXPECT_TRUE(BB1->IsNewDbgInfoFormat);

  // 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();
  EXPECT_TRUE(BB2->IsNewDbgInfoFormat);
  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_FALSE(M->IsNewDbgInfoFormat);
  EXPECT_FALSE(F->IsNewDbgInfoFormat);
  EXPECT_FALSE(BB1->IsNewDbgInfoFormat);

  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);

  UseNewDbgInfoFormat = OldDbgValueMode;
}

// 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);
}

} // end namespace
