ListWarnings.cpp revision d6471f7c1921c7802804ce3ff6fe9768310f72b9
1//===- 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 DiagnosticsEngine D(Diags); 52 53 std::vector<Entry> Flagged, Unflagged; 54 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 107