//===- llvm/unittest/DebugInfo/DWARFDebugInfoTest.cpp ---------------------===//
//
// 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 "DwarfGenerator.h"
#include "DwarfUtils.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/ObjectYAML/DWARFEmitter.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
#include <string>

// AIX doesn't support debug_str_offsets or debug_addr sections
#ifdef _AIX
#define NO_SUPPORT_DEBUG_STR_OFFSETS
#define NO_SUPPORT_DEBUG_ADDR
#endif

using namespace llvm;
using namespace dwarf;
using namespace utils;

namespace {

template <uint16_t Version, class AddrType, class RefAddrType>
void TestAllForms() {
  Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  // Test that we can decode all DW_FORM values correctly.
  const AddrType AddrValue = (AddrType)0x0123456789abcdefULL;
  const AddrType AddrxValue = (AddrType)0x4231abcd4231abcdULL;
  const AddrType Addrx1Value = (AddrType)0x0000aaaabbbbccccULL;
  const AddrType Addrx2Value = (AddrType)0xf00123f00456f000ULL;
  const AddrType Addrx3Value = (AddrType)0xABABA000B111C222ULL;
  const AddrType Addrx4Value = (AddrType)0xa1b2c3d4e5f6e5d4ULL;

  const uint8_t BlockData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
  const uint32_t BlockSize = sizeof(BlockData);
  const RefAddrType RefAddr = 0x12345678;
  const uint8_t Data1 = 0x01U;
  const uint16_t Data2 = 0x2345U;
  const uint32_t Data4 = 0x6789abcdU;
  const uint64_t Data8 = 0x0011223344556677ULL;
  const uint64_t Data8_2 = 0xAABBCCDDEEFF0011ULL;
  const uint8_t Data16[16] = {1, 2,  3,  4,  5,  6,  7,  8,
                              9, 10, 11, 12, 13, 14, 15, 16};
  const int64_t SData = INT64_MIN;
  const int64_t ICSData = INT64_MAX; // DW_FORM_implicit_const SData
  const uint64_t UData[] = {UINT64_MAX - 1, UINT64_MAX - 2, UINT64_MAX - 3,
                            UINT64_MAX - 4, UINT64_MAX - 5, UINT64_MAX - 6,
                            UINT64_MAX - 7, UINT64_MAX - 8, UINT64_MAX - 9};
#define UDATA_1 18446744073709551614ULL
  const uint32_t Dwarf32Values[] = {1, 2, 3, 4, 5, 6, 7, 8};
  const char *StringValue = "Hello";
  const char *StrpValue = "World";
  const char *StrxValue = "Indexed";
  const char *Strx1Value = "Indexed1";
  const char *Strx2Value = "Indexed2";
  const char *Strx3Value = "Indexed3";
  const char *Strx4Value = "Indexed4";

  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();
  dwarfgen::DIE CUDie = CU.getUnitDIE();

  if (Version >= 5) {
    CUDie.addStrOffsetsBaseAttribute();
    CUDie.addAddrBaseAttribute();
  }

  uint16_t Attr = DW_AT_lo_user;

  //----------------------------------------------------------------------
  // Test address forms
  //----------------------------------------------------------------------
  const auto Attr_DW_FORM_addr = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_addr, DW_FORM_addr, AddrValue);

  const auto Attr_DW_FORM_addrx = static_cast<dwarf::Attribute>(Attr++);
  const auto Attr_DW_FORM_addrx1 = static_cast<dwarf::Attribute>(Attr++);
  const auto Attr_DW_FORM_addrx2 = static_cast<dwarf::Attribute>(Attr++);
  const auto Attr_DW_FORM_addrx3 = static_cast<dwarf::Attribute>(Attr++);
  const auto Attr_DW_FORM_addrx4 = static_cast<dwarf::Attribute>(Attr++);

  if (Version >= 5) {
    CUDie.addAttribute(Attr_DW_FORM_addrx, DW_FORM_addrx, AddrxValue);
    CUDie.addAttribute(Attr_DW_FORM_addrx1, DW_FORM_addrx1, Addrx1Value);
    CUDie.addAttribute(Attr_DW_FORM_addrx2, DW_FORM_addrx2, Addrx2Value);
    CUDie.addAttribute(Attr_DW_FORM_addrx3, DW_FORM_addrx3, Addrx3Value);
    CUDie.addAttribute(Attr_DW_FORM_addrx4, DW_FORM_addrx4, Addrx4Value);
  }

  //----------------------------------------------------------------------
  // Test block forms
  //----------------------------------------------------------------------
  const auto Attr_DW_FORM_block = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_block, DW_FORM_block, BlockData, BlockSize);

  const auto Attr_DW_FORM_block1 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_block1, DW_FORM_block1, BlockData, BlockSize);

  const auto Attr_DW_FORM_block2 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_block2, DW_FORM_block2, BlockData, BlockSize);

  const auto Attr_DW_FORM_block4 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_block4, DW_FORM_block4, BlockData, BlockSize);

  // We handle data16 as a block form.
  const auto Attr_DW_FORM_data16 = static_cast<dwarf::Attribute>(Attr++);
  if (Version >= 5)
    CUDie.addAttribute(Attr_DW_FORM_data16, DW_FORM_data16, Data16, 16);

  //----------------------------------------------------------------------
  // Test data forms
  //----------------------------------------------------------------------
  const auto Attr_DW_FORM_data1 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_data1, DW_FORM_data1, Data1);

  const auto Attr_DW_FORM_data2 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_data2, DW_FORM_data2, Data2);

  const auto Attr_DW_FORM_data4 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_data4, DW_FORM_data4, Data4);

  const auto Attr_DW_FORM_data8 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_data8, DW_FORM_data8, Data8);

  //----------------------------------------------------------------------
  // Test string forms
  //----------------------------------------------------------------------
  const auto Attr_DW_FORM_string = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_string, DW_FORM_string, StringValue);

  const auto Attr_DW_FORM_strx = static_cast<dwarf::Attribute>(Attr++);
  const auto Attr_DW_FORM_strx1 = static_cast<dwarf::Attribute>(Attr++);
  const auto Attr_DW_FORM_strx2 = static_cast<dwarf::Attribute>(Attr++);
  const auto Attr_DW_FORM_strx3 = static_cast<dwarf::Attribute>(Attr++);
  const auto Attr_DW_FORM_strx4 = static_cast<dwarf::Attribute>(Attr++);
  if (Version >= 5) {
    CUDie.addAttribute(Attr_DW_FORM_strx, DW_FORM_strx, StrxValue);
    CUDie.addAttribute(Attr_DW_FORM_strx1, DW_FORM_strx1, Strx1Value);
    CUDie.addAttribute(Attr_DW_FORM_strx2, DW_FORM_strx2, Strx2Value);
    CUDie.addAttribute(Attr_DW_FORM_strx3, DW_FORM_strx3, Strx3Value);
    CUDie.addAttribute(Attr_DW_FORM_strx4, DW_FORM_strx4, Strx4Value);
  }

  const auto Attr_DW_FORM_strp = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_strp, DW_FORM_strp, StrpValue);

  //----------------------------------------------------------------------
  // Test reference forms
  //----------------------------------------------------------------------
  const auto Attr_DW_FORM_ref_addr = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_ref_addr, DW_FORM_ref_addr, RefAddr);

  const auto Attr_DW_FORM_ref1 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_ref1, DW_FORM_ref1, Data1);

  const auto Attr_DW_FORM_ref2 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_ref2, DW_FORM_ref2, Data2);

  const auto Attr_DW_FORM_ref4 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_ref4, DW_FORM_ref4, Data4);

  const auto Attr_DW_FORM_ref8 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_ref8, DW_FORM_ref8, Data8);

  const auto Attr_DW_FORM_ref_sig8 = static_cast<dwarf::Attribute>(Attr++);
  if (Version >= 4)
    CUDie.addAttribute(Attr_DW_FORM_ref_sig8, DW_FORM_ref_sig8, Data8_2);

  const auto Attr_DW_FORM_ref_udata = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_ref_udata, DW_FORM_ref_udata, UData[0]);

  //----------------------------------------------------------------------
  // Test flag forms
  //----------------------------------------------------------------------
  const auto Attr_DW_FORM_flag_true = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_flag_true, DW_FORM_flag, true);

  const auto Attr_DW_FORM_flag_false = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_flag_false, DW_FORM_flag, false);

  const auto Attr_DW_FORM_flag_present = static_cast<dwarf::Attribute>(Attr++);
  if (Version >= 4)
    CUDie.addAttribute(Attr_DW_FORM_flag_present, DW_FORM_flag_present);

  //----------------------------------------------------------------------
  // Test SLEB128 based forms
  //----------------------------------------------------------------------
  const auto Attr_DW_FORM_sdata = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_sdata, DW_FORM_sdata, SData);

  const auto Attr_DW_FORM_implicit_const =
    static_cast<dwarf::Attribute>(Attr++);
  if (Version >= 5)
    CUDie.addAttribute(Attr_DW_FORM_implicit_const, DW_FORM_implicit_const,
                       ICSData);

  //----------------------------------------------------------------------
  // Test ULEB128 based forms
  //----------------------------------------------------------------------
  const auto Attr_DW_FORM_udata = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_udata, DW_FORM_udata, UData[0]);

  //----------------------------------------------------------------------
  // Test DWARF32/DWARF64 forms
  //----------------------------------------------------------------------
  const auto Attr_DW_FORM_GNU_ref_alt = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_DW_FORM_GNU_ref_alt, DW_FORM_GNU_ref_alt,
                     Dwarf32Values[0]);

  const auto Attr_DW_FORM_sec_offset = static_cast<dwarf::Attribute>(Attr++);
  if (Version >= 4)
    CUDie.addAttribute(Attr_DW_FORM_sec_offset, DW_FORM_sec_offset,
                       Dwarf32Values[1]);

  //----------------------------------------------------------------------
  // Add an address at the end to make sure we can decode this value
  //----------------------------------------------------------------------
  const auto Attr_Last = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr_Last, DW_FORM_addr, AddrValue);

  //----------------------------------------------------------------------
  // Generate the DWARF
  //----------------------------------------------------------------------
  StringRef FileBytes = DG->generate();
  MemoryBufferRef FileBuffer(FileBytes, "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  EXPECT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  EXPECT_EQ(NumCUs, 1u);
  DWARFCompileUnit *U =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
  auto DieDG = U->getUnitDIE(false);
  EXPECT_TRUE(DieDG.isValid());

  //----------------------------------------------------------------------
  // Test address forms
  //----------------------------------------------------------------------
  EXPECT_EQ(AddrValue, toAddress(DieDG.find(Attr_DW_FORM_addr), 0));

  if (Version >= 5) {
    auto ExtractedAddrxValue = toAddress(DieDG.find(Attr_DW_FORM_addrx));
    EXPECT_TRUE(ExtractedAddrxValue.has_value());
    EXPECT_EQ(AddrxValue, *ExtractedAddrxValue);

    auto ExtractedAddrx1Value = toAddress(DieDG.find(Attr_DW_FORM_addrx1));
    EXPECT_TRUE(ExtractedAddrx1Value.has_value());
    EXPECT_EQ(Addrx1Value, *ExtractedAddrx1Value);

    auto ExtractedAddrx2Value = toAddress(DieDG.find(Attr_DW_FORM_addrx2));
    EXPECT_TRUE(ExtractedAddrx2Value.has_value());
    EXPECT_EQ(Addrx2Value, *ExtractedAddrx2Value);

    auto ExtractedAddrx3Value = toAddress(DieDG.find(Attr_DW_FORM_addrx3));
    EXPECT_TRUE(ExtractedAddrx3Value.has_value());
    EXPECT_EQ(Addrx3Value, *ExtractedAddrx3Value);

    auto ExtractedAddrx4Value = toAddress(DieDG.find(Attr_DW_FORM_addrx4));
    EXPECT_TRUE(ExtractedAddrx1Value.has_value());
    EXPECT_EQ(Addrx4Value, *ExtractedAddrx4Value);
  }

  //----------------------------------------------------------------------
  // Test block forms
  //----------------------------------------------------------------------
  std::optional<DWARFFormValue> FormValue;
  ArrayRef<uint8_t> ExtractedBlockData;
  std::optional<ArrayRef<uint8_t>> BlockDataOpt;

  FormValue = DieDG.find(Attr_DW_FORM_block);
  EXPECT_TRUE((bool)FormValue);
  BlockDataOpt = FormValue->getAsBlock();
  EXPECT_TRUE(BlockDataOpt.has_value());
  ExtractedBlockData = *BlockDataOpt;
  EXPECT_EQ(ExtractedBlockData.size(), BlockSize);
  EXPECT_TRUE(memcmp(ExtractedBlockData.data(), BlockData, BlockSize) == 0);

  FormValue = DieDG.find(Attr_DW_FORM_block1);
  EXPECT_TRUE((bool)FormValue);
  BlockDataOpt = FormValue->getAsBlock();
  EXPECT_TRUE(BlockDataOpt.has_value());
  ExtractedBlockData = *BlockDataOpt;
  EXPECT_EQ(ExtractedBlockData.size(), BlockSize);
  EXPECT_TRUE(memcmp(ExtractedBlockData.data(), BlockData, BlockSize) == 0);

  FormValue = DieDG.find(Attr_DW_FORM_block2);
  EXPECT_TRUE((bool)FormValue);
  BlockDataOpt = FormValue->getAsBlock();
  EXPECT_TRUE(BlockDataOpt.has_value());
  ExtractedBlockData = *BlockDataOpt;
  EXPECT_EQ(ExtractedBlockData.size(), BlockSize);
  EXPECT_TRUE(memcmp(ExtractedBlockData.data(), BlockData, BlockSize) == 0);

  FormValue = DieDG.find(Attr_DW_FORM_block4);
  EXPECT_TRUE((bool)FormValue);
  BlockDataOpt = FormValue->getAsBlock();
  EXPECT_TRUE(BlockDataOpt.has_value());
  ExtractedBlockData = *BlockDataOpt;
  EXPECT_EQ(ExtractedBlockData.size(), BlockSize);
  EXPECT_TRUE(memcmp(ExtractedBlockData.data(), BlockData, BlockSize) == 0);

  // Data16 is handled like a block.
  if (Version >= 5) {
    FormValue = DieDG.find(Attr_DW_FORM_data16);
    EXPECT_TRUE((bool)FormValue);
    BlockDataOpt = FormValue->getAsBlock();
    EXPECT_TRUE(BlockDataOpt.has_value());
    ExtractedBlockData = *BlockDataOpt;
    EXPECT_EQ(ExtractedBlockData.size(), 16u);
    EXPECT_TRUE(memcmp(ExtractedBlockData.data(), Data16, 16) == 0);
  }

  //----------------------------------------------------------------------
  // Test data forms
  //----------------------------------------------------------------------
  EXPECT_EQ(Data1, toUnsigned(DieDG.find(Attr_DW_FORM_data1), 0));
  EXPECT_EQ(Data2, toUnsigned(DieDG.find(Attr_DW_FORM_data2), 0));
  EXPECT_EQ(Data4, toUnsigned(DieDG.find(Attr_DW_FORM_data4), 0));
  EXPECT_EQ(Data8, toUnsigned(DieDG.find(Attr_DW_FORM_data8), 0));

  //----------------------------------------------------------------------
  // Test string forms
  //----------------------------------------------------------------------
  auto ExtractedStringValue = toString(DieDG.find(Attr_DW_FORM_string));
  EXPECT_TRUE((bool)ExtractedStringValue);
  EXPECT_STREQ(StringValue, *ExtractedStringValue);

  if (Version >= 5) {
    auto ExtractedStrxValue = toString(DieDG.find(Attr_DW_FORM_strx));
    EXPECT_TRUE((bool)ExtractedStrxValue);
    EXPECT_STREQ(StrxValue, *ExtractedStrxValue);

    auto ExtractedStrx1Value = toString(DieDG.find(Attr_DW_FORM_strx1));
    EXPECT_TRUE((bool)ExtractedStrx1Value);
    EXPECT_STREQ(Strx1Value, *ExtractedStrx1Value);

    auto ExtractedStrx2Value = toString(DieDG.find(Attr_DW_FORM_strx2));
    EXPECT_TRUE((bool)ExtractedStrx2Value);
    EXPECT_STREQ(Strx2Value, *ExtractedStrx2Value);

    auto ExtractedStrx3Value = toString(DieDG.find(Attr_DW_FORM_strx3));
    EXPECT_TRUE((bool)ExtractedStrx3Value);
    EXPECT_STREQ(Strx3Value, *ExtractedStrx3Value);

    auto ExtractedStrx4Value = toString(DieDG.find(Attr_DW_FORM_strx4));
    EXPECT_TRUE((bool)ExtractedStrx4Value);
    EXPECT_STREQ(Strx4Value, *ExtractedStrx4Value);
  }

  auto ExtractedStrpValue = toString(DieDG.find(Attr_DW_FORM_strp));
  EXPECT_TRUE((bool)ExtractedStrpValue);
  EXPECT_STREQ(StrpValue, *ExtractedStrpValue);

  //----------------------------------------------------------------------
  // Test reference forms
  //----------------------------------------------------------------------
  EXPECT_EQ(RefAddr, toReference(DieDG.find(Attr_DW_FORM_ref_addr), 0));
  EXPECT_EQ(Data1, toReference(DieDG.find(Attr_DW_FORM_ref1), 0));
  EXPECT_EQ(Data2, toReference(DieDG.find(Attr_DW_FORM_ref2), 0));
  EXPECT_EQ(Data4, toReference(DieDG.find(Attr_DW_FORM_ref4), 0));
  EXPECT_EQ(Data8, toReference(DieDG.find(Attr_DW_FORM_ref8), 0));
  if (Version >= 4) {
    EXPECT_EQ(Data8_2, toReference(DieDG.find(Attr_DW_FORM_ref_sig8), 0));
  }
  EXPECT_EQ(UData[0], toReference(DieDG.find(Attr_DW_FORM_ref_udata), 0));

  //----------------------------------------------------------------------
  // Test flag forms
  //----------------------------------------------------------------------
  EXPECT_EQ(1ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_true), 0));
  EXPECT_EQ(0ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_false), 1));
  if (Version >= 4) {
    EXPECT_EQ(1ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_present), 0));
  }

  //----------------------------------------------------------------------
  // Test SLEB128 based forms
  //----------------------------------------------------------------------
  EXPECT_EQ(SData, toSigned(DieDG.find(Attr_DW_FORM_sdata), 0));
  if (Version >= 5) {
    EXPECT_EQ(ICSData, toSigned(DieDG.find(Attr_DW_FORM_implicit_const), 0));
  }

  //----------------------------------------------------------------------
  // Test ULEB128 based forms
  //----------------------------------------------------------------------
  EXPECT_EQ(UData[0], toUnsigned(DieDG.find(Attr_DW_FORM_udata), 0));

  //----------------------------------------------------------------------
  // Test DWARF32/DWARF64 forms
  //----------------------------------------------------------------------
  EXPECT_EQ(Dwarf32Values[0],
            toReference(DieDG.find(Attr_DW_FORM_GNU_ref_alt), 0));
  if (Version >= 4) {
    EXPECT_EQ(Dwarf32Values[1],
              toSectionOffset(DieDG.find(Attr_DW_FORM_sec_offset), 0));
  }

  //----------------------------------------------------------------------
  // Add an address at the end to make sure we can decode this value
  //----------------------------------------------------------------------
  EXPECT_EQ(AddrValue, toAddress(DieDG.find(Attr_Last), 0));
}

TEST(DWARFDebugInfo, TestDWARF32Version2Addr4AllForms) {
  // Test that we can decode all forms for DWARF32, version 2, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  // DW_FORM_ref_addr are the same as the address type in DWARF32 version 2.
  typedef AddrType RefAddrType;
  TestAllForms<2, AddrType, RefAddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version2Addr8AllForms) {
  // Test that we can decode all forms for DWARF32, version 2, with 4 byte
  // addresses.
  typedef uint64_t AddrType;
  // DW_FORM_ref_addr are the same as the address type in DWARF32 version 2.
  typedef AddrType RefAddrType;
  TestAllForms<2, AddrType, RefAddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version3Addr4AllForms) {
  // Test that we can decode all forms for DWARF32, version 3, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later.
  typedef uint32_t RefAddrType;
  TestAllForms<3, AddrType, RefAddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version3Addr8AllForms) {
  // Test that we can decode all forms for DWARF32, version 3, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later
  typedef uint32_t RefAddrType;
  TestAllForms<3, AddrType, RefAddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version4Addr4AllForms) {
  // Test that we can decode all forms for DWARF32, version 4, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later
  typedef uint32_t RefAddrType;
  TestAllForms<4, AddrType, RefAddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version4Addr8AllForms) {
  // Test that we can decode all forms for DWARF32, version 4, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later
  typedef uint32_t RefAddrType;
  TestAllForms<4, AddrType, RefAddrType>();
}

#ifdef NO_SUPPORT_DEBUG_STR_OFFSETS
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version5Addr4AllForms) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version5Addr4AllForms) {
#endif
  // Test that we can decode all forms for DWARF32, version 5, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later
  typedef uint32_t RefAddrType;
  TestAllForms<5, AddrType, RefAddrType>();
}

#ifdef NO_SUPPORT_DEBUG_STR_OFFSETS
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version5Addr8AllForms) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version5Addr8AllForms) {
#endif
  // Test that we can decode all forms for DWARF32, version 5, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  // DW_FORM_ref_addr are 4 bytes in DWARF32 for version 3 and later
  typedef uint32_t RefAddrType;
  TestAllForms<5, AddrType, RefAddrType>();
}

template <uint16_t Version, class AddrType> void TestChildren() {
  Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  // Test that we can decode DW_FORM_ref_addr values correctly in DWARF 2 with
  // 4 byte addresses. DW_FORM_ref_addr values should be 4 bytes when using
  // 8 byte addresses.

  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();
  dwarfgen::DIE CUDie = CU.getUnitDIE();

  CUDie.addAttribute(DW_AT_name, DW_FORM_strp, "/tmp/main.c");
  CUDie.addAttribute(DW_AT_language, DW_FORM_data2, DW_LANG_C);

  dwarfgen::DIE SubprogramDie = CUDie.addChild(DW_TAG_subprogram);
  SubprogramDie.addAttribute(DW_AT_name, DW_FORM_strp, "main");
  SubprogramDie.addAttribute(DW_AT_low_pc, DW_FORM_addr, 0x1000U);
  SubprogramDie.addAttribute(DW_AT_high_pc, DW_FORM_addr, 0x2000U);

  dwarfgen::DIE IntDie = CUDie.addChild(DW_TAG_base_type);
  IntDie.addAttribute(DW_AT_name, DW_FORM_strp, "int");
  IntDie.addAttribute(DW_AT_encoding, DW_FORM_data1, DW_ATE_signed);
  IntDie.addAttribute(DW_AT_byte_size, DW_FORM_data1, 4);

  dwarfgen::DIE ArgcDie = SubprogramDie.addChild(DW_TAG_formal_parameter);
  ArgcDie.addAttribute(DW_AT_name, DW_FORM_strp, "argc");
  // ArgcDie.addAttribute(DW_AT_type, DW_FORM_ref4, IntDie);
  ArgcDie.addAttribute(DW_AT_type, DW_FORM_ref_addr, IntDie);

  StringRef FileBytes = DG->generate();
  MemoryBufferRef FileBuffer(FileBytes, "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  EXPECT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);

  // Verify the number of compile units is correct.
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  EXPECT_EQ(NumCUs, 1u);
  DWARFCompileUnit *U =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));

  // Get the compile unit DIE is valid.
  auto DieDG = U->getUnitDIE(false);
  EXPECT_TRUE(DieDG.isValid());

  // Verify the first child of the compile unit DIE is our subprogram.
  auto SubprogramDieDG = DieDG.getFirstChild();
  EXPECT_TRUE(SubprogramDieDG.isValid());
  EXPECT_EQ(SubprogramDieDG.getTag(), DW_TAG_subprogram);

  // Verify the first child of the subprogram is our formal parameter.
  auto ArgcDieDG = SubprogramDieDG.getFirstChild();
  EXPECT_TRUE(ArgcDieDG.isValid());
  EXPECT_EQ(ArgcDieDG.getTag(), DW_TAG_formal_parameter);

  // Verify our formal parameter has a NULL tag sibling.
  auto NullDieDG = ArgcDieDG.getSibling();
  EXPECT_TRUE(NullDieDG.isValid());
  if (NullDieDG) {
    EXPECT_EQ(NullDieDG.getTag(), DW_TAG_null);
    EXPECT_TRUE(!NullDieDG.getSibling().isValid());
    EXPECT_TRUE(!NullDieDG.getFirstChild().isValid());
  }

  // Verify the sibling of our subprogram is our integer base type.
  auto IntDieDG = SubprogramDieDG.getSibling();
  EXPECT_TRUE(IntDieDG.isValid());
  EXPECT_EQ(IntDieDG.getTag(), DW_TAG_base_type);

  // Verify the sibling of our subprogram is our integer base is a NULL tag.
  NullDieDG = IntDieDG.getSibling();
  EXPECT_TRUE(NullDieDG.isValid());
  if (NullDieDG) {
    EXPECT_EQ(NullDieDG.getTag(), DW_TAG_null);
    EXPECT_TRUE(!NullDieDG.getSibling().isValid());
    EXPECT_TRUE(!NullDieDG.getFirstChild().isValid());
  }

  // Verify the previous sibling of our subprogram is our integer base type.
  IntDieDG = NullDieDG.getPreviousSibling();
  EXPECT_TRUE(IntDieDG.isValid());
  EXPECT_EQ(IntDieDG.getTag(), DW_TAG_base_type);
}

TEST(DWARFDebugInfo, TestDWARF32Version2Addr4Children) {
  // Test that we can decode all forms for DWARF32, version 2, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  TestChildren<2, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version2Addr8Children) {
  // Test that we can decode all forms for DWARF32, version 2, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  TestChildren<2, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version3Addr4Children) {
  // Test that we can decode all forms for DWARF32, version 3, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  TestChildren<3, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version3Addr8Children) {
  // Test that we can decode all forms for DWARF32, version 3, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  TestChildren<3, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version4Addr4Children) {
  // Test that we can decode all forms for DWARF32, version 4, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  TestChildren<4, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version4Addr8Children) {
  // Test that we can decode all forms for DWARF32, version 4, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  TestChildren<4, AddrType>();
}

template <uint16_t Version, class AddrType> void TestReferences() {
  Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  // Test that we can decode DW_FORM_refXXX values correctly in DWARF.
  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU1 = DG->addCompileUnit();
  dwarfgen::CompileUnit &CU2 = DG->addCompileUnit();

  dwarfgen::DIE CU1Die = CU1.getUnitDIE();
  CU1Die.addAttribute(DW_AT_name, DW_FORM_strp, "/tmp/main.c");
  CU1Die.addAttribute(DW_AT_language, DW_FORM_data2, DW_LANG_C);

  dwarfgen::DIE CU1TypeDie = CU1Die.addChild(DW_TAG_base_type);
  CU1TypeDie.addAttribute(DW_AT_name, DW_FORM_strp, "int");
  CU1TypeDie.addAttribute(DW_AT_encoding, DW_FORM_data1, DW_ATE_signed);
  CU1TypeDie.addAttribute(DW_AT_byte_size, DW_FORM_data1, 4);

  dwarfgen::DIE CU1Ref1Die = CU1Die.addChild(DW_TAG_variable);
  CU1Ref1Die.addAttribute(DW_AT_name, DW_FORM_strp, "CU1Ref1");
  CU1Ref1Die.addAttribute(DW_AT_type, DW_FORM_ref1, CU1TypeDie);

  dwarfgen::DIE CU1Ref2Die = CU1Die.addChild(DW_TAG_variable);
  CU1Ref2Die.addAttribute(DW_AT_name, DW_FORM_strp, "CU1Ref2");
  CU1Ref2Die.addAttribute(DW_AT_type, DW_FORM_ref2, CU1TypeDie);

  dwarfgen::DIE CU1Ref4Die = CU1Die.addChild(DW_TAG_variable);
  CU1Ref4Die.addAttribute(DW_AT_name, DW_FORM_strp, "CU1Ref4");
  CU1Ref4Die.addAttribute(DW_AT_type, DW_FORM_ref4, CU1TypeDie);

  dwarfgen::DIE CU1Ref8Die = CU1Die.addChild(DW_TAG_variable);
  CU1Ref8Die.addAttribute(DW_AT_name, DW_FORM_strp, "CU1Ref8");
  CU1Ref8Die.addAttribute(DW_AT_type, DW_FORM_ref8, CU1TypeDie);

  dwarfgen::DIE CU1RefAddrDie = CU1Die.addChild(DW_TAG_variable);
  CU1RefAddrDie.addAttribute(DW_AT_name, DW_FORM_strp, "CU1RefAddr");
  CU1RefAddrDie.addAttribute(DW_AT_type, DW_FORM_ref_addr, CU1TypeDie);

  dwarfgen::DIE CU2Die = CU2.getUnitDIE();
  CU2Die.addAttribute(DW_AT_name, DW_FORM_strp, "/tmp/foo.c");
  CU2Die.addAttribute(DW_AT_language, DW_FORM_data2, DW_LANG_C);

  dwarfgen::DIE CU2TypeDie = CU2Die.addChild(DW_TAG_base_type);
  CU2TypeDie.addAttribute(DW_AT_name, DW_FORM_strp, "float");
  CU2TypeDie.addAttribute(DW_AT_encoding, DW_FORM_data1, DW_ATE_float);
  CU2TypeDie.addAttribute(DW_AT_byte_size, DW_FORM_data1, 4);

  dwarfgen::DIE CU2Ref1Die = CU2Die.addChild(DW_TAG_variable);
  CU2Ref1Die.addAttribute(DW_AT_name, DW_FORM_strp, "CU2Ref1");
  CU2Ref1Die.addAttribute(DW_AT_type, DW_FORM_ref1, CU2TypeDie);

  dwarfgen::DIE CU2Ref2Die = CU2Die.addChild(DW_TAG_variable);
  CU2Ref2Die.addAttribute(DW_AT_name, DW_FORM_strp, "CU2Ref2");
  CU2Ref2Die.addAttribute(DW_AT_type, DW_FORM_ref2, CU2TypeDie);

  dwarfgen::DIE CU2Ref4Die = CU2Die.addChild(DW_TAG_variable);
  CU2Ref4Die.addAttribute(DW_AT_name, DW_FORM_strp, "CU2Ref4");
  CU2Ref4Die.addAttribute(DW_AT_type, DW_FORM_ref4, CU2TypeDie);

  dwarfgen::DIE CU2Ref8Die = CU2Die.addChild(DW_TAG_variable);
  CU2Ref8Die.addAttribute(DW_AT_name, DW_FORM_strp, "CU2Ref8");
  CU2Ref8Die.addAttribute(DW_AT_type, DW_FORM_ref8, CU2TypeDie);

  dwarfgen::DIE CU2RefAddrDie = CU2Die.addChild(DW_TAG_variable);
  CU2RefAddrDie.addAttribute(DW_AT_name, DW_FORM_strp, "CU2RefAddr");
  CU2RefAddrDie.addAttribute(DW_AT_type, DW_FORM_ref_addr, CU2TypeDie);

  // Refer to a type in CU1 from CU2
  dwarfgen::DIE CU2ToCU1RefAddrDie = CU2Die.addChild(DW_TAG_variable);
  CU2ToCU1RefAddrDie.addAttribute(DW_AT_name, DW_FORM_strp, "CU2ToCU1RefAddr");
  CU2ToCU1RefAddrDie.addAttribute(DW_AT_type, DW_FORM_ref_addr, CU1TypeDie);

  // Refer to a type in CU2 from CU1
  dwarfgen::DIE CU1ToCU2RefAddrDie = CU1Die.addChild(DW_TAG_variable);
  CU1ToCU2RefAddrDie.addAttribute(DW_AT_name, DW_FORM_strp, "CU1ToCU2RefAddr");
  CU1ToCU2RefAddrDie.addAttribute(DW_AT_type, DW_FORM_ref_addr, CU2TypeDie);

  StringRef FileBytes = DG->generate();
  MemoryBufferRef FileBuffer(FileBytes, "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  EXPECT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);

  // Verify the number of compile units is correct.
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  EXPECT_EQ(NumCUs, 2u);
  DWARFCompileUnit *U1 =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
  DWARFCompileUnit *U2 =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(1));

  // Get the compile unit DIE is valid.
  auto Unit1DieDG = U1->getUnitDIE(false);
  EXPECT_TRUE(Unit1DieDG.isValid());

  auto Unit2DieDG = U2->getUnitDIE(false);
  EXPECT_TRUE(Unit2DieDG.isValid());

  // Verify the first child of the compile unit 1 DIE is our int base type.
  auto CU1TypeDieDG = Unit1DieDG.getFirstChild();
  EXPECT_TRUE(CU1TypeDieDG.isValid());
  EXPECT_EQ(CU1TypeDieDG.getTag(), DW_TAG_base_type);
  EXPECT_EQ(DW_ATE_signed, toUnsigned(CU1TypeDieDG.find(DW_AT_encoding), 0));

  // Verify the first child of the compile unit 2 DIE is our float base type.
  auto CU2TypeDieDG = Unit2DieDG.getFirstChild();
  EXPECT_TRUE(CU2TypeDieDG.isValid());
  EXPECT_EQ(CU2TypeDieDG.getTag(), DW_TAG_base_type);
  EXPECT_EQ(DW_ATE_float, toUnsigned(CU2TypeDieDG.find(DW_AT_encoding), 0));

  // Verify the sibling of the base type DIE is our Ref1 DIE and that its
  // DW_AT_type points to our base type DIE.
  auto CU1Ref1DieDG = CU1TypeDieDG.getSibling();
  EXPECT_TRUE(CU1Ref1DieDG.isValid());
  EXPECT_EQ(CU1Ref1DieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU1TypeDieDG.getOffset(),
            toReference(CU1Ref1DieDG.find(DW_AT_type), -1ULL));
  // Verify the sibling is our Ref2 DIE and that its DW_AT_type points to our
  // base type DIE in CU1.
  auto CU1Ref2DieDG = CU1Ref1DieDG.getSibling();
  EXPECT_TRUE(CU1Ref2DieDG.isValid());
  EXPECT_EQ(CU1Ref2DieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU1TypeDieDG.getOffset(),
            toReference(CU1Ref2DieDG.find(DW_AT_type), -1ULL));

  // Verify the sibling is our Ref4 DIE and that its DW_AT_type points to our
  // base type DIE in CU1.
  auto CU1Ref4DieDG = CU1Ref2DieDG.getSibling();
  EXPECT_TRUE(CU1Ref4DieDG.isValid());
  EXPECT_EQ(CU1Ref4DieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU1TypeDieDG.getOffset(),
            toReference(CU1Ref4DieDG.find(DW_AT_type), -1ULL));

  // Verify the sibling is our Ref8 DIE and that its DW_AT_type points to our
  // base type DIE in CU1.
  auto CU1Ref8DieDG = CU1Ref4DieDG.getSibling();
  EXPECT_TRUE(CU1Ref8DieDG.isValid());
  EXPECT_EQ(CU1Ref8DieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU1TypeDieDG.getOffset(),
            toReference(CU1Ref8DieDG.find(DW_AT_type), -1ULL));

  // Verify the sibling is our RefAddr DIE and that its DW_AT_type points to our
  // base type DIE in CU1.
  auto CU1RefAddrDieDG = CU1Ref8DieDG.getSibling();
  EXPECT_TRUE(CU1RefAddrDieDG.isValid());
  EXPECT_EQ(CU1RefAddrDieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU1TypeDieDG.getOffset(),
            toReference(CU1RefAddrDieDG.find(DW_AT_type), -1ULL));

  // Verify the sibling of the Ref4 DIE is our RefAddr DIE and that its
  // DW_AT_type points to our base type DIE.
  auto CU1ToCU2RefAddrDieDG = CU1RefAddrDieDG.getSibling();
  EXPECT_TRUE(CU1ToCU2RefAddrDieDG.isValid());
  EXPECT_EQ(CU1ToCU2RefAddrDieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU2TypeDieDG.getOffset(),
            toReference(CU1ToCU2RefAddrDieDG.find(DW_AT_type), -1ULL));

  // Verify the sibling of the base type DIE is our Ref1 DIE and that its
  // DW_AT_type points to our base type DIE.
  auto CU2Ref1DieDG = CU2TypeDieDG.getSibling();
  EXPECT_TRUE(CU2Ref1DieDG.isValid());
  EXPECT_EQ(CU2Ref1DieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU2TypeDieDG.getOffset(),
            toReference(CU2Ref1DieDG.find(DW_AT_type), -1ULL));
  // Verify the sibling is our Ref2 DIE and that its DW_AT_type points to our
  // base type DIE in CU2.
  auto CU2Ref2DieDG = CU2Ref1DieDG.getSibling();
  EXPECT_TRUE(CU2Ref2DieDG.isValid());
  EXPECT_EQ(CU2Ref2DieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU2TypeDieDG.getOffset(),
            toReference(CU2Ref2DieDG.find(DW_AT_type), -1ULL));

  // Verify the sibling is our Ref4 DIE and that its DW_AT_type points to our
  // base type DIE in CU2.
  auto CU2Ref4DieDG = CU2Ref2DieDG.getSibling();
  EXPECT_TRUE(CU2Ref4DieDG.isValid());
  EXPECT_EQ(CU2Ref4DieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU2TypeDieDG.getOffset(),
            toReference(CU2Ref4DieDG.find(DW_AT_type), -1ULL));

  // Verify the sibling is our Ref8 DIE and that its DW_AT_type points to our
  // base type DIE in CU2.
  auto CU2Ref8DieDG = CU2Ref4DieDG.getSibling();
  EXPECT_TRUE(CU2Ref8DieDG.isValid());
  EXPECT_EQ(CU2Ref8DieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU2TypeDieDG.getOffset(),
            toReference(CU2Ref8DieDG.find(DW_AT_type), -1ULL));

  // Verify the sibling is our RefAddr DIE and that its DW_AT_type points to our
  // base type DIE in CU2.
  auto CU2RefAddrDieDG = CU2Ref8DieDG.getSibling();
  EXPECT_TRUE(CU2RefAddrDieDG.isValid());
  EXPECT_EQ(CU2RefAddrDieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU2TypeDieDG.getOffset(),
            toReference(CU2RefAddrDieDG.find(DW_AT_type), -1ULL));

  // Verify the sibling of the Ref4 DIE is our RefAddr DIE and that its
  // DW_AT_type points to our base type DIE.
  auto CU2ToCU1RefAddrDieDG = CU2RefAddrDieDG.getSibling();
  EXPECT_TRUE(CU2ToCU1RefAddrDieDG.isValid());
  EXPECT_EQ(CU2ToCU1RefAddrDieDG.getTag(), DW_TAG_variable);
  EXPECT_EQ(CU1TypeDieDG.getOffset(),
            toReference(CU2ToCU1RefAddrDieDG.find(DW_AT_type), -1ULL));
}

TEST(DWARFDebugInfo, TestDWARF32Version2Addr4References) {
  // Test that we can decode all forms for DWARF32, version 2, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  TestReferences<2, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version2Addr8References) {
  // Test that we can decode all forms for DWARF32, version 2, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  TestReferences<2, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version3Addr4References) {
  // Test that we can decode all forms for DWARF32, version 3, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  TestReferences<3, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version3Addr8References) {
  // Test that we can decode all forms for DWARF32, version 3, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  TestReferences<3, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version4Addr4References) {
  // Test that we can decode all forms for DWARF32, version 4, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  TestReferences<4, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version4Addr8References) {
  // Test that we can decode all forms for DWARF32, version 4, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  TestReferences<4, AddrType>();
}

template <uint16_t Version, class AddrType> void TestAddresses() {
  Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  // Test the DWARF APIs related to accessing the DW_AT_low_pc and
  // DW_AT_high_pc.
  const bool SupportsHighPCAsOffset = Version >= 4;
  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();
  dwarfgen::DIE CUDie = CU.getUnitDIE();

  CUDie.addAttribute(DW_AT_name, DW_FORM_strp, "/tmp/main.c");
  CUDie.addAttribute(DW_AT_language, DW_FORM_data2, DW_LANG_C);

  // Create a subprogram DIE with no low or high PC.
  dwarfgen::DIE SubprogramNoPC = CUDie.addChild(DW_TAG_subprogram);
  SubprogramNoPC.addAttribute(DW_AT_name, DW_FORM_strp, "no_pc");

  // Create a subprogram DIE with a low PC only.
  dwarfgen::DIE SubprogramLowPC = CUDie.addChild(DW_TAG_subprogram);
  SubprogramLowPC.addAttribute(DW_AT_name, DW_FORM_strp, "low_pc");
  const uint64_t ActualLowPC = 0x1000;
  const uint64_t ActualHighPC = 0x2000;
  const uint64_t ActualHighPCOffset = ActualHighPC - ActualLowPC;
  SubprogramLowPC.addAttribute(DW_AT_low_pc, DW_FORM_addr, ActualLowPC);

  // Create a subprogram DIE with a low and high PC.
  dwarfgen::DIE SubprogramLowHighPC = CUDie.addChild(DW_TAG_subprogram);
  SubprogramLowHighPC.addAttribute(DW_AT_name, DW_FORM_strp, "low_high_pc");
  SubprogramLowHighPC.addAttribute(DW_AT_low_pc, DW_FORM_addr, ActualLowPC);
  // Encode the high PC as an offset from the low PC if supported.
  if (SupportsHighPCAsOffset)
    SubprogramLowHighPC.addAttribute(DW_AT_high_pc, DW_FORM_data4,
                                     ActualHighPCOffset);
  else
    SubprogramLowHighPC.addAttribute(DW_AT_high_pc, DW_FORM_addr, ActualHighPC);

  StringRef FileBytes = DG->generate();
  MemoryBufferRef FileBuffer(FileBytes, "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  EXPECT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);

  // Verify the number of compile units is correct.
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  EXPECT_EQ(NumCUs, 1u);
  DWARFCompileUnit *U =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));

  // Get the compile unit DIE is valid.
  auto DieDG = U->getUnitDIE(false);
  EXPECT_TRUE(DieDG.isValid());

  uint64_t LowPC, HighPC, SectionIndex;
  std::optional<uint64_t> OptU64;
  // Verify the that our subprogram with no PC value fails appropriately when
  // asked for any PC values.
  auto SubprogramDieNoPC = DieDG.getFirstChild();
  EXPECT_TRUE(SubprogramDieNoPC.isValid());
  EXPECT_EQ(SubprogramDieNoPC.getTag(), DW_TAG_subprogram);
  OptU64 = toAddress(SubprogramDieNoPC.find(DW_AT_low_pc));
  EXPECT_FALSE((bool)OptU64);
  OptU64 = toAddress(SubprogramDieNoPC.find(DW_AT_high_pc));
  EXPECT_FALSE((bool)OptU64);
  EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));
  OptU64 = toAddress(SubprogramDieNoPC.find(DW_AT_high_pc));
  EXPECT_FALSE((bool)OptU64);
  OptU64 = toUnsigned(SubprogramDieNoPC.find(DW_AT_high_pc));
  EXPECT_FALSE((bool)OptU64);
  OptU64 = SubprogramDieNoPC.getHighPC(ActualLowPC);
  EXPECT_FALSE((bool)OptU64);
  EXPECT_FALSE(SubprogramDieNoPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));

  // Verify the that our subprogram with only a low PC value succeeds when
  // we ask for the Low PC, but fails appropriately when asked for the high PC
  // or both low and high PC values.
  auto SubprogramDieLowPC = SubprogramDieNoPC.getSibling();
  EXPECT_TRUE(SubprogramDieLowPC.isValid());
  EXPECT_EQ(SubprogramDieLowPC.getTag(), DW_TAG_subprogram);
  OptU64 = toAddress(SubprogramDieLowPC.find(DW_AT_low_pc));
  EXPECT_TRUE((bool)OptU64);
  EXPECT_EQ(*OptU64, ActualLowPC);
  OptU64 = toAddress(SubprogramDieLowPC.find(DW_AT_high_pc));
  EXPECT_FALSE((bool)OptU64);
  OptU64 = toUnsigned(SubprogramDieLowPC.find(DW_AT_high_pc));
  EXPECT_FALSE((bool)OptU64);
  OptU64 = SubprogramDieLowPC.getHighPC(ActualLowPC);
  EXPECT_FALSE((bool)OptU64);
  EXPECT_FALSE(SubprogramDieLowPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));

  // Verify the that our subprogram with only a low PC value succeeds when
  // we ask for the Low PC, but fails appropriately when asked for the high PC
  // or both low and high PC values.
  auto SubprogramDieLowHighPC = SubprogramDieLowPC.getSibling();
  EXPECT_TRUE(SubprogramDieLowHighPC.isValid());
  EXPECT_EQ(SubprogramDieLowHighPC.getTag(), DW_TAG_subprogram);
  OptU64 = toAddress(SubprogramDieLowHighPC.find(DW_AT_low_pc));
  EXPECT_TRUE((bool)OptU64);
  EXPECT_EQ(*OptU64, ActualLowPC);
  // Get the high PC as an address. This should succeed if the high PC was
  // encoded as an address and fail if the high PC was encoded as an offset.
  OptU64 = toAddress(SubprogramDieLowHighPC.find(DW_AT_high_pc));
  if (SupportsHighPCAsOffset) {
    EXPECT_FALSE((bool)OptU64);
  } else {
    EXPECT_TRUE((bool)OptU64);
    EXPECT_EQ(*OptU64, ActualHighPC);
  }
  // Get the high PC as an unsigned constant. This should succeed if the high PC
  // was encoded as an offset and fail if the high PC was encoded as an address.
  OptU64 = toUnsigned(SubprogramDieLowHighPC.find(DW_AT_high_pc));
  if (SupportsHighPCAsOffset) {
    EXPECT_TRUE((bool)OptU64);
    EXPECT_EQ(*OptU64, ActualHighPCOffset);
  } else {
    EXPECT_FALSE((bool)OptU64);
  }

  OptU64 = SubprogramDieLowHighPC.getHighPC(ActualLowPC);
  EXPECT_TRUE((bool)OptU64);
  EXPECT_EQ(*OptU64, ActualHighPC);

  EXPECT_TRUE(SubprogramDieLowHighPC.getLowAndHighPC(LowPC, HighPC, SectionIndex));
  EXPECT_EQ(LowPC, ActualLowPC);
  EXPECT_EQ(HighPC, ActualHighPC);
}

TEST(DWARFDebugInfo, TestDWARF32Version2Addr4Addresses) {
  // Test that we can decode address values in DWARF32, version 2, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  TestAddresses<2, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version2Addr8Addresses) {
  // Test that we can decode address values in DWARF32, version 2, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  TestAddresses<2, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version3Addr4Addresses) {
  // Test that we can decode address values in DWARF32, version 3, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  TestAddresses<3, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version3Addr8Addresses) {
  // Test that we can decode address values in DWARF32, version 3, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  TestAddresses<3, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version4Addr4Addresses) {
  // Test that we can decode address values in DWARF32, version 4, with 4 byte
  // addresses.
  typedef uint32_t AddrType;
  TestAddresses<4, AddrType>();
}

TEST(DWARFDebugInfo, TestDWARF32Version4Addr8Addresses) {
  // Test that we can decode address values in DWARF32, version 4, with 8 byte
  // addresses.
  typedef uint64_t AddrType;
  TestAddresses<4, AddrType>();
}

#ifdef NO_SUPPORT_DEBUG_STR_OFFSETS
TEST(DWARFDebugInfo, DISABLED_TestStringOffsets) {
#else
TEST(DWARFDebugInfo, TestStringOffsets) {
#endif
  Triple Triple = getNormalizedDefaultTargetTriple();
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  const char *String1 = "Hello";
  const char *String2 = "World";

  auto ExpectedDG = dwarfgen::Generator::create(Triple, 5);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();
  dwarfgen::DIE CUDie = CU.getUnitDIE();

  CUDie.addStrOffsetsBaseAttribute();

  uint16_t Attr = DW_AT_lo_user;

  // Create our strings. First we create a non-indexed reference to String1,
  // followed by an indexed String2. Finally, we add an indexed reference to
  // String1.
  const auto Attr1 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr1, DW_FORM_strp, String1);

  const auto Attr2 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr2, DW_FORM_strx, String2);

  const auto Attr3 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr3, DW_FORM_strx, String1);

  // Generate the DWARF
  StringRef FileBytes = DG->generate();
  MemoryBufferRef FileBuffer(FileBytes, "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  ASSERT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  ASSERT_EQ(NumCUs, 1u);
  DWARFUnit *U = DwarfContext->getUnitAtIndex(0);
  auto DieDG = U->getUnitDIE(false);
  ASSERT_TRUE(DieDG.isValid());
  ASSERT_TRUE(U->isLittleEndian() == Triple.isLittleEndian());

  // Now make sure the string offsets came out properly. Attr2 should have index
  // 0 (because it was the first indexed string) even though the string itself
  // was added eariler.
  auto Extracted1 = toString(DieDG.find(Attr1));
  ASSERT_TRUE((bool)Extracted1);
  EXPECT_STREQ(String1, *Extracted1);

  std::optional<DWARFFormValue> Form2 = DieDG.find(Attr2);
  ASSERT_TRUE((bool)Form2);
  EXPECT_EQ(0u, Form2->getRawUValue());
  auto Extracted2 = toString(Form2);
  ASSERT_TRUE((bool)Extracted2);
  EXPECT_STREQ(String2, *Extracted2);

  std::optional<DWARFFormValue> Form3 = DieDG.find(Attr3);
  ASSERT_TRUE((bool)Form3);
  EXPECT_EQ(1u, Form3->getRawUValue());
  auto Extracted3 = toString(Form3);
  ASSERT_TRUE((bool)Extracted3);
  EXPECT_STREQ(String1, *Extracted3);
}

#ifdef NO_SUPPORT_DEBUG_ADDR
TEST(DWARFDebugInfo, DISABLED_TestEmptyStringOffsets) {
#else
TEST(DWARFDebugInfo, TestEmptyStringOffsets) {
#endif

  Triple Triple = getNormalizedDefaultTargetTriple();
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  const char *String1 = "Hello";

  auto ExpectedDG = dwarfgen::Generator::create(Triple, 5);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();
  dwarfgen::DIE CUDie = CU.getUnitDIE();

  uint16_t Attr = DW_AT_lo_user;

  // We shall insert only one string. It will be referenced directly.
  const auto Attr1 = static_cast<dwarf::Attribute>(Attr++);
  CUDie.addAttribute(Attr1, DW_FORM_strp, String1);

  // Generate the DWARF
  StringRef FileBytes = DG->generate();
  MemoryBufferRef FileBuffer(FileBytes, "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  ASSERT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
  EXPECT_TRUE(
      DwarfContext->getDWARFObj().getStrOffsetsSection().Data.empty());
}

TEST(DWARFDebugInfo, TestRelations) {
  Triple Triple = getNormalizedDefaultTargetTriple();
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  // Test the DWARF APIs related to accessing the DW_AT_low_pc and
  // DW_AT_high_pc.
  uint16_t Version = 4;
  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();

  enum class Tag: uint16_t  {
    A = dwarf::DW_TAG_lo_user,
    B,
    C,
    C1,
    C2,
    D,
    D1
  };

  // Scope to allow us to re-use the same DIE names
  {
    // Create DWARF tree that looks like:
    //
    // CU
    //   A
    //     B
    //     C
    //       C1
    //       C2
    //     D
    //       D1
    dwarfgen::DIE CUDie = CU.getUnitDIE();
    dwarfgen::DIE A = CUDie.addChild((dwarf::Tag)Tag::A);
    A.addChild((dwarf::Tag)Tag::B);
    dwarfgen::DIE C = A.addChild((dwarf::Tag)Tag::C);
    dwarfgen::DIE D = A.addChild((dwarf::Tag)Tag::D);
    C.addChild((dwarf::Tag)Tag::C1);
    C.addChild((dwarf::Tag)Tag::C2);
    D.addChild((dwarf::Tag)Tag::D1);
  }

  MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  EXPECT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);

  // Verify the number of compile units is correct.
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  EXPECT_EQ(NumCUs, 1u);
  DWARFCompileUnit *U =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));

  // Get the compile unit DIE is valid.
  auto CUDie = U->getUnitDIE(false);
  EXPECT_TRUE(CUDie.isValid());

  // The compile unit doesn't have a parent or a sibling.
  auto ParentDie = CUDie.getParent();
  EXPECT_FALSE(ParentDie.isValid());
  auto SiblingDie = CUDie.getSibling();
  EXPECT_FALSE(SiblingDie.isValid());

  // Get the children of the compile unit
  auto A = CUDie.getFirstChild();
  auto B = A.getFirstChild();
  auto C = B.getSibling();
  auto D = C.getSibling();
  auto Null = D.getSibling();

  // Verify NULL Die is NULL and has no children or siblings
  EXPECT_TRUE(Null.isNULL());
  EXPECT_FALSE(Null.getSibling().isValid());
  EXPECT_FALSE(Null.getFirstChild().isValid());

  // Verify all children of the compile unit DIE are correct.
  EXPECT_EQ(A.getTag(), (dwarf::Tag)Tag::A);
  EXPECT_EQ(B.getTag(), (dwarf::Tag)Tag::B);
  EXPECT_EQ(C.getTag(), (dwarf::Tag)Tag::C);
  EXPECT_EQ(D.getTag(), (dwarf::Tag)Tag::D);

  // Verify who has children
  EXPECT_TRUE(A.hasChildren());
  EXPECT_FALSE(B.hasChildren());
  EXPECT_TRUE(C.hasChildren());
  EXPECT_TRUE(D.hasChildren());

  // Make sure the parent of all the children of the compile unit are the
  // compile unit.
  EXPECT_EQ(A.getParent(), CUDie);

  // Make sure the parent of all the children of A are the A.
  // B is the first child in A, so we need to verify we can get the previous
  // DIE as the parent.
  EXPECT_EQ(B.getParent(), A);
  // C is the second child in A, so we need to make sure we can backup across
  // other DIE (B) at the same level to get the correct parent.
  EXPECT_EQ(C.getParent(), A);
  // D is the third child of A. We need to verify we can backup across other DIE
  // (B and C) including DIE that have children (D) to get the correct parent.
  EXPECT_EQ(D.getParent(), A);

  // Verify that a DIE with no children returns an invalid DWARFDie.
  EXPECT_FALSE(B.getFirstChild().isValid());

  // Verify the children of the B DIE
  auto C1 = C.getFirstChild();
  auto C2 = C1.getSibling();
  EXPECT_TRUE(C2.getSibling().isNULL());

  // Verify all children of the B DIE correctly valid or invalid.
  EXPECT_EQ(C1.getTag(), (dwarf::Tag)Tag::C1);
  EXPECT_EQ(C2.getTag(), (dwarf::Tag)Tag::C2);

  // Make sure the parent of all the children of the B are the B.
  EXPECT_EQ(C1.getParent(), C);
  EXPECT_EQ(C2.getParent(), C);

  // Make sure iterators work as expected.
  EXPECT_THAT(std::vector<DWARFDie>(A.begin(), A.end()),
              testing::ElementsAre(B, C, D));
  EXPECT_THAT(std::vector<DWARFDie>(A.rbegin(), A.rend()),
              testing::ElementsAre(D, C, B));

  // Make sure conversion from reverse iterator works as expected.
  EXPECT_EQ(A.rbegin().base(), A.end());
  EXPECT_EQ(A.rend().base(), A.begin());

  // Make sure iterator is bidirectional.
  {
    auto Begin = A.begin();
    auto End = A.end();
    auto It = A.begin();

    EXPECT_EQ(It, Begin);
    EXPECT_EQ(*It, B);
    ++It;
    EXPECT_EQ(*It, C);
    ++It;
    EXPECT_EQ(*It, D);
    ++It;
    EXPECT_EQ(It, End);
    --It;
    EXPECT_EQ(*It, D);
    --It;
    EXPECT_EQ(*It, C);
    --It;
    EXPECT_EQ(*It, B);
    EXPECT_EQ(It, Begin);
  }

  // Make sure reverse iterator is bidirectional.
  {
    auto Begin = A.rbegin();
    auto End = A.rend();
    auto It = A.rbegin();

    EXPECT_EQ(It, Begin);
    EXPECT_EQ(*It, D);
    ++It;
    EXPECT_EQ(*It, C);
    ++It;
    EXPECT_EQ(*It, B);
    ++It;
    EXPECT_EQ(It, End);
    --It;
    EXPECT_EQ(*It, B);
    --It;
    EXPECT_EQ(*It, C);
    --It;
    EXPECT_EQ(*It, D);
    EXPECT_EQ(It, Begin);
  }
}

TEST(DWARFDebugInfo, TestDWARFDie) {
  // Make sure a default constructed DWARFDie doesn't have any parent, sibling
  // or child;
  DWARFDie DefaultDie;
  EXPECT_FALSE(DefaultDie.getParent().isValid());
  EXPECT_FALSE(DefaultDie.getFirstChild().isValid());
  EXPECT_FALSE(DefaultDie.getSibling().isValid());
}

TEST(DWARFDebugInfo, TestChildIterators) {
  Triple Triple = getNormalizedDefaultTargetTriple();
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  // Test the DWARF APIs related to iterating across the children of a DIE using
  // the DWARFDie::iterator class.
  uint16_t Version = 4;
  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();

  enum class Tag: uint16_t  {
    A = dwarf::DW_TAG_lo_user,
    B,
  };

  // Scope to allow us to re-use the same DIE names
  {
    // Create DWARF tree that looks like:
    //
    // CU
    //   A
    //   B
    auto CUDie = CU.getUnitDIE();
    CUDie.addChild((dwarf::Tag)Tag::A);
    CUDie.addChild((dwarf::Tag)Tag::B);
  }

  MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  EXPECT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);

  // Verify the number of compile units is correct.
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  EXPECT_EQ(NumCUs, 1u);
  DWARFCompileUnit *U =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));

  // Get the compile unit DIE is valid.
  auto CUDie = U->getUnitDIE(false);
  EXPECT_TRUE(CUDie.isValid());
  uint32_t Index;
  DWARFDie A;
  DWARFDie B;

  // Verify the compile unit DIE's children.
  Index = 0;
  for (auto Die : CUDie.children()) {
    switch (Index++) {
      case 0: A = Die; break;
      case 1: B = Die; break;
    }
  }

  EXPECT_EQ(A.getTag(), (dwarf::Tag)Tag::A);
  EXPECT_EQ(B.getTag(), (dwarf::Tag)Tag::B);

  // Verify that A has no children by verifying that the begin and end contain
  // invalid DIEs and also that the iterators are equal.
  EXPECT_EQ(A.begin(), A.end());
}

TEST(DWARFDebugInfo, TestChildIteratorsOnInvalidDie) {
  // Verify that an invalid DIE has no children.
  DWARFDie Invalid;
  auto begin = Invalid.begin();
  auto end = Invalid.end();
  EXPECT_FALSE(begin->isValid());
  EXPECT_FALSE(end->isValid());
  EXPECT_EQ(begin, end);
}

TEST(DWARFDebugInfo, TestEmptyChildren) {
  const char *yamldata = "debug_abbrev:\n"
                         "  - Table:\n"
                         "      - Code:            0x00000001\n"
                         "        Tag:             DW_TAG_compile_unit\n"
                         "        Children:        DW_CHILDREN_yes\n"
                         "debug_info:\n"
                         "  - Version:         4\n"
                         "    AddrSize:        8\n"
                         "    Entries:\n"
                         "      - AbbrCode:        0x00000001\n"
                         "      - AbbrCode:        0x00000000\n";

  auto ErrOrSections = DWARFYAML::emitDebugSections(StringRef(yamldata));
  ASSERT_TRUE((bool)ErrOrSections);
  std::unique_ptr<DWARFContext> DwarfContext =
      DWARFContext::create(*ErrOrSections, 8);

  // Verify the number of compile units is correct.
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  EXPECT_EQ(NumCUs, 1u);
  DWARFCompileUnit *U =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));

  // Get the compile unit DIE is valid.
  auto CUDie = U->getUnitDIE(false);
  EXPECT_TRUE(CUDie.isValid());

  // Verify that the CU Die that says it has children, but doesn't, actually
  // has begin and end iterators that are equal. We want to make sure we don't
  // see the Null DIEs during iteration.
  EXPECT_EQ(CUDie.begin(), CUDie.end());
}

TEST(DWARFDebugInfo, TestAttributeIterators) {
  Triple Triple = getNormalizedDefaultTargetTriple();
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  // Test the DWARF APIs related to iterating across all attribute values in a
  // a DWARFDie.
  uint16_t Version = 4;
  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();
  const uint64_t CULowPC = 0x1000;
  StringRef CUPath("/tmp/main.c");

  // Scope to allow us to re-use the same DIE names
  {
    auto CUDie = CU.getUnitDIE();
    // Encode an attribute value before an attribute with no data.
    CUDie.addAttribute(DW_AT_name, DW_FORM_strp, CUPath.data());
    // Encode an attribute value with no data in .debug_info/types to ensure
    // the iteration works correctly.
    CUDie.addAttribute(DW_AT_declaration, DW_FORM_flag_present);
    // Encode an attribute value after an attribute with no data.
    CUDie.addAttribute(DW_AT_low_pc, DW_FORM_addr, CULowPC);
  }

  MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  EXPECT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);

  // Verify the number of compile units is correct.
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  EXPECT_EQ(NumCUs, 1u);
  DWARFCompileUnit *U =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));

  // Get the compile unit DIE is valid.
  auto CUDie = U->getUnitDIE(false);
  EXPECT_TRUE(CUDie.isValid());

  auto R = CUDie.attributes();
  auto I = R.begin();
  auto E = R.end();

  ASSERT_NE(E, I);
  EXPECT_EQ(I->Attr, DW_AT_name);
  auto ActualCUPath = toString(I->Value);
  EXPECT_EQ(CUPath, *ActualCUPath);

  ASSERT_NE(E, ++I);
  EXPECT_EQ(I->Attr, DW_AT_declaration);
  EXPECT_EQ(1ull, *I->Value.getAsUnsignedConstant());

  ASSERT_NE(E, ++I);
  EXPECT_EQ(I->Attr, DW_AT_low_pc);
  EXPECT_EQ(CULowPC, *I->Value.getAsAddress());

  EXPECT_EQ(E, ++I);
}

TEST(DWARFDebugInfo, TestFindRecurse) {
  Triple Triple = getNormalizedDefaultTargetTriple();
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  uint16_t Version = 4;
  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();

  StringRef SpecDieName = "spec";
  StringRef SpecLinkageName = "spec_linkage";
  StringRef AbsDieName = "abs";
  // Scope to allow us to re-use the same DIE names
  {
    auto CUDie = CU.getUnitDIE();
    auto FuncSpecDie = CUDie.addChild(DW_TAG_subprogram);
    auto FuncAbsDie = CUDie.addChild(DW_TAG_subprogram);
    // Put the linkage name in a second abstract origin DIE to ensure we
    // recurse through more than just one DIE when looking for attributes.
    auto FuncAbsDie2 = CUDie.addChild(DW_TAG_subprogram);
    auto FuncDie = CUDie.addChild(DW_TAG_subprogram);
    auto VarAbsDie = CUDie.addChild(DW_TAG_variable);
    auto VarDie = CUDie.addChild(DW_TAG_variable);
    FuncSpecDie.addAttribute(DW_AT_name, DW_FORM_strp, SpecDieName);
    FuncAbsDie2.addAttribute(DW_AT_linkage_name, DW_FORM_strp, SpecLinkageName);
    FuncAbsDie.addAttribute(DW_AT_specification, DW_FORM_ref4, FuncSpecDie);
    FuncAbsDie.addAttribute(DW_AT_abstract_origin, DW_FORM_ref4, FuncAbsDie2);
    FuncDie.addAttribute(DW_AT_abstract_origin, DW_FORM_ref4, FuncAbsDie);
    VarAbsDie.addAttribute(DW_AT_name, DW_FORM_strp, AbsDieName);
    VarDie.addAttribute(DW_AT_abstract_origin, DW_FORM_ref4, VarAbsDie);
  }

  MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  EXPECT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);

  // Verify the number of compile units is correct.
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  EXPECT_EQ(NumCUs, 1u);
  DWARFCompileUnit *U =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));

  // Get the compile unit DIE is valid.
  auto CUDie = U->getUnitDIE(false);
  EXPECT_TRUE(CUDie.isValid());

  auto FuncSpecDie = CUDie.getFirstChild();
  auto FuncAbsDie = FuncSpecDie.getSibling();
  auto FuncAbsDie2 = FuncAbsDie.getSibling();
  auto FuncDie = FuncAbsDie2.getSibling();
  auto VarAbsDie = FuncDie.getSibling();
  auto VarDie = VarAbsDie.getSibling();

  // Make sure we can't extract the name from the specification die when using
  // DWARFDie::find() since it won't check the DW_AT_specification DIE.
  EXPECT_FALSE(FuncDie.find(DW_AT_name));

  // Make sure we can extract the name from the specification die when using
  // DWARFDie::findRecursively() since it should recurse through the
  // DW_AT_specification DIE.
  auto NameOpt = FuncDie.findRecursively(DW_AT_name);
  EXPECT_TRUE(NameOpt);
  // Test the dwarf::toString() helper function.
  auto StringOpt = toString(NameOpt);
  EXPECT_TRUE(StringOpt);
  EXPECT_EQ(SpecDieName, StringOpt.value_or(nullptr));
  // Test the dwarf::toString() helper function with a default value specified.
  EXPECT_EQ(SpecDieName, toString(NameOpt, nullptr));

  auto LinkageNameOpt = FuncDie.findRecursively(DW_AT_linkage_name);
  EXPECT_EQ(SpecLinkageName, toString(LinkageNameOpt).value_or(nullptr));

  // Make sure we can't extract the name from the abstract origin die when using
  // DWARFDie::find() since it won't check the DW_AT_abstract_origin DIE.
  EXPECT_FALSE(VarDie.find(DW_AT_name));

  // Make sure we can extract the name from the abstract origin die when using
  // DWARFDie::findRecursively() since it should recurse through the
  // DW_AT_abstract_origin DIE.
  NameOpt = VarDie.findRecursively(DW_AT_name);
  EXPECT_TRUE(NameOpt);
  // Test the dwarf::toString() helper function.
  StringOpt = toString(NameOpt);
  EXPECT_TRUE(StringOpt);
  EXPECT_EQ(AbsDieName, StringOpt.value_or(nullptr));
}

TEST(DWARFDebugInfo, TestSelfRecursiveType) {
  typedef uint32_t AddrType;
  Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  auto ExpectedDG = dwarfgen::Generator::create(Triple, 4);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();
  dwarfgen::DIE CUDie = CU.getUnitDIE();

  // Create an invalid self-recursive typedef.
  dwarfgen::DIE TypedefDie = CUDie.addChild(DW_TAG_typedef);
  TypedefDie.addAttribute(DW_AT_name, DW_FORM_strp, "illegal");
  TypedefDie.addAttribute(DW_AT_type, DW_FORM_ref_addr, TypedefDie);

  MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  EXPECT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);

  // Verify the number of compile units is correct.
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  EXPECT_EQ(NumCUs, 1u);
  DWARFCompileUnit *U = cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
  {
    DWARFDie CUDie = U->getUnitDIE(false);
    EXPECT_TRUE(CUDie.isValid());
    DWARFDie TypedefDie = CUDie.getFirstChild();

    // Test that getTypeSize doesn't get into an infinite loop.
    EXPECT_EQ(TypedefDie.getTypeSize(sizeof(AddrType)), std::nullopt);
  }
}

TEST(DWARFDebugInfo, TestDwarfToFunctions) {
  // Test all of the dwarf::toXXX functions that take a
  // std::optional<DWARFFormValue> and extract the values from it.
  uint64_t InvalidU64 = 0xBADBADBADBADBADB;
  int64_t InvalidS64 = 0xBADBADBADBADBADB;

  // First test that we don't get valid values back when using an optional with
  // no value.
  std::optional<DWARFFormValue> FormValOpt1 = DWARFFormValue();
  EXPECT_FALSE(toString(FormValOpt1).has_value());
  EXPECT_FALSE(toUnsigned(FormValOpt1).has_value());
  EXPECT_FALSE(toReference(FormValOpt1).has_value());
  EXPECT_FALSE(toSigned(FormValOpt1).has_value());
  EXPECT_FALSE(toAddress(FormValOpt1).has_value());
  EXPECT_FALSE(toSectionOffset(FormValOpt1).has_value());
  EXPECT_FALSE(toBlock(FormValOpt1).has_value());
  EXPECT_EQ(nullptr, toString(FormValOpt1, nullptr));
  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt1, InvalidU64));
  EXPECT_EQ(InvalidU64, toReference(FormValOpt1, InvalidU64));
  EXPECT_EQ(InvalidU64, toAddress(FormValOpt1, InvalidU64));
  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt1, InvalidU64));
  EXPECT_EQ(InvalidS64, toSigned(FormValOpt1, InvalidS64));

  // Test successful and unsuccessful address decoding.
  uint64_t Address = 0x100000000ULL;
  std::optional<DWARFFormValue> FormValOpt2 =
      DWARFFormValue::createFromUValue(DW_FORM_addr, Address);

  EXPECT_FALSE(toString(FormValOpt2).has_value());
  EXPECT_FALSE(toUnsigned(FormValOpt2).has_value());
  EXPECT_FALSE(toReference(FormValOpt2).has_value());
  EXPECT_FALSE(toSigned(FormValOpt2).has_value());
  EXPECT_TRUE(toAddress(FormValOpt2).has_value());
  EXPECT_FALSE(toSectionOffset(FormValOpt2).has_value());
  EXPECT_FALSE(toBlock(FormValOpt2).has_value());
  EXPECT_EQ(nullptr, toString(FormValOpt2, nullptr));
  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt2, InvalidU64));
  EXPECT_EQ(InvalidU64, toReference(FormValOpt2, InvalidU64));
  EXPECT_EQ(Address, toAddress(FormValOpt2, InvalidU64));
  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt2, InvalidU64));
  EXPECT_EQ(InvalidS64, toSigned(FormValOpt2, InvalidU64));

  // Test successful and unsuccessful unsigned constant decoding.
  uint64_t UData8 = 0x1020304050607080ULL;
  std::optional<DWARFFormValue> FormValOpt3 =
      DWARFFormValue::createFromUValue(DW_FORM_udata, UData8);

  EXPECT_FALSE(toString(FormValOpt3).has_value());
  EXPECT_TRUE(toUnsigned(FormValOpt3).has_value());
  EXPECT_FALSE(toReference(FormValOpt3).has_value());
  EXPECT_TRUE(toSigned(FormValOpt3).has_value());
  EXPECT_FALSE(toAddress(FormValOpt3).has_value());
  EXPECT_FALSE(toSectionOffset(FormValOpt3).has_value());
  EXPECT_FALSE(toBlock(FormValOpt3).has_value());
  EXPECT_EQ(nullptr, toString(FormValOpt3, nullptr));
  EXPECT_EQ(UData8, toUnsigned(FormValOpt3, InvalidU64));
  EXPECT_EQ(InvalidU64, toReference(FormValOpt3, InvalidU64));
  EXPECT_EQ(InvalidU64, toAddress(FormValOpt3, InvalidU64));
  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt3, InvalidU64));
  EXPECT_EQ((int64_t)UData8, toSigned(FormValOpt3, InvalidU64));

  // Test successful and unsuccessful reference decoding.
  uint32_t RefData = 0x11223344U;
  std::optional<DWARFFormValue> FormValOpt4 =
      DWARFFormValue::createFromUValue(DW_FORM_ref_addr, RefData);

  EXPECT_FALSE(toString(FormValOpt4).has_value());
  EXPECT_FALSE(toUnsigned(FormValOpt4).has_value());
  EXPECT_TRUE(toReference(FormValOpt4).has_value());
  EXPECT_FALSE(toSigned(FormValOpt4).has_value());
  EXPECT_FALSE(toAddress(FormValOpt4).has_value());
  EXPECT_FALSE(toSectionOffset(FormValOpt4).has_value());
  EXPECT_FALSE(toBlock(FormValOpt4).has_value());
  EXPECT_EQ(nullptr, toString(FormValOpt4, nullptr));
  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt4, InvalidU64));
  EXPECT_EQ(RefData, toReference(FormValOpt4, InvalidU64));
  EXPECT_EQ(InvalidU64, toAddress(FormValOpt4, InvalidU64));
  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt4, InvalidU64));
  EXPECT_EQ(InvalidS64, toSigned(FormValOpt4, InvalidU64));

  // Test successful and unsuccessful signed constant decoding.
  int64_t SData8 = 0x1020304050607080ULL;
  std::optional<DWARFFormValue> FormValOpt5 =
      DWARFFormValue::createFromSValue(DW_FORM_udata, SData8);

  EXPECT_FALSE(toString(FormValOpt5).has_value());
  EXPECT_TRUE(toUnsigned(FormValOpt5).has_value());
  EXPECT_FALSE(toReference(FormValOpt5).has_value());
  EXPECT_TRUE(toSigned(FormValOpt5).has_value());
  EXPECT_FALSE(toAddress(FormValOpt5).has_value());
  EXPECT_FALSE(toSectionOffset(FormValOpt5).has_value());
  EXPECT_FALSE(toBlock(FormValOpt5).has_value());
  EXPECT_EQ(nullptr, toString(FormValOpt5, nullptr));
  EXPECT_EQ((uint64_t)SData8, toUnsigned(FormValOpt5, InvalidU64));
  EXPECT_EQ(InvalidU64, toReference(FormValOpt5, InvalidU64));
  EXPECT_EQ(InvalidU64, toAddress(FormValOpt5, InvalidU64));
  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt5, InvalidU64));
  EXPECT_EQ(SData8, toSigned(FormValOpt5, InvalidU64));

  // Test successful and unsuccessful block decoding.
  uint8_t Data[] = { 2, 3, 4 };
  ArrayRef<uint8_t> Array(Data);
  std::optional<DWARFFormValue> FormValOpt6 =
      DWARFFormValue::createFromBlockValue(DW_FORM_block1, Array);

  EXPECT_FALSE(toString(FormValOpt6).has_value());
  EXPECT_FALSE(toUnsigned(FormValOpt6).has_value());
  EXPECT_FALSE(toReference(FormValOpt6).has_value());
  EXPECT_FALSE(toSigned(FormValOpt6).has_value());
  EXPECT_FALSE(toAddress(FormValOpt6).has_value());
  EXPECT_FALSE(toSectionOffset(FormValOpt6).has_value());
  auto BlockOpt = toBlock(FormValOpt6);
  EXPECT_TRUE(BlockOpt.has_value());
  EXPECT_EQ(*BlockOpt, Array);
  EXPECT_EQ(nullptr, toString(FormValOpt6, nullptr));
  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt6, InvalidU64));
  EXPECT_EQ(InvalidU64, toReference(FormValOpt6, InvalidU64));
  EXPECT_EQ(InvalidU64, toAddress(FormValOpt6, InvalidU64));
  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt6, InvalidU64));
  EXPECT_EQ(InvalidS64, toSigned(FormValOpt6, InvalidU64));

  // Test
}

TEST(DWARFDebugInfo, TestFindAttrs) {
  Triple Triple = getNormalizedDefaultTargetTriple();
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  // Test the DWARFDie::find() and DWARFDie::findRecursively() that take an
  // ArrayRef<dwarf::Attribute> value to make sure they work correctly.
  uint16_t Version = 4;
  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();

  StringRef DieMangled("_Z3fooi");
  // Scope to allow us to re-use the same DIE names
  {
    auto CUDie = CU.getUnitDIE();
    auto FuncSpecDie = CUDie.addChild(DW_TAG_subprogram);
    auto FuncDie = CUDie.addChild(DW_TAG_subprogram);
    FuncSpecDie.addAttribute(DW_AT_MIPS_linkage_name, DW_FORM_strp, DieMangled);
    FuncDie.addAttribute(DW_AT_specification, DW_FORM_ref4, FuncSpecDie);
  }

  MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  EXPECT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);

  // Verify the number of compile units is correct.
  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
  EXPECT_EQ(NumCUs, 1u);
  DWARFCompileUnit *U =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));

  // Get the compile unit DIE is valid.
  auto CUDie = U->getUnitDIE(false);
  EXPECT_TRUE(CUDie.isValid());

  auto FuncSpecDie = CUDie.getFirstChild();
  auto FuncDie = FuncSpecDie.getSibling();

  // Make sure that passing in an empty attribute list behave correctly.
  EXPECT_FALSE(FuncDie.find(ArrayRef<dwarf::Attribute>()).has_value());

  // Make sure that passing in a list of attribute that are not contained
  // in the DIE returns nothing.
  EXPECT_FALSE(FuncDie.find({DW_AT_low_pc, DW_AT_entry_pc}).has_value());

  const dwarf::Attribute Attrs[] = {DW_AT_linkage_name,
                                    DW_AT_MIPS_linkage_name};

  // Make sure we can't extract the linkage name attributes when using
  // DWARFDie::find() since it won't check the DW_AT_specification DIE.
  EXPECT_FALSE(FuncDie.find(Attrs).has_value());

  // Make sure we can extract the name from the specification die when using
  // DWARFDie::findRecursively() since it should recurse through the
  // DW_AT_specification DIE.
  auto NameOpt = FuncDie.findRecursively(Attrs);
  EXPECT_TRUE(NameOpt.has_value());
  EXPECT_EQ(DieMangled, toString(NameOpt, ""));
}

#ifdef NO_SUPPORT_DEBUG_ADDR
TEST(DWARFDebugInfo, DISABLED_TestImplicitConstAbbrevs) {
#else
TEST(DWARFDebugInfo, TestImplicitConstAbbrevs) {
#endif
  Triple Triple = getNormalizedDefaultTargetTriple();
  if (!isConfigurationSupported(Triple))
    GTEST_SKIP();

  uint16_t Version = 5;
  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
  dwarfgen::Generator *DG = ExpectedDG.get().get();
  dwarfgen::CompileUnit &CU = DG->addCompileUnit();
  dwarfgen::DIE CUDie = CU.getUnitDIE();
  const dwarf::Attribute Attr = DW_AT_lo_user;
  const int64_t Val1 = 42;
  const int64_t Val2 = 43;

  auto FirstVal1DIE = CUDie.addChild(DW_TAG_class_type);
  FirstVal1DIE.addAttribute(Attr, DW_FORM_implicit_const, Val1);

  auto SecondVal1DIE = CUDie.addChild(DW_TAG_class_type);
  SecondVal1DIE.addAttribute(Attr, DW_FORM_implicit_const, Val1);

  auto Val2DIE = CUDie.addChild(DW_TAG_class_type);
  Val2DIE.addAttribute(Attr, DW_FORM_implicit_const, Val2);

  MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
  EXPECT_TRUE((bool)Obj);
  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
  DWARFCompileUnit *U =
      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
  EXPECT_TRUE((bool)U);

  const auto *Abbrevs = U->getAbbreviations();
  EXPECT_TRUE((bool)Abbrevs);

  // Let's find implicit_const abbrevs and verify,
  // that there are exactly two of them and both of them
  // can be dumped correctly.
  typedef decltype(Abbrevs->begin()) AbbrevIt;
  AbbrevIt Val1Abbrev = Abbrevs->end();
  AbbrevIt Val2Abbrev = Abbrevs->end();
  for(auto it = Abbrevs->begin(); it != Abbrevs->end(); ++it) {
    if (it->getNumAttributes() == 0)
      continue; // root abbrev for DW_TAG_compile_unit

    auto A = it->getAttrByIndex(0);
    EXPECT_EQ(A, Attr);

    std::optional<uint32_t> AttrIndex = it->findAttributeIndex(A);
    EXPECT_TRUE((bool)AttrIndex);
    EXPECT_EQ(*AttrIndex, 0u);
    uint64_t OffsetVal =
        it->getAttributeOffsetFromIndex(*AttrIndex, /* offset */ 0, *U);
    EXPECT_TRUE(it->getAttributeValueFromOffset(*AttrIndex, OffsetVal, *U));

    auto FormValue = it->getAttributeValue(/* offset */ 0, A, *U);
    EXPECT_TRUE((bool)FormValue);
    EXPECT_EQ(FormValue->getForm(), dwarf::DW_FORM_implicit_const);

    const auto V = FormValue->getAsSignedConstant();
    EXPECT_TRUE((bool)V);

    auto VerifyAbbrevDump = [&V](AbbrevIt it) {
      std::string S;
      llvm::raw_string_ostream OS(S);
      it->dump(OS);
      auto FormPos = OS.str().find("DW_FORM_implicit_const");
      EXPECT_NE(FormPos, std::string::npos);
      auto ValPos = S.find_first_of("-0123456789", FormPos);
      EXPECT_NE(ValPos, std::string::npos);
      int64_t Val = std::atoll(S.substr(ValPos).c_str());
      EXPECT_EQ(Val, *V);
    };

    switch(*V) {
    case Val1:
      EXPECT_EQ(Val1Abbrev, Abbrevs->end());
      Val1Abbrev = it;
      VerifyAbbrevDump(it);
      break;
    case Val2:
      EXPECT_EQ(Val2Abbrev, Abbrevs->end());
      Val2Abbrev = it;
      VerifyAbbrevDump(it);
      break;
    default:
      FAIL() << "Unexpected attribute value: " << *V;
    }
  }

  // Now let's make sure that two Val1-DIEs refer to the same abbrev,
  // and Val2-DIE refers to another one.
  auto DieDG = U->getUnitDIE(false);
  auto it = DieDG.begin();
  std::multimap<int64_t, decltype(it->getAbbreviationDeclarationPtr())> DIEs;
  const DWARFAbbreviationDeclaration *AbbrevPtrVal1 = nullptr;
  const DWARFAbbreviationDeclaration *AbbrevPtrVal2 = nullptr;
  for (; it != DieDG.end(); ++it) {
    const auto *AbbrevPtr = it->getAbbreviationDeclarationPtr();
    EXPECT_TRUE((bool)AbbrevPtr);
    auto FormValue = it->find(Attr);
    EXPECT_TRUE((bool)FormValue);
    const auto V = FormValue->getAsSignedConstant();
    EXPECT_TRUE((bool)V);
    switch(*V) {
    case Val1:
      AbbrevPtrVal1 = AbbrevPtr;
      break;
    case Val2:
      AbbrevPtrVal2 = AbbrevPtr;
      break;
    default:
      FAIL() << "Unexpected attribute value: " << *V;
    }
    DIEs.insert(std::make_pair(*V, AbbrevPtr));
  }
  EXPECT_EQ(DIEs.count(Val1), 2u);
  EXPECT_EQ(DIEs.count(Val2), 1u);
  auto Val1Range = DIEs.equal_range(Val1);
  for (auto it = Val1Range.first; it != Val1Range.second; ++it)
    EXPECT_EQ(it->second, AbbrevPtrVal1);
  EXPECT_EQ(DIEs.find(Val2)->second, AbbrevPtrVal2);
}

TEST(DWARFDebugInfo, TestDWARFDieRangeInfoContains) {
  DWARFVerifier::DieRangeInfo Empty;
  ASSERT_TRUE(Empty.contains(Empty));

  DWARFVerifier::DieRangeInfo Ranges(
      {{0x10, 0x20}, {0x30, 0x40}, {0x40, 0x50}});

  ASSERT_TRUE(Ranges.contains(Empty));
  ASSERT_FALSE(Ranges.contains({{{0x0f, 0x10}}}));
  ASSERT_FALSE(Ranges.contains({{{0x0f, 0x20}}}));
  ASSERT_FALSE(Ranges.contains({{{0x0f, 0x21}}}));

  // Test ranges that start at R's start address
  ASSERT_TRUE(Ranges.contains({{{0x10, 0x10}}}));
  ASSERT_TRUE(Ranges.contains({{{0x10, 0x11}}}));
  ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}}}));
  ASSERT_FALSE(Ranges.contains({{{0x10, 0x21}}}));

  ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}}}));

  // Test ranges that start at last bytes of Range
  ASSERT_TRUE(Ranges.contains({{{0x1f, 0x20}}}));
  ASSERT_FALSE(Ranges.contains({{{0x1f, 0x21}}}));

  // Test ranges that start after Range
  ASSERT_TRUE(Ranges.contains({{{0x20, 0x20}}}));
  ASSERT_FALSE(Ranges.contains({{{0x20, 0x21}}}));

  ASSERT_TRUE(Ranges.contains({{{0x31, 0x32}}}));
  ASSERT_TRUE(Ranges.contains({{{0x3f, 0x40}}}));
  ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}, {0x30, 0x40}}}));
  ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}, {0x31, 0x32}}}));
  ASSERT_TRUE(Ranges.contains(
      {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x33}}}));
  ASSERT_FALSE(Ranges.contains({{{0x11, 0x12},
                                 {0x12, 0x13},
                                 {0x20, 0x21},
                                 {0x31, 0x32},
                                 {0x32, 0x33}}}));
  ASSERT_FALSE(Ranges.contains(
      {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x51}}}));
  ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}, {0x30, 0x50}}}));
  ASSERT_FALSE(Ranges.contains({{{0x30, 0x51}}}));
  ASSERT_FALSE(Ranges.contains({{{0x50, 0x51}}}));
}

namespace {

void AssertRangesIntersect(const DWARFAddressRange &LHS,
                           const DWARFAddressRange &RHS) {
  ASSERT_TRUE(LHS.intersects(RHS));
  ASSERT_TRUE(RHS.intersects(LHS));
}
void AssertRangesDontIntersect(const DWARFAddressRange &LHS,
                               const DWARFAddressRange &RHS) {
  ASSERT_FALSE(LHS.intersects(RHS));
  ASSERT_FALSE(RHS.intersects(LHS));
}

void AssertRangesIntersect(const DWARFVerifier::DieRangeInfo &LHS,
                           const DWARFAddressRangesVector &Ranges) {
  DWARFVerifier::DieRangeInfo RHS(Ranges);
  ASSERT_TRUE(LHS.intersects(RHS));
  ASSERT_TRUE(RHS.intersects(LHS));
}

void AssertRangesDontIntersect(const DWARFVerifier::DieRangeInfo &LHS,
                               const DWARFAddressRangesVector &Ranges) {
  DWARFVerifier::DieRangeInfo RHS(Ranges);
  ASSERT_FALSE(LHS.intersects(RHS));
  ASSERT_FALSE(RHS.intersects(LHS));
}

} // namespace
TEST(DWARFDebugInfo, TestDwarfRangesIntersect) {
  DWARFAddressRange R(0x10, 0x20);

  //----------------------------------------------------------------------
  // Test ranges that start before R...
  //----------------------------------------------------------------------
  // Other range ends before start of R
  AssertRangesDontIntersect(R, {0x00, 0x10});
  // Other range end address is start of a R
  AssertRangesIntersect(R, {0x00, 0x11});
  // Other range end address is in R
  AssertRangesIntersect(R, {0x00, 0x15});
  // Other range end address is at and of R
  AssertRangesIntersect(R, {0x00, 0x20});
  // Other range end address is past end of R
  AssertRangesIntersect(R, {0x00, 0x40});

  //----------------------------------------------------------------------
  // Test ranges that start at R's start address
  //----------------------------------------------------------------------
  // Ensure empty ranges doesn't match
  AssertRangesDontIntersect(R, {0x10, 0x10});
  // 1 byte of Range
  AssertRangesIntersect(R, {0x10, 0x11});
  // same as Range
  AssertRangesIntersect(R, {0x10, 0x20});
  // 1 byte past Range
  AssertRangesIntersect(R, {0x10, 0x21});

  //----------------------------------------------------------------------
  // Test ranges that start inside Range
  //----------------------------------------------------------------------
  // empty in range
  AssertRangesDontIntersect(R, {0x11, 0x11});
  // all in Range
  AssertRangesIntersect(R, {0x11, 0x1f});
  // ends at end of Range
  AssertRangesIntersect(R, {0x11, 0x20});
  // ends past Range
  AssertRangesIntersect(R, {0x11, 0x21});

  //----------------------------------------------------------------------
  // Test ranges that start at last bytes of Range
  //----------------------------------------------------------------------
  // ends at end of Range
  AssertRangesIntersect(R, {0x1f, 0x20});
  // ends past Range
  AssertRangesIntersect(R, {0x1f, 0x21});

  //----------------------------------------------------------------------
  // Test ranges that start after Range
  //----------------------------------------------------------------------
  // empty just past in Range
  AssertRangesDontIntersect(R, {0x20, 0x20});
  // valid past Range
  AssertRangesDontIntersect(R, {0x20, 0x21});
}

TEST(DWARFDebugInfo, TestDWARFDieRangeInfoIntersects) {

  DWARFVerifier::DieRangeInfo Ranges({{0x10, 0x20}, {0x30, 0x40}});

  // Test empty range
  AssertRangesDontIntersect(Ranges, {});
  // Test range that appears before all ranges in Ranges
  AssertRangesDontIntersect(Ranges, {{0x00, 0x10}});
  // Test range that appears between ranges in Ranges
  AssertRangesDontIntersect(Ranges, {{0x20, 0x30}});
  // Test range that appears after ranges in Ranges
  AssertRangesDontIntersect(Ranges, {{0x40, 0x50}});

  // Test range that start before first range
  AssertRangesIntersect(Ranges, {{0x00, 0x11}});
  // Test range that start at first range
  AssertRangesIntersect(Ranges, {{0x10, 0x11}});
  // Test range that start in first range
  AssertRangesIntersect(Ranges, {{0x11, 0x12}});
  // Test range that start at end of first range
  AssertRangesIntersect(Ranges, {{0x1f, 0x20}});
  // Test range that starts at end of first range
  AssertRangesDontIntersect(Ranges, {{0x20, 0x21}});
  // Test range that starts at end of first range
  AssertRangesIntersect(Ranges, {{0x20, 0x31}});

  // Test range that start before second range and ends before second
  AssertRangesDontIntersect(Ranges, {{0x2f, 0x30}});
  // Test range that start before second range and ends in second
  AssertRangesIntersect(Ranges, {{0x2f, 0x31}});
  // Test range that start at second range
  AssertRangesIntersect(Ranges, {{0x30, 0x31}});
  // Test range that start in second range
  AssertRangesIntersect(Ranges, {{0x31, 0x32}});
  // Test range that start at end of second range
  AssertRangesIntersect(Ranges, {{0x3f, 0x40}});
  // Test range that starts at end of second range
  AssertRangesDontIntersect(Ranges, {{0x40, 0x41}});

  AssertRangesDontIntersect(Ranges, {{0x20, 0x21}, {0x2f, 0x30}});
  AssertRangesIntersect(Ranges, {{0x20, 0x21}, {0x2f, 0x31}});
}

TEST(DWARFDebugInfo, TestDWARF64UnitLength) {
  static const char DebugInfoSecRaw[] =
      "\xff\xff\xff\xff"                 // DWARF64 mark
      "\x88\x77\x66\x55\x44\x33\x22\x11" // Length
      "\x05\x00"                         // Version
      "\x01"                             // DW_UT_compile
      "\x04"                             // Address size
      "\0\0\0\0\0\0\0\0";                // Offset Into Abbrev. Sec.
  StringMap<std::unique_ptr<MemoryBuffer>> Sections;
  Sections.insert(std::make_pair(
      "debug_info", MemoryBuffer::getMemBuffer(StringRef(
                        DebugInfoSecRaw, sizeof(DebugInfoSecRaw) - 1))));
  auto Context = DWARFContext::create(Sections, /* AddrSize = */ 4,
                                      /* isLittleEndian = */ true);
  const auto &Obj = Context->getDWARFObj();
  Obj.forEachInfoSections([&](const DWARFSection &Sec) {
    DWARFUnitHeader Header;
    DWARFDataExtractor Data(Obj, Sec, /* IsLittleEndian = */ true,
                            /* AddressSize = */ 4);
    uint64_t Offset = 0;
    ASSERT_THAT_ERROR(
        Header.extract(*Context, Data, &Offset, DW_SECT_INFO),
        FailedWithMessage(
            "DWARF unit from offset 0x00000000 incl. to offset  "
            "0x1122334455667794 excl. extends past section size 0x00000018"));
    // Header.extract() returns false because there is not enough space
    // in the section for the declared length. Anyway, we can check that
    // the properties are read correctly.
    ASSERT_EQ(DwarfFormat::DWARF64, Header.getFormat());
    ASSERT_EQ(0x1122334455667788ULL, Header.getLength());
    ASSERT_EQ(5, Header.getVersion());
    ASSERT_EQ(DW_UT_compile, Header.getUnitType());
    ASSERT_EQ(4, Header.getAddressByteSize());

    // Check that the length can be correctly read in the unit class.
    DWARFUnitVector DummyUnitVector;
    DWARFSection DummySec;
    DWARFCompileUnit CU(*Context, Sec, Header, /* DA = */ 0, /* RS = */ 0,
                        /* LocSection = */ 0, /* SS = */ StringRef(),
                        /* SOS = */ DummySec, /* AOS = */ 0,
                        /* LS = */ DummySec, /* LE = */ true,
                        /* isDWO= */ false, DummyUnitVector);
    ASSERT_EQ(0x1122334455667788ULL, CU.getLength());
  });
}

} // end anonymous namespace
