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