2013-07-29 16:19:24 +08:00
|
|
|
//===--- 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.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-03-10 00:52:33 +08:00
|
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDY_H
|
|
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDY_H
|
2013-07-29 16:19:24 +08:00
|
|
|
|
2014-01-08 04:05:01 +08:00
|
|
|
#include "ClangTidyDiagnosticConsumer.h"
|
2014-04-29 23:20:10 +08:00
|
|
|
#include "ClangTidyOptions.h"
|
2013-07-29 16:19:24 +08:00
|
|
|
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
|
|
|
#include "clang/Basic/Diagnostic.h"
|
|
|
|
#include "clang/Basic/SourceManager.h"
|
|
|
|
#include "clang/Tooling/Refactoring.h"
|
2014-09-12 16:53:36 +08:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2014-06-05 21:31:45 +08:00
|
|
|
#include <memory>
|
2014-09-12 16:53:36 +08:00
|
|
|
#include <type_traits>
|
2014-05-09 20:24:09 +08:00
|
|
|
#include <vector>
|
2013-07-29 16:19:24 +08:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
|
|
|
|
class CompilerInstance;
|
|
|
|
namespace tooling {
|
|
|
|
class CompilationDatabase;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace tidy {
|
|
|
|
|
2016-03-06 12:05:59 +08:00
|
|
|
/// \brief Provides access to the ``ClangTidyCheck`` options via check-local
|
2014-09-12 16:53:36 +08:00
|
|
|
/// names.
|
|
|
|
///
|
2016-03-06 12:05:59 +08:00
|
|
|
/// Methods of this class prepend ``CheckName + "."`` to translate check-local
|
|
|
|
/// option names to global option names.
|
2014-09-12 16:53:36 +08:00
|
|
|
class OptionsView {
|
|
|
|
public:
|
|
|
|
/// \brief Initializes the instance using \p CheckName + "." as a prefix.
|
|
|
|
OptionsView(StringRef CheckName,
|
|
|
|
const ClangTidyOptions::OptionMap &CheckOptions);
|
|
|
|
|
2016-03-06 12:05:59 +08:00
|
|
|
/// \brief Read a named option from the ``Context``.
|
2014-09-12 16:53:36 +08:00
|
|
|
///
|
|
|
|
/// Reads the option with the check-local name \p LocalName from the
|
2016-03-06 12:05:59 +08:00
|
|
|
/// ``CheckOptions``. If the corresponding key is not present, returns
|
2014-09-12 16:53:36 +08:00
|
|
|
/// \p Default.
|
2016-02-05 19:23:59 +08:00
|
|
|
std::string get(StringRef LocalName, StringRef Default) const;
|
|
|
|
|
2016-03-06 12:05:59 +08:00
|
|
|
/// \brief Read a named option from the ``Context``.
|
2016-02-05 19:23:59 +08:00
|
|
|
///
|
|
|
|
/// Reads the option with the check-local name \p LocalName from local or
|
2016-03-06 12:05:59 +08:00
|
|
|
/// global ``CheckOptions``. Gets local option first. If local is not present,
|
|
|
|
/// falls back to get global option. If global option is not present either,
|
|
|
|
/// returns Default.
|
2016-02-05 19:23:59 +08:00
|
|
|
std::string getLocalOrGlobal(StringRef LocalName, StringRef Default) const;
|
2014-09-12 16:53:36 +08:00
|
|
|
|
2016-03-06 12:05:59 +08:00
|
|
|
/// \brief Read a named option from the ``Context`` and parse it as an
|
|
|
|
/// integral type ``T``.
|
2014-09-12 16:53:36 +08:00
|
|
|
///
|
|
|
|
/// Reads the option with the check-local name \p LocalName from the
|
2016-03-06 12:05:59 +08:00
|
|
|
/// ``CheckOptions``. If the corresponding key is not present, returns
|
2014-09-12 16:53:36 +08:00
|
|
|
/// \p Default.
|
|
|
|
template <typename T>
|
|
|
|
typename std::enable_if<std::is_integral<T>::value, T>::type
|
|
|
|
get(StringRef LocalName, T Default) const {
|
|
|
|
std::string Value = get(LocalName, "");
|
|
|
|
T Result = Default;
|
|
|
|
if (!Value.empty())
|
|
|
|
StringRef(Value).getAsInteger(10, Result);
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2016-08-04 22:54:54 +08:00
|
|
|
/// \brief Read a named option from the ``Context`` and parse it as an
|
|
|
|
/// integral type ``T``.
|
|
|
|
///
|
|
|
|
/// Reads the option with the check-local name \p LocalName from local or
|
|
|
|
/// global ``CheckOptions``. Gets local option first. If local is not present,
|
|
|
|
/// falls back to get global option. If global option is not present either,
|
|
|
|
/// returns Default.
|
|
|
|
template <typename T>
|
|
|
|
typename std::enable_if<std::is_integral<T>::value, T>::type
|
|
|
|
getLocalOrGlobal(StringRef LocalName, T Default) const {
|
|
|
|
std::string Value = getLocalOrGlobal(LocalName, "");
|
|
|
|
T Result = Default;
|
|
|
|
if (!Value.empty())
|
|
|
|
StringRef(Value).getAsInteger(10, Result);
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2014-09-12 16:53:36 +08:00
|
|
|
/// \brief Stores an option with the check-local name \p LocalName with string
|
|
|
|
/// value \p Value to \p Options.
|
|
|
|
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
|
|
|
|
StringRef Value) const;
|
|
|
|
|
|
|
|
/// \brief Stores an option with the check-local name \p LocalName with
|
2016-03-06 12:05:59 +08:00
|
|
|
/// ``int64_t`` value \p Value to \p Options.
|
2014-09-12 16:53:36 +08:00
|
|
|
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
|
|
|
|
int64_t Value) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::string NamePrefix;
|
|
|
|
const ClangTidyOptions::OptionMap &CheckOptions;
|
|
|
|
};
|
|
|
|
|
2013-07-29 16:19:24 +08:00
|
|
|
/// \brief Base class for all clang-tidy checks.
|
|
|
|
///
|
2016-03-06 12:05:59 +08:00
|
|
|
/// To implement a ``ClangTidyCheck``, write a subclass and override some of the
|
2013-07-29 16:19:24 +08:00
|
|
|
/// base class's methods. E.g. to implement a check that validates namespace
|
2016-03-06 12:05:59 +08:00
|
|
|
/// declarations, override ``registerMatchers``:
|
2013-07-29 16:19:24 +08:00
|
|
|
///
|
2016-06-17 19:43:33 +08:00
|
|
|
/// ~~~{.cpp}
|
2016-03-06 12:05:59 +08:00
|
|
|
/// void registerMatchers(ast_matchers::MatchFinder *Finder) override {
|
2013-07-29 16:19:24 +08:00
|
|
|
/// Finder->addMatcher(namespaceDecl().bind("namespace"), this);
|
|
|
|
/// }
|
2016-06-17 19:43:33 +08:00
|
|
|
/// ~~~
|
2013-07-29 16:19:24 +08:00
|
|
|
///
|
2016-03-06 12:05:59 +08:00
|
|
|
/// and then override ``check(const MatchResult &Result)`` to do the actual
|
2013-07-29 16:19:24 +08:00
|
|
|
/// check for each match.
|
|
|
|
///
|
2016-03-06 12:05:59 +08:00
|
|
|
/// A new ``ClangTidyCheck`` instance is created per translation unit.
|
2013-07-29 16:19:24 +08:00
|
|
|
///
|
|
|
|
/// FIXME: Figure out whether carrying information from one TU to another is
|
|
|
|
/// useful/necessary.
|
|
|
|
class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
|
|
|
|
public:
|
2014-09-12 16:53:36 +08:00
|
|
|
/// \brief Initializes the check with \p CheckName and \p Context.
|
|
|
|
///
|
|
|
|
/// Derived classes must implement the constructor with this signature or
|
|
|
|
/// delegate it. If a check needs to read options, it can do this in the
|
|
|
|
/// constructor using the Options.get() methods below.
|
|
|
|
ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context)
|
|
|
|
: CheckName(CheckName), Context(Context),
|
|
|
|
Options(CheckName, Context->getOptions().CheckOptions) {
|
|
|
|
assert(Context != nullptr);
|
|
|
|
assert(!CheckName.empty());
|
|
|
|
}
|
|
|
|
|
2016-03-06 12:05:59 +08:00
|
|
|
/// \brief Override this to register ``PPCallbacks`` with ``Compiler``.
|
2013-07-29 16:19:24 +08:00
|
|
|
///
|
|
|
|
/// 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) {}
|
|
|
|
|
2016-06-17 19:43:33 +08:00
|
|
|
/// \brief Override this to register AST matchers with \p Finder.
|
2013-07-29 16:19:24 +08:00
|
|
|
///
|
|
|
|
/// 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) {}
|
|
|
|
|
2016-03-06 12:05:59 +08:00
|
|
|
/// \brief ``ClangTidyChecks`` that register ASTMatchers should do the actual
|
2013-07-29 16:19:24 +08:00
|
|
|
/// work in here.
|
|
|
|
virtual void check(const ast_matchers::MatchFinder::MatchResult &Result) {}
|
|
|
|
|
2014-01-13 18:50:51 +08:00
|
|
|
/// \brief Add a diagnostic with the check's name.
|
2014-03-03 07:34:48 +08:00
|
|
|
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description,
|
|
|
|
DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
|
2014-01-13 18:50:51 +08:00
|
|
|
|
2014-09-12 16:53:36 +08:00
|
|
|
/// \brief Should store all options supported by this check with their
|
|
|
|
/// current values or default values for options that haven't been overridden.
|
|
|
|
///
|
2016-03-06 12:05:59 +08:00
|
|
|
/// The check should use ``Options.store()`` to store each option it supports
|
2014-09-12 16:53:36 +08:00
|
|
|
/// whether it has the default value or it has been overridden.
|
|
|
|
virtual void storeOptions(ClangTidyOptions::OptionMap &Options) {}
|
2013-07-29 16:19:24 +08:00
|
|
|
|
|
|
|
private:
|
2014-03-02 18:20:11 +08:00
|
|
|
void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
2014-10-24 01:23:20 +08:00
|
|
|
StringRef getID() const override { return CheckName; }
|
2014-01-13 18:50:51 +08:00
|
|
|
std::string CheckName;
|
2014-09-12 16:53:36 +08:00
|
|
|
ClangTidyContext *Context;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
OptionsView Options;
|
2015-05-21 22:08:56 +08:00
|
|
|
/// \brief Returns the main file name of the current translation unit.
|
|
|
|
StringRef getCurrentMainFile() const { return Context->getCurrentFile(); }
|
2015-08-28 21:20:46 +08:00
|
|
|
/// \brief Returns the language options from the context.
|
|
|
|
LangOptions getLangOpts() const { return Context->getLangOpts(); }
|
2013-07-29 16:19:24 +08:00
|
|
|
};
|
|
|
|
|
2014-01-03 17:31:57 +08:00
|
|
|
class ClangTidyCheckFactories;
|
|
|
|
|
|
|
|
class ClangTidyASTConsumerFactory {
|
|
|
|
public:
|
2014-06-05 21:31:45 +08:00
|
|
|
ClangTidyASTConsumerFactory(ClangTidyContext &Context);
|
2014-01-03 17:31:57 +08:00
|
|
|
|
|
|
|
/// \brief Returns an ASTConsumer that runs the specified clang-tidy checks.
|
2014-08-11 03:56:59 +08:00
|
|
|
std::unique_ptr<clang::ASTConsumer>
|
|
|
|
CreateASTConsumer(clang::CompilerInstance &Compiler, StringRef File);
|
2014-01-03 17:31:57 +08:00
|
|
|
|
|
|
|
/// \brief Get the list of enabled checks.
|
2014-09-12 16:53:36 +08:00
|
|
|
std::vector<std::string> getCheckNames();
|
|
|
|
|
|
|
|
/// \brief Get the union of options from all checks.
|
|
|
|
ClangTidyOptions::OptionMap getCheckOptions();
|
2014-01-03 17:31:57 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
ClangTidyContext &Context;
|
2014-03-09 17:24:40 +08:00
|
|
|
std::unique_ptr<ClangTidyCheckFactories> CheckFactories;
|
2014-01-03 17:31:57 +08:00
|
|
|
};
|
|
|
|
|
Clang-tidy: added --disable-checks, --list-checks options.
Summary:
Allow disabling checks by regex. By default, disable alpha.* checks,
that are not particularly good tested (e.g. IdempotentOperationChecker, see
http://llvm-reviews.chandlerc.com/D2427).
Fixed a bug, that would disable all analyzer checks, when using a regex more
strict, than 'clang-analyzer-', for example --checks='clang-analyzer-deadcode-'.
Added --list-checks to list all enabled checks. This is useful to test specific
values in --checks/--disable-checks.
Reviewers: djasper, klimek
Reviewed By: klimek
CC: cfe-commits, klimek
Differential Revision: http://llvm-reviews.chandlerc.com/D2444
llvm-svn: 197717
2013-12-20 03:57:05 +08:00
|
|
|
/// \brief Fills the list of check names that are enabled when the provided
|
|
|
|
/// filters are applied.
|
2014-04-29 23:20:10 +08:00
|
|
|
std::vector<std::string> getCheckNames(const ClangTidyOptions &Options);
|
Clang-tidy: added --disable-checks, --list-checks options.
Summary:
Allow disabling checks by regex. By default, disable alpha.* checks,
that are not particularly good tested (e.g. IdempotentOperationChecker, see
http://llvm-reviews.chandlerc.com/D2427).
Fixed a bug, that would disable all analyzer checks, when using a regex more
strict, than 'clang-analyzer-', for example --checks='clang-analyzer-deadcode-'.
Added --list-checks to list all enabled checks. This is useful to test specific
values in --checks/--disable-checks.
Reviewers: djasper, klimek
Reviewed By: klimek
CC: cfe-commits, klimek
Differential Revision: http://llvm-reviews.chandlerc.com/D2444
llvm-svn: 197717
2013-12-20 03:57:05 +08:00
|
|
|
|
2014-09-12 16:53:36 +08:00
|
|
|
/// \brief Returns the effective check-specific options.
|
|
|
|
///
|
|
|
|
/// The method configures ClangTidy with the specified \p Options and collects
|
|
|
|
/// effective options from all created checks. The returned set of options
|
|
|
|
/// includes default check-specific options for all keys not overridden by \p
|
|
|
|
/// Options.
|
|
|
|
ClangTidyOptions::OptionMap getCheckOptions(const ClangTidyOptions &Options);
|
|
|
|
|
2013-07-29 16:19:24 +08:00
|
|
|
/// \brief Run a set of clang-tidy checks on a set of files.
|
2014-10-24 01:23:20 +08:00
|
|
|
///
|
2018-05-09 04:24:45 +08:00
|
|
|
/// \param EnableCheckProfile If provided, it enables check profile collection
|
|
|
|
/// in MatchFinder, and will contain the result of the profile.
|
2017-04-06 21:41:29 +08:00
|
|
|
void runClangTidy(clang::tidy::ClangTidyContext &Context,
|
|
|
|
const tooling::CompilationDatabase &Compilations,
|
|
|
|
ArrayRef<std::string> InputFiles,
|
2018-01-23 20:31:06 +08:00
|
|
|
llvm::IntrusiveRefCntPtr<vfs::FileSystem> BaseFS,
|
[clang-tidy] Profile is a per-AST (per-TU) data.
Summary:
As discussed in D45931, currently, profiling output of clang-tidy is somewhat not great.
It outputs one profile at the end of the execution, and that profile contains the data
from the last TU that was processed. So if the tool run on multiple TU's, the data is
not accumulated, it is simply discarded.
It would be nice to improve this.
This differential is the first step - make this profiling info per-TU,
and output it after the tool has finished processing each TU.
In particular, when `ClangTidyASTConsumer` destructor runs.
Next step will be to add a CSV (JSON?) printer to store said profiles under user-specified directory prefix.
Reviewers: alexfh, sbenza
Reviewed By: alexfh
Subscribers: Eugene.Zelenko, mgorny, xazax.hun, mgrang, klimek, cfe-commits
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D46504
llvm-svn: 331763
2018-05-08 21:14:21 +08:00
|
|
|
bool EnableCheckProfile = false);
|
2013-07-29 16:19:24 +08:00
|
|
|
|
|
|
|
// 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
|
2016-12-01 02:06:42 +08:00
|
|
|
/// Errors containing fixes are automatically applied and reformatted. If no
|
|
|
|
/// clang-format configuration file is found, the given \P FormatStyle is used.
|
2017-04-06 21:41:29 +08:00
|
|
|
void handleErrors(ClangTidyContext &Context, bool Fix,
|
2018-01-23 20:31:06 +08:00
|
|
|
unsigned &WarningsAsErrorsCount,
|
|
|
|
llvm::IntrusiveRefCntPtr<vfs::FileSystem> BaseFS);
|
2013-07-29 16:19:24 +08:00
|
|
|
|
2014-09-04 18:31:23 +08:00
|
|
|
/// \brief Serializes replacements into YAML and writes them to the specified
|
|
|
|
/// output stream.
|
2017-01-03 22:36:13 +08:00
|
|
|
void exportReplacements(StringRef MainFilePath,
|
|
|
|
const std::vector<ClangTidyError> &Errors,
|
2014-09-04 18:31:23 +08:00
|
|
|
raw_ostream &OS);
|
|
|
|
|
2013-07-29 16:19:24 +08:00
|
|
|
} // end namespace tidy
|
|
|
|
} // end namespace clang
|
|
|
|
|
2015-03-10 00:52:33 +08:00
|
|
|
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDY_H
|