C++程序  |  103行  |  3.05 KB

#include <cassert>
#include <cstdlib>
#include <list>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Option.h"
#include "clang/Driver/OptTable.h"

#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"

#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"

#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"

#include "Compiler.h"

// FIXME: Add parameter feature '-D macro=xxx'
static llvm::cl::opt<std::string>
InputFilename(llvm::cl::Positional, llvm::cl::Required,
              llvm::cl::desc("<input file>"));

static llvm::cl::list<std::string>
HeaderSearchDirs("I", llvm::cl::desc("Header search directory"), llvm::cl::Prefix);

static llvm::cl::list<std::string>
PreDefinedSymbols("D", llvm::cl::desc("Pre-define symbol"));

static llvm::cl::opt<std::string>
OutputFilename(llvm::cl::Required, "o", llvm::cl::desc("Override output filename"));

// split "xxx"     => "xxx" ""
// split "xxx=yyy" => "xxx" "yyy"
static void splitPreDefinedSymbol(const std::string& In,
                             std::string& Key, std::string& Value) {
  size_t FoundPos = In.find("=");
  if (FoundPos == std::string::npos) {
    Key = In;
    Value = "";
  } else {
    Key = In.substr(0, FoundPos);
    Value = In.substr(FoundPos+1, std::string::npos);
  }
}


int main(int argc, char** argv) {
  llvm::llvm_shutdown_obj _ShutdownObj;
  llvm::cl::ParseCommandLineOptions(argc, argv, "P-NDK Compile Tool");

  clang::TextDiagnosticPrinter* DiagClient =
      new clang::TextDiagnosticPrinter(llvm::errs(), clang::DiagnosticOptions());
  DiagClient->setPrefix(argv[0]);

  llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs>
      DiagIDs(new clang::DiagnosticIDs());
  clang::Diagnostic Diags(DiagIDs, DiagClient, true);

  if (Diags.hasErrorOccurred())
    return 1;

  std::vector<std::string> IncludePaths;
  for(unsigned i = 0, e = HeaderSearchDirs.size(); i<e; ++i) {
    IncludePaths.push_back(HeaderSearchDirs[i]);
  }

  std::map<std::string, std::string> PreDefinedSymbolMap;
  for(unsigned i = 0, e = PreDefinedSymbols.size(); i<e; ++i) {
    std::string Key;
    std::string Value;
    splitPreDefinedSymbol(PreDefinedSymbols[i], Key, Value);
    PreDefinedSymbolMap.insert(
        std::pair<std::string, std::string>(Key,Value));
  }

  ndkpc::Compiler Compiler;
  Compiler.init(std::string(),
                std::string(),
                std::vector<std::string>(),
                llvm::StringRef(InputFilename).endswith(".cpp"));
  Compiler.setInputSource(InputFilename);
  Compiler.setIncludePaths(IncludePaths);
  Compiler.setOutput(OutputFilename.c_str());
  Compiler.setPreDefinedSymbol(PreDefinedSymbolMap);

  int ret = Compiler.compile();
  return ret;
}