1 //===--- IncorrectEnableIfCheck.cpp - clang-tidy --------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "IncorrectEnableIfCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 using namespace clang::ast_matchers
;
15 namespace clang::tidy::bugprone
{
19 AST_MATCHER_P(TemplateTypeParmDecl
, hasUnnamedDefaultArgument
,
20 ast_matchers::internal::Matcher
<TypeLoc
>, InnerMatcher
) {
21 if (Node
.getIdentifier() != nullptr || !Node
.hasDefaultArgument() ||
22 Node
.getDefaultArgumentInfo() == nullptr)
25 TypeLoc DefaultArgTypeLoc
= Node
.getDefaultArgumentInfo()->getTypeLoc();
26 return InnerMatcher
.matches(DefaultArgTypeLoc
, Finder
, Builder
);
31 void IncorrectEnableIfCheck::registerMatchers(MatchFinder
*Finder
) {
34 hasUnnamedDefaultArgument(
36 hasNamedTypeLoc(templateSpecializationTypeLoc(
37 loc(qualType(hasDeclaration(namedDecl(
38 hasName("::std::enable_if"))))))
39 .bind("enable_if_specialization")))
45 void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult
&Result
) {
46 const auto *EnableIf
=
47 Result
.Nodes
.getNodeAs
<TemplateTypeParmDecl
>("enable_if");
48 const auto *ElaboratedLoc
=
49 Result
.Nodes
.getNodeAs
<ElaboratedTypeLoc
>("elaborated");
50 const auto *EnableIfSpecializationLoc
=
51 Result
.Nodes
.getNodeAs
<TemplateSpecializationTypeLoc
>(
52 "enable_if_specialization");
54 if (!EnableIf
|| !ElaboratedLoc
|| !EnableIfSpecializationLoc
)
57 const SourceManager
&SM
= *Result
.SourceManager
;
58 SourceLocation RAngleLoc
=
59 SM
.getExpansionLoc(EnableIfSpecializationLoc
->getRAngleLoc());
61 auto Diag
= diag(EnableIf
->getBeginLoc(),
62 "incorrect std::enable_if usage detected; use "
63 "'typename std::enable_if<...>::type'");
64 if (!getLangOpts().CPlusPlus20
) {
65 Diag
<< FixItHint::CreateInsertion(ElaboratedLoc
->getBeginLoc(),
68 Diag
<< FixItHint::CreateInsertion(RAngleLoc
.getLocWithOffset(1), "::type");
71 } // namespace clang::tidy::bugprone