int main()
{
  using clang::CompilerInstance;
  using clang::TargetOptions;
  using clang::TargetInfo;
  using clang::FileEntry;

  CompilerInstance ci;
  ci.createDiagnostics(0,NULL);

  TargetOptions to;
  to.Triple = llvm::sys::getDefaultTargetTriple();
  TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to);
  ci.setTarget(pti);

  ci.createFileManager();
  ci.createSourceManager(ci.getFileManager());
  ci.createPreprocessor();
  ci.getPreprocessorOpts().UsePredefines = false;
  MyASTConsumer *astConsumer = new MyASTConsumer();
  ci.setASTConsumer(astConsumer);

  ci.createASTContext();

  const FileEntry *pFile = ci.getFileManager().getFile("test.c");
  ci.getSourceManager().createMainFileID(pFile);
  ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(),
                                           &ci.getPreprocessor());
  clang::ParseAST(ci.getPreprocessor(), astConsumer, ci.getASTContext());
  ci.getDiagnosticClient().EndSourceFile();

  return 0;
}
예제 #2
0
파일: h2j.cpp 프로젝트: 5tivi/julia
int main()
{
    CompilerInstance ci;
    ci.createDiagnostics(0,NULL);

    TargetOptions to;
    to.Triple = llvm::sys::getDefaultTargetTriple();
    TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to);
    ci.setTarget(pti);

    ci.getHeaderSearchOpts().AddPath(
        StringRef("../usr/lib/clang/3.0/include"), frontend::Angled, false, false, false
    );
    ci.getHeaderSearchOpts().AddPath(
        StringRef("support"), frontend::Quoted, true, false, false
    );

    ci.createFileManager();
    ci.createSourceManager(ci.getFileManager());
    ci.createPreprocessor();
    PrintFunctionsConsumer *astConsumer = new PrintFunctionsConsumer();
    ci.setASTConsumer(astConsumer);

    ci.createASTContext();
    const FileEntry *pFile = ci.getFileManager().getFile("julia.h");
    ci.getSourceManager().createMainFileID(pFile);
    ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor());
    clang::ParseAST(ci.getPreprocessor(), astConsumer, ci.getASTContext());
    ci.getDiagnosticClient().EndSourceFile();

    return 0;
}
int main(int argc, char *argv[]) {
  if (argc != 2) {
    llvm::errs() << "Usage: rewritersample <filename>\n";
    return 1;
  }

  // CompilerInstance will hold the instance of the Clang compiler for us,
  // managing the various objects needed to run the compiler.
  CompilerInstance TheCompInst;
  TheCompInst.createDiagnostics();

  LangOptions &lo = TheCompInst.getLangOpts();
  lo.CPlusPlus = 1;

  // Initialize target info with the default triple for our platform.
  auto TO = std::make_shared<TargetOptions>();
  TO->Triple = llvm::sys::getDefaultTargetTriple();
  TargetInfo *TI =
      TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO);
  TheCompInst.setTarget(TI);

  TheCompInst.createFileManager();
  FileManager &FileMgr = TheCompInst.getFileManager();
  TheCompInst.createSourceManager(FileMgr);
  SourceManager &SourceMgr = TheCompInst.getSourceManager();
  TheCompInst.createPreprocessor(TU_Module);
  TheCompInst.createASTContext();

  // A Rewriter helps us manage the code rewriting task.
  Rewriter TheRewriter;
  TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts());

  // Set the main file handled by the source manager to the input file.
  const FileEntry *FileIn = FileMgr.getFile(argv[1]);
  SourceMgr.setMainFileID(
      SourceMgr.createFileID(FileIn, SourceLocation(), SrcMgr::C_User));
  TheCompInst.getDiagnosticClient().BeginSourceFile(
      TheCompInst.getLangOpts(), &TheCompInst.getPreprocessor());

  // Create an AST consumer instance which is going to get called by
  // ParseAST.
  MyASTConsumer TheConsumer(TheRewriter);

  // Parse the file to AST, registering our consumer as the AST consumer.
  ParseAST(TheCompInst.getPreprocessor(), &TheConsumer,
           TheCompInst.getASTContext());

  // At this point the rewriter's buffer should be full with the rewritten
  // file contents.
  const RewriteBuffer *RewriteBuf =
      TheRewriter.getRewriteBufferFor(SourceMgr.getMainFileID());
  llvm::outs() << std::string(RewriteBuf->begin(), RewriteBuf->end());

  return 0;
}
예제 #4
0
int main(int argc, char *argv[])
{
    if (argc != 2) {
        llvm::errs() << "Usage: rewritersample <filename>\n";
        return 1;
    }

    // CompilerInstance will hold the instance of the Clang compiler for us,
    // managing the various objects needed to run the compiler.
    CompilerInstance ci;
    ci.createDiagnostics(0, 0);

    // Initialize target info with the default triple for our platform.
    TargetOptions TO;
    TO.Triple = llvm::sys::getDefaultTargetTriple();
    TargetInfo *TI = TargetInfo::CreateTargetInfo(
        ci.getDiagnostics(), TO);
    ci.setTarget(TI);

    ci.createFileManager();
    FileManager &fm = ci.getFileManager();
    ci.createSourceManager(fm);
    SourceManager &SourceMgr = ci.getSourceManager();
    ci.createPreprocessor();
    ci.createASTContext();

    // A Rewriter helps us manage the code rewriting task.
    Rewriter rw;
    rw.setSourceMgr(SourceMgr, ci.getLangOpts());

    // Set the main file handled by the source manager to the input file.
    const FileEntry *fi = fm.getFile(argv[1]);
    SourceMgr.createMainFileID(fi);
    ci.getDiagnosticClient().BeginSourceFile(
        ci.getLangOpts(),
        &ci.getPreprocessor());

    // Create an AST consumer instance which is going to get called by
    // ParseAST.
    MyASTConsumer astc(rw);

    // Parse the file to AST, registering our consumer as the AST consumer.
    ParseAST(ci.getPreprocessor(), &astc,
             ci.getASTContext());

    // At this point the rewriter's buffer should be full with the rewritten
    // file contents.
    const RewriteBuffer *rwb =
        rw.getRewriteBufferFor(SourceMgr.getMainFileID());
    llvm::outs() << string(rwb->begin(), rwb->end());

    return 0;
}
예제 #5
0
파일: scaffold.cpp 프로젝트: hoangt/ScaffCC
int main(int argc, char *argv[]) {
    using clang::CompilerInstance;
    using clang::TargetOptions;
    using clang::TargetInfo;
    using clang::FileEntry;
    using clang::ASTConsumer;
    using clang::DiagnosticOptions;
    using clang::TextDiagnosticPrinter;

    CompilerInstance CI;
    DiagnosticOptions diagnosticOptions;
    TextDiagnosticPrinter *pTextDiagnosticPrinter =
        new TextDiagnosticPrinter(
        llvm::outs(), diagnosticOptions, true);
    CI.createDiagnostics(0, NULL, pTextDiagnosticPrinter);

    TargetOptions targetOptions;
    targetOptions.Triple = llvm::sys::getDefaultTargetTriple();
    TargetInfo *pTargetInfo = TargetInfo::CreateTargetInfo(
                                  CI.getDiagnostics(), targetOptions);
    CI.setTarget(pTargetInfo);

    CI.createFileManager();
    CI.createSourceManager(CI.getFileManager());
    CI.createPreprocessor();
    CI.getPreprocessorOpts().UsePredefines = false;
    ASTConsumer *astConsumer = new ASTConsumer();
    CI.setASTConsumer(astConsumer);

    CI.createASTContext();
    CI.createSema(clang::TU_Complete, NULL);

    const FileEntry *pFile = CI.getFileManager().getFile(argv[1]);
    CI.getSourceManager().createMainFileID(pFile);

    CI.getASTContext().BuiltinInfo.InitializeBuiltins(
        CI.getPreprocessor().getIdentifierTable(), CI.getLangOpts());

    CI.getDiagnosticClient().BeginSourceFile(
        CI.getLangOpts(), &(CI.getPreprocessor()));
    clang::ParseAST(CI.getSema());
    CI.getDiagnosticClient().EndSourceFile();

    return 0;
}
예제 #6
0
void checkVariables(string filename, vector<Issue>& lineIssues){
  // CompilerInstance will hold the instance of the Clang compiler for us,
  // managing the various objects needed to run the compiler.
  CompilerInstance TheCompInst;
  TheCompInst.createDiagnostics();

  CompilerInvocation TheCompInv;

  LangOptions &lo = TheCompInst.getLangOpts();
  lo.CPlusPlus = 1;
  lo.Bool = 1;
  lo.WChar = 1;
  lo.NoBuiltin = 0;

  // Initialize target info with the default triple for our platform.
  auto TO = std::make_shared<TargetOptions>();
  TO->Triple = llvm::sys::getDefaultTargetTriple();
  TargetInfo *TI =
      TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO);
  TheCompInst.setTarget(TI);

  TheCompInst.createFileManager();
  FileManager &FileMgr = TheCompInst.getFileManager();
  TheCompInst.createSourceManager(FileMgr);
  SourceManager &SourceMgr = TheCompInst.getSourceManager();
  TheCompInst.createPreprocessor(TU_Module);

  Preprocessor& pp = TheCompInst.getPreprocessor();

  pp.getBuiltinInfo().InitializeBuiltins(pp.getIdentifierTable(), lo);
                                          //pp.getLangOpts().NoBuiltin);

  TheCompInst.createASTContext();

  // Set the main file handled by the source manager to the input file.
  const FileEntry *FileIn = FileMgr.getFile(filename);
  SourceMgr.setMainFileID(
      SourceMgr.createFileID(FileIn, SourceLocation(), SrcMgr::C_User));
  TheCompInst.getDiagnosticClient().BeginSourceFile(
      TheCompInst.getLangOpts(), &TheCompInst.getPreprocessor());

  MyASTConsumer consm{lineIssues, SourceMgr};

  ParseAST(TheCompInst.getPreprocessor(), &consm, TheCompInst.getASTContext());
}
예제 #7
0
int main()
{
    using clang::CompilerInstance;
    using clang::TargetOptions;
    using clang::TargetInfo;
    using clang::FileEntry;
    using clang::Token;
    using clang::ASTContext;
    using clang::ASTConsumer;
    using clang::Parser;
    using clang::DiagnosticOptions;
    using clang::TextDiagnosticPrinter;

    CompilerInstance ci;
    DiagnosticOptions diagnosticOptions;
    ci.createDiagnostics();

    llvm::IntrusiveRefCntPtr<TargetOptions> pto( new TargetOptions());
    pto->Triple = llvm::sys::getDefaultTargetTriple();
    TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto.getPtr());
    ci.setTarget(pti);

    ci.createFileManager();
    ci.createSourceManager(ci.getFileManager());
#ifdef CLANG_3_5
    ci.createPreprocessor(clang::TU_Complete);
#else
    ci.createPreprocessor(); 
#endif
    ci.getPreprocessorOpts().UsePredefines = false;
    ASTConsumer *astConsumer = new ASTConsumer();
    ci.setASTConsumer(astConsumer);

    ci.createASTContext();
    ci.createSema(clang::TU_Complete, NULL);

	  const FileEntry *pFile = ci.getFileManager().getFile("test.c");
    ci.getSourceManager().createMainFileID(pFile);
    clang::ParseAST(ci.getSema());
    ci.getASTContext().Idents.PrintStats();

    return 0;
}
int
main(int argc, const char *argv[])
{
    struct stat sb;

    if (argc != 2)
    {
        std::cout << "Usage: ./PrintFunctionInfo <filename>" << std::endl;
        exit(1);
    }

    if (stat(argv[1], &sb) == -1)
    {
        perror(argv[1]);
        exit(EXIT_FAILURE);
    }

    CompilerInstance ci;
    ci.createDiagnostics(0,NULL);

    TargetOptions to;
    to.Triple = llvm::sys::getDefaultTargetTriple();
    TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to);
    ci.setTarget(pti);

    ci.createFileManager();
    ci.createSourceManager(ci.getFileManager());
    ci.createPreprocessor();
    ci.getPreprocessorOpts().UsePredefines = false;
    FunctionLocConsumer *astConsumer = new FunctionLocConsumer();
    ci.setASTConsumer(astConsumer);

    ci.createASTContext();

	const FileEntry *pFile = ci.getFileManager().getFile(argv[1]);
    ci.getSourceManager().createMainFileID(pFile);
    ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(),
                                             &ci.getPreprocessor());
    ParseAST(ci.getPreprocessor(), astConsumer, ci.getASTContext());
    ci.getDiagnosticClient().EndSourceFile();

    return 0;
}
예제 #9
0
int main()
{
    using clang::CompilerInstance;
    using clang::TargetOptions;
    using clang::TargetInfo;
    using clang::FileEntry;
    using clang::Token;
    using clang::ASTContext;
    using clang::ASTConsumer;
    using clang::Parser;

    CompilerInstance ci;
    ci.createDiagnostics(0,NULL);

    TargetOptions to;
    to.Triple = llvm::sys::getDefaultTargetTriple();
    TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), to);
    ci.setTarget(pti);

    ci.createFileManager();
    ci.createSourceManager(ci.getFileManager());
    ci.createPreprocessor();
    ci.getPreprocessorOpts().UsePredefines = false;
    ASTConsumer *astConsumer = new ASTConsumer();
    ci.setASTConsumer(astConsumer);

    ci.createASTContext();
    ci.createSema(clang::TU_Complete, NULL);

	const FileEntry *pFile = ci.getFileManager().getFile("test.c");
    ci.getSourceManager().createMainFileID(pFile);
    ci.getPreprocessor().EnterMainSourceFile();
    ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(),
                                             &ci.getPreprocessor());
    Parser parser(ci.getPreprocessor(), ci.getSema(), false /*skipFunctionBodies*/);
    parser.ParseTranslationUnit();
    ci.getDiagnosticClient().EndSourceFile();
    ci.getASTContext().Idents.PrintStats();

    return 0;
}
예제 #10
0
int main()
{
    using clang::CompilerInstance;
    using clang::TargetOptions;
    using clang::TargetInfo;
    using clang::FileEntry;
    using clang::Token;
    using clang::ASTContext;
    using clang::ASTConsumer;
    using clang::Parser;
    using clang::DiagnosticOptions;
    using clang::TextDiagnosticPrinter;

    CompilerInstance ci;
    DiagnosticOptions diagnosticOptions;
    ci.createDiagnostics();

    std::shared_ptr<clang::TargetOptions> pto = std::make_shared<clang::TargetOptions>();
    pto->Triple = llvm::sys::getDefaultTargetTriple();
    TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto);
    ci.setTarget(pti);

    ci.createFileManager();
    ci.createSourceManager(ci.getFileManager());
    ci.createPreprocessor(clang::TU_Complete);
    ci.getPreprocessorOpts().UsePredefines = false;

    ci.setASTConsumer(llvm::make_unique<ASTConsumer>());

    ci.createASTContext();
    ci.createSema(clang::TU_Complete, NULL);

    const FileEntry *pFile = ci.getFileManager().getFile("test.c");
    ci.getSourceManager().setMainFileID( ci.getSourceManager().createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User));
    clang::ParseAST(ci.getSema());
    ci.getASTContext().Idents.PrintStats();

    return 0;
}
예제 #11
0
bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                     llvm::StringRef Filename,
                                     bool IsAST) {
  assert(!Instance && "Already processing a source file!");
  assert(!Filename.empty() && "Unexpected empty filename!");
  setCurrentFile(Filename);
  setCompilerInstance(&CI);

  // AST files follow a very different path, since they share objects via the
  // AST unit.
  if (IsAST) {
    assert(!usesPreprocessorOnly() &&
           "Attempt to pass AST file to preprocessor only action!");
    assert(hasASTSupport() && "This action does not have AST support!");

    llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
    std::string Error;
    ASTUnit *AST = ASTUnit::LoadFromPCHFile(Filename, Diags);
    if (!AST)
      goto failure;

    setCurrentFile(Filename, AST);

    // Set the shared objects, these are reset when we finish processing the
    // file, otherwise the CompilerInstance will happily destroy them.
    CI.setFileManager(&AST->getFileManager());
    CI.setSourceManager(&AST->getSourceManager());
    CI.setPreprocessor(&AST->getPreprocessor());
    CI.setASTContext(&AST->getASTContext());

    // Initialize the action.
    if (!BeginSourceFileAction(CI, Filename))
      goto failure;

    /// Create the AST consumer.
    CI.setASTConsumer(CreateASTConsumer(CI, Filename));
    if (!CI.hasASTConsumer())
      goto failure;

    return true;
  }

  // Inform the diagnostic client we are processing a source file.
  CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
                                           &CI.getPreprocessor());

  // Initialize the action.
  if (!BeginSourceFileAction(CI, Filename))
    goto failure;

  /// Create the AST context and consumer unless this is a preprocessor only
  /// action.
  if (!usesPreprocessorOnly()) {
    CI.createASTContext();
    CI.setASTConsumer(CreateASTConsumer(CI, Filename));
    if (!CI.hasASTConsumer())
      goto failure;

    /// Use PCH?
    if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
      assert(hasPCHSupport() && "This action does not have PCH support!");
      CI.createPCHExternalASTSource(
        CI.getPreprocessorOpts().ImplicitPCHInclude);
      if (!CI.getASTContext().getExternalSource())
        goto failure;
    }
  }

  // Initialize builtin info as long as we aren't using an external AST
  // source.
  if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
    Preprocessor &PP = CI.getPreprocessor();
    PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOptions().NoBuiltin);
  }

  return true;

  // If we failed, reset state since the client will not end up calling the
  // matching EndSourceFile().
  failure:
  if (isCurrentFileAST()) {
    CI.takeASTContext();
    CI.takePreprocessor();
    CI.takeSourceManager();
    CI.takeFileManager();
  }

  CI.getDiagnosticClient().EndSourceFile();
  setCurrentFile("");
  setCompilerInstance(0);
  return false;
}
예제 #12
0
bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                     const FrontendInputFile &Input) {
  assert(!Instance && "Already processing a source file!");
  assert(!Input.isEmpty() && "Unexpected empty filename!");
  setCurrentInput(Input);
  setCompilerInstance(&CI);

  StringRef InputFile = Input.getFile();
  bool HasBegunSourceFile = false;
  if (!BeginInvocation(CI))
    goto failure;

  // AST files follow a very different path, since they share objects via the
  // AST unit.
  if (Input.getKind() == IK_AST) {
    assert(!usesPreprocessorOnly() &&
           "Attempt to pass AST file to preprocessor only action!");
    assert(hasASTFileSupport() &&
           "This action does not have AST file support!");

    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());

    std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
        InputFile, CI.getPCHContainerReader(), Diags, CI.getFileSystemOpts(),
        CI.getCodeGenOpts().DebugTypeExtRefs);

    if (!AST)
      goto failure;

    // Inform the diagnostic client we are processing a source file.
    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
    HasBegunSourceFile = true;

    // Set the shared objects, these are reset when we finish processing the
    // file, otherwise the CompilerInstance will happily destroy them.
    CI.setFileManager(&AST->getFileManager());
    CI.setSourceManager(&AST->getSourceManager());
    CI.setPreprocessor(AST->getPreprocessorPtr());
    CI.setASTContext(&AST->getASTContext());

    setCurrentInput(Input, std::move(AST));

    // Initialize the action.
    if (!BeginSourceFileAction(CI, InputFile))
      goto failure;

    // Create the AST consumer.
    CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));
    if (!CI.hasASTConsumer())
      goto failure;

    return true;
  }

  if (!CI.hasVirtualFileSystem()) {
    if (IntrusiveRefCntPtr<vfs::FileSystem> VFS =
          createVFSFromCompilerInvocation(CI.getInvocation(),
                                          CI.getDiagnostics()))
      CI.setVirtualFileSystem(VFS);
    else
      goto failure;
  }

  // Set up the file and source managers, if needed.
  if (!CI.hasFileManager())
    CI.createFileManager();
  if (!CI.hasSourceManager())
    CI.createSourceManager(CI.getFileManager());

  // IR files bypass the rest of initialization.
  if (Input.getKind() == IK_LLVM_IR) {
    assert(hasIRSupport() &&
           "This action does not have IR file support!");

    // Inform the diagnostic client we are processing a source file.
    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
    HasBegunSourceFile = true;

    // Initialize the action.
    if (!BeginSourceFileAction(CI, InputFile))
      goto failure;

    // Initialize the main file entry.
    if (!CI.InitializeSourceManager(CurrentInput))
      goto failure;

    return true;
  }

  // If the implicit PCH include is actually a directory, rather than
  // a single file, search for a suitable PCH file in that directory.
  if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
    FileManager &FileMgr = CI.getFileManager();
    PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
    StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
    std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
    if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) {
      std::error_code EC;
      SmallString<128> DirNative;
      llvm::sys::path::native(PCHDir->getName(), DirNative);
      bool Found = false;
      vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
      for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
           Dir != DirEnd && !EC; Dir.increment(EC)) {
        // Check whether this is an acceptable AST file.
        if (ASTReader::isAcceptableASTFile(
                Dir->getName(), FileMgr, CI.getPCHContainerReader(),
                CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(),
                SpecificModuleCachePath)) {
          PPOpts.ImplicitPCHInclude = Dir->getName();
          Found = true;
          break;
        }
      }

      if (!Found) {
        CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
        goto failure;
      }
    }
  }

  // Set up the preprocessor if needed. When parsing model files the
  // preprocessor of the original source is reused.
  if (!isModelParsingAction())
    CI.createPreprocessor(getTranslationUnitKind());

  // Inform the diagnostic client we are processing a source file.
  CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
                                           &CI.getPreprocessor());
  HasBegunSourceFile = true;

  // Initialize the action.
  if (!BeginSourceFileAction(CI, InputFile))
    goto failure;

  // Initialize the main file entry. It is important that this occurs after
  // BeginSourceFileAction, which may change CurrentInput during module builds.
  if (!CI.InitializeSourceManager(CurrentInput))
    goto failure;

  // Create the AST context and consumer unless this is a preprocessor only
  // action.
  if (!usesPreprocessorOnly()) {
    // Parsing a model file should reuse the existing ASTContext.
    if (!isModelParsingAction())
      CI.createASTContext();

    std::unique_ptr<ASTConsumer> Consumer =
        CreateWrappedASTConsumer(CI, InputFile);
    if (!Consumer)
      goto failure;

    // FIXME: should not overwrite ASTMutationListener when parsing model files?
    if (!isModelParsingAction())
      CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());

    if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
      // Convert headers to PCH and chain them.
      IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
      source = createChainedIncludesSource(CI, FinalReader);
      if (!source)
        goto failure;
      CI.setModuleManager(static_cast<ASTReader *>(FinalReader.get()));
      CI.getASTContext().setExternalSource(source);
    } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
      // Use PCH.
      assert(hasPCHSupport() && "This action does not have PCH support!");
      ASTDeserializationListener *DeserialListener =
          Consumer->GetASTDeserializationListener();
      bool DeleteDeserialListener = false;
      if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) {
        DeserialListener = new DeserializedDeclsDumper(DeserialListener,
                                                       DeleteDeserialListener);
        DeleteDeserialListener = true;
      }
      if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) {
        DeserialListener = new DeserializedDeclsChecker(
            CI.getASTContext(),
            CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
            DeserialListener, DeleteDeserialListener);
        DeleteDeserialListener = true;
      }
      CI.createPCHExternalASTSource(
          CI.getPreprocessorOpts().ImplicitPCHInclude,
          CI.getPreprocessorOpts().DisablePCHValidation,
          CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener,
          DeleteDeserialListener);
      if (!CI.getASTContext().getExternalSource())
        goto failure;
    }

    CI.setASTConsumer(std::move(Consumer));
    if (!CI.hasASTConsumer())
      goto failure;
  }

  // Initialize built-in info as long as we aren't using an external AST
  // source.
  if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
    Preprocessor &PP = CI.getPreprocessor();

    // If modules are enabled, create the module manager before creating
    // any builtins, so that all declarations know that they might be
    // extended by an external source.
    if (CI.getLangOpts().Modules)
      CI.createModuleManager();

    PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOpts());
  } else {
    // FIXME: If this is a problem, recover from it by creating a multiplex
    // source.
    assert((!CI.getLangOpts().Modules || CI.getModuleManager()) &&
           "modules enabled but created an external source that "
           "doesn't support modules");
  }

  // If we were asked to load any module map files, do so now.
  for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
    if (auto *File = CI.getFileManager().getFile(Filename))
      CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile(
          File, /*IsSystem*/false);
    else
      CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
  }

  // If we were asked to load any module files, do so now.
  for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles)
    if (!CI.loadModuleFile(ModuleFile))
      goto failure;

  // If there is a layout overrides file, attach an external AST source that
  // provides the layouts from that file.
  if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && 
      CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
    IntrusiveRefCntPtr<ExternalASTSource> 
      Override(new LayoutOverrideSource(
                     CI.getFrontendOpts().OverrideRecordLayoutsFile));
    CI.getASTContext().setExternalSource(Override);
  }

  return true;

  // If we failed, reset state since the client will not end up calling the
  // matching EndSourceFile().
  failure:
  if (isCurrentFileAST()) {
    CI.setASTContext(nullptr);
    CI.setPreprocessor(nullptr);
    CI.setSourceManager(nullptr);
    CI.setFileManager(nullptr);
  }

  if (HasBegunSourceFile)
    CI.getDiagnosticClient().EndSourceFile();
  CI.clearOutputFiles(/*EraseFiles=*/true);
  setCurrentInput(FrontendInputFile());
  setCompilerInstance(nullptr);
  return false;
}
예제 #13
0
bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                     llvm::StringRef Filename,
                                     InputKind InputKind) {
  assert(!Instance && "Already processing a source file!");
  assert(!Filename.empty() && "Unexpected empty filename!");
  setCurrentFile(Filename, InputKind);
  setCompilerInstance(&CI);

  if (!BeginInvocation(CI))
    goto failure;

  // AST files follow a very different path, since they share objects via the
  // AST unit.
  if (InputKind == IK_AST) {
    assert(!usesPreprocessorOnly() &&
           "Attempt to pass AST file to preprocessor only action!");
    assert(hasASTFileSupport() &&
           "This action does not have AST file support!");

    llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics());
    std::string Error;
    ASTUnit *AST = ASTUnit::LoadFromASTFile(Filename, Diags,
                                            CI.getFileSystemOpts());
    if (!AST)
      goto failure;

    setCurrentFile(Filename, InputKind, AST);

    // Set the shared objects, these are reset when we finish processing the
    // file, otherwise the CompilerInstance will happily destroy them.
    CI.setFileManager(&AST->getFileManager());
    CI.setSourceManager(&AST->getSourceManager());
    CI.setPreprocessor(&AST->getPreprocessor());
    CI.setASTContext(&AST->getASTContext());

    // Initialize the action.
    if (!BeginSourceFileAction(CI, Filename))
      goto failure;

    /// Create the AST consumer.
    CI.setASTConsumer(CreateWrappedASTConsumer(CI, Filename));
    if (!CI.hasASTConsumer())
      goto failure;

    return true;
  }

  // Set up the file and source managers, if needed.
  if (!CI.hasFileManager())
    CI.createFileManager();
  if (!CI.hasSourceManager())
    CI.createSourceManager(CI.getFileManager());

  // IR files bypass the rest of initialization.
  if (InputKind == IK_LLVM_IR) {
    assert(hasIRSupport() &&
           "This action does not have IR file support!");

    // Inform the diagnostic client we are processing a source file.
    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);

    // Initialize the action.
    if (!BeginSourceFileAction(CI, Filename))
      goto failure;

    return true;
  }

  // Set up the preprocessor.
  CI.createPreprocessor();

  // Inform the diagnostic client we are processing a source file.
  CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
                                           &CI.getPreprocessor());

  // Initialize the action.
  if (!BeginSourceFileAction(CI, Filename))
    goto failure;

  /// Create the AST context and consumer unless this is a preprocessor only
  /// action.
  if (!usesPreprocessorOnly()) {
    CI.createASTContext();

    llvm::OwningPtr<ASTConsumer> Consumer(
        CreateWrappedASTConsumer(CI, Filename));
    if (!Consumer)
      goto failure;

    CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());

    if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
      // Convert headers to PCH and chain them.
      llvm::OwningPtr<ExternalASTSource> source;
      source.reset(ChainedIncludesSource::create(CI));
      if (!source)
        goto failure;
      CI.getASTContext().setExternalSource(source);

    } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
      // Use PCH.
      assert(hasPCHSupport() && "This action does not have PCH support!");
      ASTDeserializationListener *DeserialListener
          = CI.getInvocation().getFrontendOpts().ChainedPCH ?
                  Consumer->GetASTDeserializationListener() : 0;
      if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls)
        DeserialListener = new DeserializedDeclsDumper(DeserialListener);
      if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty())
        DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(),
                         CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
                                                        DeserialListener);
      CI.createPCHExternalASTSource(
                                CI.getPreprocessorOpts().ImplicitPCHInclude,
                                CI.getPreprocessorOpts().DisablePCHValidation,
                                CI.getPreprocessorOpts().DisableStatCache,
                                DeserialListener);
      if (!CI.getASTContext().getExternalSource())
        goto failure;
    }

    CI.setASTConsumer(Consumer.take());
    if (!CI.hasASTConsumer())
      goto failure;
  }

  // Initialize builtin info as long as we aren't using an external AST
  // source.
  if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
    Preprocessor &PP = CI.getPreprocessor();
    PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOptions());
  }

  return true;

  // If we failed, reset state since the client will not end up calling the
  // matching EndSourceFile().
  failure:
  if (isCurrentFileAST()) {
    CI.setASTContext(0);
    CI.setPreprocessor(0);
    CI.setSourceManager(0);
    CI.setFileManager(0);
  }

  CI.getDiagnosticClient().EndSourceFile();
  setCurrentFile("", IK_None);
  setCompilerInstance(0);
  return false;
}
예제 #14
0
//使用的格式:  ./checkMemory 被测试文件名 --
int main(int argc,const char **argv) {

	//----此块基本一样    start----
    struct stat sb;             

    //set compilerinstance for rewriter		
	std::string fileName(argv[1]);
	if (stat(fileName.c_str(), &sb) == -1){
        perror(fileName.c_str());
        exit(EXIT_FAILURE);
    }

	
	CompilerInstance compiler;
	DiagnosticOptions diagnosticOptions;
	compiler.createDiagnostics();


	//invocation可以传递任何flag给preprocessor
	CompilerInvocation *Invocation = new CompilerInvocation;

	CompilerInvocation::CreateFromArgs(*Invocation, argv + 1, argv + argc-1,compiler.getDiagnostics());

	compiler.setInvocation(Invocation);


	//建立TargetOptions和TargetInfo,并设置好Target
	// Set default target triple
	llvm::IntrusiveRefCntPtr<TargetOptions> pto( new TargetOptions());
	pto->Triple = llvm::sys::getDefaultTargetTriple();
	llvm::IntrusiveRefCntPtr<TargetInfo>
	 pti(TargetInfo::CreateTargetInfo(compiler.getDiagnostics(),
		                              pto.getPtr()));
	compiler.setTarget(pti.getPtr());

	//FileManager,SourceManager 以及heaDREearch的Options的设置
	compiler.createFileManager();
	compiler.createSourceManager(compiler.getFileManager());

	HeaderSearchOptions &headerSearchOptions = compiler.getHeaderSearchOpts();
	headerSearchOptions.AddPath("/usr/include/c++",
		  clang::frontend::Angled,
		  false,
		  false);
	
    headerSearchOptions.AddPath("/usr/local/lib/clang/3.5.0/include",
          clang::frontend::Angled,
          false,
          false);
    headerSearchOptions.AddPath("/usr/include/i386-linux-gnu",
          clang::frontend::Angled,
          false,
          false);
    headerSearchOptions.AddPath("/usr/include",
          clang::frontend::Angled,
          false,
          false);
	
    
    
/*
    headerSearchOptions.AddPath("/usr/include",
          clang::frontend::Angled,
          false,
          false);
	*/
	//langOptions设置,要传给rewriter
   	LangOptions langOpts;
	langOpts.GNUMode = 1; 
	langOpts.CXXExceptions = 1; 
	langOpts.RTTI = 1; 
	langOpts.Bool = 1; 
	langOpts.CPlusPlus = 1; 
	Invocation->setLangDefaults(langOpts, clang::IK_CXX,clang::LangStandard::lang_cxx0x);

	//create PP
	compiler.createPreprocessor();//(TU_Complete);//
	compiler.getPreprocessorOpts().UsePredefines = false;
	//createASTContext
	compiler.createASTContext();
  
 	//set the sourceManager for rewriter 

	
	rewrite.setSourceMgr(compiler.getSourceManager(), compiler.getLangOpts());
	
	//插装文件入口

	const FileEntry *pFile = compiler.getFileManager().getFile(fileName);
	compiler.getSourceManager().createMainFileID(pFile);
	compiler.getDiagnosticClient().BeginSourceFile(compiler.getLangOpts(),&compiler.getPreprocessor());
	                                        
	
	MyASTConsumer astConsumer(rewrite);
	//将.c转成_out.c
	// Convert <file>.c to <file_out>.c
	std::string outName (fileName);
	/*size_t ext = outName.rfind(".");
	//根据有没有找到‘。’来决定在哪里加入_out
	if (ext == std::string::npos)
		ext = outName.length();
	outName.insert(ext, "_out");
	*/
	outName.insert(outName.length(),"_out");
	llvm::errs() << "Output to: " << outName << "\n";
	
	std::string OutErrorInfo;
	//新建输入到新文件的流
	llvm::raw_fd_ostream outFile(outName.c_str(), OutErrorInfo);//,llvm::sys::fs::F_None);//版本问题//////


	//----此块基本一样    end----

	if (OutErrorInfo.empty()){
		// Parse the AST
		//用PP,astConsumer,ASTContext来解释AST
		ParseAST(compiler.getPreprocessor(), &astConsumer, compiler.getASTContext());
		compiler.getDiagnosticClient().EndSourceFile();
    
		//建立ClangTool 
        CommonOptionsParser OptionsParser(argc, argv);//, MyToolCategory);
        ClangTool Tool(OptionsParser.getCompilations(),
                 OptionsParser.getSourcePathList());
		//开始匹配             
        
        MallocVarPrinter mallocVarPrinter;
        MatchFinder mallocVarFinder;
        mallocVarFinder.addMatcher(MallocVarMatcher, &mallocVarPrinter);
        Tool.run(newFrontendActionFactory(&mallocVarFinder));
        
        MallocPrinter mallocPrinter;
        MatchFinder mallocFinder;
        mallocFinder.addMatcher(MallocMatcher, &mallocPrinter);
        Tool.run(newFrontendActionFactory(&mallocFinder));
        
        FreeVarPrinter freeVarPrinter;
        MatchFinder freeVarFinder;
        freeVarFinder.addMatcher(FreeVarMatcher, &freeVarPrinter);
        Tool.run(newFrontendActionFactory(&freeVarFinder));
        
        FreePrinter freePrinter;
        MatchFinder freeFinder;
        freeFinder.addMatcher(FreeMatcher, &freePrinter);
        Tool.run(newFrontendActionFactory(&freeFinder));
   
    
                  
    	const RewriteBuffer *RewriteBuf =rewrite.getRewriteBufferFor(compiler.getSourceManager().getMainFileID());
		
        if(RewriteBuf != NULL){
            #ifdef DEBUG
            llvm::errs() << " RewriteBuf not NULL \n";
			//在文件头加上改头文件,防止没有 stdlib,stdio 而不能使用printf和exit函数
		    #endif
			outFile << "#include\"plugHead.h\"\n";
            
            outFile << std::string(RewriteBuf->begin(), RewriteBuf->end());		
        }else{
            #ifdef DEBUG
            llvm::errs() << " RewriteBuf is NULL \n";
			#endif

        	outFile << "#include\"plugHead.h\"\n";
            std::ifstream infile(fileName.c_str());
            if(!infile){
                llvm::errs() << " fail to open the input file!\n";
                exit(-1);                
            }
            std::string str_in;
            while(std::getline(infile,str_in)){
                outFile << str_in <<"\n";
            }
        
        }
        outFile.close();


        #ifdef DEBUG        
        std::string checkStructErrorInfo;
        std::string checkStructFileName = "checkStruct.txt";
        //新建输入到新文件的流,将已经找到的malloc过的结构体信息写入文件,供另一个处理程序读取
        llvm::raw_fd_ostream csFile(checkStructFileName.c_str(),checkStructErrorInfo);//,llvm::sys::fs::F_None);
        if (checkStructErrorInfo.empty()){
      	    for(unsigned int i=0;i<cpVec.size();++i){            
    	        csFile << cpVec[i].name << " " << cpVec[i].row << " " << cpVec[i].col << " " << cpVec[i].declName << " " << cpVec[i].declRow << " " << cpVec[i].declCol << "\n" ;
	        }            
        }
	    csFile.close();  
        for(unsigned int i=0;i<cpVec.size();++i){
	        llvm::errs()<<cpVec[i].name<<"|"<<cpVec[i].declName<<":"<<cpVec[i].declRow<<":"<<cpVec[i].declCol<<"\n";  
	    }	
        #endif
	    
	}
	else{
		llvm::errs() << "Cannot open " << outName << " for writing\n";
	}
	

      
    return 0;
}
예제 #15
0
int main(int argc, char *argv[])
{
#if 0
    vector<string> args;
    args.push_back("tool-executable");
    for (int i = 1; i < argc; ++i) {
        args.push_back(argv[i]);
    }
    parse_with_tool(args);
    return 0;
#endif
    string user_defines;
    for (int i = 1; i < argc; ++i) {
        if (argv[i][0] == '-' && argv[i][1] == 'D') {
            user_defines += "#define ";
            char *def = argv[i]+2;
            char* eq_pos = strchr(def, '=');
            if (eq_pos) {
                user_defines += string(def, eq_pos - def);
                user_defines += " ";
                user_defines += string(def+1);
            } else {
                user_defines += string(def);
            }
            user_defines += "\n";
        }
    }


    if (argc < 2) {
        llvm::errs() << "Usage: mkapi filename [-Ddefine1 -Ddefine2...]\n";
        return 1;
    }

    string file(argv[1]);

    // CompilerInstance will hold the instance of the Clang compiler for us,
    // managing the various objects needed to run the compiler.
    CompilerInstance TheCompInst;
    TheCompInst.createDiagnostics(0, true); //() for clang3.3, (0,0) for clang3.2

    // Initialize target info with the default triple for our platform.
    TargetOptions *TO = new TargetOptions(); //TODO: why on stack crash when dtor called
    TO->Triple = llvm::sys::getDefaultTargetTriple();
    TargetInfo *TI = TargetInfo::CreateTargetInfo(
        TheCompInst.getDiagnostics(), TO);
    TheCompInst.setTarget(TI);

    TheCompInst.createFileManager();
    FileManager &FileMgr = TheCompInst.getFileManager();
    TheCompInst.createSourceManager(FileMgr);
    SourceManager &SourceMgr = TheCompInst.getSourceManager();
    TheCompInst.createPreprocessor();
    TheCompInst.createASTContext();

    if (!user_defines.empty()) {
        clang::Preprocessor &PP = TheCompInst.getPreprocessor();
        PP.setPredefines(PP.getPredefines() + user_defines);
    }


    //cout << "predefines: " << TheCompInst.getPreprocessor().getPredefines() << endl;
    // A Rewriter helps us manage the code rewriting task.
    Rewriter TheRewriter;
    TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts());

    // Set the main file handled by the source manager to the input file.
    const FileEntry *FileIn = FileMgr.getFile(file);
    SourceMgr.createMainFileID(FileIn);
    TheCompInst.getDiagnosticClient().BeginSourceFile(
        TheCompInst.getLangOpts(),
        &TheCompInst.getPreprocessor());

    // Create an AST consumer instance which is going to get called by
    // ParseAST.
    MkApiASTConsumer TheConsumer(TheRewriter);

    // Parse the file to AST, registering our consumer as the AST consumer.
    ParseAST(TheCompInst.getPreprocessor(), &TheConsumer,
             TheCompInst.getASTContext()
             , clang::TU_Complete);

    // At this point the rewriter's buffer should be full with the rewritten
    // file contents.
#if 0
    const RewriteBuffer *RewriteBuf =
        TheRewriter.getRewriteBufferFor(SourceMgr.getMainFileID());
    llvm::outs() << string(RewriteBuf->begin(), RewriteBuf->end());
#endif

    std::vector<func_info> fi = TheConsumer.GetFuncInfo();
    stringstream stream;
    for (std::vector<func_info>::const_iterator it = fi.begin(); it != fi.end(); ++it) {
        std::vector<std::string> params = (*it).argv;
        stream << "DEFINE_DLLAPI_ARG(" << params.size() << ", " << (*it).return_type << ", " << (*it).name;
        for (int i = 0; i < params.size(); ++i) {
            stream << ", " << params[i];
        }
        stream << ")" << endl;
    }
    
    cout << stream.str() << endl;
    return 0;
}
예제 #16
0
bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                     const FrontendInputFile &RealInput) {
  FrontendInputFile Input(RealInput);
  assert(!Instance && "Already processing a source file!");
  assert(!Input.isEmpty() && "Unexpected empty filename!");
  setCurrentInput(Input);
  setCompilerInstance(&CI);

  StringRef InputFile = Input.getFile();
  bool HasBegunSourceFile = false;
  bool ReplayASTFile = Input.getKind().getFormat() == InputKind::Precompiled &&
                       usesPreprocessorOnly();
  if (!BeginInvocation(CI))
    goto failure;

  // If we're replaying the build of an AST file, import it and set up
  // the initial state from its build.
  if (ReplayASTFile) {
    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());

    // The AST unit populates its own diagnostics engine rather than ours.
    IntrusiveRefCntPtr<DiagnosticsEngine> ASTDiags(
        new DiagnosticsEngine(Diags->getDiagnosticIDs(),
                              &Diags->getDiagnosticOptions()));
    ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false);

    std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
        InputFile, CI.getPCHContainerReader(), ASTUnit::LoadPreprocessorOnly,
        ASTDiags, CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs);
    if (!AST)
      goto failure;

    // Options relating to how we treat the input (but not what we do with it)
    // are inherited from the AST unit.
    CI.getHeaderSearchOpts() = AST->getHeaderSearchOpts();
    CI.getPreprocessorOpts() = AST->getPreprocessorOpts();
    CI.getLangOpts() = AST->getLangOpts();

    // Set the shared objects, these are reset when we finish processing the
    // file, otherwise the CompilerInstance will happily destroy them.
    CI.setFileManager(&AST->getFileManager());
    CI.createSourceManager(CI.getFileManager());
    CI.getSourceManager().initializeForReplay(AST->getSourceManager());

    // Preload all the module files loaded transitively by the AST unit. Also
    // load all module map files that were parsed as part of building the AST
    // unit.
    if (auto ASTReader = AST->getASTReader()) {
      auto &MM = ASTReader->getModuleManager();
      auto &PrimaryModule = MM.getPrimaryModule();

      for (ModuleFile &MF : MM)
        if (&MF != &PrimaryModule)
          CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName);

      ASTReader->visitTopLevelModuleMaps(PrimaryModule,
                                         [&](const FileEntry *FE) {
        CI.getFrontendOpts().ModuleMapFiles.push_back(FE->getName());
      });
    }

    // Set up the input file for replay purposes.
    auto Kind = AST->getInputKind();
    if (Kind.getFormat() == InputKind::ModuleMap) {
      Module *ASTModule =
          AST->getPreprocessor().getHeaderSearchInfo().lookupModule(
              AST->getLangOpts().CurrentModule, /*AllowSearch*/ false);
      assert(ASTModule && "module file does not define its own module");
      Input = FrontendInputFile(ASTModule->PresumedModuleMapFile, Kind);
    } else {
      auto &SM = CI.getSourceManager();
      FileID ID = SM.getMainFileID();
      if (auto *File = SM.getFileEntryForID(ID))
        Input = FrontendInputFile(File->getName(), Kind);
      else
        Input = FrontendInputFile(SM.getBuffer(ID), Kind);
    }
    setCurrentInput(Input, std::move(AST));
  }

  // AST files follow a very different path, since they share objects via the
  // AST unit.
  if (Input.getKind().getFormat() == InputKind::Precompiled) {
    assert(!usesPreprocessorOnly() && "this case was handled above");
    assert(hasASTFileSupport() &&
           "This action does not have AST file support!");

    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());

    std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
        InputFile, CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags,
        CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs);

    if (!AST)
      goto failure;

    // Inform the diagnostic client we are processing a source file.
    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
    HasBegunSourceFile = true;

    // Set the shared objects, these are reset when we finish processing the
    // file, otherwise the CompilerInstance will happily destroy them.
    CI.setFileManager(&AST->getFileManager());
    CI.setSourceManager(&AST->getSourceManager());
    CI.setPreprocessor(AST->getPreprocessorPtr());
    Preprocessor &PP = CI.getPreprocessor();
    PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOpts());
    CI.setASTContext(&AST->getASTContext());

    setCurrentInput(Input, std::move(AST));

    // Initialize the action.
    if (!BeginSourceFileAction(CI))
      goto failure;

    // Create the AST consumer.
    CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));
    if (!CI.hasASTConsumer())
      goto failure;

    return true;
  }

  // Set up the file and source managers, if needed.
  if (!CI.hasFileManager()) {
    if (!CI.createFileManager()) {
      goto failure;
    }
  }
  if (!CI.hasSourceManager())
    CI.createSourceManager(CI.getFileManager());

  // Set up embedding for any specified files. Do this before we load any
  // source files, including the primary module map for the compilation.
  for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
    if (const auto *FE = CI.getFileManager().getFile(F, /*openFile*/true))
      CI.getSourceManager().setFileIsTransient(FE);
    else
      CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
  }
  if (CI.getFrontendOpts().ModulesEmbedAllFiles)
    CI.getSourceManager().setAllFilesAreTransient(true);

  // IR files bypass the rest of initialization.
  if (Input.getKind().getLanguage() == InputKind::LLVM_IR) {
    assert(hasIRSupport() &&
           "This action does not have IR file support!");

    // Inform the diagnostic client we are processing a source file.
    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
    HasBegunSourceFile = true;

    // Initialize the action.
    if (!BeginSourceFileAction(CI))
      goto failure;

    // Initialize the main file entry.
    if (!CI.InitializeSourceManager(CurrentInput))
      goto failure;

    return true;
  }

  // If the implicit PCH include is actually a directory, rather than
  // a single file, search for a suitable PCH file in that directory.
  if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
    FileManager &FileMgr = CI.getFileManager();
    PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
    StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
    std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
    if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) {
      std::error_code EC;
      SmallString<128> DirNative;
      llvm::sys::path::native(PCHDir->getName(), DirNative);
      bool Found = false;
      vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
      for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
           Dir != DirEnd && !EC; Dir.increment(EC)) {
        // Check whether this is an acceptable AST file.
        if (ASTReader::isAcceptableASTFile(
                Dir->getName(), FileMgr, CI.getPCHContainerReader(),
                CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(),
                SpecificModuleCachePath)) {
          PPOpts.ImplicitPCHInclude = Dir->getName();
          Found = true;
          break;
        }
      }

      if (!Found) {
        CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
        goto failure;
      }
    }
  }

  // Set up the preprocessor if needed. When parsing model files the
  // preprocessor of the original source is reused.
  if (!isModelParsingAction())
    CI.createPreprocessor(getTranslationUnitKind());

  // Inform the diagnostic client we are processing a source file.
  CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
                                           &CI.getPreprocessor());
  HasBegunSourceFile = true;

  // Initialize the main file entry.
  if (!CI.InitializeSourceManager(Input))
    goto failure;

  // For module map files, we first parse the module map and synthesize a
  // "<module-includes>" buffer before more conventional processing.
  if (Input.getKind().getFormat() == InputKind::ModuleMap) {
    CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);

    std::string PresumedModuleMapFile;
    unsigned OffsetToContents;
    if (loadModuleMapForModuleBuild(CI, Input.isSystem(),
                                    Input.isPreprocessed(),
                                    PresumedModuleMapFile, OffsetToContents))
      goto failure;

    auto *CurrentModule = prepareToBuildModule(CI, Input.getFile());
    if (!CurrentModule)
      goto failure;

    CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;

    if (OffsetToContents)
      // If the module contents are in the same file, skip to them.
      CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true);
    else {
      // Otherwise, convert the module description to a suitable input buffer.
      auto Buffer = getInputBufferForModule(CI, CurrentModule);
      if (!Buffer)
        goto failure;

      // Reinitialize the main file entry to refer to the new input.
      auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
      auto &SourceMgr = CI.getSourceManager();
      auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);
      assert(BufferID.isValid() && "couldn't creaate module buffer ID");
      SourceMgr.setMainFileID(BufferID);
    }
  }

  // Initialize the action.
  if (!BeginSourceFileAction(CI))
    goto failure;

  // If we were asked to load any module map files, do so now.
  for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
    if (auto *File = CI.getFileManager().getFile(Filename))
      CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile(
          File, /*IsSystem*/false);
    else
      CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
  }

  // Add a module declaration scope so that modules from -fmodule-map-file
  // arguments may shadow modules found implicitly in search paths.
  CI.getPreprocessor()
      .getHeaderSearchInfo()
      .getModuleMap()
      .finishModuleDeclarationScope();

  // Create the AST context and consumer unless this is a preprocessor only
  // action.
  if (!usesPreprocessorOnly()) {
    // Parsing a model file should reuse the existing ASTContext.
    if (!isModelParsingAction())
      CI.createASTContext();

    // For preprocessed files, check if the first line specifies the original
    // source file name with a linemarker.
    std::string PresumedInputFile = InputFile;
    if (Input.isPreprocessed())
      ReadOriginalFileName(CI, PresumedInputFile);

    std::unique_ptr<ASTConsumer> Consumer =
        CreateWrappedASTConsumer(CI, PresumedInputFile);
    if (!Consumer)
      goto failure;

    // FIXME: should not overwrite ASTMutationListener when parsing model files?
    if (!isModelParsingAction())
      CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());

    if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
      // Convert headers to PCH and chain them.
      IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
      source = createChainedIncludesSource(CI, FinalReader);
      if (!source)
        goto failure;
      CI.setModuleManager(static_cast<ASTReader *>(FinalReader.get()));
      CI.getASTContext().setExternalSource(source);
    } else if (CI.getLangOpts().Modules ||
               !CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
      // Use PCM or PCH.
      assert(hasPCHSupport() && "This action does not have PCH support!");
      ASTDeserializationListener *DeserialListener =
          Consumer->GetASTDeserializationListener();
      bool DeleteDeserialListener = false;
      if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) {
        DeserialListener = new DeserializedDeclsDumper(DeserialListener,
                                                       DeleteDeserialListener);
        DeleteDeserialListener = true;
      }
      if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) {
        DeserialListener = new DeserializedDeclsChecker(
            CI.getASTContext(),
            CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
            DeserialListener, DeleteDeserialListener);
        DeleteDeserialListener = true;
      }
      if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
        CI.createPCHExternalASTSource(
            CI.getPreprocessorOpts().ImplicitPCHInclude,
            CI.getPreprocessorOpts().DisablePCHValidation,
          CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener,
            DeleteDeserialListener);
        if (!CI.getASTContext().getExternalSource())
          goto failure;
      }
      // If modules are enabled, create the module manager before creating
      // any builtins, so that all declarations know that they might be
      // extended by an external source.
      if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
          !CI.getASTContext().getExternalSource()) {
        CI.createModuleManager();
        CI.getModuleManager()->setDeserializationListener(DeserialListener,
                                                        DeleteDeserialListener);
      }
    }

    CI.setASTConsumer(std::move(Consumer));
    if (!CI.hasASTConsumer())
      goto failure;
  }

  // Initialize built-in info as long as we aren't using an external AST
  // source.
  if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
      !CI.getASTContext().getExternalSource()) {
    Preprocessor &PP = CI.getPreprocessor();
    PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOpts());
  } else {
    // FIXME: If this is a problem, recover from it by creating a multiplex
    // source.
    assert((!CI.getLangOpts().Modules || CI.getModuleManager()) &&
           "modules enabled but created an external source that "
           "doesn't support modules");
  }

  // If we were asked to load any module files, do so now.
  for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles)
    if (!CI.loadModuleFile(ModuleFile))
      goto failure;

  // If there is a layout overrides file, attach an external AST source that
  // provides the layouts from that file.
  if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
      CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
    IntrusiveRefCntPtr<ExternalASTSource>
      Override(new LayoutOverrideSource(
                     CI.getFrontendOpts().OverrideRecordLayoutsFile));
    CI.getASTContext().setExternalSource(Override);
  }

  return true;

  // If we failed, reset state since the client will not end up calling the
  // matching EndSourceFile().
failure:
  if (HasBegunSourceFile)
    CI.getDiagnosticClient().EndSourceFile();
  CI.clearOutputFiles(/*EraseFiles=*/true);
  CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
  setCurrentInput(FrontendInputFile());
  setCompilerInstance(nullptr);
  return false;
}
예제 #17
0
bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                     const FrontendInputFile &Input) {
  assert(!Instance && "Already processing a source file!");
  assert(!Input.isEmpty() && "Unexpected empty filename!");
  setCurrentInput(Input);
  setCompilerInstance(&CI);

  StringRef InputFile = Input.getFile();
  bool HasBegunSourceFile = false;
  if (!BeginInvocation(CI))
    goto failure;

  // AST files follow a very different path, since they share objects via the
  // AST unit.
  if (Input.getKind() == IK_AST) {
    assert(!usesPreprocessorOnly() &&
           "Attempt to pass AST file to preprocessor only action!");
    assert(hasASTFileSupport() &&
           "This action does not have AST file support!");

    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());

    ASTUnit *AST = ASTUnit::LoadFromASTFile(InputFile, Diags,
                                            CI.getFileSystemOpts());
    if (!AST)
      goto failure;

    setCurrentInput(Input, AST);

    // Inform the diagnostic client we are processing a source file.
    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
    HasBegunSourceFile = true;

    // Set the shared objects, these are reset when we finish processing the
    // file, otherwise the CompilerInstance will happily destroy them.
    CI.setFileManager(&AST->getFileManager());
    CI.setSourceManager(&AST->getSourceManager());
    CI.setPreprocessor(&AST->getPreprocessor());
    CI.setASTContext(&AST->getASTContext());

    // Initialize the action.
    if (!BeginSourceFileAction(CI, InputFile))
      goto failure;

    // Create the AST consumer.
    CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));
    if (!CI.hasASTConsumer())
      goto failure;

    return true;
  }

  // Set up the file and source managers, if needed.
  if (!CI.hasFileManager())
    CI.createFileManager();
  if (!CI.hasSourceManager())
    CI.createSourceManager(CI.getFileManager());

  // IR files bypass the rest of initialization.
  if (Input.getKind() == IK_LLVM_IR) {
    assert(hasIRSupport() &&
           "This action does not have IR file support!");

    // Inform the diagnostic client we are processing a source file.
    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
    HasBegunSourceFile = true;

    // Initialize the action.
    if (!BeginSourceFileAction(CI, InputFile))
      goto failure;

    return true;
  }

  // If the implicit PCH include is actually a directory, rather than
  // a single file, search for a suitable PCH file in that directory.
  if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
    FileManager &FileMgr = CI.getFileManager();
    PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
    StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
    if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) {
      llvm::error_code EC;
      SmallString<128> DirNative;
      llvm::sys::path::native(PCHDir->getName(), DirNative);
      bool Found = false;
      for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
           Dir != DirEnd && !EC; Dir.increment(EC)) {
        // Check whether this is an acceptable AST file.
        if (ASTReader::isAcceptableASTFile(Dir->path(), FileMgr,
                                           CI.getLangOpts(),
                                           CI.getTargetOpts(),
                                           CI.getPreprocessorOpts())) {
          PPOpts.ImplicitPCHInclude = Dir->path();
          Found = true;
          break;
        }
      }

      if (!Found) {
        CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
        return true;
      }
    }
  }

  // Set up the preprocessor.
  CI.createPreprocessor();

  // Inform the diagnostic client we are processing a source file.
  CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
                                           &CI.getPreprocessor());
  HasBegunSourceFile = true;

  // Initialize the action.
  if (!BeginSourceFileAction(CI, InputFile))
    goto failure;

  // Create the AST context and consumer unless this is a preprocessor only
  // action.
  if (!usesPreprocessorOnly()) {
    CI.createASTContext();

    OwningPtr<ASTConsumer> Consumer(
                                   CreateWrappedASTConsumer(CI, InputFile));
    if (!Consumer)
      goto failure;

    CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
    
    if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
      // Convert headers to PCH and chain them.
      OwningPtr<ExternalASTSource> source;
      source.reset(ChainedIncludesSource::create(CI));
      if (!source)
        goto failure;
      CI.setModuleManager(static_cast<ASTReader*>(
         &static_cast<ChainedIncludesSource*>(source.get())->getFinalReader()));
      CI.getASTContext().setExternalSource(source);

    } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
      // Use PCH.
      assert(hasPCHSupport() && "This action does not have PCH support!");
      ASTDeserializationListener *DeserialListener =
          Consumer->GetASTDeserializationListener();
      if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls)
        DeserialListener = new DeserializedDeclsDumper(DeserialListener);
      if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty())
        DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(),
                         CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
                                                        DeserialListener);
      CI.createPCHExternalASTSource(
                                CI.getPreprocessorOpts().ImplicitPCHInclude,
                                CI.getPreprocessorOpts().DisablePCHValidation,
                            CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
                                DeserialListener);
      if (!CI.getASTContext().getExternalSource())
        goto failure;
    }

    CI.setASTConsumer(Consumer.take());
    if (!CI.hasASTConsumer())
      goto failure;
  }

  // Initialize built-in info as long as we aren't using an external AST
  // source.
  if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
    Preprocessor &PP = CI.getPreprocessor();
    PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOpts());
  }

  // If there is a layout overrides file, attach an external AST source that
  // provides the layouts from that file.
  if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && 
      CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
    OwningPtr<ExternalASTSource> 
      Override(new LayoutOverrideSource(
                     CI.getFrontendOpts().OverrideRecordLayoutsFile));
    CI.getASTContext().setExternalSource(Override);
  }
  
  return true;

  // If we failed, reset state since the client will not end up calling the
  // matching EndSourceFile().
  failure:
  if (isCurrentFileAST()) {
    CI.setASTContext(0);
    CI.setPreprocessor(0);
    CI.setSourceManager(0);
    CI.setFileManager(0);
  }

  if (HasBegunSourceFile)
    CI.getDiagnosticClient().EndSourceFile();
  CI.clearOutputFiles(/*EraseFiles=*/true);
  setCurrentInput(FrontendInputFile());
  setCompilerInstance(0);
  return false;
}
예제 #18
0
int main(int argc, char *argv[])
{
    if (argc != 2) {
        llvm::errs() << "Usage: kcov-branch-identify <filename>\n";
        return 1;
    }

    // CompilerInstance will hold the instance of the Clang compiler for us,
    // managing the various objects needed to run the compiler.
    CompilerInstance TheCompInst;
    
    // Diagnostics manage problems and issues in compile 
    TheCompInst.createDiagnostics(NULL, false);

    // Set target platform options 
    // Initialize target info with the default triple for our platform.
    TargetOptions *TO = new TargetOptions();
    TO->Triple = llvm::sys::getDefaultTargetTriple();
    TargetInfo *TI = TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO);
    TheCompInst.setTarget(TI);

    // FileManager supports for file system lookup, file system caching, and directory search management.
    TheCompInst.createFileManager();
    FileManager &FileMgr = TheCompInst.getFileManager();
    
    // SourceManager handles loading and caching of source files into memory.
    TheCompInst.createSourceManager(FileMgr);
    SourceManager &SourceMgr = TheCompInst.getSourceManager();
    //global var  m_srcmgr
    //m_srcmgr = &SourceMgr;

    // Prreprocessor runs within a single source file
    TheCompInst.createPreprocessor();
    
    // ASTContext holds long-lived AST nodes (such as types and decls) .
    TheCompInst.createASTContext();

    // Enable HeaderSearch option
    llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> hso( new HeaderSearchOptions());
    HeaderSearch headerSearch(hso,
                              TheCompInst.getFileManager(),
                              TheCompInst.getDiagnostics(),
                              TheCompInst.getLangOpts(),
                              TI);

    // <Warning!!> -- Platform Specific Code lives here
    // This depends on A) that you're running linux and
    // B) that you have the same GCC LIBs installed that I do. 
    /*
    $ gcc -xc -E -v -
    ..
     /usr/local/include
     /usr/lib/gcc/x86_64-linux-gnu/4.4.5/include
     /usr/lib/gcc/x86_64-linux-gnu/4.4.5/include-fixed
     /usr/include
    End of search list.
    */
    const char *include_paths[] = {"/usr/local/include",
                "/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include",
                "/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include-fixed",
                "/usr/include"};

    for (int i=0; i<4; i++) 
        hso->AddPath(include_paths[i], 
                    clang::frontend::Angled, 
                    false, 
                    false);
    // </Warning!!> -- End of Platform Specific Code

    InitializePreprocessor(TheCompInst.getPreprocessor(), 
                  TheCompInst.getPreprocessorOpts(),
                  *hso,
                  TheCompInst.getFrontendOpts());


    // A Rewriter helps us manage the code rewriting task.
    Rewriter TheRewriter;
    TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts());

    // Set the main file handled by the source manager to the input file.
    const FileEntry *FileIn = FileMgr.getFile(argv[1]);
    SourceMgr.createMainFileID(FileIn);
    
    // Inform Diagnostics that processing of a source file is beginning. 
    TheCompInst.getDiagnosticClient().BeginSourceFile(TheCompInst.getLangOpts(),&TheCompInst.getPreprocessor());
    
    // Create an AST consumer instance which is going to get called by ParseAST.
    MyASTConsumer TheConsumer(SourceMgr);

    // Parse the file to AST, registering our consumer as the AST consumer.
    ParseAST(TheCompInst.getPreprocessor(), &TheConsumer, TheCompInst.getASTContext());
    TheConsumer.printBranchNum();
    return 0;
}
예제 #19
0
int main(int argc, char *argv[] )
{
	type_for_quoting[ "void" ] = 1;
	type_for_quoting[ "bool" ] = 1;
	type_for_quoting[ "char" ] = 1;
	type_for_quoting[ "wchar_t" ] = 1;
	type_for_quoting[ "short" ] = 1;
	type_for_quoting[ "long" ] = 1;
	type_for_quoting[ "size_t" ] = 1;
	type_for_quoting[ "int8_t" ] = 1;
	type_for_quoting[ "int16_t" ] = 1;
	type_for_quoting[ "int32_t" ] = 1;
	type_for_quoting[ "int64_t" ] = 1;
	type_for_quoting[ "uint8_t" ] = 1;
	type_for_quoting[ "uint16_t" ] = 1;
	type_for_quoting[ "uint32_t" ] = 1;
	type_for_quoting[ "uint64_t" ] = 1;
	type_substitutions[ "_Bool" ] = "bool";

	size_t i;
	cl::ParseCommandLineOptions( argc, argv, 
			"ClangDao: Clang-based automatic binding tool for Dao." );

	if (!ignored_arguments.empty()) {
		errs() << "Ignoring the following arguments:";
		copy(ignored_arguments.begin(), ignored_arguments.end(),
				std::ostream_iterator<std::string>(std::cerr, " "));
	}

	CompilerInstance compiler;
	CDaoModule module( & compiler, main_input_file );

	compiler.createDiagnostics();
	//compiler.getInvocation().setLangDefaults(IK_CXX);
	//compiler.getInvocation().setLangDefaults(IK_ObjC);
	CompilerInvocation::CreateFromArgs( compiler.getInvocation(),
			argv + 1, argv + argc, compiler.getDiagnostics() );

	std::shared_ptr<TargetOptions> taropts( new TargetOptions( compiler.getTargetOpts() ) ); 
	compiler.setTarget( TargetInfo::CreateTargetInfo(
				compiler.getDiagnostics(), taropts ) );

	compiler.createFileManager();
	compiler.createSourceManager(compiler.getFileManager());
	compiler.createPreprocessor( TU_Complete );
	compiler.createASTContext();

	std::unique_ptr<ASTConsumer> astConsumer( new CDaoASTConsumer( & compiler, & module ) );
	compiler.setASTConsumer( std::move(astConsumer) );
	//XXX compiler.createSema(false, NULL);
	//compiler.createSema(TU_Module, NULL);
	compiler.createSema(TU_Prefix, NULL);

	Preprocessor & pp = compiler.getPreprocessor();

	//outs()<<pp.getPredefines()<<"\n";
	string builtinDefines = pp.getPredefines();

#if 1
	ClangDao_RemoveDefine( builtinDefines, "#define __APPLE_CC__" );
	ClangDao_RemoveDefine( builtinDefines, "#define __APPLE__" );
	ClangDao_RemoveDefine( builtinDefines, "#define __MACH__" );
	ClangDao_RemoveDefine( builtinDefines, "#define __ENVIRONMENT_MAC_OS_X" );
	ClangDao_RemoveDefine( builtinDefines, "#define OBJC_" );
#endif

	//outs()<<builtinDefines<<"\n";

	std::unique_ptr<PPCallbacks> ppCallbacks( new CDaoPPCallbacks( & compiler, & module ) );
	pp.setPredefines( builtinDefines + "\n" + predefines + "\n#define __CLANGDAO__\n" );
	pp.addPPCallbacks( std::move( ppCallbacks ) );

	InputKind ik = FrontendOptions::getInputKindForExtension( main_input_file );
	compiler.InitializeSourceManager( FrontendInputFile( main_input_file, ik ) );
	compiler.getDiagnosticClient().BeginSourceFile( compiler.getLangOpts(), & pp );
	ParseAST( pp, &compiler.getASTConsumer(), compiler.getASTContext() );
	compiler.getDiagnosticClient().EndSourceFile();

	return module.Generate( output_dir );
}