@@ -16,69 +16,59 @@ using namespace clang::ast_matchers;
16
16
namespace clang ::tidy::bugprone {
17
17
18
18
static bool hasPrivateConstructor (const CXXRecordDecl *RD) {
19
- for (auto &&Ctor : RD->ctors ()) {
20
- if (Ctor->getAccess () == AS_private)
21
- return true ;
22
- }
23
-
24
- return false ;
19
+ return llvm::any_of (RD->ctors (), [](const CXXConstructorDecl *Ctor) {
20
+ return Ctor->getAccess () == AS_private;
21
+ });
25
22
}
26
23
27
24
static bool isDerivedParameterBefriended (const CXXRecordDecl *CRTP,
28
25
const NamedDecl *Param) {
29
- for ( auto &&Friend : CRTP->friends ()) {
26
+ return llvm::any_of ( CRTP->friends (), [&]( const FriendDecl *Friend ) {
30
27
const auto *TTPT =
31
28
dyn_cast<TemplateTypeParmType>(Friend->getFriendType ()->getType ());
32
29
33
- if (TTPT && TTPT->getDecl () == Param)
34
- return true ;
35
- }
36
-
37
- return false ;
30
+ return TTPT && TTPT->getDecl () == Param;
31
+ });
38
32
}
39
33
40
34
static bool isDerivedClassBefriended (const CXXRecordDecl *CRTP,
41
35
const CXXRecordDecl *Derived) {
42
- for (auto &&Friend : CRTP->friends ()) {
43
- if (Friend->getFriendType ()->getType ()->getAsCXXRecordDecl () == Derived)
44
- return true ;
45
- }
46
-
47
- return false ;
36
+ return llvm::any_of (CRTP->friends (), [&](const FriendDecl *Friend) {
37
+ return Friend->getFriendType ()->getType ()->getAsCXXRecordDecl () == Derived;
38
+ });
48
39
}
49
40
50
- static std::optional< const NamedDecl *>
41
+ static const NamedDecl *
51
42
getDerivedParameter (const ClassTemplateSpecializationDecl *CRTP,
52
43
const CXXRecordDecl *Derived) {
53
44
size_t Idx = 0 ;
54
- bool Found = false ;
55
- for (auto &&TemplateArg : CRTP->getTemplateArgs ().asArray ()) {
56
- if (TemplateArg.getKind () == TemplateArgument::Type &&
57
- TemplateArg.getAsType ()->getAsCXXRecordDecl () == Derived) {
58
- Found = true ;
59
- break ;
60
- }
61
- ++Idx;
62
- }
63
-
64
- if (!Found)
65
- return std::nullopt;
66
-
67
- return CRTP->getSpecializedTemplate ()->getTemplateParameters ()->getParam (Idx);
45
+ bool AnyOf = llvm::any_of (
46
+ CRTP->getTemplateArgs ().asArray (), [&](const TemplateArgument &Arg) {
47
+ ++Idx;
48
+ return Arg.getKind () == TemplateArgument::Type &&
49
+ Arg.getAsType ()->getAsCXXRecordDecl () == Derived;
50
+ });
51
+
52
+ return AnyOf ? CRTP->getSpecializedTemplate ()
53
+ ->getTemplateParameters ()
54
+ ->getParam (Idx - 1 )
55
+ : nullptr ;
68
56
}
69
57
70
58
static std::vector<FixItHint>
71
59
hintMakeCtorPrivate (const CXXConstructorDecl *Ctor,
72
- const std::string &OriginalAccess, const SourceManager &SM,
73
- const LangOptions &LangOpts) {
60
+ const std::string &OriginalAccess) {
74
61
std::vector<FixItHint> Hints;
75
62
76
63
Hints.emplace_back (FixItHint::CreateInsertion (
77
64
Ctor->getBeginLoc ().getLocWithOffset (-1 ), " private:\n " ));
78
65
66
+ const ASTContext &ASTCtx = Ctor->getASTContext ();
79
67
const SourceLocation CtorEndLoc =
80
68
Ctor->isExplicitlyDefaulted ()
81
- ? utils::lexer::findNextTerminator (Ctor->getEndLoc (), SM, LangOpts)
69
+ ? utils::lexer::findNextTerminator (Ctor->getEndLoc (),
70
+ ASTCtx.getSourceManager (),
71
+ ASTCtx.getLangOpts ())
82
72
: Ctor->getEndLoc ();
83
73
Hints.emplace_back (FixItHint::CreateInsertion (
84
74
CtorEndLoc.getLocWithOffset (1 ), ' \n ' + OriginalAccess + ' :' + ' \n ' ));
@@ -121,7 +111,10 @@ void CrtpConstructorAccessibilityCheck::check(
121
111
}
122
112
123
113
const auto *DerivedTemplateParameter =
124
- *getDerivedParameter (CRTPInstantiation, DerivedRecord);
114
+ getDerivedParameter (CRTPInstantiation, DerivedRecord);
115
+
116
+ assert (DerivedTemplateParameter &&
117
+ " No template parameter corresponds to the derived class of the CRTP." );
125
118
126
119
if (hasPrivateConstructor (CRTPDeclaration) &&
127
120
!isDerivedParameterBefriended (CRTPDeclaration,
@@ -148,9 +141,7 @@ void CrtpConstructorAccessibilityCheck::check(
148
141
diag (Ctor->getLocation (),
149
142
" %0 contructor allows the CRTP to be %select{inherited "
150
143
" from|constructed}1 as a regular template class" )
151
- << Access << IsPublic << Ctor
152
- << hintMakeCtorPrivate (Ctor, Access, *Result.SourceManager ,
153
- getLangOpts ());
144
+ << Access << IsPublic << Ctor << hintMakeCtorPrivate (Ctor, Access);
154
145
diag (Ctor->getLocation (), " consider making it private" ,
155
146
DiagnosticIDs::Note);
156
147
}
0 commit comments