//===- 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 "DiagnosticNames.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;
using namespace diagtool;

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;
  
  ArrayRef<DiagnosticRecord> AllDiagnostics = getBuiltinDiagnosticsByName();

  for (ArrayRef<DiagnosticRecord>::iterator di = AllDiagnostics.begin(),
                                            de = AllDiagnostics.end();
       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);
    }
  }
  
  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 << "  Number in -Wpedantic (not covered by other -W flags): "
      << flagHistogram.GetOrCreateValue("pedantic").getValue().size()
      << '\n';
  
  out << '\n';
  
  return 0;
}

