Skip to content

Commit

Permalink
[clang-tidy] Added virtual isLanguageVersionSupported to ClangTidyCheck
Browse files Browse the repository at this point in the history
Summary:
Motivated by [[ https://bugs.llvm.org/show_bug.cgi?id=45045 | Tune inspections to a specific C++ standard. ]]
Moves the isLanguageVersionSupported virtual function from `MakeSmartPtrCheck` to the base `ClangTidyCheck` class.
This will disable registering matchers or pp callbacks on unsupported language versions for a check.
Having it as a standalone function is cleaner than manually disabling the check in the register function and should hopefully
encourage check developers to actually restrict the check based on language version.
As an added bonus this could enable automatic detection of what language version a check runs on for the purpose of documentation generation

Reviewers: aaron.ballman, gribozavr2, Eugene.Zelenko, JonasToth, alexfh, hokein

Reviewed By: gribozavr2

Subscribers: xazax.hun, jkorous, arphaman, kadircet, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D75289
  • Loading branch information
njames93 committed Feb 28, 2020
1 parent f829615 commit 39c4246
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 6 deletions.
2 changes: 2 additions & 0 deletions clang-tools-extra/clang-tidy/ClangTidy.cpp
Expand Up @@ -409,6 +409,8 @@ ClangTidyASTConsumerFactory::CreateASTConsumer(
}

for (auto &Check : Checks) {
if (!Check->isLanguageVersionSupported(Context.getLangOpts()))
continue;
Check->registerMatchers(&*Finder);
Check->registerPPCallbacks(*SM, PP, ModuleExpanderPP);
}
Expand Down
16 changes: 16 additions & 0 deletions clang-tools-extra/clang-tidy/ClangTidyCheck.h
Expand Up @@ -53,11 +53,24 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
/// constructor using the Options.get() methods below.
ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);

/// Override this to disable registering matchers and PP callbacks if an
/// invalid language version is being used.
///
/// For example if a check is examining overloaded functions then this should
/// be overridden to return false when the CPlusPlus flag is not set in
/// \p LangOpts.
virtual bool isLanguageVersionSupported(const LangOptions &LangOpts) const {
return true;
}

/// Override this to register ``PPCallbacks`` in the preprocessor.
///
/// This should be used for clang-tidy checks that analyze preprocessor-
/// dependent properties, e.g. include directives and macro definitions.
///
/// This will only be executed if the function isLanguageVersionSupported
/// returns true.
///
/// There are two Preprocessors to choose from that differ in how they handle
/// modular #includes:
/// - PP is the real Preprocessor. It doesn't walk into modular #includes and
Expand All @@ -80,6 +93,9 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
/// "this" will be used as callback, but you can also specify other callback
/// classes. Thereby, different matchers can trigger different callbacks.
///
/// This will only be executed if the function isLanguageVersionSupported
/// returns true.
///
/// 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.
Expand Down
5 changes: 0 additions & 5 deletions clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
Expand Up @@ -68,17 +68,12 @@ bool MakeSmartPtrCheck::isLanguageVersionSupported(
void MakeSmartPtrCheck::registerPPCallbacks(const SourceManager &SM,
Preprocessor *PP,
Preprocessor *ModuleExpanderPP) {
if (isLanguageVersionSupported(getLangOpts())) {
Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
IncludeStyle);
PP->addPPCallbacks(Inserter->CreatePPCallbacks());
}
}

void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
if (!isLanguageVersionSupported(getLangOpts()))
return;

// Calling make_smart_ptr from within a member function of a type with a
// private or protected constructor would be ill-formed.
auto CanCallCtor = unless(has(ignoringImpCasts(
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
Expand Up @@ -41,7 +41,7 @@ class MakeSmartPtrCheck : public ClangTidyCheck {
virtual SmartPtrTypeMatcher getSmartPointerTypeMatcher() const = 0;

/// Returns whether the C++ version is compatible with current check.
virtual bool isLanguageVersionSupported(const LangOptions &LangOpts) const;
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override;

static const char PointerType[];

Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/clangd/ParsedAST.cpp
Expand Up @@ -301,6 +301,8 @@ ParsedAST::build(std::unique_ptr<clang::CompilerInvocation> CI,
});
Preprocessor *PP = &Clang->getPreprocessor();
for (const auto &Check : CTChecks) {
if (!Check->isLanguageVersionSupported(CTContext->getLangOpts()))
continue;
// FIXME: the PP callbacks skip the entire preamble.
// Checks that want to see #includes in the main file do not see them.
Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
Expand Up @@ -67,6 +67,8 @@ class TestClangTidyAction : public ASTFrontendAction {
// `getLangOpts()`).
CheckFactory<CheckTypes...>::createChecks(&Context, Checks);
for (auto &Check : Checks) {
if (!Check->isLanguageVersionSupported(Context.getLangOpts()))
continue;
Check->registerMatchers(&Finder);
Check->registerPPCallbacks(Compiler.getSourceManager(), PP, PP);
}
Expand Down

0 comments on commit 39c4246

Please sign in to comment.