@@ -93,22 +93,70 @@ std::string ConfusableIdentifierCheck::skeleton(StringRef Name) {
93
93
return Skeleton;
94
94
}
95
95
96
+ static bool mayShadowImpl (const NamedDecl *ND0, const NamedDecl *ND1) {
97
+ const DeclContext *DC0 = ND0->getDeclContext ()->getPrimaryContext ();
98
+ const DeclContext *DC1 = ND1->getDeclContext ()->getPrimaryContext ();
99
+
100
+ if (isa<TemplateTypeParmDecl>(ND0) || isa<TemplateTypeParmDecl>(ND0))
101
+ return true ;
102
+
103
+ while (DC0->isTransparentContext ())
104
+ DC0 = DC0->getParent ();
105
+ while (DC1->isTransparentContext ())
106
+ DC1 = DC1->getParent ();
107
+
108
+ if (DC0->Equals (DC1))
109
+ return true ;
110
+
111
+ return false ;
112
+ }
113
+
114
+ static bool isMemberOf (const NamedDecl *ND, const CXXRecordDecl *RD) {
115
+ const DeclContext *NDParent = ND->getDeclContext ();
116
+ if (!NDParent || !isa<CXXRecordDecl>(NDParent))
117
+ return false ;
118
+ if (NDParent == RD)
119
+ return true ;
120
+ return !RD->forallBases (
121
+ [NDParent](const CXXRecordDecl *Base) { return NDParent != Base; });
122
+ }
123
+
124
+ static bool mayShadow (const NamedDecl *ND0, const NamedDecl *ND1) {
125
+
126
+ const DeclContext *DC0 = ND0->getDeclContext ()->getPrimaryContext ();
127
+ const DeclContext *DC1 = ND1->getDeclContext ()->getPrimaryContext ();
128
+
129
+ if (const CXXRecordDecl *RD0 = dyn_cast<CXXRecordDecl>(DC0)) {
130
+ if (ND1->getAccess () != AS_private && isMemberOf (ND1, RD0))
131
+ return true ;
132
+ }
133
+ if (const CXXRecordDecl *RD1 = dyn_cast<CXXRecordDecl>(DC1)) {
134
+ if (ND0->getAccess () != AS_private && isMemberOf (ND0, RD1))
135
+ return true ;
136
+ }
137
+
138
+ if (DC0->Encloses (DC1))
139
+ return mayShadowImpl (ND0, ND1);
140
+ if (DC1->Encloses (DC0))
141
+ return mayShadowImpl (ND1, ND0);
142
+ return false ;
143
+ }
144
+
96
145
void ConfusableIdentifierCheck::check (
97
146
const ast_matchers::MatchFinder::MatchResult &Result) {
98
147
if (const auto *ND = Result.Nodes .getNodeAs <NamedDecl>(" nameddecl" )) {
99
- if (IdentifierInfo *II = ND->getIdentifier ()) {
100
- StringRef NDName = II ->getName ();
148
+ if (IdentifierInfo *NDII = ND->getIdentifier ()) {
149
+ StringRef NDName = NDII ->getName ();
101
150
llvm::SmallVector<const NamedDecl *> &Mapped = Mapper[skeleton (NDName)];
102
- const DeclContext *NDDecl = ND->getDeclContext ();
103
151
for (const NamedDecl *OND : Mapped) {
104
- if (!NDDecl-> isDeclInLexicalTraversal (OND) &&
105
- !OND-> getDeclContext ()-> isDeclInLexicalTraversal (ND))
106
- continue ;
107
- if (OND-> getIdentifier ()-> getName () != NDName) {
108
- diag (OND ->getLocation (), " %0 is confusable with %1" )
109
- << OND->getName () << NDName;
110
- diag (ND-> getLocation (), " other declaration found here " ,
111
- DiagnosticIDs::Note);
152
+ const IdentifierInfo *ONDII = OND-> getIdentifier ();
153
+ if ( mayShadow (ND, OND)) {
154
+ StringRef ONDName = ONDII-> getName () ;
155
+ if (ONDName != NDName) {
156
+ diag (ND ->getLocation (), " %0 is confusable with %1" ) << ND << OND;
157
+ diag ( OND->getLocation (), " other declaration found here " ,
158
+ DiagnosticIDs::Note);
159
+ }
112
160
}
113
161
}
114
162
Mapped.push_back (ND);
0 commit comments