Clang static analyzer plugin is now passed as a clang tidy argument.
If you find this approach reasonable I will update the clang part of this patch
as well.
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,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,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 {
@@ -261,6 +267,7 @@
OverrideOptions);
}
+
static int clangTidyMain(int argc, const char **argv) {
CommonOptionsParser OptionsParser(argc, argv, ClangTidyCategory);
@@ -270,6 +277,7 @@
std::string FileName = OptionsParser.getSourcePathList().front();
ClangTidyOptions EffectiveOptions = OptionsProvider->getOptions(FileName);
+ 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,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