//===--- tools/pp-trace/PPTrace.cpp - Clang preprocessor tracer -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements pp-trace, a tool for displaying a textual trace
// of the Clang preprocessor activity.  It's based on a derivation of the
// PPCallbacks class, that once registerd with Clang, receives callback calls
// to its virtual members, and outputs the information passed to the callbacks
// in a high-level YAML format.
//
// The pp-trace tool also serves as the basis for a test of the PPCallbacks
// mechanism.
//
// The pp-trace tool supports the following general command line format:
//
//    pp-trace [pp-trace options] (source file) [compiler options]
//
// Basically you put the pp-trace options first, then the source file or files,
// and then any options you want to pass to the compiler.
//
// These are the pp-trace options:
//
//    -ignore (callback list)     Don't display output for a comma-separated
//                                list of callbacks, i.e.:
//                                  -ignore "FileChanged,InclusionDirective"
//
//    -output (file)              Output trace to the given file in a YAML
//                                format, e.g.:
//
//                                  ---
//                                  - Callback: Name
//                                    Argument1: Value1
//                                    Argument2: Value2
//                                  (etc.)
//                                  ...
//
// Future Directions:
//
// 1. Add option opposite to "-ignore" that specifys a comma-separated option
// list of callbacs.  Perhaps "-only" or "-exclusive".
//
//===----------------------------------------------------------------------===//

#include "PPCallbacksTracker.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ToolOutputFile.h"
#include <algorithm>
#include <fstream>
#include <iterator>
#include <string>
#include <vector>

using namespace clang;
using namespace clang::driver;
using namespace clang::driver::options;
using namespace clang::tooling;
using namespace llvm;
using namespace llvm::opt;

// Options:

// Collect the source files.
static cl::list<std::string> SourcePaths(cl::Positional,
                                         cl::desc("<source0> [... <sourceN>]"),
                                         cl::OneOrMore);

// Option to specify a list or one or more callback names to ignore.
static cl::opt<std::string> IgnoreCallbacks(
    "ignore", cl::init(""),
    cl::desc("Ignore callbacks, i.e. \"Callback1, Callback2...\"."));

// Option to specify the trace output file name.
static cl::opt<std::string> OutputFileName(
    "output", cl::init(""),
    cl::desc("Output trace to the given file name or '-' for stdout."));

// Collect all other arguments, which will be passed to the front end.
static cl::list<std::string>
    CC1Arguments(cl::ConsumeAfter,
                 cl::desc("<arguments to be passed to front end>..."));

// Frontend action stuff:

namespace {
// Consumer is responsible for setting up the callbacks.
class PPTraceConsumer : public ASTConsumer {
public:
  PPTraceConsumer(SmallSet<std::string, 4> &Ignore,
                  std::vector<CallbackCall> &CallbackCalls, Preprocessor &PP) {
    // PP takes ownership.
    PP.addPPCallbacks(llvm::make_unique<PPCallbacksTracker>(Ignore,
                                                            CallbackCalls, PP));
  }
};

class PPTraceAction : public SyntaxOnlyAction {
public:
  PPTraceAction(SmallSet<std::string, 4> &Ignore,
                std::vector<CallbackCall> &CallbackCalls)
      : Ignore(Ignore), CallbackCalls(CallbackCalls) {}

protected:
  std::unique_ptr<clang::ASTConsumer>
  CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
    return llvm::make_unique<PPTraceConsumer>(Ignore, CallbackCalls,
                                              CI.getPreprocessor());
  }

private:
  SmallSet<std::string, 4> &Ignore;
  std::vector<CallbackCall> &CallbackCalls;
};

class PPTraceFrontendActionFactory : public FrontendActionFactory {
public:
  PPTraceFrontendActionFactory(SmallSet<std::string, 4> &Ignore,
                               std::vector<CallbackCall> &CallbackCalls)
      : Ignore(Ignore), CallbackCalls(CallbackCalls) {}

  PPTraceAction *create() override {
    return new PPTraceAction(Ignore, CallbackCalls);
  }

private:
  SmallSet<std::string, 4> &Ignore;
  std::vector<CallbackCall> &CallbackCalls;
};
} // namespace

// Output the trace given its data structure and a stream.
static int outputPPTrace(std::vector<CallbackCall> &CallbackCalls,
                         llvm::raw_ostream &OS) {
  // Mark start of document.
  OS << "---\n";

  for (std::vector<CallbackCall>::const_iterator I = CallbackCalls.begin(),
                                                 E = CallbackCalls.end();
       I != E; ++I) {
    const CallbackCall &Callback = *I;
    OS << "- Callback: " << Callback.Name << "\n";

    for (auto AI = Callback.Arguments.begin(), AE = Callback.Arguments.end();
         AI != AE; ++AI) {
      const Argument &Arg = *AI;
      OS << "  " << Arg.Name << ": " << Arg.Value << "\n";
    }
  }

  // Mark end of document.
  OS << "...\n";

  return 0;
}

// Program entry point.
int main(int Argc, const char **Argv) {

  // Parse command line.
  cl::ParseCommandLineOptions(Argc, Argv, "pp-trace.\n");

  // Parse the IgnoreCallbacks list into strings.
  SmallVector<StringRef, 32> IgnoreCallbacksStrings;
  StringRef(IgnoreCallbacks).split(IgnoreCallbacksStrings, ",",
                                   /*MaxSplit=*/ -1, /*KeepEmpty=*/false);
  SmallSet<std::string, 4> Ignore;
  for (SmallVector<StringRef, 32>::iterator I = IgnoreCallbacksStrings.begin(),
                                            E = IgnoreCallbacksStrings.end();
       I != E; ++I)
    Ignore.insert(*I);

  // Create the compilation database.
  SmallString<256> PathBuf;
  sys::fs::current_path(PathBuf);
  std::unique_ptr<CompilationDatabase> Compilations;
  Compilations.reset(
      new FixedCompilationDatabase(Twine(PathBuf), CC1Arguments));

  // Store the callback trace information here.
  std::vector<CallbackCall> CallbackCalls;

  // Create the tool and run the compilation.
  ClangTool Tool(*Compilations, SourcePaths);
  PPTraceFrontendActionFactory Factory(Ignore, CallbackCalls);
  int HadErrors = Tool.run(&Factory);

  // If we had errors, exit early.
  if (HadErrors)
    return HadErrors;

  // Do the output.
  if (!OutputFileName.size()) {
    HadErrors = outputPPTrace(CallbackCalls, llvm::outs());
  } else {
    // Set up output file.
    std::error_code EC;
    llvm::ToolOutputFile Out(OutputFileName, EC, llvm::sys::fs::F_Text);
    if (EC) {
      llvm::errs() << "pp-trace: error creating " << OutputFileName << ":"
                   << EC.message() << "\n";
      return 1;
    }

    HadErrors = outputPPTrace(CallbackCalls, Out.os());

    // Tell ToolOutputFile that we want to keep the file.
    if (HadErrors == 0)
      Out.keep();
  }

  return HadErrors;
}
