diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h index 288ddf77bdfda..b75dc8db54336 100644 --- a/llvm/include/llvm/DebugInfo/DIContext.h +++ b/llvm/include/llvm/DebugInfo/DIContext.h @@ -206,6 +206,7 @@ struct DIDumpOptions { bool IsEH = false; bool DumpNonSkeleton = false; bool ShowAggregateErrors = false; + std::string JsonErrSummaryFile; std::function GetNameForDWARFReg; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp index 20ef59e7b4422..520debe513d9f 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -29,7 +29,9 @@ #include "llvm/Support/DJB.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/JSON.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include @@ -2026,12 +2028,37 @@ void OutputCategoryAggregator::EnumerateResults( } void DWARFVerifier::summarize() { - if (ErrorCategory.GetNumCategories() && DumpOpts.ShowAggregateErrors) { + if (DumpOpts.ShowAggregateErrors && ErrorCategory.GetNumCategories()) { error() << "Aggregated error counts:\n"; ErrorCategory.EnumerateResults([&](StringRef s, unsigned count) { error() << s << " occurred " << count << " time(s).\n"; }); } + if (!DumpOpts.JsonErrSummaryFile.empty()) { + std::error_code EC; + raw_fd_ostream JsonStream(DumpOpts.JsonErrSummaryFile, EC, + sys::fs::OF_Text); + if (EC) { + error() << "unable to open json summary file '" + << DumpOpts.JsonErrSummaryFile + << "' for writing: " << EC.message() << '\n'; + return; + } + + llvm::json::Object Categories; + uint64_t ErrorCount = 0; + ErrorCategory.EnumerateResults([&](StringRef Category, unsigned Count) { + llvm::json::Object Val; + Val.try_emplace("count", Count); + Categories.try_emplace(Category, std::move(Val)); + ErrorCount += Count; + }); + llvm::json::Object RootNode; + RootNode.try_emplace("error-categories", std::move(Categories)); + RootNode.try_emplace("error-count", ErrorCount); + + JsonStream << llvm::json::Value(std::move(RootNode)); + } } raw_ostream &DWARFVerifier::error() const { return WithColor::error(OS); } diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index 2b438a8b13461..2bfc9705368e4 100644 --- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -286,6 +286,8 @@ static opt Verify("verify", desc("Verify the DWARF debug info."), cat(DwarfDumpCategory)); static opt ErrorDetails( "error-display", init(Unspecified), + desc("Set the level of detail and summary to display when verifying " + "(implies --verify)"), values(clEnumValN(NoDetailsOrSummary, "quiet", "Only display whether errors occurred."), clEnumValN(NoDetailsOnlySummary, "summary", @@ -295,6 +297,11 @@ static opt ErrorDetails( clEnumValN(BothDetailsAndSummary, "full", "Display each error as well as a summary. [default]")), cat(DwarfDumpCategory)); +static opt JsonErrSummaryFile( + "verify-json", init(""), + desc("Output JSON-formatted error summary to the specified file. " + "(Implies --verify)"), + value_desc("filename.json"), cat(DwarfDumpCategory)); static opt Quiet("quiet", desc("Use with -verify to not emit to STDOUT."), cat(DwarfDumpCategory)); static opt DumpUUID("uuid", desc("Show the UUID for each architecture."), @@ -349,6 +356,7 @@ static DIDumpOptions getDumpOpts(DWARFContext &C) { ErrorDetails != NoDetailsOrSummary; DumpOpts.ShowAggregateErrors = ErrorDetails != OnlyDetailsNoSummary && ErrorDetails != NoDetailsOnlySummary; + DumpOpts.JsonErrSummaryFile = JsonErrSummaryFile; return DumpOpts.noImplicitRecursion(); } return DumpOpts; @@ -834,8 +842,10 @@ int main(int argc, char **argv) { "-verbose is currently not supported"; return 1; } - if (!Verify && ErrorDetails != Unspecified) - WithColor::warning() << "-error-detail has no affect without -verify"; + // -error-detail and -json-summary-file both imply -verify + if (ErrorDetails != Unspecified || !JsonErrSummaryFile.empty()) { + Verify = true; + } std::error_code EC; ToolOutputFile OutputFile(OutputFilename, EC, sys::fs::OF_TextWithCRLF);