diff options
Diffstat (limited to 'clang/tools/diagtool/ListWarnings.cpp')
| -rw-r--r-- | clang/tools/diagtool/ListWarnings.cpp | 126 | 
1 files changed, 126 insertions, 0 deletions
| diff --git a/clang/tools/diagtool/ListWarnings.cpp b/clang/tools/diagtool/ListWarnings.cpp new file mode 100644 index 0000000..2bbeca8 --- /dev/null +++ b/clang/tools/diagtool/ListWarnings.cpp @@ -0,0 +1,126 @@ +//===- ListWarnings.h - diagtool tool for printing warning flags ----------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides a diagtool tool that displays warning flags for +// diagnostics. +// +//===----------------------------------------------------------------------===// + +#include "DiagTool.h" +#include "clang/Basic/Diagnostic.h" +#include "llvm/Support/Format.h" +#include "llvm/ADT/StringMap.h" +#include "clang/AST/ASTDiagnostic.h" +#include "clang/Basic/AllDiagnostics.h" + +DEF_DIAGTOOL("list-warnings", +             "List warnings and their corresponding flags", +             ListWarnings) +   +using namespace clang; + +namespace { +struct StaticDiagNameIndexRec { +  const char *NameStr; +  unsigned short DiagID; +  uint8_t NameLen; + +  StringRef getName() const { +    return StringRef(NameStr, NameLen); +  } +}; +} + +static const StaticDiagNameIndexRec StaticDiagNameIndex[] = { +#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) }, +#include "clang/Basic/DiagnosticIndexName.inc" +#undef DIAG_NAME_INDEX +  { 0, 0, 0 } +}; + +static const unsigned StaticDiagNameIndexSize = +  sizeof(StaticDiagNameIndex)/sizeof(StaticDiagNameIndex[0])-1; + +namespace { +struct Entry { +  llvm::StringRef DiagName; +  llvm::StringRef Flag; +   +  Entry(llvm::StringRef diagN, llvm::StringRef flag) +    : DiagName(diagN), Flag(flag) {} +   +  bool operator<(const Entry &x) const { return DiagName < x.DiagName; } +}; +} + +static void printEntries(std::vector<Entry> &entries, llvm::raw_ostream &out) { +  for (std::vector<Entry>::iterator it = entries.begin(), ei = entries.end(); +       it != ei; ++it) { +    out << "  " << it->DiagName; +    if (!it->Flag.empty()) +      out << " [-W" << it->Flag << "]"; +    out << '\n'; +  } +} + +int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) { +  std::vector<Entry> Flagged, Unflagged; +  llvm::StringMap<std::vector<unsigned> > flagHistogram; +   +  for (const StaticDiagNameIndexRec *di = StaticDiagNameIndex, *de = StaticDiagNameIndex + StaticDiagNameIndexSize; +       di != de; ++di) { +     +    unsigned diagID = di->DiagID; +     +    if (DiagnosticIDs::isBuiltinNote(diagID)) +      continue; +         +    if (!DiagnosticIDs::isBuiltinWarningOrExtension(diagID)) +      continue; +   +    Entry entry(di->getName(), +                DiagnosticIDs::getWarningOptionForDiag(diagID)); +     +    if (entry.Flag.empty()) +      Unflagged.push_back(entry); +    else { +      Flagged.push_back(entry); +      flagHistogram.GetOrCreateValue(entry.Flag).getValue().push_back(diagID); +    } +  } +   +  std::sort(Flagged.begin(), Flagged.end()); +  std::sort(Unflagged.begin(), Unflagged.end()); + +  out << "Warnings with flags (" << Flagged.size() << "):\n"; +  printEntries(Flagged, out); +   +  out << "Warnings without flags (" << Unflagged.size() << "):\n"; +  printEntries(Unflagged, out); + +  out << "\nSTATISTICS:\n\n"; + +  double percentFlagged = ((double) Flagged.size())  +    / (Flagged.size() + Unflagged.size()) * 100.0; +   +  out << "  Percentage of warnings with flags: "  +      << llvm::format("%.4g",percentFlagged) << "%\n"; +   +  out << "  Number of unique flags: " +      << flagHistogram.size() << '\n'; +   +  double avgDiagsPerFlag = (double) Flagged.size() / flagHistogram.size(); +  out << "  Average number of diagnostics per flag: " +      << llvm::format("%.4g", avgDiagsPerFlag) << '\n'; +     +  out << '\n'; +   +  return 0; +} + | 
