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