//===- 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/SmallString.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>

using namespace llvm;
using namespace dwarf;
using namespace utils;
using ::testing::HasSubstr;

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

#ifdef _AIX
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version2Addr8AllForms) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version2Addr8AllForms) {
#endif
  // 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>();
}

#ifdef _AIX
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version3Addr8AllForms) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version3Addr8AllForms) {
#endif
  // 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>();
}

#ifdef _AIX
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version4Addr8AllForms) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version4Addr8AllForms) {
#endif
  // 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 _AIX
TEST(DWARFDebigInfo, 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 _AIX
TEST(DWARFDebigInfo, 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>();
}

#ifdef _AIX
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version2Addr8Children) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version2Addr8Children) {
#endif
  // 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>();
}

#ifdef _AIX
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version3Addr8Children) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version3Addr8Children) {
#endif
  // 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>();
}

#ifdef _AIX
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version4Addr8Children) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version4Addr8Children) {
#endif
  // 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>();
}

#ifdef _AIX
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version2Addr8References) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version2Addr8References) {
#endif
  // 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>();
}

#ifdef _AIX
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version3Addr8References) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version3Addr8References) {
#endif
  // 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>();
}

#ifdef _AIX
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version4Addr8References) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version4Addr8References) {
#endif
  // 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>();
}

#ifdef _AIX
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version2Addr8Addresses) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version2Addr8Addresses) {
#endif
  // 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>();
}

#ifdef _AIX
TEST(DWARFDebugInfo, DISABLED_TestDWARF32Version3Addr8Addresses) {
#else
TEST(DWARFDebugInfo, TestDWARF32Version3Addr8Addresses) {
#endif
  // 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>();
}

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

#ifdef _AIX
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);
}

// AIX does not support string offset section.
#if defined(_AIX)
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, 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, ""));
}

// AIX does not support debug_addr section.
#if defined(_AIX)
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;
    EXPECT_FALSE(Header.extract(*Context, Data, &Offset, DW_SECT_INFO));
    // 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
