Home | History | Annotate | Download | only in diagtool
      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 "DiagnosticNames.h"
     17 #include "clang/AST/ASTDiagnostic.h"
     18 #include "clang/Basic/AllDiagnostics.h"
     19 #include "clang/Basic/Diagnostic.h"
     20 #include "llvm/ADT/StringMap.h"
     21 #include "llvm/Support/Format.h"
     22 
     23 DEF_DIAGTOOL("list-warnings",
     24              "List warnings and their corresponding flags",
     25              ListWarnings)
     26 
     27 using namespace clang;
     28 using namespace diagtool;
     29 
     30 namespace {
     31 struct Entry {
     32   llvm::StringRef DiagName;
     33   llvm::StringRef Flag;
     34 
     35   Entry(llvm::StringRef diagN, llvm::StringRef flag)
     36     : DiagName(diagN), Flag(flag) {}
     37 
     38   bool operator<(const Entry &x) const { return DiagName < x.DiagName; }
     39 };
     40 }
     41 
     42 static void printEntries(std::vector<Entry> &entries, llvm::raw_ostream &out) {
     43   for (std::vector<Entry>::iterator it = entries.begin(), ei = entries.end();
     44        it != ei; ++it) {
     45     out << "  " << it->DiagName;
     46     if (!it->Flag.empty())
     47       out << " [-W" << it->Flag << "]";
     48     out << '\n';
     49   }
     50 }
     51 
     52 int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
     53   std::vector<Entry> Flagged, Unflagged;
     54   llvm::StringMap<std::vector<unsigned> > flagHistogram;
     55 
     56   ArrayRef<DiagnosticRecord> AllDiagnostics = getBuiltinDiagnosticsByName();
     57 
     58   for (ArrayRef<DiagnosticRecord>::iterator di = AllDiagnostics.begin(),
     59                                             de = AllDiagnostics.end();
     60        di != de; ++di) {
     61     unsigned diagID = di->DiagID;
     62 
     63     if (DiagnosticIDs::isBuiltinNote(diagID))
     64       continue;
     65 
     66     if (!DiagnosticIDs::isBuiltinWarningOrExtension(diagID))
     67       continue;
     68 
     69     Entry entry(di->getName(),
     70                 DiagnosticIDs::getWarningOptionForDiag(diagID));
     71 
     72     if (entry.Flag.empty())
     73       Unflagged.push_back(entry);
     74     else {
     75       Flagged.push_back(entry);
     76       flagHistogram[entry.Flag].push_back(diagID);
     77     }
     78   }
     79 
     80   out << "Warnings with flags (" << Flagged.size() << "):\n";
     81   printEntries(Flagged, out);
     82 
     83   out << "Warnings without flags (" << Unflagged.size() << "):\n";
     84   printEntries(Unflagged, out);
     85 
     86   out << "\nSTATISTICS:\n\n";
     87 
     88   double percentFlagged = ((double) Flagged.size())
     89     / (Flagged.size() + Unflagged.size()) * 100.0;
     90 
     91   out << "  Percentage of warnings with flags: "
     92       << llvm::format("%.4g",percentFlagged) << "%\n";
     93 
     94   out << "  Number of unique flags: "
     95       << flagHistogram.size() << '\n';
     96 
     97   double avgDiagsPerFlag = (double) Flagged.size() / flagHistogram.size();
     98   out << "  Average number of diagnostics per flag: "
     99       << llvm::format("%.4g", avgDiagsPerFlag) << '\n';
    100 
    101   out << "  Number in -Wpedantic (not covered by other -W flags): "
    102       << flagHistogram["pedantic"].size() << '\n';
    103 
    104   out << '\n';
    105 
    106   return 0;
    107 }
    108 
    109