std::unique_ptr<clang::ASTConsumer>
ClangTidyASTConsumerFactory::CreateASTConsumer(
    clang::CompilerInstance &Compiler, StringRef File) {
  // FIXME: Move this to a separate method, so that CreateASTConsumer doesn't
  // modify Compiler.
  Context.setSourceManager(&Compiler.getSourceManager());
  Context.setCurrentFile(File);
  Context.setASTContext(&Compiler.getASTContext());

  std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
  CheckFactories->createChecks(&Context, Checks);

  ast_matchers::MatchFinder::MatchFinderOptions FinderOptions;
  if (auto *P = Context.getCheckProfileData())
    FinderOptions.CheckProfiling.emplace(P->Records);

  std::unique_ptr<ast_matchers::MatchFinder> Finder(
      new ast_matchers::MatchFinder(std::move(FinderOptions)));

  for (auto &Check : Checks) {
    Check->registerMatchers(&*Finder);
    Check->registerPPCallbacks(Compiler);
  }

  std::vector<std::unique_ptr<ASTConsumer>> Consumers;
  if (!Checks.empty())
    Consumers.push_back(Finder->newASTConsumer());

  AnalyzerOptionsRef AnalyzerOptions = Compiler.getAnalyzerOpts();
  // FIXME: Remove this option once clang's cfg-temporary-dtors option defaults
  // to true.
  AnalyzerOptions->Config["cfg-temporary-dtors"] =
      Context.getOptions().AnalyzeTemporaryDtors ? "true" : "false";

  GlobList &Filter = Context.getChecksFilter();
  AnalyzerOptions->CheckersControlList = getCheckersControlList(Filter);
  if (!AnalyzerOptions->CheckersControlList.empty()) {
    setStaticAnalyzerCheckerOpts(Context.getOptions(), AnalyzerOptions);
    AnalyzerOptions->AnalysisStoreOpt = RegionStoreModel;
    AnalyzerOptions->AnalysisDiagOpt = PD_NONE;
    AnalyzerOptions->AnalyzeNestedBlocks = true;
    AnalyzerOptions->eagerlyAssumeBinOpBifurcation = true;
    std::unique_ptr<ento::AnalysisASTConsumer> AnalysisConsumer =
        ento::CreateAnalysisConsumer(Compiler);
    AnalysisConsumer->AddDiagnosticConsumer(
        new AnalyzerDiagnosticConsumer(Context));
    Consumers.push_back(std::move(AnalysisConsumer));
  }
  return llvm::make_unique<ClangTidyASTConsumer>(
      std::move(Consumers), std::move(Finder), std::move(Checks));
}
std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() {
  std::vector<std::string> CheckNames;
  GlobList &Filter = Context.getChecksFilter();
  for (const auto &CheckFactory : *CheckFactories) {
    if (Filter.contains(CheckFactory.first))
      CheckNames.push_back(CheckFactory.first);
  }

  for (const auto &AnalyzerCheck : getCheckersControlList(Filter))
    CheckNames.push_back(AnalyzerCheckNamePrefix + AnalyzerCheck.first);

  std::sort(CheckNames.begin(), CheckNames.end());
  return CheckNames;
}
Пример #3
0
clang::ASTConsumer *ClangTidyASTConsumerFactory::CreateASTConsumer(
    clang::CompilerInstance &Compiler, StringRef File) {
    // FIXME: Move this to a separate method, so that CreateASTConsumer doesn't
    // modify Compiler.
    Context.setSourceManager(&Compiler.getSourceManager());
    Context.setCurrentFile(File);

    std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
    ChecksFilter &Filter = Context.getChecksFilter();
    CheckFactories->createChecks(Filter, Checks);

    std::unique_ptr<ast_matchers::MatchFinder> Finder(
        new ast_matchers::MatchFinder);
    for (auto &Check : Checks) {
        Check->setContext(&Context);
        Check->registerMatchers(&*Finder);
        Check->registerPPCallbacks(Compiler);
    }

    SmallVector<ASTConsumer *, 2> Consumers;
    if (!Checks.empty())
        Consumers.push_back(Finder->newASTConsumer());

    AnalyzerOptionsRef AnalyzerOptions = Compiler.getAnalyzerOpts();
    // FIXME: Remove this option once clang's cfg-temporary-dtors option defaults
    // to true.
    AnalyzerOptions->Config["cfg-temporary-dtors"] =
        Context.getOptions().AnalyzeTemporaryDtors ? "true" : "false";

    AnalyzerOptions->CheckersControlList = getCheckersControlList(Filter);
    if (!AnalyzerOptions->CheckersControlList.empty()) {
        AnalyzerOptions->AnalysisStoreOpt = RegionStoreModel;
        AnalyzerOptions->AnalysisDiagOpt = PD_NONE;
        AnalyzerOptions->AnalyzeNestedBlocks = true;
        AnalyzerOptions->eagerlyAssumeBinOpBifurcation = true;
        ento::AnalysisASTConsumer *AnalysisConsumer = ento::CreateAnalysisConsumer(
                    Compiler.getPreprocessor(), Compiler.getFrontendOpts().OutputFile,
                    AnalyzerOptions, Compiler.getFrontendOpts().Plugins);
        AnalysisConsumer->AddDiagnosticConsumer(
            new AnalyzerDiagnosticConsumer(Context));
        Consumers.push_back(AnalysisConsumer);
    }
    return new ClangTidyASTConsumer(Consumers, std::move(Finder),
                                    std::move(Checks));
}