[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
This commit is contained in:
Stephen Kelly 2018-10-01 20:24:22 +00:00
parent 746eb09127
commit a3c4206e41
19 changed files with 76 additions and 39 deletions

View File

@ -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)

View File

@ -21,12 +21,17 @@ add_clang_library(clangTidy
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(hicpp)
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)

View File

@ -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 clang {
namespace tidy {
namespace {
#if CLANG_ENABLE_STATIC_ANALYZER
static const char *AnalyzerCheckNamePrefix = "clang-analyzer-";
class AnalyzerDiagnosticConsumer : public ento::PathDiagnosticConsumer {
@ -87,6 +91,7 @@ public:
private:
ClangTidyContext &Context;
};
#endif // CLANG_ENABLE_STATIC_ANALYZER
class ErrorReporter {
public:
@ -296,6 +301,7 @@ ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
}
}
#if CLANG_ENABLE_STATIC_ANALYZER
static void setStaticAnalyzerCheckerOpts(const ClangTidyOptions &Opts,
AnalyzerOptionsRef AnalyzerOptions) {
StringRef AnalyzerPrefix(AnalyzerCheckNamePrefix);
@ -339,6 +345,7 @@ static CheckersList getCheckersControlList(ClangTidyContext &Context,
}
return List;
}
#endif // CLANG_ENABLE_STATIC_ANALYZER
std::unique_ptr<clang::ASTConsumer>
ClangTidyASTConsumerFactory::CreateASTConsumer(
@ -380,6 +387,7 @@ ClangTidyASTConsumerFactory::CreateASTConsumer(
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 @@ ClangTidyASTConsumerFactory::CreateASTConsumer(
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 @@ std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() {
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;

View File

@ -20,7 +20,6 @@ add_clang_library(clangTidyPlugin
clangTidyLLVMModule
clangTidyMiscModule
clangTidyModernizeModule
clangTidyMPIModule
clangTidyObjCModule
clangTidyPerformanceModule
clangTidyPortabilityModule
@ -28,3 +27,9 @@ add_clang_library(clangTidyPlugin
clangTidyZirconModule
clangTooling
)
if(CLANG_ENABLE_STATIC_ANALYZER)
target_link_libraries(clangTidyPlugin PRIVATE
clangTidyMPIModule
)
endif()

View File

@ -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 @@ extern volatile int ModernizeModuleAnchorSource;
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;

View File

@ -29,7 +29,6 @@ target_link_libraries(clang-tidy
clangTidyLLVMModule
clangTidyMiscModule
clangTidyModernizeModule
clangTidyMPIModule
clangTidyObjCModule
clangTidyPerformanceModule
clangTidyPortabilityModule
@ -39,6 +38,12 @@ target_link_libraries(clang-tidy
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)

View File

@ -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 @@ extern volatile int ModernizeModuleAnchorSource;
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;

View File

@ -337,6 +337,10 @@ There are a few tools particularly useful when developing clang-tidy checks:
* `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

View File

@ -56,19 +56,15 @@ set(CLANG_TOOLS_TEST_DEPS
# 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}

View File

@ -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'

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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 *);

View File

@ -1,3 +1,4 @@
// REQUIRES: static-analyzer
// RUN: clang-tidy -checks='-*,clang-analyzer-core.NullDereference' %s -- | FileCheck %s
struct NoReturnDtor {

View File

@ -119,24 +119,22 @@ if platform.system() not in ['Windows']:
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",

View File

@ -18,8 +18,6 @@ add_subdirectory(change-namespace)
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)