[clang-tidy] Build it even without static analyzer

Conditionally compile the parts of clang-tidy which depend on the static
analyzer.

Funnily enough, I made the patch to exclude this from the build in 2013,
and it was committed with the comment that the tool should not be fully
excluded, but only the parts of it which depend on the analyzer should
be excluded.

 http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20130617/081797.html

This commit implements that idea.

Reviewed By: aaron.ballman

Tags: #clang-tools-extra

Differential Revision: https://reviews.llvm.org/D52334

llvm-svn: 343528
GitOrigin-RevId: a3c4206e415963b3ac84327b1946dba98ec572e7
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c434682..c3137ad 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,8 @@
 add_subdirectory(clang-apply-replacements)
 add_subdirectory(clang-reorder-fields)
 add_subdirectory(modularize)
-if(CLANG_ENABLE_STATIC_ANALYZER)
 add_subdirectory(clang-tidy)
 add_subdirectory(clang-tidy-vs)
-endif()
 
 add_subdirectory(change-namespace)
 add_subdirectory(clang-doc)
diff --git a/clang-tidy/CMakeLists.txt b/clang-tidy/CMakeLists.txt
index a872469..0037268 100644
--- a/clang-tidy/CMakeLists.txt
+++ b/clang-tidy/CMakeLists.txt
@@ -21,12 +21,17 @@
   clangLex
   clangRewrite
   clangSema
-  clangStaticAnalyzerCore
-  clangStaticAnalyzerFrontend
   clangTooling
   clangToolingCore
   )
 
+if(CLANG_ENABLE_STATIC_ANALYZER)
+  target_link_libraries(clangTidy PRIVATE
+    clangStaticAnalyzerCore
+    clangStaticAnalyzerFrontend
+  )
+endif()
+
 add_subdirectory(android)
 add_subdirectory(abseil)
 add_subdirectory(boost)
@@ -39,7 +44,9 @@
 add_subdirectory(llvm)
 add_subdirectory(misc)
 add_subdirectory(modernize)
-add_subdirectory(mpi)
+if(CLANG_ENABLE_STATIC_ANALYZER)
+  add_subdirectory(mpi)
+endif()
 add_subdirectory(objc)
 add_subdirectory(performance)
 add_subdirectory(plugin)
diff --git a/clang-tidy/ClangTidy.cpp b/clang-tidy/ClangTidy.cpp
index d9eb1a5..729371f 100644
--- a/clang-tidy/ClangTidy.cpp
+++ b/clang-tidy/ClangTidy.cpp
@@ -23,6 +23,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Config/config.h"
 #include "clang/Format/Format.h"
 #include "clang/Frontend/ASTConsumers.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -34,8 +35,10 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Rewrite/Frontend/FixItRewriter.h"
 #include "clang/Rewrite/Frontend/FrontendActions.h"
+#if CLANG_ENABLE_STATIC_ANALYZER
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
+#endif // CLANG_ENABLE_STATIC_ANALYZER
 #include "clang/Tooling/DiagnosticsYaml.h"
 #include "clang/Tooling/Refactoring.h"
 #include "clang/Tooling/ReplacementsYaml.h"
@@ -56,6 +59,7 @@
 namespace tidy {
 
 namespace {
+#if CLANG_ENABLE_STATIC_ANALYZER
 static const char *AnalyzerCheckNamePrefix = "clang-analyzer-";
 
 class AnalyzerDiagnosticConsumer : public ento::PathDiagnosticConsumer {
@@ -87,6 +91,7 @@
 private:
   ClangTidyContext &Context;
 };
+#endif // CLANG_ENABLE_STATIC_ANALYZER
 
 class ErrorReporter {
 public:
@@ -296,6 +301,7 @@
   }
 }
 
+#if CLANG_ENABLE_STATIC_ANALYZER
 static void setStaticAnalyzerCheckerOpts(const ClangTidyOptions &Opts,
                                          AnalyzerOptionsRef AnalyzerOptions) {
   StringRef AnalyzerPrefix(AnalyzerCheckNamePrefix);
@@ -339,6 +345,7 @@
   }
   return List;
 }
+#endif // CLANG_ENABLE_STATIC_ANALYZER
 
 std::unique_ptr<clang::ASTConsumer>
 ClangTidyASTConsumerFactory::CreateASTConsumer(
@@ -380,6 +387,7 @@
   if (!Checks.empty())
     Consumers.push_back(Finder->newASTConsumer());
 
+#if CLANG_ENABLE_STATIC_ANALYZER
   AnalyzerOptionsRef AnalyzerOptions = Compiler.getAnalyzerOpts();
   AnalyzerOptions->CheckersControlList =
       getCheckersControlList(Context, Context.canEnableAnalyzerAlphaCheckers());
@@ -395,6 +403,7 @@
         new AnalyzerDiagnosticConsumer(Context));
     Consumers.push_back(std::move(AnalysisConsumer));
   }
+#endif // CLANG_ENABLE_STATIC_ANALYZER
   return llvm::make_unique<ClangTidyASTConsumer>(
       std::move(Consumers), std::move(Profiling), std::move(Finder),
       std::move(Checks));
@@ -407,9 +416,11 @@
       CheckNames.push_back(CheckFactory.first);
   }
 
+#if CLANG_ENABLE_STATIC_ANALYZER
   for (const auto &AnalyzerCheck : getCheckersControlList(
            Context, Context.canEnableAnalyzerAlphaCheckers()))
     CheckNames.push_back(AnalyzerCheckNamePrefix + AnalyzerCheck.first);
+#endif // CLANG_ENABLE_STATIC_ANALYZER
 
   std::sort(CheckNames.begin(), CheckNames.end());
   return CheckNames;
diff --git a/clang-tidy/plugin/CMakeLists.txt b/clang-tidy/plugin/CMakeLists.txt
index 3540b2b..7a12d7f 100644
--- a/clang-tidy/plugin/CMakeLists.txt
+++ b/clang-tidy/plugin/CMakeLists.txt
@@ -20,7 +20,6 @@
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyModernizeModule
-  clangTidyMPIModule
   clangTidyObjCModule
   clangTidyPerformanceModule
   clangTidyPortabilityModule
@@ -28,3 +27,9 @@
   clangTidyZirconModule
   clangTooling
   )
+
+if(CLANG_ENABLE_STATIC_ANALYZER)
+  target_link_libraries(clangTidyPlugin PRIVATE
+    clangTidyMPIModule
+  )
+endif()
diff --git a/clang-tidy/plugin/ClangTidyPlugin.cpp b/clang-tidy/plugin/ClangTidyPlugin.cpp
index 3455612..2244893 100644
--- a/clang-tidy/plugin/ClangTidyPlugin.cpp
+++ b/clang-tidy/plugin/ClangTidyPlugin.cpp
@@ -9,6 +9,7 @@
 
 #include "../ClangTidy.h"
 #include "../ClangTidyModule.h"
+#include "clang/Config/config.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendPluginRegistry.h"
 #include "clang/Frontend/MultiplexConsumer.h"
@@ -133,10 +134,12 @@
 static int LLVM_ATTRIBUTE_UNUSED ModernizeModuleAnchorDestination =
     ModernizeModuleAnchorSource;
 
+#if CLANG_ENABLE_STATIC_ANALYZER
 // This anchor is used to force the linker to link the MPIModule.
 extern volatile int MPIModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED MPIModuleAnchorDestination =
     MPIModuleAnchorSource;
+#endif
 
 // This anchor is used to force the linker to link the ObjCModule.
 extern volatile int ObjCModuleAnchorSource;
diff --git a/clang-tidy/tool/CMakeLists.txt b/clang-tidy/tool/CMakeLists.txt
index a3ec4ae..f58cfea 100644
--- a/clang-tidy/tool/CMakeLists.txt
+++ b/clang-tidy/tool/CMakeLists.txt
@@ -29,7 +29,6 @@
   clangTidyLLVMModule
   clangTidyMiscModule
   clangTidyModernizeModule
-  clangTidyMPIModule
   clangTidyObjCModule
   clangTidyPerformanceModule
   clangTidyPortabilityModule
@@ -39,6 +38,12 @@
   clangToolingCore
   )
 
+if(CLANG_ENABLE_STATIC_ANALYZER)
+  target_link_libraries(clang-tidy PRIVATE
+    clangTidyMPIModule
+  )
+endif()
+
 install(PROGRAMS clang-tidy-diff.py
   DESTINATION share/clang
   COMPONENT clang-tidy)
diff --git a/clang-tidy/tool/ClangTidyMain.cpp b/clang-tidy/tool/ClangTidyMain.cpp
index b458b29..d272a48 100644
--- a/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tidy/tool/ClangTidyMain.cpp
@@ -16,6 +16,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "../ClangTidy.h"
+#include "clang/Config/config.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "llvm/Support/Process.h"
 #include "llvm/Support/TargetSelect.h"
@@ -534,10 +535,12 @@
 static int LLVM_ATTRIBUTE_UNUSED ModernizeModuleAnchorDestination =
     ModernizeModuleAnchorSource;
 
+#if CLANG_ENABLE_STATIC_ANALYZER
 // This anchor is used to force the linker to link the MPIModule.
 extern volatile int MPIModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED MPIModuleAnchorDestination =
     MPIModuleAnchorSource;
+#endif
 
 // This anchor is used to force the linker to link the PerformanceModule.
 extern volatile int PerformanceModuleAnchorSource;
diff --git a/docs/clang-tidy/index.rst b/docs/clang-tidy/index.rst
index 3b7443c..ab165d8 100644
--- a/docs/clang-tidy/index.rst
+++ b/docs/clang-tidy/index.rst
@@ -337,6 +337,10 @@
   * `clang-check`_ with the ``-ast-dump`` (and optionally ``-ast-dump-filter``)
     provides a convenient way to dump AST of a C++ program.
 
+If CMake is configured with ``CLANG_ENABLE_STATIC_ANALYZER``,
+:program:`clang-tidy` will not be built with support for the 
+``clang-analyzer-*`` checks or the ``mpi-*`` checks.
+
 
 .. _AST Matchers: http://clang.llvm.org/docs/LibASTMatchers.html
 .. _PPCallbacks: http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a1bda50..e2d7e12 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -56,19 +56,15 @@
 
   # Unit tests
   ExtraToolsUnitTests
+
+  # For the clang-tidy libclang integration test.
+  c-index-test
+  # clang-tidy tests require it.
+  clang-headers
+
+  clang-tidy
   )
 
-if(CLANG_ENABLE_STATIC_ANALYZER)
-  list(APPEND CLANG_TOOLS_TEST_DEPS
-    # For the clang-tidy libclang integration test.
-    c-index-test
-    # clang-tidy tests require it.
-    clang-headers
-
-    clang-tidy
-    )
-endif()
-
 add_lit_testsuite(check-clang-tools "Running the Clang extra tools' regression tests"
   ${CMAKE_CURRENT_BINARY_DIR}
   DEPENDS ${CLANG_TOOLS_TEST_DEPS}
diff --git a/test/clang-tidy/enable-alpha-checks.cpp b/test/clang-tidy/enable-alpha-checks.cpp
index b1e5130..74bdfdb 100644
--- a/test/clang-tidy/enable-alpha-checks.cpp
+++ b/test/clang-tidy/enable-alpha-checks.cpp
@@ -1,3 +1,5 @@
+// REQUIRES: static-analyzer
+
 // Check if '-allow-enabling-analyzer-alpha-checkers' is visible for users.
 // RUN: clang-tidy -help | not grep 'allow-enabling-analyzer-alpha-checkers'
 
diff --git a/test/clang-tidy/mpi-buffer-deref.cpp b/test/clang-tidy/mpi-buffer-deref.cpp
index 67304d2..47d58a5 100644
--- a/test/clang-tidy/mpi-buffer-deref.cpp
+++ b/test/clang-tidy/mpi-buffer-deref.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: static-analyzer
 // RUN: %check_clang_tidy %s mpi-buffer-deref %t -- -- -I %S/Inputs/mpi-type-mismatch
 
 #include "mpimock.h"
diff --git a/test/clang-tidy/mpi-type-mismatch.cpp b/test/clang-tidy/mpi-type-mismatch.cpp
index 5e230b8..bf978dc 100644
--- a/test/clang-tidy/mpi-type-mismatch.cpp
+++ b/test/clang-tidy/mpi-type-mismatch.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: static-analyzer
 // RUN: %check_clang_tidy %s mpi-type-mismatch %t -- -- -I %S/Inputs/mpi-type-mismatch
 
 #include "mpimock.h"
diff --git a/test/clang-tidy/nolint.cpp b/test/clang-tidy/nolint.cpp
index 893e819..24c3722 100644
--- a/test/clang-tidy/nolint.cpp
+++ b/test/clang-tidy/nolint.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: static-analyzer
 // RUN: %check_clang_tidy %s google-explicit-constructor,clang-diagnostic-unused-variable,clang-analyzer-core.UndefinedBinaryOperatorResult %t -- -extra-arg=-Wunused-variable -- -I%S/Inputs/nolint
 
 #include "trigger_warning.h"
diff --git a/test/clang-tidy/read_file_config.cpp b/test/clang-tidy/read_file_config.cpp
index 3635c21..3e39b4d 100644
--- a/test/clang-tidy/read_file_config.cpp
+++ b/test/clang-tidy/read_file_config.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: static-analyzer
 // RUN: mkdir -p %T/read-file-config/
 // RUN: cp %s %T/read-file-config/test.cpp
 // RUN: echo 'Checks: "-*,modernize-use-nullptr"' > %T/read-file-config/.clang-tidy
diff --git a/test/clang-tidy/static-analyzer-config.cpp b/test/clang-tidy/static-analyzer-config.cpp
index cee0a4c..9ca87cf 100644
--- a/test/clang-tidy/static-analyzer-config.cpp
+++ b/test/clang-tidy/static-analyzer-config.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: static-analyzer
 // RUN: clang-tidy %s -checks='-*,clang-analyzer-unix.Malloc' -config='{CheckOptions: [{ key: "clang-analyzer-unix.Malloc:Optimistic", value: true}]}' -- | FileCheck %s
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
diff --git a/test/clang-tidy/static-analyzer.cpp b/test/clang-tidy/static-analyzer.cpp
index b0015aa..af9693a 100644
--- a/test/clang-tidy/static-analyzer.cpp
+++ b/test/clang-tidy/static-analyzer.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: static-analyzer
 // RUN: clang-tidy %s -checks='-*,clang-analyzer-*' -- | FileCheck %s
 extern void *malloc(unsigned long);
 extern void free(void *);
diff --git a/test/clang-tidy/temporaries.cpp b/test/clang-tidy/temporaries.cpp
index 3df4c60..0aa60ed 100644
--- a/test/clang-tidy/temporaries.cpp
+++ b/test/clang-tidy/temporaries.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: static-analyzer
 // RUN: clang-tidy -checks='-*,clang-analyzer-core.NullDereference' %s -- | FileCheck %s
 
 struct NoReturnDtor {
diff --git a/test/lit.cfg b/test/lit.cfg
index 8e755c8..8f8ebaf 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -119,24 +119,22 @@
 
 if config.clang_staticanalyzer:
     config.available_features.add('static-analyzer')
-    check_clang_tidy = os.path.join(
-        config.test_source_root, "clang-tidy", "check_clang_tidy.py")
-    config.substitutions.append(
-        ('%check_clang_tidy',
-         '%s %s' % (config.python_executable, check_clang_tidy)) )
-    clang_tidy_diff = os.path.join(
-        config.test_source_root, "..", "clang-tidy", "tool", "clang-tidy-diff.py")
-    config.substitutions.append(
-        ('%clang_tidy_diff',
-         '%s %s' % (config.python_executable, clang_tidy_diff)) )
-    run_clang_tidy = os.path.join(
-        config.test_source_root, "..", "clang-tidy", "tool", "run-clang-tidy.py")
-    config.substitutions.append(
-        ('%run_clang_tidy',
-         '%s %s' % (config.python_executable, run_clang_tidy)) )
-else:
-    # exclude the clang-tidy test directory
-    config.excludes.append('clang-tidy')
+
+check_clang_tidy = os.path.join(
+    config.test_source_root, "clang-tidy", "check_clang_tidy.py")
+config.substitutions.append(
+    ('%check_clang_tidy',
+     '%s %s' % (config.python_executable, check_clang_tidy)) )
+clang_tidy_diff = os.path.join(
+    config.test_source_root, "..", "clang-tidy", "tool", "clang-tidy-diff.py")
+config.substitutions.append(
+    ('%clang_tidy_diff',
+     '%s %s' % (config.python_executable, clang_tidy_diff)) )
+run_clang_tidy = os.path.join(
+    config.test_source_root, "..", "clang-tidy", "tool", "run-clang-tidy.py")
+config.substitutions.append(
+    ('%run_clang_tidy',
+     '%s %s' % (config.python_executable, run_clang_tidy)) )
 
 clangd_benchmarks_dir = os.path.join(os.path.dirname(config.clang_tools_dir),
                                      "tools", "clang", "tools", "extra",
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 82f54d5..d123700 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -18,8 +18,6 @@
 add_subdirectory(clang-apply-replacements)
 add_subdirectory(clang-move)
 add_subdirectory(clang-query)
-if(CLANG_ENABLE_STATIC_ANALYZER)
-  add_subdirectory(clang-tidy)
-endif()
+add_subdirectory(clang-tidy)
 add_subdirectory(clangd)
 add_subdirectory(include-fixer)