| //===- ListWarnings.h - diagtool tool for printing warning flags ----------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file provides a diagtool tool that displays warning flags for |
| // diagnostics. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "DiagTool.h" |
| #include "DiagnosticNames.h" |
| #include "clang/AST/ASTDiagnostic.h" |
| #include "clang/Basic/AllDiagnostics.h" |
| #include "clang/Basic/Diagnostic.h" |
| #include "llvm/ADT/StringMap.h" |
| #include "llvm/Support/Format.h" |
| |
| DEF_DIAGTOOL("list-warnings", |
| "List warnings and their corresponding flags", |
| ListWarnings) |
| |
| using namespace clang; |
| using namespace diagtool; |
| |
| namespace { |
| struct Entry { |
| llvm::StringRef DiagName; |
| llvm::StringRef Flag; |
| |
| Entry(llvm::StringRef diagN, llvm::StringRef flag) |
| : DiagName(diagN), Flag(flag) {} |
| |
| bool operator<(const Entry &x) const { return DiagName < x.DiagName; } |
| }; |
| } |
| |
| static void printEntries(std::vector<Entry> &entries, llvm::raw_ostream &out) { |
| for (const Entry &E : entries) { |
| out << " " << E.DiagName; |
| if (!E.Flag.empty()) |
| out << " [-W" << E.Flag << "]"; |
| out << '\n'; |
| } |
| } |
| |
| int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) { |
| std::vector<Entry> Flagged, Unflagged; |
| llvm::StringMap<std::vector<unsigned> > flagHistogram; |
| |
| for (const DiagnosticRecord &DR : getBuiltinDiagnosticsByName()) { |
| const unsigned diagID = DR.DiagID; |
| |
| if (DiagnosticIDs::isBuiltinNote(diagID)) |
| continue; |
| |
| if (!DiagnosticIDs::isBuiltinWarningOrExtension(diagID)) |
| continue; |
| |
| Entry entry(DR.getName(), DiagnosticIDs::getWarningOptionForDiag(diagID)); |
| |
| if (entry.Flag.empty()) |
| Unflagged.push_back(entry); |
| else { |
| Flagged.push_back(entry); |
| flagHistogram[entry.Flag].push_back(diagID); |
| } |
| } |
| |
| out << "Warnings with flags (" << Flagged.size() << "):\n"; |
| printEntries(Flagged, out); |
| |
| out << "Warnings without flags (" << Unflagged.size() << "):\n"; |
| printEntries(Unflagged, out); |
| |
| out << "\nSTATISTICS:\n\n"; |
| |
| double percentFlagged = |
| ((double)Flagged.size()) / (Flagged.size() + Unflagged.size()) * 100.0; |
| |
| out << " Percentage of warnings with flags: " |
| << llvm::format("%.4g", percentFlagged) << "%\n"; |
| |
| out << " Number of unique flags: " |
| << flagHistogram.size() << '\n'; |
| |
| double avgDiagsPerFlag = (double) Flagged.size() / flagHistogram.size(); |
| out << " Average number of diagnostics per flag: " |
| << llvm::format("%.4g", avgDiagsPerFlag) << '\n'; |
| |
| out << " Number in -Wpedantic (not covered by other -W flags): " |
| << flagHistogram["pedantic"].size() << '\n'; |
| |
| out << '\n'; |
| |
| return 0; |
| } |
| |