//===- ShowEnabledWarnings - diagtool tool for printing enabled flags -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "DiagTool.h"
#include "DiagnosticNames.h"
#include "clang/Basic/LLVM.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
#include "llvm/Support/TargetSelect.h"

DEF_DIAGTOOL("show-enabled",
             "Show which warnings are enabled for a given command line",
             ShowEnabledWarnings)

using namespace clang;

namespace {
  struct PrettyDiag {
    StringRef Name;
    StringRef Flag;
    DiagnosticsEngine::Level Level;

    PrettyDiag(StringRef name, StringRef flag, DiagnosticsEngine::Level level)
    : Name(name), Flag(flag), Level(level) {}

    bool operator<(const PrettyDiag &x) const { return Name < x.Name; }
  };
}

static void printUsage() {
  llvm::errs() << "Usage: diagtool show-enabled [<flags>] <single-input.c>\n";
}

static char getCharForLevel(DiagnosticsEngine::Level Level) {
  switch (Level) {
  case DiagnosticsEngine::Ignored: return ' ';
  case DiagnosticsEngine::Note:    return '-';
  case DiagnosticsEngine::Warning: return 'W';
  case DiagnosticsEngine::Error:   return 'E';
  case DiagnosticsEngine::Fatal:   return 'F';
  }

  llvm_unreachable("Unknown diagnostic level");
}

static IntrusiveRefCntPtr<DiagnosticsEngine>
createDiagnostics(unsigned int argc, char **argv) {
  IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs());

  // Buffer diagnostics from argument parsing so that we can output them using a
  // well formed diagnostic object.
  TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
  IntrusiveRefCntPtr<DiagnosticsEngine> InterimDiags(
    new DiagnosticsEngine(DiagIDs, DiagsBuffer));

  // Try to build a CompilerInvocation.
  OwningPtr<CompilerInvocation> Invocation(
    createInvocationFromCommandLine(ArrayRef<const char *>(argv, argc),
                                    InterimDiags));
  if (!Invocation)
    return NULL;

  // Build the diagnostics parser
  IntrusiveRefCntPtr<DiagnosticsEngine> FinalDiags =
    CompilerInstance::createDiagnostics(Invocation->getDiagnosticOpts(),
                                        argc, argv);
  if (!FinalDiags)
    return NULL;
  
  // Flush any errors created when initializing everything. This could happen
  // for invalid command lines, which will probably give non-sensical results.
  DiagsBuffer->FlushDiagnostics(*FinalDiags);

  return FinalDiags;
}

int ShowEnabledWarnings::run(unsigned int argc, char **argv, raw_ostream &Out) {
  // First check our one flag (--levels).
  bool ShouldShowLevels = true;
  if (argc > 0) {
    StringRef FirstArg(*argv);
    if (FirstArg.equals("--no-levels")) {
      ShouldShowLevels = false;
      --argc;
      ++argv;
    } else if (FirstArg.equals("--levels")) {
      ShouldShowLevels = true;
      --argc;
      ++argv;
    }
  }

  // Create the diagnostic engine.
  IntrusiveRefCntPtr<DiagnosticsEngine> Diags = createDiagnostics(argc, argv);
  if (!Diags) {
    printUsage();
    return EXIT_FAILURE;
  }

  // Now we have our diagnostics. Iterate through EVERY diagnostic and see
  // which ones are turned on.
  // FIXME: It would be very nice to print which flags are turning on which
  // diagnostics, but this can be done with a diff.
  std::vector<PrettyDiag> Active;

  for (const diagtool::DiagnosticRecord *I = diagtool::BuiltinDiagnostics,
       *E = I + diagtool::BuiltinDiagnosticsCount; I != E; ++I) {
    unsigned DiagID = I->DiagID;
    
    if (DiagnosticIDs::isBuiltinNote(DiagID))
      continue;
    
    if (!DiagnosticIDs::isBuiltinWarningOrExtension(DiagID))
      continue;

    DiagnosticsEngine::Level DiagLevel =
      Diags->getDiagnosticLevel(DiagID, SourceLocation());
    if (DiagLevel == DiagnosticsEngine::Ignored)
      continue;

    StringRef WarningOpt = DiagnosticIDs::getWarningOptionForDiag(DiagID);
    Active.push_back(PrettyDiag(I->getName(), WarningOpt, DiagLevel));
  }

  std::sort(Active.begin(), Active.end());

  // Print them all out.
  for (std::vector<PrettyDiag>::const_iterator I = Active.begin(),
       E = Active.end(); I != E; ++I) {
    if (ShouldShowLevels)
      Out << getCharForLevel(I->Level) << "  ";
    Out << I->Name;
    if (!I->Flag.empty())
      Out << " [-W" << I->Flag << "]";
    Out << '\n';
  }

  return EXIT_SUCCESS;
}
