- New approach to get the list of static analyzer checkers dynamically:
- Manually create a new compiler invocation object from the command line and 
get the plugin list from that invocation object.

Clang part:
tooling::newDriver and tooling::getCC1Arguments was not the part of the public 
API. To make this patch work, they need to be added to the public API. If you 
find this approach a good enough I will update the clang part of this patch.


http://reviews.llvm.org/D9555

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/ClangTidy.cpp
  clang-tidy/ClangTidy.h
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/tool/Makefile
  test/clang-tidy/clang-static-analyzer-plugin.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: clang-tidy/CMakeLists.txt
===================================================================
--- clang-tidy/CMakeLists.txt
+++ clang-tidy/CMakeLists.txt
@@ -2,6 +2,10 @@
   Support
   )
 
+if(CLANG_PLUGIN_SUPPORT)
+  set(LLVM_NO_DEAD_STRIP 1)
+endif()
+
 add_clang_library(clangTidy
   ClangTidy.cpp
   ClangTidyModule.cpp
Index: clang-tidy/ClangTidy.cpp
===================================================================
--- clang-tidy/ClangTidy.cpp
+++ clang-tidy/ClangTidy.cpp
@@ -18,6 +18,8 @@
 #include "ClangTidy.h"
 #include "ClangTidyDiagnosticConsumer.h"
 #include "ClangTidyModuleRegistry.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Compilation.h" // TODO: Remove
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
@@ -33,6 +35,7 @@
 #include "clang/Rewrite/Frontend/FixItRewriter.h"
 #include "clang/Rewrite/Frontend/FrontendActions.h"
 #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
+#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
 #include "clang/Tooling/Refactoring.h"
 #include "clang/Tooling/ReplacementsYaml.h"
 #include "clang/Tooling/Tooling.h"
@@ -55,14 +58,7 @@
 namespace {
 static const char *AnalyzerCheckNamePrefix = "clang-analyzer-";
 
-static StringRef StaticAnalyzerChecks[] = {
-#define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, DESCFILE, HELPTEXT, GROUPINDEX, HIDDEN)       \
-  FULLNAME,
-#include "../../../lib/StaticAnalyzer/Checkers/Checkers.inc"
-#undef CHECKER
-#undef GET_CHECKERS
-};
+static std::vector<std::string> StaticAnalyzerChecks;
 
 class AnalyzerDiagnosticConsumer : public ento::PathDiagnosticConsumer {
 public:
@@ -410,6 +406,38 @@
   return Context.getStats();
 }
 
+void populateStaticAnalyzerCheckerList(
+    StringRef File, int Argc, const char** Argv) {
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
+  TextDiagnosticPrinter DiagPrinter(llvm::outs(), &*DiagOpts);
+  DiagnosticsEngine DiagEng(
+      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts,
+      &DiagPrinter, /*ShouldOwn=*/false);
+  std::unique_ptr<driver::Driver> ClangDriver(
+      tooling::newDriver(&DiagEng, Argv[0]));
+  const char **DoubleDash = std::find(Argv, Argv + Argc, StringRef("--"));
+  if (DoubleDash == Argv+Argc) {
+    return;
+  }
+  std::vector<const char *> CommandLine(DoubleDash + 1, Argv + Argc);
+  Argc = DoubleDash - Argv;
+  CommandLine.insert(CommandLine.begin(), Argv[0]);
+  CommandLine.push_back("-c");
+  CommandLine.push_back(File.data());
+
+  std::unique_ptr<Compilation> Comp(ClangDriver->BuildCompilation(CommandLine));
+  if (!Comp)
+    return;
+
+  auto ArgList(getCC1Arguments(&DiagEng, &*Comp));
+  if (ArgList == nullptr)
+    return;
+
+  std::unique_ptr<CompilerInvocation> CI(
+      tooling::newInvocation(&DiagEng, *ArgList));
+  StaticAnalyzerChecks = ento::getCheckerList(CI->getFrontendOpts().Plugins);
+}
+
 void handleErrors(const std::vector<ClangTidyError> &Errors, bool Fix) {
   ErrorReporter Reporter(Fix);
   for (const ClangTidyError &Error : Errors)
Index: clang-tidy/ClangTidy.h
===================================================================
--- clang-tidy/ClangTidy.h
+++ clang-tidy/ClangTidy.h
@@ -217,6 +217,8 @@
 void exportReplacements(const std::vector<ClangTidyError> &Errors,
                         raw_ostream &OS);
 
+void populateStaticAnalyzerCheckerList(
+    StringRef File, int Argc, const char** Argv); 
 } // end namespace tidy
 } // end namespace clang
 
Index: clang-tidy/tool/CMakeLists.txt
===================================================================
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -20,3 +20,6 @@
 install(TARGETS clang-tidy
   RUNTIME DESTINATION bin)
 
+if(CLANG_PLUGIN_SUPPORT)
+  set_target_properties(clang-tidy PROPERTIES ENABLE_EXPORTS 1)
+endif()
Index: clang-tidy/tool/ClangTidyMain.cpp
===================================================================
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -261,15 +261,18 @@
                                                 OverrideOptions);
 }
 
+
 static int clangTidyMain(int argc, const char **argv) {
+  int OrigArgc = argc;
   CommonOptionsParser OptionsParser(argc, argv, ClangTidyCategory);
 
   auto OptionsProvider = createOptionsProvider();
   if (!OptionsProvider)
     return 1;
 
   std::string FileName = OptionsParser.getSourcePathList().front();
   ClangTidyOptions EffectiveOptions = OptionsProvider->getOptions(FileName);
+  populateStaticAnalyzerCheckerList(FileName, OrigArgc, argv);
   std::vector<std::string> EnabledChecks = getCheckNames(EffectiveOptions);
 
   // FIXME: Allow using --list-checks without positional arguments.
@@ -294,7 +297,7 @@
     llvm::cl::PrintHelpMessage(/*Hidden=*/false, /*Categorized=*/true);
     return 1;
   }
-
+  
   ProfileData Profile;
 
   std::vector<ClangTidyError> Errors;
Index: clang-tidy/tool/Makefile
===================================================================
--- clang-tidy/tool/Makefile
+++ clang-tidy/tool/Makefile
@@ -11,9 +11,12 @@
 
 TOOLNAME = clang-tidy
 
-# No plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
+ifeq ($(CLANG_PLUGIN_SUPPORT), 1)
+NO_DEAD_STRIP := 1
+else
+TOOL_NO_EXPORTS := 1
 
+endif
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
 USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
Index: test/clang-tidy/clang-static-analyzer-plugin.cpp
===================================================================
--- test/clang-tidy/clang-static-analyzer-plugin.cpp
+++ test/clang-tidy/clang-static-analyzer-plugin.cpp
@@ -0,0 +1,12 @@
+// RUN: clang-tidy %s -checks='-*,clang-analyzer-example.MainCallChecker' -- -load %llvmshlibdir/SampleAnalyzerPlugin%pluginext | FileCheck %s
+// REQUIRES: plugins, examples
+
+// Test that the MainCallChecker example analyzer plugin loads and runs.
+
+int main();
+
+void caller() {
+  main();
+  // CHECK: warning: call to main
+}
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to