diff options
author | Daniel Jasper <djasper@google.com> | 2013-07-29 08:19:24 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2013-07-29 08:19:24 +0000 |
commit | 62bb8df359f9552f40a673671d9ee0c918b0f002 (patch) | |
tree | 30a844bd1ef568fd3270aaba0f9fe2820131a544 /clang-tidy/ClangTidy.h | |
parent | 1245ea23fab19e891bf11c41177409ae30235e1e (diff) |
Initial architecture for clang-tidy.
This is the first version of a possible clang-tidy architecture. The
purpose of clang-tidy is to detect errors in adhering to common coding
patterns, e.g. described in the LLVM Coding Standards.
This is still heavily in flux.
Review: http://llvm-reviews.chandlerc.com/D884
git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@187345 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'clang-tidy/ClangTidy.h')
-rw-r--r-- | clang-tidy/ClangTidy.h | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/clang-tidy/ClangTidy.h b/clang-tidy/ClangTidy.h new file mode 100644 index 00000000..3e17c298 --- /dev/null +++ b/clang-tidy/ClangTidy.h @@ -0,0 +1,161 @@ +//===--- ClangTidy.h - clang-tidy -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_H + +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Tooling/Refactoring.h" + +namespace clang { + +class CompilerInstance; +namespace ast_matchers { +class MatchFinder; +} +namespace tooling { +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 +/// base class's methods. E.g. to implement a check that validates namespace +/// declarations, overwrite \c registerMatchers: +/// +/// \code +/// registerMatchers(ast_matchers::MatchFinder *Finder) { +/// Finder->addMatcher(namespaceDecl().bind("namespace"), this); +/// } +/// \endcode +/// +/// and then overwrite \c check(const MatchResult &Result) to do the actual +/// check for each match. +/// +/// A new \c ClangTidyCheck instance is created per translation unit. +/// +/// FIXME: Figure out whether carrying information from one TU to another is +/// useful/necessary. +class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { +public: + virtual ~ClangTidyCheck() {} + + /// \brief Overwrite this to register \c PPCallbacks with \c Compiler. + /// + /// This should be used for clang-tidy checks that analyze preprocessor- + /// dependent properties, e.g. the order of include directives. + virtual void registerPPCallbacks(CompilerInstance &Compiler) {} + + /// \brief Overwrite this to register ASTMatchers with \p Finder. + /// + /// This should be used by clang-tidy checks that analyze code properties that + /// dependent on AST knowledge. + /// + /// You can register as many matchers as necessary with \p Finder. Usually, + /// "this" will be used as callback, but you can also specify other callback + /// classes. Thereby, different matchers can trigger different callbacks. + /// + /// If you need to merge information between the different matchers, you can + /// store these as members of the derived class. However, note that all + /// matches occur in the order of the AST traversal. + virtual void registerMatchers(ast_matchers::MatchFinder *Finder) {} + + /// \brief \c ClangTidyChecks that register ASTMatchers should do the actual + /// work in here. + virtual void check(const ast_matchers::MatchFinder::MatchResult &Result) {} + + /// \brief The infrastructure sets the context to \p Ctx with this function. + void setContext(ClangTidyContext *Ctx) { Context = Ctx; } + +protected: + ClangTidyContext *Context; + +private: + virtual void run(const ast_matchers::MatchFinder::MatchResult &Result); +}; + +/// \brief Run a set of clang-tidy checks on a set of files. +void runClangTidy(StringRef CheckRegexString, + const tooling::CompilationDatabase &Compilations, + ArrayRef<std::string> Ranges, + SmallVectorImpl<ClangTidyError> *Errors); + +// FIXME: This interface will need to be significantly extended to be useful. +// FIXME: Implement confidence levels for displaying/fixing errors. +// +/// \brief Displays the found \p Errors to the users. If \p Fix is true, \p +/// Errors containing fixes are automatically applied. +void handleErrors(SmallVectorImpl<ClangTidyError> &Errors, bool Fix); + +} // end namespace tidy +} // end namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_H |