[clang-tools-extra] r194707 - Make clang's static analyzer checks available through clang-tidy.
Manuel Klimek
klimek at google.com
Thu Nov 14 07:49:44 PST 2013
Author: klimek
Date: Thu Nov 14 09:49:44 2013
New Revision: 194707
URL: http://llvm.org/viewvc/llvm-project?rev=194707&view=rev
Log:
Make clang's static analyzer checks available through clang-tidy.
This is implemented in a way that the current static analyzer
architecture allows, in the future we might want to revisit this.
With this change static analyzer checks are available from clang-tidy
by specifying -checks=clang-analyzer-<name>.
This change also fixes the use of the compilation database to allow
clang-tidy to be used like any other clang tool.
Added:
clang-tools-extra/trunk/test/clang-tidy/static-analyzer.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/CMakeLists.txt
clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
clang-tools-extra/trunk/clang-tidy/ClangTidy.h
clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h
clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt
clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp
clang-tools-extra/trunk/clang-tidy/tool/Makefile
clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h
clang-tools-extra/trunk/unittests/clang-tidy/Makefile
Modified: clang-tools-extra/trunk/clang-tidy/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/CMakeLists.txt?rev=194707&r1=194706&r2=194707&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/CMakeLists.txt Thu Nov 14 09:49:44 2013
@@ -14,6 +14,8 @@ target_link_libraries(clangTidy
clangTooling
clangBasic
clangRewriteFrontend
+ clangStaticAnalyzerFrontend
+ clangStaticAnalyzerCheckers
)
add_subdirectory(tool)
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp?rev=194707&r1=194706&r2=194707&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp Thu Nov 14 09:49:44 2013
@@ -30,6 +30,7 @@
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Rewrite/Frontend/FixItRewriter.h"
#include "clang/Rewrite/Frontend/FrontendActions.h"
+#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Tooling/Refactoring.h"
#include "llvm/Support/Path.h"
@@ -45,15 +46,83 @@ namespace clang {
namespace tidy {
namespace {
-class ClangTidyPPAction : public PreprocessOnlyAction {
+/// \brief A combined ASTConsumer that forwards calls to two different
+/// consumers.
+///
+/// FIXME: This currently forwards just enough methods for the static analyzer
+/// and the \c MatchFinder's consumer to work; expand this to all methods of
+/// ASTConsumer and put it into a common location.
+class CombiningASTConsumer : public ASTConsumer {
public:
- ClangTidyPPAction(SmallVectorImpl<ClangTidyCheck *> &Checks,
- ClangTidyContext &Context)
- : Checks(Checks), Context(Context) {}
+ CombiningASTConsumer(ASTConsumer *Consumer1, ASTConsumer *Consumer2)
+ : Consumer1(Consumer1), Consumer2(Consumer2) {}
+
+ virtual void Initialize(ASTContext &Context) LLVM_OVERRIDE {
+ Consumer1->Initialize(Context);
+ Consumer2->Initialize(Context);
+ }
+ virtual bool HandleTopLevelDecl(DeclGroupRef D) LLVM_OVERRIDE {
+ return Consumer1->HandleTopLevelDecl(D) && Consumer2->HandleTopLevelDecl(D);
+ }
+ virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) LLVM_OVERRIDE {
+ Consumer1->HandleTopLevelDeclInObjCContainer(D);
+ Consumer2->HandleTopLevelDeclInObjCContainer(D);
+ }
+ virtual void HandleTranslationUnit(ASTContext &Context) LLVM_OVERRIDE {
+ Consumer1->HandleTranslationUnit(Context);
+ Consumer2->HandleTranslationUnit(Context);
+ }
+
+private:
+ llvm::OwningPtr<ASTConsumer> Consumer1;
+ llvm::OwningPtr<ASTConsumer> Consumer2;
+};
+
+/// \brief Action that runs clang-tidy and static analyzer checks.
+///
+/// FIXME: Note that this inherits from \c AnalysisAction as this is the only
+/// way we can currently get to AnalysisAction::CreateASTConsumer. Ideally
+/// we'd want to build a more generic way to use \c FrontendAction based
+/// checkers in clang-tidy, but that needs some preperation work first.
+class ClangTidyAction : public ento::AnalysisAction {
+public:
+ ClangTidyAction(StringRef CheckRegexString,
+ SmallVectorImpl<ClangTidyCheck *> &Checks,
+ ClangTidyContext &Context, MatchFinder &Finder)
+ : CheckRegexString(CheckRegexString), Checks(Checks), Context(Context),
+ Finder(Finder) {}
private:
+ clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &Compiler,
+ StringRef File) LLVM_OVERRIDE {
+ AnalyzerOptionsRef Options = Compiler.getAnalyzerOpts();
+ llvm::Regex CheckRegex(CheckRegexString);
+
+// Run our regex against all possible static analyzer checkers.
+// Note that debug checkers print values / run programs to visualize the CFG
+// and are thus not applicable to clang-tidy in general.
+#define GET_CHECKERS
+#define CHECKER(FULLNAME, CLASS, DESCFILE, HELPTEXT, GROUPINDEX, HIDDEN) \
+ if (!StringRef(FULLNAME).startswith("debug") && \
+ CheckRegex.match("clang-analyzer-" FULLNAME)) \
+ Options->CheckersControlList.push_back(std::make_pair(FULLNAME, true));
+#include "../../../lib/StaticAnalyzer/Checkers/Checkers.inc"
+#undef CHECKER
+#undef GET_CHECKERS
+
+ Options->AnalysisStoreOpt = RegionStoreModel;
+ Options->AnalysisDiagOpt = PD_TEXT;
+ Options->AnalyzeNestedBlocks = true;
+ Options->eagerlyAssumeBinOpBifurcation = true;
+ return new CombiningASTConsumer(
+ Finder.newASTConsumer(),
+ ento::AnalysisAction::CreateASTConsumer(Compiler, File));
+ }
+
virtual bool BeginSourceFileAction(CompilerInstance &Compiler,
- llvm::StringRef file_name) {
+ llvm::StringRef Filename) LLVM_OVERRIDE {
+ if (!ento::AnalysisAction::BeginSourceFileAction(Compiler, Filename))
+ return false;
Context.setSourceManager(&Compiler.getSourceManager());
for (SmallVectorImpl<ClangTidyCheck *>::iterator I = Checks.begin(),
E = Checks.end();
@@ -62,35 +131,61 @@ private:
return true;
}
+ std::string CheckRegexString;
SmallVectorImpl<ClangTidyCheck *> &Checks;
ClangTidyContext &Context;
+ MatchFinder &Finder;
};
-class ClangTidyPPActionFactory : public FrontendActionFactory {
+class ClangTidyActionFactory : public FrontendActionFactory {
public:
- ClangTidyPPActionFactory(SmallVectorImpl<ClangTidyCheck *> &Checks,
- ClangTidyContext &Context)
- : Checks(Checks), Context(Context) {}
+ ClangTidyActionFactory(StringRef CheckRegexString, ClangTidyContext &Context)
+ : CheckRegexString(CheckRegexString), Context(Context) {
+ ClangTidyCheckFactories CheckFactories;
+ for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
+ E = ClangTidyModuleRegistry::end();
+ I != E; ++I) {
+ OwningPtr<ClangTidyModule> Module(I->instantiate());
+ Module->addCheckFactories(CheckFactories);
+ }
+
+ SmallVector<ClangTidyCheck *, 16> Checks;
+ CheckFactories.createChecks(CheckRegexString, Checks);
+
+ for (SmallVectorImpl<ClangTidyCheck *>::iterator I = Checks.begin(),
+ E = Checks.end();
+ I != E; ++I) {
+ (*I)->setContext(&Context);
+ (*I)->registerMatchers(&Finder);
+ }
+ }
virtual FrontendAction *create() {
- return new ClangTidyPPAction(Checks, Context);
+ return new ClangTidyAction(CheckRegexString, Checks, Context, Finder);
}
private:
- SmallVectorImpl<ClangTidyCheck *> &Checks;
+ std::string CheckRegexString;
+ SmallVector<ClangTidyCheck *, 8> Checks;
ClangTidyContext &Context;
+ MatchFinder Finder;
};
} // namespace
-ClangTidyError::ClangTidyError(const SourceManager &Sources, SourceLocation Loc,
- StringRef Message,
- const tooling::Replacements &Fix)
- : Message(Message), Fix(Fix) {
+ClangTidyMessage::ClangTidyMessage(StringRef Message) : Message(Message) {}
+
+ClangTidyMessage::ClangTidyMessage(StringRef Message,
+ const SourceManager &Sources,
+ SourceLocation Loc)
+ : Message(Message) {
FilePath = Sources.getFilename(Loc);
FileOffset = Sources.getFileOffset(Loc);
}
+ClangTidyError::ClangTidyError(const ClangTidyMessage &Message)
+ : Message(Message) {}
+
DiagnosticBuilder ClangTidyContext::Diag(SourceLocation Loc,
StringRef Message) {
return DiagEngine->Report(
@@ -115,6 +210,11 @@ void ClangTidyCheck::run(const ast_match
check(Result);
}
+FrontendActionFactory *createClangTidyActionFactory(StringRef CheckRegexString,
+ ClangTidyContext &Context) {
+ return new ClangTidyActionFactory(CheckRegexString, Context);
+}
+
void runClangTidy(StringRef CheckRegexString,
const tooling::CompilationDatabase &Compilations,
ArrayRef<std::string> Ranges,
@@ -124,27 +224,24 @@ void runClangTidy(StringRef CheckRegexSt
ClangTool Tool(Compilations, Ranges);
clang::tidy::ClangTidyContext Context(Errors);
ClangTidyDiagnosticConsumer DiagConsumer(Context);
- ClangTidyCheckFactories CheckFactories;
- for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
- E = ClangTidyModuleRegistry::end();
- I != E; ++I) {
- OwningPtr<ClangTidyModule> Module(I->instantiate());
- Module->addCheckFactories(CheckFactories);
- }
- SmallVector<ClangTidyCheck *, 16> Checks;
- CheckFactories.createChecks(CheckRegexString, Checks);
+ Tool.setDiagnosticConsumer(&DiagConsumer);
+ Tool.run(createClangTidyActionFactory(CheckRegexString, Context));
+}
- MatchFinder Finder;
- for (SmallVectorImpl<ClangTidyCheck *>::iterator I = Checks.begin(),
- E = Checks.end();
- I != E; ++I) {
- (*I)->setContext(&Context);
- (*I)->registerMatchers(&Finder);
+static void reportDiagnostic(const ClangTidyMessage &Message,
+ SourceManager &SourceMgr,
+ DiagnosticsEngine::Level Level,
+ DiagnosticsEngine &Diags) {
+ SourceLocation Loc;
+ if (!Message.FilePath.empty()) {
+ const FileEntry *File =
+ SourceMgr.getFileManager().getFile(Message.FilePath);
+ FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
+ Loc = SourceMgr.getLocForStartOfFile(ID);
+ Loc = Loc.getLocWithOffset(Message.FileOffset);
}
-
- Tool.run(new ClangTidyPPActionFactory(Checks, Context));
- Tool.run(newFrontendActionFactory(&Finder));
+ Diags.Report(Loc, Diags.getCustomDiagID(Level, Message.Message));
}
void handleErrors(SmallVectorImpl<ClangTidyError> &Errors, bool Fix) {
@@ -160,11 +257,10 @@ void handleErrors(SmallVectorImpl<ClangT
for (SmallVectorImpl<ClangTidyError>::iterator I = Errors.begin(),
E = Errors.end();
I != E; ++I) {
- const FileEntry *File = Files.getFile(I->FilePath);
- FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
- SourceLocation Loc = SourceMgr.getLocForStartOfFile(ID);
- Diags.Report(Loc.getLocWithOffset(I->FileOffset),
- Diags.getCustomDiagID(DiagnosticsEngine::Warning, I->Message));
+ reportDiagnostic(I->Message, SourceMgr, DiagnosticsEngine::Warning, Diags);
+ for (unsigned i = 0, e = I->Notes.size(); i != e; ++i) {
+ reportDiagnostic(I->Notes[i], SourceMgr, DiagnosticsEngine::Note, Diags);
+ }
tooling::applyAllReplacements(I->Fix, Rewrite);
}
// FIXME: Run clang-format on changes.
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.h?rev=194707&r1=194706&r2=194707&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidy.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidy.h Thu Nov 14 09:49:44 2013
@@ -14,6 +14,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Tooling/Refactoring.h"
+#include "ClangTidyDiagnosticConsumer.h"
namespace clang {
@@ -27,64 +28,6 @@ class CompilationDatabase;
namespace tidy {
-/// \brief A detected error complete with information to display diagnostic and
-/// automatic fix.
-///
-/// This is used as an intermediate format to transport Diagnostics without a
-/// dependency on a SourceManager.
-///
-/// FIXME: Make Diagnostics flexible enough to support this directly.
-struct ClangTidyError {
- ClangTidyError(const SourceManager &Sources, SourceLocation Loc,
- StringRef Message, const tooling::Replacements &Fix);
-
- std::string Message;
- unsigned FileOffset;
- std::string FilePath;
- tooling::Replacements Fix;
-};
-
-/// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticEngine
-/// provided by this context.
-///
-/// A \c ClangTidyCheck always has access to the active context to report
-/// warnings like:
-/// \code
-/// Context->Diag(Loc, "Single-argument constructors must be explicit")
-/// << FixItHint::CreateInsertion(Loc, "explicit ");
-/// \endcode
-class ClangTidyContext {
-public:
- ClangTidyContext(SmallVectorImpl<ClangTidyError> *Errors) : Errors(Errors) {}
-
- /// \brief Report any errors detected using this method.
- ///
- /// This is still under heavy development and will likely change towards using
- /// tablegen'd diagnostic IDs.
- /// FIXME: Figure out a way to manage ID spaces.
- DiagnosticBuilder Diag(SourceLocation Loc, StringRef Message);
-
- /// \brief Sets the \c DiagnosticsEngine so that Diagnostics can be generated
- /// correctly.
- ///
- /// This is called from the \c ClangTidyCheck base class.
- void setDiagnosticsEngine(DiagnosticsEngine *Engine);
-
- /// \brief Sets the \c SourceManager of the used \c DiagnosticsEngine.
- ///
- /// This is called from the \c ClangTidyCheck base class.
- void setSourceManager(SourceManager *SourceMgr);
-
-private:
- friend class ClangTidyDiagnosticConsumer; // Calls storeError().
-
- /// \brief Store a \c ClangTidyError.
- void storeError(const ClangTidyError &Error);
-
- SmallVectorImpl<ClangTidyError> *Errors;
- DiagnosticsEngine *DiagEngine;
-};
-
/// \brief Base class for all clang-tidy checks.
///
/// To implement a \c ClangTidyCheck, write a subclass and overwrite some of the
@@ -142,6 +85,11 @@ private:
virtual void run(const ast_matchers::MatchFinder::MatchResult &Result);
};
+/// \brief Returns an action factory that runs the specified clang-tidy checks.
+tooling::FrontendActionFactory *
+createClangTidyActionFactory(StringRef CheckRegexString,
+ ClangTidyContext &Context);
+
/// \brief Run a set of clang-tidy checks on a set of files.
void runClangTidy(StringRef CheckRegexString,
const tooling::CompilationDatabase &Compilations,
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h?rev=194707&r1=194706&r2=194707&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h Thu Nov 14 09:49:44 2013
@@ -27,6 +27,74 @@ class CompilationDatabase;
namespace tidy {
+/// \brief A message from a clang-tidy check.
+///
+/// Note that this is independent of a \c SourceManager.
+struct ClangTidyMessage {
+ ClangTidyMessage(StringRef Message = "");
+ ClangTidyMessage(StringRef Message, const SourceManager &Sources,
+ SourceLocation Loc);
+ std::string Message;
+ std::string FilePath;
+ unsigned FileOffset;
+};
+
+/// \brief A detected error complete with information to display diagnostic and
+/// automatic fix.
+///
+/// This is used as an intermediate format to transport Diagnostics without a
+/// dependency on a SourceManager.
+///
+/// FIXME: Make Diagnostics flexible enough to support this directly.
+struct ClangTidyError {
+ ClangTidyError(const ClangTidyMessage &Message);
+
+ ClangTidyMessage Message;
+ tooling::Replacements Fix;
+ SmallVector<ClangTidyMessage, 1> Notes;
+};
+
+/// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticEngine
+/// provided by this context.
+///
+/// A \c ClangTidyCheck always has access to the active context to report
+/// warnings like:
+/// \code
+/// Context->Diag(Loc, "Single-argument constructors must be explicit")
+/// << FixItHint::CreateInsertion(Loc, "explicit ");
+/// \endcode
+class ClangTidyContext {
+public:
+ ClangTidyContext(SmallVectorImpl<ClangTidyError> *Errors) : Errors(Errors) {}
+
+ /// \brief Report any errors detected using this method.
+ ///
+ /// This is still under heavy development and will likely change towards using
+ /// tablegen'd diagnostic IDs.
+ /// FIXME: Figure out a way to manage ID spaces.
+ DiagnosticBuilder Diag(SourceLocation Loc, StringRef Message);
+
+ /// \brief Sets the \c DiagnosticsEngine so that Diagnostics can be generated
+ /// correctly.
+ ///
+ /// This is called from the \c ClangTidyCheck base class.
+ void setDiagnosticsEngine(DiagnosticsEngine *Engine);
+
+ /// \brief Sets the \c SourceManager of the used \c DiagnosticsEngine.
+ ///
+ /// This is called from the \c ClangTidyCheck base class.
+ void setSourceManager(SourceManager *SourceMgr);
+
+private:
+ friend class ClangTidyDiagnosticConsumer; // Calls storeError().
+
+ /// \brief Store a \c ClangTidyError.
+ void storeError(const ClangTidyError &Error);
+
+ SmallVectorImpl<ClangTidyError> *Errors;
+ DiagnosticsEngine *DiagEngine;
+};
+
/// \brief A diagnostic consumer that turns each \c Diagnostic into a
/// \c SourceManager-independent \c ClangTidyError.
//
@@ -47,22 +115,46 @@ public:
// library.
virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const Diagnostic &Info) {
- tooling::Replacements Replacements;
+ if (DiagLevel != DiagnosticsEngine::Note) {
+ Errors.push_back(ClangTidyError(getMessage(Info)));
+ } else {
+ Errors.back().Notes.push_back(getMessage(Info));
+ }
+ addFixes(Info, Errors.back());
+ }
+
+ virtual void finish() {
+ for (unsigned i = 0, e = Errors.size(); i != e; ++i) {
+ Context.storeError(Errors[i]);
+ }
+ }
+
+private:
+ void addFixes(const Diagnostic &Info, ClangTidyError &Error) {
+ if (!Info.hasSourceManager())
+ return;
SourceManager &SourceMgr = Info.getSourceManager();
+ tooling::Replacements Replacements;
for (unsigned i = 0, e = Info.getNumFixItHints(); i != e; ++i) {
- Replacements.insert(tooling::Replacement(
+ Error.Fix.insert(tooling::Replacement(
SourceMgr, Info.getFixItHint(i).RemoveRange.getBegin(), 0,
Info.getFixItHint(i).CodeToInsert));
}
+ }
+
+ ClangTidyMessage getMessage(const Diagnostic &Info) const {
SmallString<100> Buf;
Info.FormatDiagnostic(Buf);
- Context.storeError(
- ClangTidyError(SourceMgr, Info.getLocation(), Buf.str(), Replacements));
+ if (!Info.hasSourceManager()) {
+ return ClangTidyMessage(Buf.str());
+ }
+ return ClangTidyMessage(Buf.str(), Info.getSourceManager(),
+ Info.getLocation());
}
-private:
ClangTidyContext &Context;
OwningPtr<DiagnosticsEngine> Diags;
+ SmallVector<ClangTidyError, 8> Errors;
};
} // end namespace tidy
Modified: clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt?rev=194707&r1=194706&r2=194707&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/tool/CMakeLists.txt Thu Nov 14 09:49:44 2013
@@ -13,6 +13,7 @@ target_link_libraries(clang-tidy
clangTidy
clangTidyLLVMModule
clangTidyGoogleModule
+ clangStaticAnalyzerCheckers
)
install(TARGETS clang-tidy
Modified: clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp?rev=194707&r1=194706&r2=194707&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp Thu Nov 14 09:49:44 2013
@@ -16,6 +16,7 @@
//===----------------------------------------------------------------------===//
#include "../ClangTidy.h"
+#include "clang/Tooling/CommonOptionsParser.h"
#include "llvm/Support/CommandLine.h"
#include <vector>
@@ -26,8 +27,7 @@ using namespace llvm;
cl::OptionCategory ClangTidyCategory("clang-tidy options");
-cl::list<std::string>
-Ranges(cl::Positional, cl::desc("<range0> [... <rangeN>]"), cl::OneOrMore);
+static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::opt<std::string> Checks(
"checks",
@@ -39,15 +39,11 @@ static cl::opt<bool> Fix("fix", cl::desc
// FIXME: Add option to list name/description of all checks.
int main(int argc, const char **argv) {
- cl::ParseCommandLineOptions(argc, argv, "TBD\n");
- OwningPtr<clang::tooling::CompilationDatabase> Compilations(
- FixedCompilationDatabase::loadFromCommandLine(argc, argv));
- if (!Compilations)
- return 0;
- // FIXME: Load other compilation databases.
+ CommonOptionsParser OptionsParser(argc, argv);
SmallVector<clang::tidy::ClangTidyError, 16> Errors;
- clang::tidy::runClangTidy(Checks, *Compilations, Ranges, &Errors);
+ clang::tidy::runClangTidy(Checks, OptionsParser.getCompilations(),
+ OptionsParser.getSourcePathList(), &Errors);
clang::tidy::handleErrors(Errors, Fix);
return 0;
Modified: clang-tools-extra/trunk/clang-tidy/tool/Makefile
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/tool/Makefile?rev=194707&r1=194706&r2=194707&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/tool/Makefile (original)
+++ clang-tools-extra/trunk/clang-tidy/tool/Makefile Thu Nov 14 09:49:44 2013
@@ -17,6 +17,8 @@ TOOL_NO_EXPORTS = 1
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
+ clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
+ clangStaticAnalyzerCore.a \
clangFormat.a clangASTMatchers.a clangTooling.a clangFrontend.a \
clangSerialization.a clangDriver.a clangParse.a clangSema.a \
clangAnalysis.a clangRewriteFrontend.a clangRewriteCore.a \
Added: clang-tools-extra/trunk/test/clang-tidy/static-analyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/static-analyzer.cpp?rev=194707&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/static-analyzer.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/static-analyzer.cpp Thu Nov 14 09:49:44 2013
@@ -0,0 +1,8 @@
+// RUN: clang-tidy %s -checks='clang-analyzer-cplusplus' -- | FileCheck %s
+
+void f() {
+ int *p = new int(42);
+ delete p;
+ delete p;
+ // CHECK: warning: Attempt to free released memory
+}
Modified: clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h?rev=194707&r1=194706&r2=194707&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h (original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h Thu Nov 14 09:49:44 2013
@@ -36,6 +36,7 @@ protected:
OwningPtr<tooling::FrontendActionFactory> Factory(
tooling::newFrontendActionFactory(&Finder));
EXPECT_TRUE(tooling::runToolOnCode(Factory->create(), Code));
+ DiagConsumer.finish();
tooling::Replacements Fixes;
for (SmallVector<ClangTidyError, 16>::const_iterator I = Errors.begin(),
E = Errors.end();
Modified: clang-tools-extra/trunk/unittests/clang-tidy/Makefile
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/Makefile?rev=194707&r1=194706&r2=194707&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-tidy/Makefile (original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/Makefile Thu Nov 14 09:49:44 2013
@@ -14,6 +14,8 @@ TESTNAME = ClangTidy
LINK_COMPONENTS := asmparser bitreader support MC MCParser option \
TransformUtils
USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
+ clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
+ clangStaticAnalyzerCore.a \
clangFormat.a clangTooling.a clangFrontend.a clangSerialization.a \
clangDriver.a clangRewriteFrontend.a clangRewriteCore.a \
clangParse.a clangSema.a clangAnalysis.a clangAST.a \
More information about the cfe-commits
mailing list