- The global static analyzer checker list now initialized with the static list. 
It is only updated if plugin-path command line argument is given.
- Fixed some nits.


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"
 #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,7 +58,7 @@
 namespace {
 static const char *AnalyzerCheckNamePrefix = "clang-analyzer-";
 
-static StringRef StaticAnalyzerChecks[] = {
+static std::vector<std::string> StaticAnalyzerChecks = {
 #define GET_CHECKERS
 #define CHECKER(FULLNAME, CLASS, DESCFILE, HELPTEXT, GROUPINDEX, HIDDEN)       \
   FULLNAME,
@@ -410,6 +413,36 @@
   return Context.getStats();
 }
 
+void populateStaticAnalyzerCheckerList(StringRef Plugin, 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]));
+  ClangDriver->setCheckInputsExist(false);
+  std::vector<const char *> CommandLine{Argv[0], "-c", "dummy.cpp"};
+  if (!Plugin.empty()) {
+    CommandLine.push_back("-Xclang");
+    CommandLine.push_back("-load");
+    CommandLine.push_back("-Xclang");
+    CommandLine.push_back(Plugin.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
@@ -219,6 +219,7 @@
 void exportReplacements(const std::vector<ClangTidyError> &Errors,
                         raw_ostream &OS);
 
+void populateStaticAnalyzerCheckerList(StringRef Plugin, 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
@@ -146,6 +146,12 @@
              "code with clang-apply-replacements."),
     cl::value_desc("filename"), cl::cat(ClangTidyCategory));
 
+static cl::opt<std::string> PluginPath(
+    "plugin-path",
+    cl::desc("Path of the shared object that contains static\n"
+             "analyzer checkers."),
+    cl::value_desc("filename"), cl::cat(ClangTidyCategory));
+
 namespace clang {
 namespace tidy {
 
@@ -270,6 +276,8 @@
 
   std::string FileName = OptionsParser.getSourcePathList().front();
   ClangTidyOptions EffectiveOptions = OptionsProvider->getOptions(FileName);
+  if (!PluginPath.empty())
+    populateStaticAnalyzerCheckerList(PluginPath, argv);
   std::vector<std::string> EnabledChecks = getCheckNames(EffectiveOptions);
 
   // FIXME: Allow using --list-checks without positional arguments.
@@ -294,7 +302,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,8 +11,11 @@
 
 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
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' -plugin-path %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