//===--- clang.cpp - C-Language Front-end ---------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This utility may be invoked in the following manner:
//   clang --help                - Output help info.
//   clang [options]             - Read from stdin.
//   clang [options] file        - Read from "file".
//   clang [options] file1 file2 - Read these files.
//
//===----------------------------------------------------------------------===//

#include "Options.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/AnalysisConsumer.h"
#include "clang/Frontend/ChainedDiagnosticClient.h"
#include "clang/Frontend/CommandLineSourceLoc.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/FixItRewriter.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/PCHReader.h"
#include "clang/Frontend/PathDiagnosticClients.h"
#include "clang/Frontend/PreprocessorOptions.h"
#include "clang/Frontend/PreprocessorOutputOptions.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Parse/Parser.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Sema/ParseAST.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/LLVMContext.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Config/config.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Host.h"
#include "llvm/System/Path.h"
#include "llvm/System/Program.h"
#include "llvm/System/Signals.h"
#include "llvm/Target/TargetSelect.h"
#include <cstdlib>
#if HAVE_SYS_TYPES_H
#  include <sys/types.h>
#endif

using namespace clang;

//===----------------------------------------------------------------------===//
// Global options.
//===----------------------------------------------------------------------===//

/// ClangFrontendTimer - The front-end activities should charge time to it with
/// TimeRegion.  The -ftime-report option controls whether this will do
/// anything.
llvm::Timer *ClangFrontendTimer = 0;

static llvm::cl::opt<bool>
Verbose("v", llvm::cl::desc("Enable verbose output"));
static llvm::cl::opt<bool>
Stats("print-stats",
      llvm::cl::desc("Print performance metrics and statistics"));
static llvm::cl::opt<bool>
DisableFree("disable-free",
           llvm::cl::desc("Disable freeing of memory on exit"),
           llvm::cl::init(false));
static llvm::cl::opt<bool>
EmptyInputOnly("empty-input-only",
      llvm::cl::desc("Force running on an empty input file"));

enum ProgActions {
  RewriteObjC,                  // ObjC->C Rewriter.
  RewriteBlocks,                // ObjC->C Rewriter for Blocks.
  RewriteMacros,                // Expand macros but not #includes.
  RewriteTest,                  // Rewriter playground
  FixIt,                        // Fix-It Rewriter
  HTMLTest,                     // HTML displayer testing stuff.
  EmitAssembly,                 // Emit a .s file.
  EmitLLVM,                     // Emit a .ll file.
  EmitBC,                       // Emit a .bc file.
  EmitLLVMOnly,                 // Generate LLVM IR, but do not
  EmitHTML,                     // Translate input source into HTML.
  ASTPrint,                     // Parse ASTs and print them.
  ASTPrintXML,                  // Parse ASTs and print them in XML.
  ASTDump,                      // Parse ASTs and dump them.
  ASTView,                      // Parse ASTs and view them in Graphviz.
  PrintDeclContext,             // Print DeclContext and their Decls.
  DumpRecordLayouts,            // Dump record layout information.
  ParsePrintCallbacks,          // Parse and print each callback.
  ParseSyntaxOnly,              // Parse and perform semantic analysis.
  ParseNoop,                    // Parse with noop callbacks.
  RunPreprocessorOnly,          // Just lex, no output.
  PrintPreprocessedInput,       // -E mode.
  DumpTokens,                   // Dump out preprocessed tokens.
  DumpRawTokens,                // Dump out raw tokens.
  RunAnalysis,                  // Run one or more source code analyses.
  GeneratePTH,                  // Generate pre-tokenized header.
  GeneratePCH,                  // Generate pre-compiled header.
  InheritanceView               // View C++ inheritance for a specified class.
};

static llvm::cl::opt<ProgActions>
ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
           llvm::cl::init(ParseSyntaxOnly),
           llvm::cl::values(
             clEnumValN(RunPreprocessorOnly, "Eonly",
                        "Just run preprocessor, no output (for timings)"),
             clEnumValN(PrintPreprocessedInput, "E",
                        "Run preprocessor, emit preprocessed file"),
             clEnumValN(DumpRawTokens, "dump-raw-tokens",
                        "Lex file in raw mode and dump raw tokens"),
             clEnumValN(RunAnalysis, "analyze",
                        "Run static analysis engine"),
             clEnumValN(DumpTokens, "dump-tokens",
                        "Run preprocessor, dump internal rep of tokens"),
             clEnumValN(ParseNoop, "parse-noop",
                        "Run parser with noop callbacks (for timings)"),
             clEnumValN(ParseSyntaxOnly, "fsyntax-only",
                        "Run parser and perform semantic analysis"),
             clEnumValN(ParsePrintCallbacks, "parse-print-callbacks",
                        "Run parser and print each callback invoked"),
             clEnumValN(EmitHTML, "emit-html",
                        "Output input source as HTML"),
             clEnumValN(ASTPrint, "ast-print",
                        "Build ASTs and then pretty-print them"),
             clEnumValN(ASTPrintXML, "ast-print-xml",
                        "Build ASTs and then print them in XML format"),
             clEnumValN(ASTDump, "ast-dump",
                        "Build ASTs and then debug dump them"),
             clEnumValN(ASTView, "ast-view",
                        "Build ASTs and view them with GraphViz"),
             clEnumValN(PrintDeclContext, "print-decl-contexts",
                        "Print DeclContexts and their Decls"),
             clEnumValN(DumpRecordLayouts, "dump-record-layouts",
                        "Dump record layout information"),
             clEnumValN(GeneratePTH, "emit-pth",
                        "Generate pre-tokenized header file"),
             clEnumValN(GeneratePCH, "emit-pch",
                        "Generate pre-compiled header file"),
             clEnumValN(EmitAssembly, "S",
                        "Emit native assembly code"),
             clEnumValN(EmitLLVM, "emit-llvm",
                        "Build ASTs then convert to LLVM, emit .ll file"),
             clEnumValN(EmitBC, "emit-llvm-bc",
                        "Build ASTs then convert to LLVM, emit .bc file"),
             clEnumValN(EmitLLVMOnly, "emit-llvm-only",
                        "Build ASTs and convert to LLVM, discarding output"),
             clEnumValN(RewriteTest, "rewrite-test",
                        "Rewriter playground"),
             clEnumValN(RewriteObjC, "rewrite-objc",
                        "Rewrite ObjC into C (code rewriter example)"),
             clEnumValN(RewriteMacros, "rewrite-macros",
                        "Expand macros without full preprocessing"),
             clEnumValN(RewriteBlocks, "rewrite-blocks",
                        "Rewrite Blocks to C"),
             clEnumValN(FixIt, "fixit",
                        "Apply fix-it advice to the input source"),
             clEnumValEnd));


enum CodeCompletionPrinter {
  CCP_Debug,
  CCP_CIndex
};

static llvm::cl::opt<ParsedSourceLocation>
CodeCompletionAt("code-completion-at",
                 llvm::cl::value_desc("file:line:column"),
              llvm::cl::desc("Dump code-completion information at a location"));

static llvm::cl::opt<CodeCompletionPrinter>
CodeCompletionPrinter("code-completion-printer",
                      llvm::cl::desc("Choose output type:"),
                      llvm::cl::init(CCP_Debug),
                      llvm::cl::values(
                        clEnumValN(CCP_Debug, "debug",
                          "Debug code-completion results"),
                        clEnumValN(CCP_CIndex, "cindex",
                          "Code-completion results for the CIndex library"),
                        clEnumValEnd));

static llvm::cl::opt<bool>
CodeCompletionWantsMacros("code-completion-macros",
                 llvm::cl::desc("Include macros in code-completion results"));

/// \brief Buld a new code-completion consumer that prints the results of
/// code completion to standard output.
static CodeCompleteConsumer *BuildPrintingCodeCompleter(Sema &S, void *) {
  switch (CodeCompletionPrinter.getValue()) {
  case CCP_Debug:
    return new PrintingCodeCompleteConsumer(S, CodeCompletionWantsMacros,
                                            llvm::outs());

  case CCP_CIndex:
    return new CIndexCodeCompleteConsumer(S, CodeCompletionWantsMacros,
                                          llvm::outs());
  };

  return 0;
}

//===----------------------------------------------------------------------===//
// C++ Visualization.
//===----------------------------------------------------------------------===//

static llvm::cl::opt<std::string>
InheritanceViewCls("cxx-inheritance-view",
                   llvm::cl::value_desc("class name"),
                  llvm::cl::desc("View C++ inheritance for a specified class"));

//===----------------------------------------------------------------------===//
// Frontend Options
//===----------------------------------------------------------------------===//

static llvm::cl::list<std::string>
InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input files>"));

static llvm::cl::opt<std::string>
OutputFile("o",
 llvm::cl::value_desc("path"),
 llvm::cl::desc("Specify output file"));

static llvm::cl::opt<bool>
TimeReport("ftime-report",
           llvm::cl::desc("Print the amount of time each "
                          "phase of compilation takes"));

static llvm::cl::opt<bool>
VerifyDiagnostics("verify",
                  llvm::cl::desc("Verify emitted diagnostics and warnings"));

//===----------------------------------------------------------------------===//
// Language Options
//===----------------------------------------------------------------------===//

static llvm::cl::opt<LangKind>
BaseLang("x", llvm::cl::desc("Base language to compile"),
         llvm::cl::init(langkind_unspecified),
   llvm::cl::values(clEnumValN(langkind_c,     "c",            "C"),
                    clEnumValN(langkind_ocl,   "cl",           "OpenCL C"),
                    clEnumValN(langkind_cxx,   "c++",          "C++"),
                    clEnumValN(langkind_objc,  "objective-c",  "Objective C"),
                    clEnumValN(langkind_objcxx,"objective-c++","Objective C++"),
                    clEnumValN(langkind_c_cpp,     "cpp-output",
                               "Preprocessed C"),
                    clEnumValN(langkind_asm_cpp,     "assembler-with-cpp",
                               "Preprocessed asm"),
                    clEnumValN(langkind_cxx_cpp,   "c++-cpp-output",
                               "Preprocessed C++"),
                    clEnumValN(langkind_objc_cpp,  "objective-c-cpp-output",
                               "Preprocessed Objective C"),
                    clEnumValN(langkind_objcxx_cpp, "objective-c++-cpp-output",
                               "Preprocessed Objective C++"),
                    clEnumValN(langkind_c, "c-header",
                               "C header"),
                    clEnumValN(langkind_objc, "objective-c-header",
                               "Objective-C header"),
                    clEnumValN(langkind_cxx, "c++-header",
                               "C++ header"),
                    clEnumValN(langkind_objcxx, "objective-c++-header",
                               "Objective-C++ header"),
                    clEnumValN(langkind_ast, "ast",
                               "Clang AST"),
                    clEnumValEnd));

static llvm::cl::opt<std::string>
TargetTriple("triple",
  llvm::cl::desc("Specify target triple (e.g. i686-apple-darwin9)"));

static llvm::cl::opt<std::string>
TargetABI("target-abi",
          llvm::cl::desc("Target a particular ABI type"));

//===----------------------------------------------------------------------===//
// SourceManager initialization.
//===----------------------------------------------------------------------===//

static bool InitializeSourceManager(Preprocessor &PP,
                                    const std::string &InFile) {
  // Figure out where to get and map in the main file.
  SourceManager &SourceMgr = PP.getSourceManager();
  FileManager &FileMgr = PP.getFileManager();

  if (EmptyInputOnly) {
    const char *EmptyStr = "";
    llvm::MemoryBuffer *SB =
      llvm::MemoryBuffer::getMemBuffer(EmptyStr, EmptyStr, "<empty input>");
    SourceMgr.createMainFileIDForMemBuffer(SB);
  } else if (InFile != "-") {
    const FileEntry *File = FileMgr.getFile(InFile);
    if (File) SourceMgr.createMainFileID(File, SourceLocation());
    if (SourceMgr.getMainFileID().isInvalid()) {
      PP.getDiagnostics().Report(diag::err_fe_error_reading) << InFile.c_str();
      return true;
    }
  } else {
    llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
    SourceMgr.createMainFileIDForMemBuffer(SB);
    if (SourceMgr.getMainFileID().isInvalid()) {
      PP.getDiagnostics().Report(diag::err_fe_error_reading_stdin);
      return true;
    }
  }

  return false;
}


//===----------------------------------------------------------------------===//
// Preprocessor Initialization
//===----------------------------------------------------------------------===//

static llvm::cl::opt<bool>
RelocatablePCH("relocatable-pch",
               llvm::cl::desc("Whether to build a relocatable precompiled "
                              "header"));

// Finally, implement the code that groks the options above.

// Add the clang headers, which are relative to the clang binary.
std::string GetBuiltinIncludePath(const char *Argv0) {
  llvm::sys::Path P =
    llvm::sys::Path::GetMainExecutable(Argv0,
                                       (void*)(intptr_t) GetBuiltinIncludePath);

  if (!P.isEmpty()) {
    P.eraseComponent();  // Remove /clang from foo/bin/clang
    P.eraseComponent();  // Remove /bin   from foo/bin

    // Get foo/lib/clang/<version>/include
    P.appendComponent("lib");
    P.appendComponent("clang");
    P.appendComponent(CLANG_VERSION_STRING);
    P.appendComponent("include");
  }

  return P.str();
}

//===----------------------------------------------------------------------===//
// Preprocessor construction
//===----------------------------------------------------------------------===//

static Preprocessor *
CreatePreprocessor(Diagnostic &Diags, const LangOptions &LangInfo,
                   const PreprocessorOptions &PPOpts,
                   const HeaderSearchOptions &HSOpts,
                   const DependencyOutputOptions &DepOpts,
                   TargetInfo &Target, SourceManager &SourceMgr,
                   FileManager &FileMgr) {
  // Create a PTH manager if we are using some form of a token cache.
  PTHManager *PTHMgr = 0;
  if (!PPOpts.getTokenCache().empty())
    PTHMgr = PTHManager::Create(PPOpts.getTokenCache(), Diags);

  // FIXME: Don't fail like this.
  if (Diags.hasErrorOccurred())
    exit(1);

  // Create the Preprocessor.
  HeaderSearch *HeaderInfo = new HeaderSearch(FileMgr);
  Preprocessor *PP = new Preprocessor(Diags, LangInfo, Target,
                                      SourceMgr, *HeaderInfo, PTHMgr,
                                      /*OwnsHeaderSearch=*/true);

  // Note that this is different then passing PTHMgr to Preprocessor's ctor.
  // That argument is used as the IdentifierInfoLookup argument to
  // IdentifierTable's ctor.
  if (PTHMgr) {
    PTHMgr->setPreprocessor(PP);
    PP->setPTHManager(PTHMgr);
  }

  InitializePreprocessor(*PP, PPOpts, HSOpts);

  // Handle generating dependencies, if requested.
  if (!DepOpts.OutputFile.empty())
    AttachDependencyFileGen(*PP, DepOpts);

  return PP;
}

//===----------------------------------------------------------------------===//
// Basic Parser driver
//===----------------------------------------------------------------------===//

static void ParseFile(Preprocessor &PP, MinimalAction *PA) {
  Parser P(PP, *PA);
  PP.EnterMainSourceFile();

  // Parsing the specified input file.
  P.ParseTranslationUnit();
  delete PA;
}

//===----------------------------------------------------------------------===//
// Fix-It Options
//===----------------------------------------------------------------------===//
static llvm::cl::list<ParsedSourceLocation>
FixItAtLocations("fixit-at", llvm::cl::value_desc("source-location"),
   llvm::cl::desc("Perform Fix-It modifications at the given source location"));

//===----------------------------------------------------------------------===//
// ObjC Rewriter Options
//===----------------------------------------------------------------------===//
static llvm::cl::opt<bool>
SilenceRewriteMacroWarning("Wno-rewrite-macros", llvm::cl::init(false),
                           llvm::cl::desc("Silence ObjC rewriting warnings"));

//===----------------------------------------------------------------------===//
// Warning Options
//===----------------------------------------------------------------------===//

// This gets all -W options, including -Werror, -W[no-]system-headers, etc.  The
// driver has stripped off -Wa,foo etc.  The driver has also translated -W to
// -Wextra, so we don't need to worry about it.
static llvm::cl::list<std::string>
OptWarnings("W", llvm::cl::Prefix, llvm::cl::ValueOptional);

static llvm::cl::opt<bool> OptPedantic("pedantic");
static llvm::cl::opt<bool> OptPedanticErrors("pedantic-errors");
static llvm::cl::opt<bool> OptNoWarnings("w");

//===----------------------------------------------------------------------===//
// -dump-build-information Stuff
//===----------------------------------------------------------------------===//

static llvm::cl::opt<std::string>
DumpBuildInformation("dump-build-information",
                     llvm::cl::value_desc("filename"),
          llvm::cl::desc("output a dump of some build information to a file"));

static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts,
                              unsigned argc, char **argv,
                              llvm::OwningPtr<DiagnosticClient> &DiagClient) {
  std::string ErrorInfo;
  llvm::raw_ostream *OS = new llvm::raw_fd_ostream(DumpBuildInformation.c_str(),
                                                   ErrorInfo);
  if (!ErrorInfo.empty()) {
    llvm::errs() << "error opening -dump-build-information file '"
                 << DumpBuildInformation << "', option ignored!\n";
    delete OS;
    return;
  }

  (*OS) << "clang-cc command line arguments: ";
  for (unsigned i = 0; i != argc; ++i)
    (*OS) << argv[i] << ' ';
  (*OS) << '\n';

  // Chain in a diagnostic client which will log the diagnostics.
  DiagnosticClient *Logger =
    new TextDiagnosticPrinter(*OS, DiagOpts, /*OwnsOutputStream=*/true);
  DiagClient.reset(new ChainedDiagnosticClient(DiagClient.take(), Logger));
}

//===----------------------------------------------------------------------===//
// Main driver
//===----------------------------------------------------------------------===//

static llvm::raw_ostream *ComputeOutFile(const CompilerInvocation &CompOpts,
                                         const std::string &InFile,
                                         const char *Extension,
                                         bool Binary,
                                         llvm::sys::Path& OutPath) {
  llvm::raw_ostream *Ret;
  std::string OutFile;
  if (!CompOpts.getOutputFile().empty())
    OutFile = CompOpts.getOutputFile();
  else if (InFile == "-") {
    OutFile = "-";
  } else if (Extension) {
    llvm::sys::Path Path(InFile);
    Path.eraseSuffix();
    Path.appendSuffix(Extension);
    OutFile = Path.str();
  } else {
    OutFile = "-";
  }

  std::string Error;
  Ret = new llvm::raw_fd_ostream(OutFile.c_str(), Error,
                                 (Binary ? llvm::raw_fd_ostream::F_Binary : 0));
  if (!Error.empty()) {
    // FIXME: Don't fail this way.
    llvm::errs() << "ERROR: " << Error << "\n";
    ::exit(1);
  }

  if (OutFile != "-")
    OutPath = OutFile;

  return Ret;
}

/// AddFixItLocations - Add any individual user specified "fix-it" locations,
/// and return true on success (if any were added).
static bool AddFixItLocations(FixItRewriter *FixItRewrite,
                              FileManager &FileMgr) {
  bool AddedFixItLocation = false;

  for (unsigned i = 0, e = FixItAtLocations.size(); i != e; ++i) {
    if (const FileEntry *File = FileMgr.getFile(FixItAtLocations[i].FileName)) {
      RequestedSourceLocation Requested;
      Requested.File = File;
      Requested.Line = FixItAtLocations[i].Line;
      Requested.Column = FixItAtLocations[i].Column;
      FixItRewrite->addFixItLocation(Requested);
      AddedFixItLocation = true;
    } else {
      llvm::errs() << "FIX-IT could not find file \""
                   << FixItAtLocations[i].FileName << "\"\n";
    }
  }

  return AddedFixItLocation;
}

static ASTConsumer *CreateConsumerAction(const CompilerInvocation &CompOpts,
                                         Preprocessor &PP,
                                         const std::string &InFile,
                                         ProgActions PA,
                                         llvm::OwningPtr<llvm::raw_ostream> &OS,
                                         llvm::sys::Path &OutPath,
                                         llvm::LLVMContext& Context) {
  switch (PA) {
  default:
    return 0;

  case ASTPrint:
    OS.reset(ComputeOutFile(CompOpts, InFile, 0, false, OutPath));
    return CreateASTPrinter(OS.get());

  case ASTPrintXML:
    OS.reset(ComputeOutFile(CompOpts, InFile, "xml", false, OutPath));
    return CreateASTPrinterXML(OS.get());

  case ASTDump:
    return CreateASTDumper();

  case ASTView:
    return CreateASTViewer();

  case DumpRecordLayouts:
    return CreateRecordLayoutDumper();

  case InheritanceView:
    return CreateInheritanceViewer(InheritanceViewCls);

  case EmitAssembly:
  case EmitLLVM:
  case EmitBC:
  case EmitLLVMOnly: {
    BackendAction Act;
    if (ProgAction == EmitAssembly) {
      Act = Backend_EmitAssembly;
      OS.reset(ComputeOutFile(CompOpts, InFile, "s", true, OutPath));
    } else if (ProgAction == EmitLLVM) {
      Act = Backend_EmitLL;
      OS.reset(ComputeOutFile(CompOpts, InFile, "ll", true, OutPath));
    } else if (ProgAction == EmitLLVMOnly) {
      Act = Backend_EmitNothing;
    } else {
      Act = Backend_EmitBC;
      OS.reset(ComputeOutFile(CompOpts, InFile, "bc", true, OutPath));
    }

    return CreateBackendConsumer(Act, PP.getDiagnostics(), PP.getLangOptions(),
                                 CompOpts.getCompileOpts(), InFile, OS.get(),
                                 Context);
  }

  case RewriteObjC:
    OS.reset(ComputeOutFile(CompOpts, InFile, "cpp", true, OutPath));
    return CreateObjCRewriter(InFile, OS.get(), PP.getDiagnostics(),
                              PP.getLangOptions(), SilenceRewriteMacroWarning);

  case RewriteBlocks:
    return CreateBlockRewriter(InFile, PP.getDiagnostics(),
                               PP.getLangOptions());

  case FixIt: // We add the rewriter later.
  case ParseSyntaxOnly:
    return new ASTConsumer();

  case PrintDeclContext:
    return CreateDeclContextPrinter();
  }
}

/// ReadPCHFile - Load a PCH file from disk, and initialize the preprocessor for
/// reading from the PCH file.
///
/// \return The AST source, or null on failure.
static ExternalASTSource *ReadPCHFile(llvm::StringRef Path,
                                      const CompilerInvocation &CompOpts,
                                      Preprocessor &PP,
                                      ASTContext &Context) {
  // If the user specified -isysroot, it will be used for relocatable PCH files.
  const char *isysrootPCH = CompOpts.getHeaderSearchOpts().Sysroot.c_str();
  if (isysrootPCH[0] == '\0')
    isysrootPCH = 0;

  llvm::OwningPtr<PCHReader> Reader;
  Reader.reset(new PCHReader(PP, &Context, isysrootPCH));

  switch (Reader->ReadPCH(Path)) {
  case PCHReader::Success:
    // Set the predefines buffer as suggested by the PCH reader. Typically, the
    // predefines buffer will be empty.
    PP.setPredefines(Reader->getSuggestedPredefines());
    return Reader.take();

  case PCHReader::Failure:
    // Unrecoverable failure: don't even try to process the input file.
    break;

  case PCHReader::IgnorePCH:
    // No suitable PCH file could be found. Return an error.
    break;
  }

  return 0;
}

/// ProcessInputFile - Process a single input file with the specified state.
///
static void ProcessInputFile(const CompilerInvocation &CompOpts,
                             Preprocessor &PP, const std::string &InFile,
                             ProgActions PA, llvm::LLVMContext& Context) {
  llvm::OwningPtr<llvm::raw_ostream> OS;
  llvm::OwningPtr<ASTConsumer> Consumer;
  bool ClearSourceMgr = false;
  FixItRewriter *FixItRewrite = 0;
  bool CompleteTranslationUnit = true;
  llvm::sys::Path OutPath;

  switch (PA) {
  default:
    Consumer.reset(CreateConsumerAction(CompOpts, PP, InFile, PA, OS, OutPath,
                                        Context));
    if (!Consumer.get()) {
      PP.getDiagnostics().Report(diag::err_fe_invalid_ast_action);
      return;
    }
    break;

  case EmitHTML:
    OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
    Consumer.reset(CreateHTMLPrinter(OS.get(), PP));
    break;

  case RunAnalysis:
    Consumer.reset(CreateAnalysisConsumer(PP, CompOpts.getOutputFile(),
                                          CompOpts.getAnalyzerOpts()));
    break;

  case GeneratePCH: {
    const std::string &Sysroot = CompOpts.getHeaderSearchOpts().Sysroot;
    if (RelocatablePCH.getValue() && Sysroot.empty()) {
      PP.Diag(SourceLocation(), diag::err_relocatable_without_without_isysroot);
      RelocatablePCH.setValue(false);
    }

    OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
    if (RelocatablePCH.getValue())
      Consumer.reset(CreatePCHGenerator(PP, OS.get(), Sysroot.c_str()));
    else
      Consumer.reset(CreatePCHGenerator(PP, OS.get()));
    CompleteTranslationUnit = false;
    break;
  }

    // Do any necessary set up for non-consumer actions.
  case DumpRawTokens:
  case DumpTokens:
  case RunPreprocessorOnly:
  case ParseNoop:
    break; // No setup.

  case GeneratePTH:
    if (CompOpts.getOutputFile().empty() || CompOpts.getOutputFile() == "-") {
      // FIXME: Don't fail this way.
      // FIXME: Verify that we can actually seek in the given file.
      llvm::errs() << "ERROR: PTH requires an seekable file for output!\n";
      ::exit(1);
    }
    OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
    break;

  case PrintPreprocessedInput:
  case ParsePrintCallbacks:
  case RewriteMacros:
  case RewriteTest:
    OS.reset(ComputeOutFile(CompOpts, InFile, 0, true, OutPath));
    break;
  }

  // Check if we want a fix-it rewriter.
  if (PA == FixIt || !FixItAtLocations.empty()) {
    FixItRewrite = new FixItRewriter(PP.getDiagnostics(),
                                     PP.getSourceManager(),
                                     PP.getLangOptions());
    if (!FixItAtLocations.empty() &&
        !AddFixItLocations(FixItRewrite, PP.getFileManager())) {
      // All of the fix-it locations were bad. Don't fix anything.
      delete FixItRewrite;
      FixItRewrite = 0;
    }
  }

  llvm::OwningPtr<ASTContext> ContextOwner;
  llvm::OwningPtr<ExternalASTSource> Source;
  const std::string &ImplicitPCHInclude =
    CompOpts.getPreprocessorOpts().getImplicitPCHInclude();
  if (Consumer) {
    ContextOwner.reset(new ASTContext(PP.getLangOptions(),
                                      PP.getSourceManager(),
                                      PP.getTargetInfo(),
                                      PP.getIdentifierTable(),
                                      PP.getSelectorTable(),
                                      PP.getBuiltinInfo(),
                                      /* FreeMemory = */ !DisableFree,
                                      /* size_reserve = */0));

    if (!ImplicitPCHInclude.empty()) {
      Source.reset(ReadPCHFile(ImplicitPCHInclude, CompOpts, PP,
                               *ContextOwner));
      if (!Source)
        return;

      // Attach the PCH reader to the AST context as an external AST source, so
      // that declarations will be deserialized from the PCH file as needed.
      ContextOwner->setExternalSource(Source);
    } else {
      // Initialize builtin info when not using PCH.
      PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                             PP.getLangOptions().NoBuiltin);
    }

    // Initialize the main file entry. This needs to be delayed until after PCH
    // has loaded.
    if (InitializeSourceManager(PP, InFile))
      return;

    CodeCompleteConsumer *(*CreateCodeCompleter)(Sema &, void *) = 0;
    void *CreateCodeCompleterData = 0;

    if (!CodeCompletionAt.FileName.empty()) {
      // Tell the source manager to chop off the given file at a specific
      // line and column.
      if (const FileEntry *Entry
            = PP.getFileManager().getFile(CodeCompletionAt.FileName)) {
        // Truncate the named file at the given line/column.
        PP.getSourceManager().truncateFileAt(Entry, CodeCompletionAt.Line,
                                             CodeCompletionAt.Column);

        // Set up the creation routine for code-completion.
        CreateCodeCompleter = BuildPrintingCodeCompleter;
      } else {
        PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
          << CodeCompletionAt.FileName;
      }
    }

    // Run the AST consumer action.
    ParseAST(PP, Consumer.get(), *ContextOwner.get(), Stats,
             CompleteTranslationUnit,
             CreateCodeCompleter, CreateCodeCompleterData);
  } else {
    // Initialize builtin info.
    PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOptions().NoBuiltin);

    // Initialize the main file entry. This needs to be delayed until after PCH
    // has loaded.
    if (InitializeSourceManager(PP, InFile))
      return;

    // Run the preprocessor actions.
    llvm::TimeRegion Timer(ClangFrontendTimer);
    switch (PA) {
    default:
      assert(0 && "unexpected program action");

    case DumpRawTokens: {
      SourceManager &SM = PP.getSourceManager();
      // Start lexing the specified input file.
      Lexer RawLex(SM.getMainFileID(), SM, PP.getLangOptions());
      RawLex.SetKeepWhitespaceMode(true);

      Token RawTok;
      RawLex.LexFromRawLexer(RawTok);
      while (RawTok.isNot(tok::eof)) {
        PP.DumpToken(RawTok, true);
        fprintf(stderr, "\n");
        RawLex.LexFromRawLexer(RawTok);
      }
      break;
    }

    case DumpTokens: {
      Token Tok;
      // Start preprocessing the specified input file.
      PP.EnterMainSourceFile();
      do {
        PP.Lex(Tok);
        PP.DumpToken(Tok, true);
        fprintf(stderr, "\n");
      } while (Tok.isNot(tok::eof));
      break;
    }

    case GeneratePTH:
      CacheTokens(PP, static_cast<llvm::raw_fd_ostream*>(OS.get()));
      break;

    case ParseNoop:
      ParseFile(PP, new MinimalAction(PP));
      break;

    case ParsePrintCallbacks:
      ParseFile(PP, CreatePrintParserActionsAction(PP, OS.get()));
      break;

    case PrintPreprocessedInput:
      DoPrintPreprocessedInput(PP, OS.get(),
                               CompOpts.getPreprocessorOutputOpts());
      break;

    case RewriteMacros:
      RewriteMacrosInInput(PP, OS.get());
      break;

    case RewriteTest:
      DoRewriteTest(PP, OS.get());
      break;

    case RunPreprocessorOnly: {    // Just lex as fast as we can, no output.
      Token Tok;
      // Start parsing the specified input file.
      PP.EnterMainSourceFile();
      do {
        PP.Lex(Tok);
      } while (Tok.isNot(tok::eof));
      break;
    }
    }

    ClearSourceMgr = true;
  }

  if (FixItRewrite)
    FixItRewrite->WriteFixedFile(InFile, CompOpts.getOutputFile());

  // Release the consumer and the AST, in that order since the consumer may
  // perform actions in its destructor which require the context.
  if (DisableFree) {
    Consumer.take();
    ContextOwner.take();
  } else {
    Consumer.reset();
    ContextOwner.reset();
  }

  if (VerifyDiagnostics)
    if (CheckDiagnostics(PP))
      exit(1);

  if (Stats) {
    fprintf(stderr, "\nSTATISTICS FOR '%s':\n", InFile.c_str());
    PP.PrintStats();
    PP.getIdentifierTable().PrintStats();
    PP.getHeaderSearchInfo().PrintStats();
    PP.getSourceManager().PrintStats();
    fprintf(stderr, "\n");
  }

  // For a multi-file compilation, some things are ok with nuking the source
  // manager tables, other require stable fileid/macroid's across multiple
  // files.
  if (ClearSourceMgr)
    PP.getSourceManager().clearIDTables();

  // Always delete the output stream because we don't want to leak file
  // handles.  Also, we don't want to try to erase an open file.
  OS.reset();

  // If we had errors, try to erase the output file.
  if (PP.getDiagnostics().getNumErrors() && !OutPath.isEmpty())
    OutPath.eraseFromDisk();
}

/// ProcessInputFile - Process a single AST input file with the specified state.
///
static void ProcessASTInputFile(const CompilerInvocation &CompOpts,
                                const std::string &InFile, ProgActions PA,
                                Diagnostic &Diags, FileManager &FileMgr,
                                llvm::LLVMContext& Context) {
  std::string Error;
  llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromPCHFile(InFile, &Error));
  if (!AST) {
    Diags.Report(diag::err_fe_invalid_ast_file) << Error;
    return;
  }

  Preprocessor &PP = AST->getPreprocessor();

  llvm::OwningPtr<llvm::raw_ostream> OS;
  llvm::sys::Path OutPath;
  llvm::OwningPtr<ASTConsumer> Consumer(CreateConsumerAction(CompOpts, PP,
                                                             InFile, PA, OS,
                                                             OutPath, Context));
  if (!Consumer.get()) {
    Diags.Report(diag::err_fe_invalid_ast_action);
    return;
  }

  // Set the main file ID to an empty file.
  //
  // FIXME: We probably shouldn't need this, but for now this is the simplest
  // way to reuse the logic in ParseAST.
  const char *EmptyStr = "";
  llvm::MemoryBuffer *SB =
    llvm::MemoryBuffer::getMemBuffer(EmptyStr, EmptyStr, "<dummy input>");
  AST->getSourceManager().createMainFileIDForMemBuffer(SB);

  // Stream the input AST to the consumer.
  Diags.getClient()->BeginSourceFile(PP.getLangOptions());
  ParseAST(PP, Consumer.get(), AST->getASTContext(), Stats);
  Diags.getClient()->EndSourceFile();

  // Release the consumer and the AST, in that order since the consumer may
  // perform actions in its destructor which require the context.
  if (DisableFree) {
    Consumer.take();
    AST.take();
  } else {
    Consumer.reset();
    AST.reset();
  }

  // Always delete the output stream because we don't want to leak file
  // handles.  Also, we don't want to try to erase an open file.
  OS.reset();

  // If we had errors, try to erase the output file.
  if (PP.getDiagnostics().getNumErrors() && !OutPath.isEmpty())
    OutPath.eraseFromDisk();
}

static void LLVMErrorHandler(void *UserData, const std::string &Message) {
  Diagnostic &Diags = *static_cast<Diagnostic*>(UserData);

  Diags.Report(diag::err_fe_error_backend) << Message;

  // We cannot recover from llvm errors.
  exit(1);
}

static LangKind GetLanguage() {
  // If -x was given, that's the language.
  if (BaseLang != langkind_unspecified)
    return BaseLang;

  // Otherwise guess it from the input filenames;
  LangKind LK = langkind_unspecified;
  for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
    llvm::StringRef Name(InputFilenames[i]);
    LangKind ThisKind =  llvm::StringSwitch<LangKind>(Name.rsplit('.').second)
      .Case("ast", langkind_ast)
      .Case("c", langkind_c)
      .Cases("S", "s", langkind_asm_cpp)
      .Case("i", langkind_c_cpp)
      .Case("ii", langkind_cxx_cpp)
      .Case("m", langkind_objc)
      .Case("mi", langkind_objc_cpp)
      .Cases("mm", "M", langkind_objcxx)
      .Case("mii", langkind_objcxx_cpp)
      .Case("C", langkind_cxx)
      .Cases("C", "cc", "cp", langkind_cxx)
      .Cases("cpp", "CPP", "c++", "cxx", langkind_cxx)
      .Case("cl", langkind_ocl)
      .Default(langkind_c);

    if (LK != langkind_unspecified && ThisKind != LK) {
      llvm::errs() << "error: cannot have multiple input files of distinct "
                   << "language kinds without -x\n";
      exit(1);
    }

    LK = ThisKind;
  }

  return LK;
}

static void FinalizeCompileOptions(CompileOptions &Opts,
                                   const LangOptions &Lang) {
  if (Lang.NoBuiltin)
    Opts.SimplifyLibCalls = 0;
  if (Lang.CPlusPlus)
    Opts.NoCommon = 1;

  // Handle -ftime-report.
  Opts.TimePasses = TimeReport;
}

static void ConstructCompilerInvocation(CompilerInvocation &Opts,
                                        const char *Argv0,
                                        const DiagnosticOptions &DiagOpts,
                                        TargetInfo &Target,
                                        LangKind LK) {
  Opts.getDiagnosticOpts() = DiagOpts;

  Opts.getOutputFile() = OutputFile;

  // Initialize backend options, which may also be used to key some language
  // options.
  InitializeCompileOptions(Opts.getCompileOpts(), Target);

  // Initialize language options.
  //
  // FIXME: These aren't used during operations on ASTs. Split onto a separate
  // code path to make this obvious.
  if (LK != langkind_ast)
    InitializeLangOptions(Opts.getLangOpts(), LK, Target,
                          Opts.getCompileOpts());

  // Initialize the static analyzer options.
  InitializeAnalyzerOptions(Opts.getAnalyzerOpts());

  // Initialize the dependency output options (-M...).
  InitializeDependencyOutputOptions(Opts.getDependencyOutputOpts());

  // Initialize the header search options.
  InitializeHeaderSearchOptions(Opts.getHeaderSearchOpts(),
                                GetBuiltinIncludePath(Argv0),
                                Verbose,
                                Opts.getLangOpts());

  // Initialize the other preprocessor options.
  InitializePreprocessorOptions(Opts.getPreprocessorOpts());

  // Initialize the preprocessed output options.
  InitializePreprocessorOutputOptions(Opts.getPreprocessorOutputOpts());

  // Finalize some code generation options.
  FinalizeCompileOptions(Opts.getCompileOpts(), Opts.getLangOpts());
}

int main(int argc, char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm::LLVMContext &Context = llvm::getGlobalContext();

  // Initialize targets first, so that --version shows registered targets.
  llvm::InitializeAllTargets();
  llvm::InitializeAllAsmPrinters();

  llvm::cl::ParseCommandLineOptions(argc, argv,
                              "LLVM 'Clang' Compiler: http://clang.llvm.org\n");

  if (TimeReport)
    ClangFrontendTimer = new llvm::Timer("Clang front-end time");

  if (Verbose)
    llvm::errs() << "clang-cc version " CLANG_VERSION_STRING
                 << " based upon " << PACKAGE_STRING
                 << " hosted on " << llvm::sys::getHostTriple() << "\n";

  // If no input was specified, read from stdin.
  if (InputFilenames.empty())
    InputFilenames.push_back("-");

  // Construct the diagnostic options first, which cannot fail, so that we can
  // build a diagnostic client to use for any errors during option handling.
  DiagnosticOptions DiagOpts;
  InitializeDiagnosticOptions(DiagOpts);

  // Create the diagnostic client for reporting errors or for
  // implementing -verify.
  llvm::OwningPtr<DiagnosticClient> DiagClient;
  if (VerifyDiagnostics) {
    // When checking diagnostics, just buffer them up.
    DiagClient.reset(new TextDiagnosticBuffer());
    if (InputFilenames.size() != 1) {
      fprintf(stderr, "-verify only works on single input files.\n");
      return 1;
    }
  } else {
    DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), DiagOpts));
  }

  if (!DumpBuildInformation.empty())
    SetUpBuildDumpLog(DiagOpts, argc, argv, DiagClient);

  // Configure our handling of diagnostics.
  Diagnostic Diags(DiagClient.get());
  if (ProcessWarningOptions(Diags, OptWarnings, OptPedantic, OptPedanticErrors,
                            OptNoWarnings))
    return 1;

  // Set an error handler, so that any LLVM backend diagnostics go through our
  // error handler.
  llvm::llvm_install_error_handler(LLVMErrorHandler,
                                   static_cast<void*>(&Diags));

  // Initialize base triple.  If a -triple option has been specified, use
  // that triple.  Otherwise, default to the host triple.
  llvm::Triple Triple(TargetTriple);
  if (Triple.getTriple().empty())
    Triple = llvm::Triple(llvm::sys::getHostTriple());

  // Get information about the target being compiled for.
  llvm::OwningPtr<TargetInfo>
  Target(TargetInfo::CreateTargetInfo(Triple.getTriple()));

  if (Target == 0) {
    Diags.Report(diag::err_fe_unknown_triple) << Triple.getTriple().c_str();
    return 1;
  }

  // Set the target ABI if specified.
  if (!TargetABI.empty()) {
    if (!Target->setABI(TargetABI)) {
      Diags.Report(diag::err_fe_unknown_target_abi) << TargetABI;
      return 1;
    }
  }

  if (!InheritanceViewCls.empty())  // C++ visualization?
    ProgAction = InheritanceView;

  // Infer the input language.
  //
  // FIXME: We should move .ast inputs to taking a separate path, they are
  // really quite different.
  LangKind LK = GetLanguage();

  // Now that we have initialized the diagnostics engine and the target, finish
  // setting up the compiler invocation.
  CompilerInvocation CompOpts;
  ConstructCompilerInvocation(CompOpts, argv[0], DiagOpts, *Target, LK);

  // Create the source manager.
  SourceManager SourceMgr;

  // Create a file manager object to provide access to and cache the filesystem.
  FileManager FileMgr;

  for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
    const std::string &InFile = InputFilenames[i];

    // AST inputs are handled specially.
    if (LK == langkind_ast) {
      ProcessASTInputFile(CompOpts, InFile, ProgAction, Diags, FileMgr,
                          Context);
      continue;
    }

    // Reset the ID tables if we are reusing the SourceManager.
    if (i)
      SourceMgr.clearIDTables();

    // Set up the preprocessor with these options.
    llvm::OwningPtr<Preprocessor>
      PP(CreatePreprocessor(Diags, CompOpts.getLangOpts(),
                            CompOpts.getPreprocessorOpts(),
                            CompOpts.getHeaderSearchOpts(),
                            CompOpts.getDependencyOutputOpts(),
                            *Target, SourceMgr, FileMgr));

    // Process the source file.
    Diags.getClient()->BeginSourceFile(CompOpts.getLangOpts());
    ProcessInputFile(CompOpts, *PP, InFile, ProgAction, Context);
    Diags.getClient()->EndSourceFile();
  }

  if (CompOpts.getDiagnosticOpts().ShowCarets)
    if (unsigned NumDiagnostics = Diags.getNumDiagnostics())
      fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics,
              (NumDiagnostics == 1 ? "" : "s"));

  if (Stats) {
    FileMgr.PrintStats();
    fprintf(stderr, "\n");
  }

  delete ClangFrontendTimer;

  // If verifying diagnostics and we reached here, all is well.
  if (VerifyDiagnostics)
    return 0;

  // Managed static deconstruction. Useful for making things like
  // -time-passes usable.
  llvm::llvm_shutdown();

  return (Diags.getNumErrors() != 0);
}
