llvm-dwarfdump: implement --recurse-depth=<N>

This patch implements the Darwin dwarfdump option --recurse-depth=<N>,
which limits the recursion depth when selectively printing DIEs at an
offset.

Differential Revision: https://reviews.llvm.org/D38064

llvm-svn: 313778
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
index 358e9bf..43b2356 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
@@ -27,7 +27,7 @@
      << ")\n";
 
   if (DWARFDie CUDie = getUnitDIE(false))
-    CUDie.dump(OS, -1U, 0, DumpOpts);
+    CUDie.dump(OS, 0, DumpOpts);
   else
     OS << "<compile unit can't be parsed!>\n\n";
 }
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 0e28954..f20a7ca 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -258,7 +258,8 @@
                            DWARFSection Section, cu_iterator_range CUs) {
     if (shouldDump(IsExplicit, Name, DIDT_ID_DebugInfo, Section.Data)) {
       if (DumpOffset)
-        getDIEForOffset(DumpOffset.getValue()).dump(OS, 0, 0, DumpOpts);
+        getDIEForOffset(DumpOffset.getValue())
+            .dump(OS, 0, DumpOpts.noImplicitRecursion());
       else
         for (const auto &CU : CUs)
           CU->dump(OS, DumpOpts);
@@ -276,7 +277,8 @@
     for (const auto &TUS : TUSections)
       for (const auto &TU : TUS)
         if (DumpOffset)
-          TU->getDIEForOffset(*DumpOffset).dump(OS, 0, 0, DumpOpts);
+          TU->getDIEForOffset(*DumpOffset)
+              .dump(OS, 0, DumpOpts.noImplicitRecursion());
         else
           TU->dump(OS, DumpOpts);
   };
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index f588f25..31074a8 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -373,19 +373,19 @@
   if (!Die)
     return Indent;
   Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts);
-  Die.dump(OS, 0, Indent, DumpOpts);
+  Die.dump(OS, Indent, DumpOpts);
   return Indent + 2;
 }
 
-void DWARFDie::dump(raw_ostream &OS, unsigned RecurseDepth, unsigned Indent,
+void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
                     DIDumpOptions DumpOpts) const {
   if (!isValid())
     return;
   DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor();
   const uint32_t Offset = getOffset();
   uint32_t offset = Offset;
-  if (DumpOpts.ShowChildren)
-    RecurseDepth++;
+  //  if (DumpOpts.ShowChildren && DumpOpts.RecurseDepth)
+  //  DumpOpts.RecurseDepth++;
   if (DumpOpts.ShowParents) {
     DumpOpts.ShowParents = false;
     Indent = dumpParentChain(getParent(), OS, Indent, DumpOpts);
@@ -423,9 +423,10 @@
         }
 
         DWARFDie child = getFirstChild();
-        if (RecurseDepth > 0 && child) {
+        if (DumpOpts.RecurseDepth > 0 && child) {
+          DumpOpts.RecurseDepth--;
           while (child) {
-            child.dump(OS, RecurseDepth-1, Indent+2, DumpOpts);
+            child.dump(OS, Indent+2, DumpOpts);
             child = child.getSibling();
           }
         }
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
index 67cc050..206c12f 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
@@ -55,7 +55,7 @@
      << " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n";
 
   if (DWARFDie TU = getUnitDIE(false))
-    TU.dump(OS, -1U, 0, DumpOpts);
+    TU.dump(OS, 0, DumpOpts);
   else
     OS << "<type unit can't be parsed!>\n\n";
 }
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 24a0e67..096d5ff 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -369,13 +369,13 @@
         ++NumErrors;
         OS << "error: DW_AT_ranges offset is beyond .debug_ranges "
               "bounds:\n";
-        Die.dump(OS, 0, 0, DumpOpts);
+        Die.dump(OS, 0, DumpOpts);
         OS << "\n";
       }
     } else {
       ++NumErrors;
       OS << "error: DIE has invalid DW_AT_ranges encoding:\n";
-      Die.dump(OS, 0, 0, DumpOpts);
+      Die.dump(OS, 0, DumpOpts);
       OS << "\n";
     }
     break;
@@ -387,13 +387,13 @@
         OS << "error: DW_AT_stmt_list offset is beyond .debug_line "
               "bounds: "
            << format("0x%08" PRIx64, *SectionOffset) << "\n";
-        Die.dump(OS, 0, 0, DumpOpts);
+        Die.dump(OS, 0, DumpOpts);
         OS << "\n";
       }
     } else {
       ++NumErrors;
       OS << "error: DIE has invalid DW_AT_stmt_list encoding:\n";
-      Die.dump(OS, 0, 0, DumpOpts);
+      Die.dump(OS, 0, DumpOpts);
       OS << "\n";
     }
     break;
@@ -428,7 +428,7 @@
            << format("0x%08" PRIx64, CUOffset)
            << " is invalid (must be less than CU size of "
            << format("0x%08" PRIx32, CUSize) << "):\n";
-        Die.dump(OS, 0, 0, DumpOpts);
+        Die.dump(OS, 0, DumpOpts);
         OS << "\n";
       } else {
         // Valid reference, but we will verify it points to an actual
@@ -448,7 +448,7 @@
         ++NumErrors;
         OS << "error: DW_FORM_ref_addr offset beyond .debug_info "
               "bounds:\n";
-        Die.dump(OS, 0, 0, DumpOpts);
+        Die.dump(OS, 0, DumpOpts);
         OS << "\n";
       } else {
         // Valid reference, but we will verify it points to an actual
@@ -464,7 +464,7 @@
     if (SecOffset && *SecOffset >= DObj.getStringSection().size()) {
       ++NumErrors;
       OS << "error: DW_FORM_strp offset beyond .debug_str bounds:\n";
-      Die.dump(OS, 0, 0, DumpOpts);
+      Die.dump(OS, 0, DumpOpts);
       OS << "\n";
     }
     break;
@@ -489,7 +489,7 @@
        << ". Offset is in between DIEs:\n";
     for (auto Offset : Pair.second) {
       auto ReferencingDie = DCtx.getDIEForOffset(Offset);
-      ReferencingDie.dump(OS, 0, 0, DumpOpts);
+      ReferencingDie.dump(OS, 0, DumpOpts);
       OS << "\n";
     }
     OS << "\n";
@@ -514,7 +514,7 @@
         ++NumDebugLineErrors;
         OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset)
            << "] was not able to be parsed for CU:\n";
-        Die.dump(OS, 0, 0, DumpOpts);
+        Die.dump(OS, 0, DumpOpts);
         OS << '\n';
         continue;
       }
@@ -532,8 +532,8 @@
          << format("0x%08" PRIx32, Iter->second.getOffset()) << " and "
          << format("0x%08" PRIx32, Die.getOffset())
          << ", have the same DW_AT_stmt_list section offset:\n";
-      Iter->second.dump(OS, 0, 0, DumpOpts);
-      Die.dump(OS, 0, 0, DumpOpts);
+      Iter->second.dump(OS, 0, DumpOpts);
+      Die.dump(OS, 0, DumpOpts);
       OS << '\n';
       // Already verified this line table before, no need to do it again.
       continue;