xref: /aosp_15_r20/external/clang/tools/diagtool/ListWarnings.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===- ListWarnings.h - diagtool tool for printing warning flags ----------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file provides a diagtool tool that displays warning flags for
11*67e74705SXin Li // diagnostics.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li 
15*67e74705SXin Li #include "DiagTool.h"
16*67e74705SXin Li #include "DiagnosticNames.h"
17*67e74705SXin Li #include "clang/AST/ASTDiagnostic.h"
18*67e74705SXin Li #include "clang/Basic/AllDiagnostics.h"
19*67e74705SXin Li #include "clang/Basic/Diagnostic.h"
20*67e74705SXin Li #include "llvm/ADT/StringMap.h"
21*67e74705SXin Li #include "llvm/Support/Format.h"
22*67e74705SXin Li 
23*67e74705SXin Li DEF_DIAGTOOL("list-warnings",
24*67e74705SXin Li              "List warnings and their corresponding flags",
25*67e74705SXin Li              ListWarnings)
26*67e74705SXin Li 
27*67e74705SXin Li using namespace clang;
28*67e74705SXin Li using namespace diagtool;
29*67e74705SXin Li 
30*67e74705SXin Li namespace {
31*67e74705SXin Li struct Entry {
32*67e74705SXin Li   llvm::StringRef DiagName;
33*67e74705SXin Li   llvm::StringRef Flag;
34*67e74705SXin Li 
Entry__anonda2ff9130111::Entry35*67e74705SXin Li   Entry(llvm::StringRef diagN, llvm::StringRef flag)
36*67e74705SXin Li     : DiagName(diagN), Flag(flag) {}
37*67e74705SXin Li 
operator <__anonda2ff9130111::Entry38*67e74705SXin Li   bool operator<(const Entry &x) const { return DiagName < x.DiagName; }
39*67e74705SXin Li };
40*67e74705SXin Li }
41*67e74705SXin Li 
printEntries(std::vector<Entry> & entries,llvm::raw_ostream & out)42*67e74705SXin Li static void printEntries(std::vector<Entry> &entries, llvm::raw_ostream &out) {
43*67e74705SXin Li   for (std::vector<Entry>::iterator it = entries.begin(), ei = entries.end();
44*67e74705SXin Li        it != ei; ++it) {
45*67e74705SXin Li     out << "  " << it->DiagName;
46*67e74705SXin Li     if (!it->Flag.empty())
47*67e74705SXin Li       out << " [-W" << it->Flag << "]";
48*67e74705SXin Li     out << '\n';
49*67e74705SXin Li   }
50*67e74705SXin Li }
51*67e74705SXin Li 
run(unsigned int argc,char ** argv,llvm::raw_ostream & out)52*67e74705SXin Li int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
53*67e74705SXin Li   std::vector<Entry> Flagged, Unflagged;
54*67e74705SXin Li   llvm::StringMap<std::vector<unsigned> > flagHistogram;
55*67e74705SXin Li 
56*67e74705SXin Li   ArrayRef<DiagnosticRecord> AllDiagnostics = getBuiltinDiagnosticsByName();
57*67e74705SXin Li 
58*67e74705SXin Li   for (ArrayRef<DiagnosticRecord>::iterator di = AllDiagnostics.begin(),
59*67e74705SXin Li                                             de = AllDiagnostics.end();
60*67e74705SXin Li        di != de; ++di) {
61*67e74705SXin Li     unsigned diagID = di->DiagID;
62*67e74705SXin Li 
63*67e74705SXin Li     if (DiagnosticIDs::isBuiltinNote(diagID))
64*67e74705SXin Li       continue;
65*67e74705SXin Li 
66*67e74705SXin Li     if (!DiagnosticIDs::isBuiltinWarningOrExtension(diagID))
67*67e74705SXin Li       continue;
68*67e74705SXin Li 
69*67e74705SXin Li     Entry entry(di->getName(),
70*67e74705SXin Li                 DiagnosticIDs::getWarningOptionForDiag(diagID));
71*67e74705SXin Li 
72*67e74705SXin Li     if (entry.Flag.empty())
73*67e74705SXin Li       Unflagged.push_back(entry);
74*67e74705SXin Li     else {
75*67e74705SXin Li       Flagged.push_back(entry);
76*67e74705SXin Li       flagHistogram[entry.Flag].push_back(diagID);
77*67e74705SXin Li     }
78*67e74705SXin Li   }
79*67e74705SXin Li 
80*67e74705SXin Li   out << "Warnings with flags (" << Flagged.size() << "):\n";
81*67e74705SXin Li   printEntries(Flagged, out);
82*67e74705SXin Li 
83*67e74705SXin Li   out << "Warnings without flags (" << Unflagged.size() << "):\n";
84*67e74705SXin Li   printEntries(Unflagged, out);
85*67e74705SXin Li 
86*67e74705SXin Li   out << "\nSTATISTICS:\n\n";
87*67e74705SXin Li 
88*67e74705SXin Li   double percentFlagged = ((double) Flagged.size())
89*67e74705SXin Li     / (Flagged.size() + Unflagged.size()) * 100.0;
90*67e74705SXin Li 
91*67e74705SXin Li   out << "  Percentage of warnings with flags: "
92*67e74705SXin Li       << llvm::format("%.4g",percentFlagged) << "%\n";
93*67e74705SXin Li 
94*67e74705SXin Li   out << "  Number of unique flags: "
95*67e74705SXin Li       << flagHistogram.size() << '\n';
96*67e74705SXin Li 
97*67e74705SXin Li   double avgDiagsPerFlag = (double) Flagged.size() / flagHistogram.size();
98*67e74705SXin Li   out << "  Average number of diagnostics per flag: "
99*67e74705SXin Li       << llvm::format("%.4g", avgDiagsPerFlag) << '\n';
100*67e74705SXin Li 
101*67e74705SXin Li   out << "  Number in -Wpedantic (not covered by other -W flags): "
102*67e74705SXin Li       << flagHistogram["pedantic"].size() << '\n';
103*67e74705SXin Li 
104*67e74705SXin Li   out << '\n';
105*67e74705SXin Li 
106*67e74705SXin Li   return 0;
107*67e74705SXin Li }
108*67e74705SXin Li 
109