diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h index 7b51bb63cd15b..f51571aa24c38 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h @@ -30,9 +30,14 @@ class DWARFDebugAbbrev; class DataExtractor; struct DWARFSection; +struct AggregationData { + unsigned OverallCount; + std::map DetailedCounts; +}; + class OutputCategoryAggregator { private: - std::map Aggregation; + std::map Aggregation; bool IncludeDetail; public: @@ -40,8 +45,13 @@ class OutputCategoryAggregator { : IncludeDetail(includeDetail) {} void ShowDetail(bool showDetail) { IncludeDetail = showDetail; } size_t GetNumCategories() const { return Aggregation.size(); } - void Report(StringRef s, std::function detailCallback); + void Report(StringRef category, std::function detailCallback); + void Report(StringRef category, StringRef sub_category, + std::function detailCallback); void EnumerateResults(std::function handleCounts); + void EnumerateDetailedResultsFor( + StringRef category, + std::function handleCounts); }; /// A class that verifies DWARF debug information given a DWARF Context. diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp index 107e79cc5a05a..05bb829cf44db 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -1941,12 +1941,14 @@ unsigned DWARFVerifier::verifyNameIndexCompleteness( if (none_of(NI.equal_range(Name), [&](const DWARFDebugNames::Entry &E) { return E.getDIEUnitOffset() == DieUnitOffset; })) { - ErrorCategory.Report("Name Index DIE entry missing name", [&]() { - error() << formatv( - "Name Index @ {0:x}: Entry for DIE @ {1:x} ({2}) with " - "name {3} missing.\n", - NI.getUnitOffset(), Die.getOffset(), Die.getTag(), Name); - }); + ErrorCategory.Report( + "Name Index DIE entry missing name", + llvm::dwarf::TagString(Die.getTag()), [&]() { + error() << formatv( + "Name Index @ {0:x}: Entry for DIE @ {1:x} ({2}) with " + "name {3} missing.\n", + NI.getUnitOffset(), Die.getOffset(), Die.getTag(), Name); + }); ++NumErrors; } } @@ -2168,15 +2170,35 @@ bool DWARFVerifier::verifyDebugStrOffsets( void OutputCategoryAggregator::Report( StringRef s, std::function detailCallback) { - Aggregation[std::string(s)]++; + this->Report(s, "", detailCallback); +} + +void OutputCategoryAggregator::Report( + StringRef category, StringRef sub_category, + std::function detailCallback) { + std::string category_str = std::string(category); + AggregationData &Agg = Aggregation[category_str]; + Agg.OverallCount++; + if (!sub_category.empty()) { + Agg.DetailedCounts[std::string(sub_category)]++; + } if (IncludeDetail) detailCallback(); } void OutputCategoryAggregator::EnumerateResults( std::function handleCounts) { - for (auto &&[name, count] : Aggregation) { - handleCounts(name, count); + for (const auto &[name, aggData] : Aggregation) { + handleCounts(name, aggData.OverallCount); + } +} +void OutputCategoryAggregator::EnumerateDetailedResultsFor( + StringRef category, std::function handleCounts) { + const auto Agg = Aggregation.find(std::string(category)); + if (Agg != Aggregation.end()) { + for (const auto &[name, aggData] : Agg->second.DetailedCounts) { + handleCounts(name, aggData); + } } } @@ -2203,6 +2225,12 @@ void DWARFVerifier::summarize() { ErrorCategory.EnumerateResults([&](StringRef Category, unsigned Count) { llvm::json::Object Val; Val.try_emplace("count", Count); + llvm::json::Object Details; + ErrorCategory.EnumerateDetailedResultsFor( + Category, [&](StringRef SubCategory, unsigned SubCount) { + Details.try_emplace(SubCategory, SubCount); + }); + Val.try_emplace("details", std::move(Details)); Categories.try_emplace(Category, std::move(Val)); ErrorCount += Count; }); diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-completeness-json-output.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-completeness-json-output.s index c4b7ffe1d2d8e..9c9658308c2f9 100644 --- a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-completeness-json-output.s +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-completeness-json-output.s @@ -1,7 +1,7 @@ # RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj -o - | not llvm-dwarfdump -verify --verify-json=%t.json - # RUN: FileCheck %s --input-file %t.json -# CHECK: {"error-categories":{"Name Index DIE entry missing name":{"count":10}},"error-count":10} +# CHECK: {"error-categories":{"Name Index DIE entry missing name":{"count":10,"details":{"DW_TAG_inlined_subroutine":1,"DW_TAG_label":1,"DW_TAG_namespace":2,"DW_TAG_subprogram":2,"DW_TAG_variable":4}}},"error-count":10} # CHECK-NOT: error: Name Index @ 0x0: Entry for DIE @ {{.*}} (DW_TAG_variable) with name var_block_addr missing. .section .debug_loc,"",@progbits diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-cu-lists-json-output.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-cu-lists-json-output.s index dfbfe04943a83..872fff801576c 100644 --- a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-cu-lists-json-output.s +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-cu-lists-json-output.s @@ -2,7 +2,7 @@ # RUN: not llvm-dwarfdump -verify -verify-json=%t.json - # RUN: FileCheck %s --input-file %t.json -# CHECK: {"error-categories":{"Duplicate Name Index":{"count":1},"Name Index doesn't index any CU":{"count":1},"Name Index references non-existing CU":{"count":1}},"error-count":3} +# CHECK: {"error-categories":{"Duplicate Name Index":{"count":1,"details":{}},"Name Index doesn't index any CU":{"count":1,"details":{}},"Name Index references non-existing CU":{"count":1,"details":{}}},"error-count":3} # CHECK-NOT : error: Name Index @ 0x58 references a CU @ 0x0, but this CU is already indexed by Name Index @ 0x28 # CHECK-NOT: warning: CU @ 0x13 not covered by any Name Index