/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/tools/diagtool/ListWarnings.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- ListWarnings.h - diagtool tool for printing warning flags ----------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file provides a diagtool tool that displays warning flags for |
10 | | // diagnostics. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "DiagTool.h" |
15 | | #include "DiagnosticNames.h" |
16 | | #include "clang/Basic/AllDiagnostics.h" |
17 | | #include "clang/Basic/Diagnostic.h" |
18 | | #include "llvm/ADT/StringMap.h" |
19 | | #include "llvm/Support/Format.h" |
20 | | |
21 | | DEF_DIAGTOOL("list-warnings", |
22 | | "List warnings and their corresponding flags", |
23 | | ListWarnings) |
24 | | |
25 | | using namespace clang; |
26 | | using namespace diagtool; |
27 | | |
28 | | namespace { |
29 | | struct Entry { |
30 | | llvm::StringRef DiagName; |
31 | | llvm::StringRef Flag; |
32 | | |
33 | | Entry(llvm::StringRef diagN, llvm::StringRef flag) |
34 | 1.82k | : DiagName(diagN), Flag(flag) {} |
35 | | |
36 | 0 | bool operator<(const Entry &x) const { return DiagName < x.DiagName; } |
37 | | }; |
38 | | } |
39 | | |
40 | 2 | static void printEntries(std::vector<Entry> &entries, llvm::raw_ostream &out) { |
41 | 1.82k | for (const Entry &E : entries) { |
42 | 1.82k | out << " " << E.DiagName; |
43 | 1.82k | if (!E.Flag.empty()) |
44 | 1.75k | out << " [-W" << E.Flag << "]"; |
45 | 1.82k | out << '\n'; |
46 | 1.82k | } |
47 | 2 | } |
48 | | |
49 | 1 | int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) { |
50 | 1 | std::vector<Entry> Flagged, Unflagged; |
51 | 1 | llvm::StringMap<std::vector<unsigned> > flagHistogram; |
52 | | |
53 | 5.95k | for (const DiagnosticRecord &DR : getBuiltinDiagnosticsByName()) { |
54 | 5.95k | const unsigned diagID = DR.DiagID; |
55 | | |
56 | 5.95k | if (DiagnosticIDs::isBuiltinNote(diagID)) |
57 | 928 | continue; |
58 | | |
59 | 5.03k | if (!DiagnosticIDs::isBuiltinWarningOrExtension(diagID)) |
60 | 3.21k | continue; |
61 | | |
62 | 1.82k | Entry entry(DR.getName(), DiagnosticIDs::getWarningOptionForDiag(diagID)); |
63 | | |
64 | 1.82k | if (entry.Flag.empty()) |
65 | 66 | Unflagged.push_back(entry); |
66 | 1.75k | else { |
67 | 1.75k | Flagged.push_back(entry); |
68 | 1.75k | flagHistogram[entry.Flag].push_back(diagID); |
69 | 1.75k | } |
70 | 1.82k | } |
71 | | |
72 | 1 | out << "Warnings with flags (" << Flagged.size() << "):\n"; |
73 | 1 | printEntries(Flagged, out); |
74 | | |
75 | 1 | out << "Warnings without flags (" << Unflagged.size() << "):\n"; |
76 | 1 | printEntries(Unflagged, out); |
77 | | |
78 | 1 | out << "\nSTATISTICS:\n\n"; |
79 | | |
80 | 1 | double percentFlagged = |
81 | 1 | ((double)Flagged.size()) / (Flagged.size() + Unflagged.size()) * 100.0; |
82 | | |
83 | 1 | out << " Percentage of warnings with flags: " |
84 | 1 | << llvm::format("%.4g", percentFlagged) << "%\n"; |
85 | | |
86 | 1 | out << " Number of unique flags: " |
87 | 1 | << flagHistogram.size() << '\n'; |
88 | | |
89 | 1 | double avgDiagsPerFlag = (double) Flagged.size() / flagHistogram.size(); |
90 | 1 | out << " Average number of diagnostics per flag: " |
91 | 1 | << llvm::format("%.4g", avgDiagsPerFlag) << '\n'; |
92 | | |
93 | 1 | out << " Number in -Wpedantic (not covered by other -W flags): " |
94 | 1 | << flagHistogram["pedantic"].size() << '\n'; |
95 | | |
96 | 1 | out << '\n'; |
97 | | |
98 | 1 | return 0; |
99 | 1 | } |
100 | | |