Index: llvm/trunk/include/llvm/DebugInfo/DIContext.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/DIContext.h +++ llvm/trunk/include/llvm/DebugInfo/DIContext.h @@ -97,11 +97,10 @@ void addFrame(const DILineInfo &Frame) { Frames.push_back(Frame); } - + void resize(unsigned i) { Frames.resize(i); } - }; /// Container for description of a global variable. @@ -157,7 +156,8 @@ /// dumped. struct DIDumpOptions { unsigned DumpType = DIDT_All; - unsigned RecurseDepth = -1U; + unsigned ChildRecurseDepth = -1U; + unsigned ParentRecurseDepth = -1U; uint16_t Version = 0; // DWARF version to assume when extracting. uint8_t AddrSize = 4; // Address byte size to assume when extracting. bool ShowAddresses = true; @@ -171,15 +171,18 @@ /// Return default option set for printing a single DIE without children. static DIDumpOptions getForSingleDIE() { DIDumpOptions Opts; - Opts.RecurseDepth = 0; + Opts.ChildRecurseDepth = 0; + Opts.ParentRecurseDepth = 0; return Opts; } /// Return the options with RecurseDepth set to 0 unless explicitly required. DIDumpOptions noImplicitRecursion() const { DIDumpOptions Opts = *this; - if (RecurseDepth == -1U && !ShowChildren) - Opts.RecurseDepth = 0; + if (ChildRecurseDepth == -1U && !ShowChildren) + Opts.ChildRecurseDepth = 0; + if (ParentRecurseDepth == -1U && !ShowParents) + Opts.ParentRecurseDepth = 0; return Opts; } }; Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -553,10 +553,12 @@ /// Helper to dump a DIE with all of its parents, but no siblings. static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent, - DIDumpOptions DumpOpts) { + DIDumpOptions DumpOpts, unsigned Depth = 0) { if (!Die) return Indent; - Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts); + if (DumpOpts.ParentRecurseDepth > 0 && Depth >= DumpOpts.ParentRecurseDepth) + return Indent; + Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts, Depth + 1); Die.dump(OS, Indent, DumpOpts); return Indent + 2; } @@ -604,8 +606,8 @@ } DWARFDie child = getFirstChild(); - if (DumpOpts.ShowChildren && DumpOpts.RecurseDepth > 0 && child) { - DumpOpts.RecurseDepth--; + if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0 && child) { + DumpOpts.ChildRecurseDepth--; DIDumpOptions ChildDumpOpts = DumpOpts; ChildDumpOpts.ShowParents = false; while (child) { Index: llvm/trunk/test/tools/llvm-dwarfdump/X86/enum.s =================================================================== --- llvm/trunk/test/tools/llvm-dwarfdump/X86/enum.s +++ llvm/trunk/test/tools/llvm-dwarfdump/X86/enum.s @@ -2,11 +2,16 @@ # RUN: llvm-dwarfdump --debug-info=0x0000002a -p %t | FileCheck %s --check-prefix=PARENTS # RUN: llvm-dwarfdump --debug-info=0x0000002a -c %t | FileCheck %s --check-prefix=CHILDREN # RUN: llvm-dwarfdump --debug-info=0x0000002a -p -c %t | FileCheck %s --check-prefix=BOTH +# RUN: llvm-dwarfdump --debug-info=0x00000032 -p -parent-recurse-depth 1 -c %t | FileCheck %s --check-prefix=ONEPARENT # PARENTS: DW_TAG_compile_unit # PARENTS: DW_TAG_enumeration_type # PARENTS-NOT: DW_TAG_enumerator +# ONEPARENT-NOT: DW_TAG_compile_unit +# ONEPARENT: DW_TAG_enumeration_type +# ONEPARENT: DW_TAG_enumerator + # CHILDREN-NOT: DW_TAG_compile_unit # CHILDREN: DW_TAG_enumerator # CHILDREN: DW_AT_name ("first") Index: llvm/trunk/test/tools/llvm-dwarfdump/cmdline.test =================================================================== --- llvm/trunk/test/tools/llvm-dwarfdump/cmdline.test +++ llvm/trunk/test/tools/llvm-dwarfdump/cmdline.test @@ -13,6 +13,7 @@ HELP: -ignore-case HELP: -lookup HELP: -name +HELP: -parent-recurse-depth= HELP: -recurse-depth= HELP: -regex HELP: -show-children Index: llvm/trunk/tools/dsymutil/DwarfLinker.cpp =================================================================== --- llvm/trunk/tools/dsymutil/DwarfLinker.cpp +++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp @@ -227,7 +227,7 @@ return; DIDumpOptions DumpOpts; - DumpOpts.RecurseDepth = 0; + DumpOpts.ChildRecurseDepth = 0; DumpOpts.Verbose = Options.Verbose; WithColor::note() << " in DIE:\n"; @@ -649,7 +649,7 @@ if (Options.Verbose) { DIDumpOptions DumpOpts; - DumpOpts.RecurseDepth = 0; + DumpOpts.ChildRecurseDepth = 0; DumpOpts.Verbose = Options.Verbose; DIE.dump(outs(), 8 /* Indent */, DumpOpts); } @@ -685,7 +685,7 @@ if (Options.Verbose) { DIDumpOptions DumpOpts; - DumpOpts.RecurseDepth = 0; + DumpOpts.ChildRecurseDepth = 0; DumpOpts.Verbose = Options.Verbose; DIE.dump(outs(), 8 /* Indent */, DumpOpts); } @@ -2096,8 +2096,10 @@ Linker.AssignAbbrev(Copy); } -uint32_t DwarfLinker::DIECloner::hashFullyQualifiedName( - DWARFDie DIE, CompileUnit &U, const DebugMapObject &DMO, int RecurseDepth) { +uint32_t +DwarfLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U, + const DebugMapObject &DMO, + int ChildRecurseDepth) { const char *Name = nullptr; DWARFUnit *OrigUnit = &U.getOrigUnit(); CompileUnit *CU = &U; @@ -2131,13 +2133,13 @@ // FIXME: dsymutil-classic compatibility. Ignore modules. CU->getOrigUnit().getDIEAtIndex(CU->getInfo(Idx).ParentIdx).getTag() == dwarf::DW_TAG_module) - return djbHash(Name ? Name : "", djbHash(RecurseDepth ? "" : "::")); + return djbHash(Name ? Name : "", djbHash(ChildRecurseDepth ? "" : "::")); DWARFDie Die = OrigUnit->getDIEAtIndex(CU->getInfo(Idx).ParentIdx); return djbHash( (Name ? Name : ""), djbHash((Name ? "::" : ""), - hashFullyQualifiedName(Die, *CU, DMO, ++RecurseDepth))); + hashFullyQualifiedName(Die, *CU, DMO, ++ChildRecurseDepth))); } static uint64_t getDwoId(const DWARFDie &CUDie, const DWARFUnit &Unit) { @@ -2656,7 +2658,7 @@ if (Options.Verbose) { outs() << "Input compilation unit:"; DIDumpOptions DumpOpts; - DumpOpts.RecurseDepth = 0; + DumpOpts.ChildRecurseDepth = 0; DumpOpts.Verbose = Options.Verbose; CUDie.dump(outs(), 0, DumpOpts); } Index: llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp =================================================================== --- llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -192,13 +192,18 @@ cat(DwarfDumpCategory)); static alias ShowFormAlias("F", desc("Alias for -show-form."), aliasopt(ShowForm), cat(DwarfDumpCategory)); -static opt RecurseDepth( - "recurse-depth", - desc("Only recurse to a depth of N when displaying debug info entries."), - cat(DwarfDumpCategory), init(-1U), value_desc("N")); -static alias RecurseDepthAlias("r", desc("Alias for -recurse-depth."), - aliasopt(RecurseDepth)); - +static opt + ChildRecurseDepth("recurse-depth", + desc("Only recurse to a depth of N when displaying " + "children of debug info entries."), + cat(DwarfDumpCategory), init(-1U), value_desc("N")); +static alias ChildRecurseDepthAlias("r", desc("Alias for -recurse-depth."), + aliasopt(ChildRecurseDepth)); +static opt + ParentRecurseDepth("parent-recurse-depth", + desc("Only recurse to a depth of N when displaying " + "parents of debug info entries."), + cat(DwarfDumpCategory), init(-1U), value_desc("N")); static opt SummarizeTypes("summarize-types", desc("Abbreviate the description of type unit entries."), @@ -233,7 +238,8 @@ static DIDumpOptions getDumpOpts() { DIDumpOptions DumpOpts; DumpOpts.DumpType = DumpType; - DumpOpts.RecurseDepth = RecurseDepth; + DumpOpts.ChildRecurseDepth = ChildRecurseDepth; + DumpOpts.ParentRecurseDepth = ParentRecurseDepth; DumpOpts.ShowAddresses = !Diff; DumpOpts.ShowChildren = ShowChildren; DumpOpts.ShowParents = ShowParents; @@ -389,7 +395,7 @@ return false; DIDumpOptions DumpOpts = getDumpOpts(); - DumpOpts.RecurseDepth = 0; + DumpOpts.ChildRecurseDepth = 0; DIEsForAddr.CompileUnit->dump(OS, DumpOpts); if (DIEsForAddr.FunctionDIE) { DIEsForAddr.FunctionDIE.dump(OS, 2, DumpOpts);