//===- 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(
      DISourceLanguageName(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(MetadataTest, InlinedAtMethodsWithMultipleLevels) {
  LLVMContext C;

  // Create IR with 3 levels of inlining:
  // main() calls inline1() which calls inline2() which calls inline3()
  // We'll test from the perspective of code in inline3()
  std::unique_ptr<Module> M = parseIR(C, R"(
    define void @main() !dbg !10 {
      ret void, !dbg !20
    }

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

    !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1)
    !1 = !DIFile(filename: "test.c", directory: "/test")
    !2 = !{i32 2, !"Debug Info Version", i32 3}

    ; Subprograms for each function in the call chain
    !10 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 100, unit: !0)
    !11 = distinct !DISubprogram(name: "inline1", scope: !1, file: !1, line: 200, unit: !0)
    !12 = distinct !DISubprogram(name: "inline2", scope: !1, file: !1, line: 300, unit: !0)
    !13 = distinct !DISubprogram(name: "inline3", scope: !1, file: !1, line: 400, unit: !0)

    ; Location in inline3 (line 401), inlined at location !21
    !20 = !DILocation(line: 401, column: 5, scope: !13, inlinedAt: !21)

    ; Location in inline2 (line 301) where inline3 was called, inlined at !22
    !21 = !DILocation(line: 301, column: 10, scope: !12, inlinedAt: !22)

    ; Location in inline1 (line 201) where inline2 was called, inlined at !23
    !22 = !DILocation(line: 201, column: 15, scope: !11, inlinedAt: !23)

    ; Location in main (line 101) where inline1 was called (no more inlinedAt)
    !23 = !DILocation(line: 101, column: 3, scope: !10)
  )");

  ASSERT_TRUE(M);

  Function *MainFunc = M->getFunction("main");
  ASSERT_TRUE(MainFunc);
  Instruction &RetInst = MainFunc->getEntryBlock().front();

  // Use getDebugLoc() to get the location from the ret instruction.
  const DILocation *InnermostLoc = RetInst.getDebugLoc().get();
  ASSERT_TRUE(InnermostLoc);

  // Test getScope() - should return the immediate scope (inline3).
  DILocalScope *ImmediateScope = InnermostLoc->getScope();
  ASSERT_TRUE(ImmediateScope);
  EXPECT_TRUE(isa<DISubprogram>(ImmediateScope));
  EXPECT_EQ(cast<DISubprogram>(ImmediateScope)->getName(), "inline3");

  // Test getInlinedAt() - should return the next level in the inlining chain.
  const DILocation *NextLevel = InnermostLoc->getInlinedAt();
  ASSERT_TRUE(NextLevel);
  EXPECT_EQ(NextLevel->getLine(), 301u);
  EXPECT_EQ(cast<DISubprogram>(NextLevel->getScope())->getName(), "inline2");

  // Test getInlinedAtLocation() - should return the outermost location.
  const DILocation *OutermostLoc = InnermostLoc->getInlinedAtLocation();
  ASSERT_TRUE(OutermostLoc);
  EXPECT_EQ(OutermostLoc->getLine(), 101u);
  EXPECT_EQ(OutermostLoc->getColumn(), 3u);
  EXPECT_EQ(OutermostLoc->getInlinedAt(), nullptr);
  EXPECT_EQ(cast<DISubprogram>(OutermostLoc->getScope())->getName(), "main");

  // Test getInlinedAtScope() - should return the scope of the outermost
  // location.
  DILocalScope *InlinedAtScope = InnermostLoc->getInlinedAtScope();
  ASSERT_TRUE(InlinedAtScope);
  EXPECT_TRUE(isa<DISubprogram>(InlinedAtScope));
  EXPECT_EQ(cast<DISubprogram>(InlinedAtScope)->getName(), "main");
  EXPECT_EQ(InlinedAtScope, OutermostLoc->getScope());
}

// 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(
      DISourceLanguageName(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(
      DISourceLanguageName(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
