[llvm] Fix a spurious error that was emitted for invalid DW_AT_decl_file. (PR #152608)

Greg Clayton via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 7 17:01:42 PDT 2025


https://github.com/clayborg updated https://github.com/llvm/llvm-project/pull/152608

>From 17aa9a0a88af0c2ba5c635dfce24f00cb89f79af Mon Sep 17 00:00:00 2001
From: Greg Clayton <clayborg at gmail.com>
Date: Thu, 7 Aug 2025 15:53:24 -0700
Subject: [PATCH] Fix a spurious error that was emitted for invalid
 DW_AT_decl_file.

The GSYM code was trying to warn if there are no line table entries for a function and if the DW_AT_decl_file attribute had a file index that was invalid. The code was always emitting a error even if a DW_TAG_subprogram DIE had no DW_AT_decl_file. We should only emit an error if there is a DW_AT_decl_file attribute and it's file index isn't valid.
---
 llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp |  23 +-
 llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp   | 467 ++++++++++++-------
 2 files changed, 317 insertions(+), 173 deletions(-)

diff --git a/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp b/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp
index 7a0256f10ea60..9d7b767b65acb 100644
--- a/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp
+++ b/llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp
@@ -82,7 +82,6 @@ struct llvm::gsym::CUInfo {
   }
 };
 
-
 static DWARFDie GetParentDeclContextDIE(DWARFDie &Die) {
   if (DWARFDie SpecDie =
           Die.getAttributeValueAsReferencedDie(dwarf::DW_AT_specification)) {
@@ -170,7 +169,7 @@ getQualifiedNameIndex(DWARFDie &Die, uint64_t Language, GsymCreator &Gsym) {
         // templates
         if (ParentName.front() == '<' && ParentName.back() == '>')
           Name = "{" + ParentName.substr(1, ParentName.size() - 2).str() + "}" +
-                "::" + Name;
+                 "::" + Name;
         else
           Name = ParentName.str() + "::" + Name;
       }
@@ -338,9 +337,13 @@ static void convertFunctionLineTable(OutputAggregator &Out, CUInfo &CUI,
     if (FilePath.empty()) {
       // If we had a DW_AT_decl_file, but got no file then we need to emit a
       // warning.
+      const uint64_t DwarfFileIdx = dwarf::toUnsigned(
+          Die.findRecursively(dwarf::DW_AT_decl_file), UINT32_MAX);
+      // Check if there is no DW_AT_decl_line attribute, and don't report an
+      // error if it isn't there.
+      if (DwarfFileIdx == UINT32_MAX)
+        return;
       Out.Report("Invalid file index in DW_AT_decl_file", [&](raw_ostream &OS) {
-        const uint64_t DwarfFileIdx = dwarf::toUnsigned(
-            Die.findRecursively(dwarf::DW_AT_decl_file), UINT32_MAX);
         OS << "error: function DIE at " << HEX32(Die.getOffset())
            << " has an invalid file index " << DwarfFileIdx
            << " in its DW_AT_decl_file attribute, unable to create a single "
@@ -432,7 +435,7 @@ static void convertFunctionLineTable(OutputAggregator &Out, CUInfo &CUI,
     // Skip multiple line entries for the same file and line.
     auto LastLE = FI.OptLineTable->last();
     if (LastLE && LastLE->File == FileIdx && LastLE->Line == Row.Line)
-        continue;
+      continue;
     // Only push a row if it isn't an end sequence. End sequence markers are
     // included for the last address in a function or the last contiguous
     // address in a sequence.
@@ -718,8 +721,8 @@ llvm::Error DwarfTransformer::verify(StringRef GsymPath,
   for (uint32_t I = 0; I < NumAddrs; ++I) {
     auto FuncAddr = Gsym->getAddress(I);
     if (!FuncAddr)
-        return createStringError(std::errc::invalid_argument,
-                                  "failed to extract address[%i]", I);
+      return createStringError(std::errc::invalid_argument,
+                               "failed to extract address[%i]", I);
 
     auto FI = Gsym->getFunctionInfo(*FuncAddr);
     if (!FI)
@@ -734,8 +737,7 @@ llvm::Error DwarfTransformer::verify(StringRef GsymPath,
       if (!LR)
         return LR.takeError();
 
-      auto DwarfInlineInfos =
-          DICtx.getInliningInfoForAddress(SectAddr, DLIS);
+      auto DwarfInlineInfos = DICtx.getInliningInfoForAddress(SectAddr, DLIS);
       uint32_t NumDwarfInlineInfos = DwarfInlineInfos.getNumberOfFrames();
       if (NumDwarfInlineInfos == 0) {
         DwarfInlineInfos.addFrame(
@@ -773,8 +775,7 @@ llvm::Error DwarfTransformer::verify(StringRef GsymPath,
         continue;
       }
 
-      for (size_t Idx = 0, count = LR->Locations.size(); Idx < count;
-            ++Idx) {
+      for (size_t Idx = 0, count = LR->Locations.size(); Idx < count; ++Idx) {
         const auto &gii = LR->Locations[Idx];
         if (Idx < NumDwarfInlineInfos) {
           const auto &dii = DwarfInlineInfos.getFrame(Idx);
diff --git a/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp b/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
index 33f53de2e77bc..8935714e00ff5 100644
--- a/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
+++ b/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
@@ -24,8 +24,8 @@
 #include "llvm/Support/DataExtractor.h"
 #include "llvm/Testing/Support/Error.h"
 
-#include "gtest/gtest.h"
 #include "gmock/gmock.h"
+#include "gtest/gtest.h"
 #include <string>
 
 using namespace llvm;
@@ -99,7 +99,7 @@ TEST(GSYMTest, TestFunctionInfo) {
   const uint32_t FileIdx = 1;
   const uint32_t Line = 12;
   FI.OptLineTable = LineTable();
-  FI.OptLineTable->push(LineEntry(StartAddr,FileIdx,Line));
+  FI.OptLineTable->push(LineEntry(StartAddr, FileIdx, Line));
   EXPECT_TRUE(FI.hasRichInfo());
   FI.clear();
   EXPECT_FALSE(FI.isValid());
@@ -135,7 +135,7 @@ TEST(GSYMTest, TestFunctionInfo) {
   FunctionInfo FISymtab(StartAddr, Size, NameOffset);
   FunctionInfo FIWithLines(StartAddr, Size, NameOffset);
   FIWithLines.OptLineTable = LineTable();
-  FIWithLines.OptLineTable->push(LineEntry(StartAddr,FileIdx,Line));
+  FIWithLines.OptLineTable->push(LineEntry(StartAddr, FileIdx, Line));
   // Test that a FunctionInfo with just a name and size is less than one
   // that has name, size and any number of line table entries
   EXPECT_LT(FISymtab, FIWithLines);
@@ -166,7 +166,7 @@ TEST(GSYMTest, TestFunctionInfo) {
   // Test if we have an entry with lines and one with more lines for the same
   // range, the ones with more lines is greater than the one with less.
   FunctionInfo FIWithMoreLines = FIWithLines;
-  FIWithMoreLines.OptLineTable->push(LineEntry(StartAddr,FileIdx,Line+5));
+  FIWithMoreLines.OptLineTable->push(LineEntry(StartAddr, FileIdx, Line + 5));
   EXPECT_LT(FIWithLines, FIWithMoreLines);
 
   // Test that if we have the same number of lines we compare the line entries
@@ -198,24 +198,27 @@ TEST(GSYMTest, TestFunctionInfoDecodeErrors) {
   FileWriter FW(OutStrm, ByteOrder);
   const uint64_t BaseAddr = 0x100;
   TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
-      "0x00000000: missing FunctionInfo Size");
+                              "0x00000000: missing FunctionInfo Size");
   FW.writeU32(0x100); // Function size.
   TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
-      "0x00000004: missing FunctionInfo Name");
+                              "0x00000004: missing FunctionInfo Name");
   // Write out an invalid Name string table offset of zero.
   FW.writeU32(0);
-  TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
+  TestFunctionInfoDecodeError(
+      ByteOrder, OutStrm.str(), BaseAddr,
       "0x00000004: invalid FunctionInfo Name value 0x00000000");
   // Modify the Name to be 0x00000001, which is a valid value.
   FW.fixup32(0x00000001, 4);
-  TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
+  TestFunctionInfoDecodeError(
+      ByteOrder, OutStrm.str(), BaseAddr,
       "0x00000008: missing FunctionInfo InfoType value");
   auto FixupOffset = FW.tell();
   FW.writeU32(1); // InfoType::LineTableInfo.
-  TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
+  TestFunctionInfoDecodeError(
+      ByteOrder, OutStrm.str(), BaseAddr,
       "0x0000000c: missing FunctionInfo InfoType length");
   FW.fixup32(7, FixupOffset); // Write an invalid InfoType enumeration value
-  FW.writeU32(0); // LineTableInfo InfoType data length.
+  FW.writeU32(0);             // LineTableInfo InfoType data length.
   TestFunctionInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
                               "0x00000008: unsupported InfoType 7");
 }
@@ -278,25 +281,24 @@ static void TestFunctionInfoEncodeDecode(llvm::endianness ByteOrder,
 }
 
 static void AddLines(uint64_t FuncAddr, uint32_t FileIdx, FunctionInfo &FI) {
-    FI.OptLineTable = LineTable();
-    LineEntry Line0(FuncAddr + 0x000, FileIdx, 10);
-    LineEntry Line1(FuncAddr + 0x010, FileIdx, 11);
-    LineEntry Line2(FuncAddr + 0x100, FileIdx, 1000);
-    FI.OptLineTable->push(Line0);
-    FI.OptLineTable->push(Line1);
-    FI.OptLineTable->push(Line2);
+  FI.OptLineTable = LineTable();
+  LineEntry Line0(FuncAddr + 0x000, FileIdx, 10);
+  LineEntry Line1(FuncAddr + 0x010, FileIdx, 11);
+  LineEntry Line2(FuncAddr + 0x100, FileIdx, 1000);
+  FI.OptLineTable->push(Line0);
+  FI.OptLineTable->push(Line1);
+  FI.OptLineTable->push(Line2);
 }
 
-
 static void AddInline(uint64_t FuncAddr, uint64_t FuncSize, FunctionInfo &FI) {
-    FI.Inline = InlineInfo();
-    FI.Inline->Ranges.insert(AddressRange(FuncAddr, FuncAddr + FuncSize));
-    InlineInfo Inline1;
-    Inline1.Ranges.insert(AddressRange(FuncAddr + 0x10, FuncAddr + 0x30));
-    Inline1.Name = 1;
-    Inline1.CallFile = 1;
-    Inline1.CallLine = 11;
-    FI.Inline->Children.push_back(Inline1);
+  FI.Inline = InlineInfo();
+  FI.Inline->Ranges.insert(AddressRange(FuncAddr, FuncAddr + FuncSize));
+  InlineInfo Inline1;
+  Inline1.Ranges.insert(AddressRange(FuncAddr + 0x10, FuncAddr + 0x30));
+  Inline1.Name = 1;
+  Inline1.CallFile = 1;
+  Inline1.CallLine = 11;
+  FI.Inline->Children.push_back(Inline1);
 }
 
 TEST(GSYMTest, TestFunctionInfoEncoding) {
@@ -514,21 +516,25 @@ TEST(GSYMTest, TestInlineInfoDecodeErrors) {
   raw_svector_ostream OutStrm(Str);
   FileWriter FW(OutStrm, ByteOrder);
   const uint64_t BaseAddr = 0x100;
-  TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
+  TestInlineInfoDecodeError(
+      ByteOrder, OutStrm.str(), BaseAddr,
       "0x00000000: missing InlineInfo address ranges data");
   AddressRanges Ranges;
-  Ranges.insert({BaseAddr, BaseAddr+0x100});
+  Ranges.insert({BaseAddr, BaseAddr + 0x100});
   encodeRanges(Ranges, FW, BaseAddr);
-  TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
+  TestInlineInfoDecodeError(
+      ByteOrder, OutStrm.str(), BaseAddr,
       "0x00000004: missing InlineInfo uint8_t indicating children");
   FW.writeU8(0);
   TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
-      "0x00000005: missing InlineInfo uint32_t for name");
+                            "0x00000005: missing InlineInfo uint32_t for name");
   FW.writeU32(0);
-  TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
+  TestInlineInfoDecodeError(
+      ByteOrder, OutStrm.str(), BaseAddr,
       "0x00000009: missing ULEB128 for InlineInfo call file");
   FW.writeU8(0);
-  TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
+  TestInlineInfoDecodeError(
+      ByteOrder, OutStrm.str(), BaseAddr,
       "0x0000000a: missing ULEB128 for InlineInfo call line");
 }
 
@@ -708,20 +714,20 @@ TEST(GSYMTest, TestLineTable) {
   const uint64_t StartAddr = 0x1000;
   const uint32_t FileIdx = 1;
   LineTable LT;
-  LineEntry Line0(StartAddr+0x000, FileIdx, 10);
-  LineEntry Line1(StartAddr+0x010, FileIdx, 11);
-  LineEntry Line2(StartAddr+0x100, FileIdx, 1000);
+  LineEntry Line0(StartAddr + 0x000, FileIdx, 10);
+  LineEntry Line1(StartAddr + 0x010, FileIdx, 11);
+  LineEntry Line2(StartAddr + 0x100, FileIdx, 1000);
   ASSERT_TRUE(LT.empty());
   ASSERT_EQ(LT.size(), (size_t)0);
   LT.push(Line0);
   ASSERT_EQ(LT.size(), (size_t)1);
   LT.push(Line1);
   LT.push(Line2);
-  LT.push(LineEntry(StartAddr+0x120, FileIdx, 900));
-  LT.push(LineEntry(StartAddr+0x120, FileIdx, 2000));
-  LT.push(LineEntry(StartAddr+0x121, FileIdx, 2001));
-  LT.push(LineEntry(StartAddr+0x122, FileIdx, 2002));
-  LT.push(LineEntry(StartAddr+0x123, FileIdx, 2003));
+  LT.push(LineEntry(StartAddr + 0x120, FileIdx, 900));
+  LT.push(LineEntry(StartAddr + 0x120, FileIdx, 2000));
+  LT.push(LineEntry(StartAddr + 0x121, FileIdx, 2001));
+  LT.push(LineEntry(StartAddr + 0x122, FileIdx, 2002));
+  LT.push(LineEntry(StartAddr + 0x123, FileIdx, 2003));
   ASSERT_FALSE(LT.empty());
   ASSERT_EQ(LT.size(), (size_t)8);
   // Test operator[].
@@ -783,30 +789,30 @@ TEST(GSYMTest, TestLineTableDecodeErrors) {
   FileWriter FW(OutStrm, ByteOrder);
   const uint64_t BaseAddr = 0x100;
   TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
-      "0x00000000: missing LineTable MinDelta");
+                           "0x00000000: missing LineTable MinDelta");
   FW.writeU8(1); // MinDelta (ULEB)
   TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
-      "0x00000001: missing LineTable MaxDelta");
+                           "0x00000001: missing LineTable MaxDelta");
   FW.writeU8(10); // MaxDelta (ULEB)
   TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
-      "0x00000002: missing LineTable FirstLine");
+                           "0x00000002: missing LineTable FirstLine");
   FW.writeU8(20); // FirstLine (ULEB)
   TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
-      "0x00000003: EOF found before EndSequence");
+                           "0x00000003: EOF found before EndSequence");
   // Test a SetFile with the argument missing from the stream
   FW.writeU8(1); // SetFile opcode (uint8_t)
   TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
-      "0x00000004: EOF found before SetFile value");
+                           "0x00000004: EOF found before SetFile value");
   FW.writeU8(5); // SetFile value as index (ULEB)
   // Test a AdvancePC with the argument missing from the stream
   FW.writeU8(2); // AdvancePC opcode (uint8_t)
   TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
-      "0x00000006: EOF found before AdvancePC value");
+                           "0x00000006: EOF found before AdvancePC value");
   FW.writeU8(20); // AdvancePC value as offset (ULEB)
   // Test a AdvancePC with the argument missing from the stream
   FW.writeU8(3); // AdvanceLine opcode (uint8_t)
   TestLineTableDecodeError(ByteOrder, OutStrm.str(), BaseAddr,
-      "0x00000008: EOF found before AdvanceLine value");
+                           "0x00000008: EOF found before AdvanceLine value");
   FW.writeU8(20); // AdvanceLine value as offset (LLEB)
 }
 
@@ -823,16 +829,17 @@ TEST(GSYMTest, TestLineTableEncodeErrors) {
 
   // Try to encode a line table where a line entry has an address that is less
   // than BaseAddr and verify we get an appropriate error.
-  LineEntry Line0(BaseAddr+0x000, FileIdx, 10);
-  LineEntry Line1(BaseAddr+0x010, FileIdx, 11);
+  LineEntry Line0(BaseAddr + 0x000, FileIdx, 10);
+  LineEntry Line1(BaseAddr + 0x010, FileIdx, 11);
   LT.push(Line0);
   LT.push(Line1);
   checkError("LineEntry has address 0x1000 which is less than the function "
-             "start address 0x1010", LT.encode(FW, BaseAddr+0x10));
+             "start address 0x1010",
+             LT.encode(FW, BaseAddr + 0x10));
   LT.clear();
 
-  // Try to encode a line table where a line entries  has an address that is less
-  // than BaseAddr and verify we get an appropriate error.
+  // Try to encode a line table where a line entries  has an address that is
+  // less than BaseAddr and verify we get an appropriate error.
   LT.push(Line1);
   LT.push(Line0);
   checkError("LineEntry in LineTable not in ascending order",
@@ -870,9 +877,9 @@ static void InitHeader(Header &H) {
   H.UUIDSize = 16;
   H.BaseAddress = 0x1000;
   H.NumAddresses = 1;
-  H.StrtabOffset= 0x2000;
+  H.StrtabOffset = 0x2000;
   H.StrtabSize = 0x1000;
-  for (size_t i=0; i<GSYM_MAX_UUID_SIZE; ++i) {
+  for (size_t i = 0; i < GSYM_MAX_UUID_SIZE; ++i) {
     if (i < H.UUIDSize)
       H.UUID[i] = i;
     else
@@ -952,10 +959,10 @@ static void TestGsymCreatorEncodeError(llvm::endianness ByteOrder,
 }
 
 TEST(GSYMTest, TestGsymCreatorEncodeErrors) {
-  const uint8_t ValidUUID[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
-                               14, 15, 16};
-  const uint8_t InvalidUUID[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
-                                 14, 15, 16, 17, 18, 19, 20, 21};
+  const uint8_t ValidUUID[] = {1, 2,  3,  4,  5,  6,  7,  8,
+                               9, 10, 11, 12, 13, 14, 15, 16};
+  const uint8_t InvalidUUID[] = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11,
+                                 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
   // Verify we get an error when trying to encode an GsymCreator with no
   // function infos. We shouldn't be saving a GSYM file in this case since
   // there is nothing inside of it.
@@ -988,7 +995,7 @@ TEST(GSYMTest, TestGsymCreatorEncodeErrors) {
   // table.
   GC.forEachFunctionInfo([](FunctionInfo &FI) -> bool {
     FI.OptLineTable = LineTable(); // Invalid line table.
-    return false; // Stop iterating
+    return false;                  // Stop iterating
   });
   TestGsymCreatorEncodeError(llvm::endianness::little, GC,
                              "attempted to encode invalid LineTable object");
@@ -997,7 +1004,7 @@ TEST(GSYMTest, TestGsymCreatorEncodeErrors) {
   GC.forEachFunctionInfo([](FunctionInfo &FI) -> bool {
     FI.OptLineTable = std::nullopt;
     FI.Inline = InlineInfo(); // Invalid InlineInfo.
-    return false; // Stop iterating
+    return false;             // Stop iterating
   });
   TestGsymCreatorEncodeError(llvm::endianness::little, GC,
                              "attempted to encode invalid InlineInfo object");
@@ -1043,8 +1050,8 @@ TEST(GSYMTest, TestGsymCreator1ByteAddrOffsets) {
   constexpr uint8_t AddrOffSize = 1;
   const uint32_t Func1Name = GC.insertString("foo");
   const uint32_t Func2Name = GC.insertString("bar");
-  GC.addFunctionInfo(FunctionInfo(BaseAddr+0x00, 0x10, Func1Name));
-  GC.addFunctionInfo(FunctionInfo(BaseAddr+0x20, 0x10, Func2Name));
+  GC.addFunctionInfo(FunctionInfo(BaseAddr + 0x00, 0x10, Func1Name));
+  GC.addFunctionInfo(FunctionInfo(BaseAddr + 0x20, 0x10, Func2Name));
   OutputAggregator Null(nullptr);
   Error Err = GC.finalize(Null);
   ASSERT_FALSE(Err);
@@ -1066,8 +1073,8 @@ TEST(GSYMTest, TestGsymCreator2ByteAddrOffsets) {
   constexpr uint8_t AddrOffSize = 2;
   const uint32_t Func1Name = GC.insertString("foo");
   const uint32_t Func2Name = GC.insertString("bar");
-  GC.addFunctionInfo(FunctionInfo(BaseAddr+0x000, 0x100, Func1Name));
-  GC.addFunctionInfo(FunctionInfo(BaseAddr+0x200, 0x100, Func2Name));
+  GC.addFunctionInfo(FunctionInfo(BaseAddr + 0x000, 0x100, Func1Name));
+  GC.addFunctionInfo(FunctionInfo(BaseAddr + 0x200, 0x100, Func2Name));
   OutputAggregator Null(nullptr);
   Error Err = GC.finalize(Null);
   ASSERT_FALSE(Err);
@@ -1089,8 +1096,8 @@ TEST(GSYMTest, TestGsymCreator4ByteAddrOffsets) {
   constexpr uint8_t AddrOffSize = 4;
   const uint32_t Func1Name = GC.insertString("foo");
   const uint32_t Func2Name = GC.insertString("bar");
-  GC.addFunctionInfo(FunctionInfo(BaseAddr+0x000, 0x100, Func1Name));
-  GC.addFunctionInfo(FunctionInfo(BaseAddr+0x20000, 0x100, Func2Name));
+  GC.addFunctionInfo(FunctionInfo(BaseAddr + 0x000, 0x100, Func1Name));
+  GC.addFunctionInfo(FunctionInfo(BaseAddr + 0x20000, 0x100, Func2Name));
   OutputAggregator Null(nullptr);
   Error Err = GC.finalize(Null);
   ASSERT_FALSE(Err);
@@ -1112,8 +1119,8 @@ TEST(GSYMTest, TestGsymCreator8ByteAddrOffsets) {
   constexpr uint8_t AddrOffSize = 8;
   const uint32_t Func1Name = GC.insertString("foo");
   const uint32_t Func2Name = GC.insertString("bar");
-  GC.addFunctionInfo(FunctionInfo(BaseAddr+0x000, 0x100, Func1Name));
-  GC.addFunctionInfo(FunctionInfo(BaseAddr+0x100000000, 0x100, Func2Name));
+  GC.addFunctionInfo(FunctionInfo(BaseAddr + 0x000, 0x100, Func1Name));
+  GC.addFunctionInfo(FunctionInfo(BaseAddr + 0x100000000, 0x100, Func2Name));
   OutputAggregator Null(nullptr);
   Error Err = GC.finalize(Null);
   ASSERT_FALSE(Err);
@@ -1147,7 +1154,7 @@ TEST(GSYMTest, TestGsymReader) {
   GC.setUUID(UUID);
   constexpr uint64_t BaseAddr = 0x1000;
   constexpr uint64_t Func1Addr = BaseAddr;
-  constexpr uint64_t Func2Addr = BaseAddr+0x20;
+  constexpr uint64_t Func2Addr = BaseAddr + 0x20;
   constexpr uint64_t FuncSize = 0x10;
   const uint32_t Func1Name = GC.insertString("foo");
   const uint32_t Func2Name = GC.insertString("bar");
@@ -1164,20 +1171,20 @@ TEST(GSYMTest, TestGsymReader) {
   ASSERT_FALSE((bool)Err);
   if (auto ExpectedGR = GsymReader::copyBuffer(OutStrm.str())) {
     const GsymReader &GR = ExpectedGR.get();
-    VerifyFunctionInfoError(GR, Func1Addr-1, "address 0xfff is not in GSYM");
+    VerifyFunctionInfoError(GR, Func1Addr - 1, "address 0xfff is not in GSYM");
 
     FunctionInfo Func1(Func1Addr, FuncSize, Func1Name);
     VerifyFunctionInfo(GR, Func1Addr, Func1);
-    VerifyFunctionInfo(GR, Func1Addr+1, Func1);
-    VerifyFunctionInfo(GR, Func1Addr+FuncSize-1, Func1);
-    VerifyFunctionInfoError(GR, Func1Addr+FuncSize,
+    VerifyFunctionInfo(GR, Func1Addr + 1, Func1);
+    VerifyFunctionInfo(GR, Func1Addr + FuncSize - 1, Func1);
+    VerifyFunctionInfoError(GR, Func1Addr + FuncSize,
                             "address 0x1010 is not in GSYM");
-    VerifyFunctionInfoError(GR, Func2Addr-1, "address 0x101f is not in GSYM");
+    VerifyFunctionInfoError(GR, Func2Addr - 1, "address 0x101f is not in GSYM");
     FunctionInfo Func2(Func2Addr, FuncSize, Func2Name);
     VerifyFunctionInfo(GR, Func2Addr, Func2);
-    VerifyFunctionInfo(GR, Func2Addr+1, Func2);
-    VerifyFunctionInfo(GR, Func2Addr+FuncSize-1, Func2);
-    VerifyFunctionInfoError(GR, Func2Addr+FuncSize,
+    VerifyFunctionInfo(GR, Func2Addr + 1, Func2);
+    VerifyFunctionInfo(GR, Func2Addr + FuncSize - 1, Func2);
+    VerifyFunctionInfoError(GR, Func2Addr + FuncSize,
                             "address 0x1030 is not in GSYM");
   }
 }
@@ -1234,53 +1241,57 @@ TEST(GSYMTest, TestGsymLookups) {
   // Verify inline info is correct when doing lookups.
   auto LR = GR->lookup(0x1000);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 5}));
+  EXPECT_THAT(LR->Locations, testing::ElementsAre(
+                                 SourceLocation{"main", "/tmp", "main.c", 5}));
   LR = GR->lookup(0x100F);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 5, 15}));
+  EXPECT_THAT(LR->Locations, testing::ElementsAre(SourceLocation{
+                                 "main", "/tmp", "main.c", 5, 15}));
 
   LR = GR->lookup(0x1010);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
 
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 10},
-                         SourceLocation{"main", "/tmp", "main.c", 6, 16}));
+  EXPECT_THAT(
+      LR->Locations,
+      testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 10},
+                           SourceLocation{"main", "/tmp", "main.c", 6, 16}));
 
   LR = GR->lookup(0x1012);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"inline2", "/tmp", "foo.h", 20},
-                         SourceLocation{"inline1", "/tmp", "foo.h", 33, 2},
-                         SourceLocation{"main", "/tmp", "main.c", 6, 18}));
+  EXPECT_THAT(
+      LR->Locations,
+      testing::ElementsAre(SourceLocation{"inline2", "/tmp", "foo.h", 20},
+                           SourceLocation{"inline1", "/tmp", "foo.h", 33, 2},
+                           SourceLocation{"main", "/tmp", "main.c", 6, 18}));
 
   LR = GR->lookup(0x1014);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 11, 4},
-                         SourceLocation{"main", "/tmp", "main.c", 6, 20}));
+  EXPECT_THAT(
+      LR->Locations,
+      testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 11, 4},
+                           SourceLocation{"main", "/tmp", "main.c", 6, 20}));
 
   LR = GR->lookup(0x1016);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"inline3", "/tmp", "foo.h", 30},
-                         SourceLocation{"inline1", "/tmp", "foo.h", 35, 6},
-                         SourceLocation{"main", "/tmp", "main.c", 6, 22}));
+  EXPECT_THAT(
+      LR->Locations,
+      testing::ElementsAre(SourceLocation{"inline3", "/tmp", "foo.h", 30},
+                           SourceLocation{"inline1", "/tmp", "foo.h", 35, 6},
+                           SourceLocation{"main", "/tmp", "main.c", 6, 22}));
 
   LR = GR->lookup(0x1018);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 12, 8},
-                         SourceLocation{"main", "/tmp", "main.c", 6, 24}));
+  EXPECT_THAT(
+      LR->Locations,
+      testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 12, 8},
+                           SourceLocation{"main", "/tmp", "main.c", 6, 24}));
 
   LR = GR->lookup(0x1020);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 8, 32}));
+  EXPECT_THAT(LR->Locations, testing::ElementsAre(SourceLocation{
+                                 "main", "/tmp", "main.c", 8, 32}));
 }
 
-
 TEST(GSYMTest, TestDWARFFunctionWithAddresses) {
   // Create a single compile unit with a single function and make sure it gets
   // converted to DWARF correctly. The function's address range is in where
@@ -1851,43 +1862,46 @@ TEST(GSYMTest, TestDWARFInlineInfo) {
   StringRef MethodName = GR->getString(ExpFI->Name);
   EXPECT_EQ(MethodName, "main");
 
-    // Verify inline info is correct when doing lookups.
+  // Verify inline info is correct when doing lookups.
   auto LR = GR->lookup(0x1000);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 10}));
-  LR = GR->lookup(0x1100-1);
+  EXPECT_THAT(LR->Locations, testing::ElementsAre(
+                                 SourceLocation{"main", "/tmp", "main.c", 10}));
+  LR = GR->lookup(0x1100 - 1);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 10, 255}));
+  EXPECT_THAT(LR->Locations, testing::ElementsAre(SourceLocation{
+                                 "main", "/tmp", "main.c", 10, 255}));
 
   LR = GR->lookup(0x1100);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"inline1", "/tmp", "inline.h", 20},
-                         SourceLocation{"main", "/tmp", "main.c", 10, 256}));
-  LR = GR->lookup(0x1180-1);
+  EXPECT_THAT(
+      LR->Locations,
+      testing::ElementsAre(SourceLocation{"inline1", "/tmp", "inline.h", 20},
+                           SourceLocation{"main", "/tmp", "main.c", 10, 256}));
+  LR = GR->lookup(0x1180 - 1);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
   EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"inline1", "/tmp", "inline.h", 20, 127},
-                         SourceLocation{"main", "/tmp", "main.c", 10, 383}));
+              testing::ElementsAre(
+                  SourceLocation{"inline1", "/tmp", "inline.h", 20, 127},
+                  SourceLocation{"main", "/tmp", "main.c", 10, 383}));
   LR = GR->lookup(0x1180);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
   EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"inline1", "/tmp", "inline.h", 21, 128},
-                         SourceLocation{"main", "/tmp", "main.c", 10, 384}));
-  LR = GR->lookup(0x1200-1);
+              testing::ElementsAre(
+                  SourceLocation{"inline1", "/tmp", "inline.h", 21, 128},
+                  SourceLocation{"main", "/tmp", "main.c", 10, 384}));
+  LR = GR->lookup(0x1200 - 1);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
   EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"inline1", "/tmp", "inline.h", 21, 255},
-                         SourceLocation{"main", "/tmp", "main.c", 10, 511}));
+              testing::ElementsAre(
+                  SourceLocation{"inline1", "/tmp", "inline.h", 21, 255},
+                  SourceLocation{"main", "/tmp", "main.c", 10, 511}));
   LR = GR->lookup(0x1200);
   ASSERT_THAT_EXPECTED(LR, Succeeded());
-  EXPECT_THAT(LR->Locations,
-    testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 11, 512}));
+  EXPECT_THAT(LR->Locations, testing::ElementsAre(SourceLocation{
+                                 "main", "/tmp", "main.c", 11, 512}));
 }
 
-
 TEST(GSYMTest, TestDWARFNoLines) {
   // Check that if a DW_TAG_subprogram doesn't have line table entries that
   // we fall back and use the DW_AT_decl_file and DW_AT_decl_line to at least
@@ -2150,7 +2164,6 @@ TEST(GSYMTest, TestDWARFNoLines) {
   EXPECT_EQ(ExpFI->OptLineTable->first()->Line, 40u);
 }
 
-
 TEST(GSYMTest, TestDWARFDeadStripAddr4) {
   // Check that various techniques that compilers use for dead code stripping
   // work for 4 byte addresses. Make sure we keep the good functions and
@@ -2459,7 +2472,8 @@ TEST(GSYMTest, TestGsymCreatorMultipleSymbolsWithNoSize) {
                    ArrayRef<uint8_t>(UUID));
 }
 
-// Helper function to quickly create a FunctionInfo in a GsymCreator for testing.
+// Helper function to quickly create a FunctionInfo in a GsymCreator for
+// testing.
 static void AddFunctionInfo(GsymCreator &GC, const char *FuncName,
                             uint64_t FuncAddr, const char *SourcePath,
                             const char *HeaderPath) {
@@ -2467,18 +2481,21 @@ static void AddFunctionInfo(GsymCreator &GC, const char *FuncName,
   FI.OptLineTable = LineTable();
   const uint32_t SourceFileIdx = GC.insertFile(SourcePath);
   const uint32_t HeaderFileIdx = GC.insertFile(HeaderPath);
-  FI.OptLineTable->push(LineEntry(FuncAddr+0x00, SourceFileIdx, 5));
-  FI.OptLineTable->push(LineEntry(FuncAddr+0x10, HeaderFileIdx, 10));
-  FI.OptLineTable->push(LineEntry(FuncAddr+0x12, HeaderFileIdx, 20));
-  FI.OptLineTable->push(LineEntry(FuncAddr+0x14, HeaderFileIdx, 11));
-  FI.OptLineTable->push(LineEntry(FuncAddr+0x16, HeaderFileIdx, 30));
-  FI.OptLineTable->push(LineEntry(FuncAddr+0x18, HeaderFileIdx, 12));
-  FI.OptLineTable->push(LineEntry(FuncAddr+0x20, SourceFileIdx, 8));
+  FI.OptLineTable->push(LineEntry(FuncAddr + 0x00, SourceFileIdx, 5));
+  FI.OptLineTable->push(LineEntry(FuncAddr + 0x10, HeaderFileIdx, 10));
+  FI.OptLineTable->push(LineEntry(FuncAddr + 0x12, HeaderFileIdx, 20));
+  FI.OptLineTable->push(LineEntry(FuncAddr + 0x14, HeaderFileIdx, 11));
+  FI.OptLineTable->push(LineEntry(FuncAddr + 0x16, HeaderFileIdx, 30));
+  FI.OptLineTable->push(LineEntry(FuncAddr + 0x18, HeaderFileIdx, 12));
+  FI.OptLineTable->push(LineEntry(FuncAddr + 0x20, SourceFileIdx, 8));
   FI.Inline = InlineInfo();
 
-  std::string InlineName1(FuncName); InlineName1.append("1");
-  std::string InlineName2(FuncName); InlineName2.append("2");
-  std::string InlineName3(FuncName); InlineName3.append("3");
+  std::string InlineName1(FuncName);
+  InlineName1.append("1");
+  std::string InlineName2(FuncName);
+  InlineName2.append("2");
+  std::string InlineName3(FuncName);
+  InlineName3.append("3");
 
   FI.Inline->Name = GC.insertString(InlineName1);
   FI.Inline->CallFile = SourceFileIdx;
@@ -2530,7 +2547,7 @@ TEST(GSYMTest, TestGsymSegmenting) {
   AddFunctionInfo(GC, "baz", 0x4000, "/tmp/baz.c", "/tmp/baz.h");
   Expected<GsymReader> GR = FinalizeEncodeAndDecode(GC);
   ASSERT_THAT_EXPECTED(GR, Succeeded());
-  //GR->dump(outs());
+  // GR->dump(outs());
 
   // Create segmented GSYM files where each file contains 1 function. We will
   // then test doing lookups on the "GR", or the full GSYM file and then test
@@ -2552,7 +2569,8 @@ TEST(GSYMTest, TestGsymSegmenting) {
       GC.createSegment(57, FuncIdx);
   ASSERT_FALSE((bool)GCError);
   checkError("a segment size of 57 is to small to fit any function infos, "
-             "specify a larger value", GCError.takeError());
+             "specify a larger value",
+             GCError.takeError());
   // Make sure that the function index didn't get incremented when we didn't
   // encode any values into the segmented GsymCreator.
   ASSERT_EQ(FuncIdx, (size_t)0);
@@ -2627,7 +2645,6 @@ TEST(GSYMTest, TestGsymSegmenting) {
     ASSERT_THAT_EXPECTED(GR2000->lookup(0x1000), Failed());
     ASSERT_THAT_EXPECTED(GR2000->lookup(0x3000), Failed());
     ASSERT_THAT_EXPECTED(GR2000->lookup(0x4000), Failed());
-
   }
 
   // Verify that all lookups match the range [0x3000-0x3030) when doing lookups
@@ -2646,7 +2663,7 @@ TEST(GSYMTest, TestGsymSegmenting) {
     ASSERT_THAT_EXPECTED(GR3000->lookup(0x1000), Failed());
     ASSERT_THAT_EXPECTED(GR3000->lookup(0x2000), Failed());
     ASSERT_THAT_EXPECTED(GR3000->lookup(0x4000), Failed());
-}
+  }
 
   // Verify that all lookups match the range [0x4000-0x4030) when doing lookups
   // in the GsymReader that contains all functions and from the segmented
@@ -2681,7 +2698,7 @@ TEST(GSYMTest, TestGsymSegmentingNoBase) {
   AddFunctionInfo(GC, "baz", 0x4000, "/tmp/baz.c", "/tmp/baz.h");
   Expected<GsymReader> GR = FinalizeEncodeAndDecode(GC);
   ASSERT_THAT_EXPECTED(GR, Succeeded());
-  //GR->dump(outs());
+  // GR->dump(outs());
 
   // Create segmented GSYM files where each file contains 1 function. We will
   // then test doing lookups on the "GR", or the full GSYM file and then test
@@ -2703,7 +2720,8 @@ TEST(GSYMTest, TestGsymSegmentingNoBase) {
       GC.createSegment(57, FuncIdx);
   ASSERT_FALSE((bool)GCError);
   checkError("a segment size of 57 is to small to fit any function infos, "
-             "specify a larger value", GCError.takeError());
+             "specify a larger value",
+             GCError.takeError());
   // Make sure that the function index didn't get incremented when we didn't
   // encode any values into the segmented GsymCreator.
   ASSERT_EQ(FuncIdx, (size_t)0);
@@ -2778,7 +2796,6 @@ TEST(GSYMTest, TestGsymSegmentingNoBase) {
     ASSERT_THAT_EXPECTED(GR2000->lookup(0x1000), Failed());
     ASSERT_THAT_EXPECTED(GR2000->lookup(0x3000), Failed());
     ASSERT_THAT_EXPECTED(GR2000->lookup(0x4000), Failed());
-
   }
 
   // Verify that all lookups match the range [0x3000-0x3030) when doing lookups
@@ -2797,7 +2814,7 @@ TEST(GSYMTest, TestGsymSegmentingNoBase) {
     ASSERT_THAT_EXPECTED(GR3000->lookup(0x1000), Failed());
     ASSERT_THAT_EXPECTED(GR3000->lookup(0x2000), Failed());
     ASSERT_THAT_EXPECTED(GR3000->lookup(0x4000), Failed());
-}
+  }
 
   // Verify that all lookups match the range [0x4000-0x4030) when doing lookups
   // in the GsymReader that contains all functions and from the segmented
@@ -2819,7 +2836,6 @@ TEST(GSYMTest, TestGsymSegmentingNoBase) {
   }
 }
 
-
 TEST(GSYMTest, TestDWARFInlineRangeScopes) {
   // Test cases where inlined functions address ranges are not contained in the
   // parent ranges and that we can successfully remove them and emit error
@@ -3074,16 +3090,19 @@ TEST(GSYMTest, TestDWARFInlineRangeScopes) {
   StringRef FuncName = GR->getString(ExpFI->Name);
   EXPECT_EQ(FuncName, "foo");
   std::vector<std::string> ExpectedLogErrors = {
-    "error: inlined function DIE at 0x0000002a has a range [0x0000000000000fff "
-    "- 0x0000000000001001) that isn't contained in any parent address ranges, "
-    "this inline range will be removed.",
-    "error: inlined function DIE at 0x00000058 has a range [0x0000000000001000 "
-    "- 0x0000000000001100) that isn't contained in any parent address ranges, "
-    "this inline range will be removed."
-  };
+      "error: inlined function DIE at 0x0000002a has a range "
+      "[0x0000000000000fff "
+      "- 0x0000000000001001) that isn't contained in any parent address "
+      "ranges, "
+      "this inline range will be removed.",
+      "error: inlined function DIE at 0x00000058 has a range "
+      "[0x0000000000001000 "
+      "- 0x0000000000001100) that isn't contained in any parent address "
+      "ranges, "
+      "this inline range will be removed."};
   // Make sure all expected errors are in the error stream for the two invalid
   // inlined functions that we removed due to invalid range scoping.
-  for (const auto &Error: ExpectedLogErrors) {
+  for (const auto &Error : ExpectedLogErrors) {
     EXPECT_TRUE(OS.str().find(Error) != std::string::npos);
   }
   // The top level inline info is for the function "foo" itself. Verify that
@@ -3096,7 +3115,6 @@ TEST(GSYMTest, TestDWARFInlineRangeScopes) {
   EXPECT_EQ(ExpFI->Inline->CallLine, 0u);
   EXPECT_EQ(ExpFI->Inline->Children.size(), 1u);
 
-
   // The first inline function "valid1" contains two inline functions in the
   // DWARF, but one has an address range which isn't contained in any ranges
   // from "foo", so only 1 inline function be parsed.
@@ -3107,7 +3125,6 @@ TEST(GSYMTest, TestDWARFInlineRangeScopes) {
   EXPECT_EQ(Inline1.CallLine, 11u);
   EXPECT_EQ(Inline1.Children.size(), 1u);
 
-
   // The second inline function "valid2" contains two inline functions in the
   // DWARF, but one has an address range which isn't contained in any ranges
   // from "valid1", so only 1 inline function be parsed.
@@ -3302,15 +3319,17 @@ TEST(GSYMTest, TestDWARFEmptyInline) {
   StringRef FuncName = GR->getString(ExpFI->Name);
   EXPECT_EQ(FuncName, "foo");
   std::vector<std::string> ExpectedLogErrors = {
-    "error: inlined function DIE at 0x0000002a has a range [0x0000000000001100"
-    " - 0x0000000000001200) that isn't contained in any parent address ranges,"
-    " this inline range will be removed.",
-    "warning: DIE contains inline function information that has no valid "
-    "ranges, removing inline information:",
+      "error: inlined function DIE at 0x0000002a has a range "
+      "[0x0000000000001100"
+      " - 0x0000000000001200) that isn't contained in any parent address "
+      "ranges,"
+      " this inline range will be removed.",
+      "warning: DIE contains inline function information that has no valid "
+      "ranges, removing inline information:",
   };
   // Make sure all expected errors are in the error stream for the two invalid
   // inlined functions that we removed due to invalid range scoping.
-  for (const auto &Error: ExpectedLogErrors) {
+  for (const auto &Error : ExpectedLogErrors) {
     EXPECT_TRUE(OS.str().find(Error) != std::string::npos);
   }
 }
@@ -3344,7 +3363,8 @@ TEST(GSYMTest, TestFinalizeForLineTables) {
   //                 DW_AT_high_pc	(0x0000000000002050)
   //
   // 0x0000003f:   NULL
-  // 0x00000040: Compile Unit: length = 0x0000003c, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000080)
+  // 0x00000040: Compile Unit: length = 0x0000003c, format = DWARF32, version =
+  // 0x0004, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000080)
   //
   // 0x0000004b: DW_TAG_compile_unit
   //               DW_AT_name	("/tmp/main.cpp")
@@ -3550,7 +3570,6 @@ TEST(GSYMTest, TestFinalizeForLineTables) {
   EXPECT_EQ(FuncName2, "bar");
 }
 
-
 TEST(GSYMTest, TestRangeWarnings) {
   // This example has a single compile unit that has a DW_TAG_subprogram that
   // has two discontiguous ranges. We will create two FunctionInfo objects for
@@ -4026,7 +4045,6 @@ TEST(GSYMTest, TestEmptyRangeWarnings) {
   EXPECT_TRUE(errors.find("error:") == std::string::npos);
 }
 
-
 TEST(GSYMTest, TestEmptyLinkageName) {
   // This example has a single compile unit that has a DW_TAG_subprogram that
   // has a function that has an empty linkage name and a valid normal name.
@@ -4051,7 +4069,6 @@ TEST(GSYMTest, TestEmptyLinkageName) {
   //
   // 0x0000002e:   NULL
 
-
   StringRef yamldata = R"(
   debug_str:
     - ''
@@ -4899,3 +4916,129 @@ TEST(GSYMTest, TestLookupsOfOverlappingAndUnequalRanges) {
   for (const auto &Line : ExpectedDumpLines)
     EXPECT_TRUE(DumpStr.find(Line) != std::string::npos);
 }
+
+TEST(GSYMTest, TestDWARFTransformNoErrorForMissingFileDecl) {
+  // Test that if llvm-gsymutil finds a line table for a compile unit and if
+  // there are no matching entries for a function in that compile unit, that
+  // it doesn't print out a error saying that a DIE has an invalid file index
+  // if there is no DW_AT_decl_file attribute.
+  //
+  // 0x0000000b: DW_TAG_compile_unit
+  //               DW_AT_name        ("main.cpp")
+  //               DW_AT_language    (DW_LANG_C)
+  //               DW_AT_stmt_list   (0x00000000)
+  //
+  // 0x00000015:   DW_TAG_subprogram
+  //                 DW_AT_name      ("foo")
+  //                 DW_AT_low_pc    (0x0000000000001000)
+  //                 DW_AT_high_pc   (0x0000000000001050)
+  //
+  // 0x0000002a:   NULL
+  //
+  // Line table that has entries, but none that match "foo":
+  //
+  // Address            Line   Column File   ISA Discriminator OpIndex Flags
+  // ------------------ ------ ------ ------ --- ------------- ------- -----
+  // 0x0000000000002000     10      0      1   0             0       0 is_stmt
+  // 0x0000000000002050     13      0      1   0             0       0 is_stmt
+
+  StringRef yamldata = R"(
+  debug_str:
+    - ''
+    - main.cpp
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x1
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_language
+              Form:            DW_FORM_udata
+            - Attribute:       DW_AT_stmt_list
+              Form:            DW_FORM_sec_offset
+        - Code:            0x2
+          Tag:             DW_TAG_subprogram
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+            - Attribute:       DW_AT_low_pc
+              Form:            DW_FORM_addr
+            - Attribute:       DW_AT_high_pc
+              Form:            DW_FORM_addr
+  debug_info:
+    - Length:          0x27
+      Version:         4
+      AbbrevTableID:   0
+      AbbrOffset:      0x0
+      AddrSize:        8
+      Entries:
+        - AbbrCode:        0x1
+          Values:
+            - Value:           0x1
+            - Value:           0x2
+            - Value:           0x0
+        - AbbrCode:        0x2
+          Values:
+            - Value:           0xDEADBEEFDEADBEEF
+              CStr:            foo
+            - Value:           0x1000
+            - Value:           0x1050
+        - AbbrCode:        0x0
+  debug_line:
+    - Length:          58
+      Version:         2
+      PrologueLength:  31
+      MinInstLength:   1
+      DefaultIsStmt:   1
+      LineBase:        251
+      LineRange:       14
+      OpcodeBase:      13
+      StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
+      Files:
+        - Name:            main.cpp
+          DirIdx:          0
+          ModTime:         0
+          Length:          0
+      Opcodes:
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          9
+          SubOpcode:       DW_LNE_set_address
+          Data:            8192
+        - Opcode:          DW_LNS_advance_line
+          SData:           9
+          Data:            0
+        - Opcode:          DW_LNS_copy
+          Data:            0
+        - Opcode:          DW_LNS_advance_pc
+          Data:            80
+        - Opcode:          DW_LNS_advance_line
+          SData:           3
+          Data:            0
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          1
+          SubOpcode:       DW_LNE_end_sequence
+          Data:            0
+  )";
+  auto ErrOrSections = DWARFYAML::emitDebugSections(yamldata);
+  ASSERT_THAT_EXPECTED(ErrOrSections, Succeeded());
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  ASSERT_TRUE(DwarfContext.get() != nullptr);
+  std::string errors;
+  raw_string_ostream OS(errors);
+  OutputAggregator OSAgg(&OS);
+  GsymCreator GC;
+  DwarfTransformer DT(*DwarfContext, GC);
+  const uint32_t ThreadCount = 1;
+  ASSERT_THAT_ERROR(DT.convert(ThreadCount, OSAgg), Succeeded());
+  ASSERT_THAT_ERROR(GC.finalize(OSAgg), Succeeded());
+
+  // Make sure this warning is not in the binary
+  std::string error_str("error: function DIE at 0x00000015 has an invalid file "
+                        "index 4294967295 in its DW_AT_decl_file attribute");
+  EXPECT_TRUE(errors.find(error_str) == std::string::npos);
+}



More information about the llvm-commits mailing list