11
11
12
12
#include " clang/Frontend/CompilerInstance.h"
13
13
#include " clang/Lex/Preprocessor.h"
14
+ #include " llvm/ADT/SmallString.h"
14
15
#include " llvm/Support/ConvertUTF.h"
15
16
16
17
namespace {
@@ -45,14 +46,13 @@ ConfusableIdentifierCheck::~ConfusableIdentifierCheck() = default;
45
46
// We're skipping 1. and 3. for the sake of simplicity, but this can lead to
46
47
// false positive.
47
48
48
- static std::string skeleton (StringRef Name) {
49
+ static llvm::SmallString< 64U > skeleton (StringRef Name) {
49
50
using namespace llvm ;
50
- std::string SName = Name.str ();
51
- std::string Skeleton;
52
- Skeleton.reserve (1 + Name.size ());
51
+ SmallString<64U > Skeleton;
52
+ Skeleton.reserve (1U + Name.size ());
53
53
54
- const char *Curr = SName. c_str ();
55
- const char *End = Curr + SName .size ();
54
+ const char *Curr = Name. data ();
55
+ const char *End = Curr + Name .size ();
56
56
while (Curr < End) {
57
57
58
58
const char *Prev = Curr;
@@ -99,8 +99,6 @@ static bool mayShadowImpl(const NamedDecl *ND0, const NamedDecl *ND1) {
99
99
100
100
static bool isMemberOf (const ConfusableIdentifierCheck::ContextInfo *DC0,
101
101
const ConfusableIdentifierCheck::ContextInfo *DC1) {
102
- if (DC0->Bases .empty ())
103
- return false ;
104
102
return llvm::is_contained (DC1->Bases , DC0->PrimaryContext );
105
103
}
106
104
@@ -117,16 +115,23 @@ static bool mayShadow(const NamedDecl *ND0,
117
115
const ConfusableIdentifierCheck::ContextInfo *DC0,
118
116
const NamedDecl *ND1,
119
117
const ConfusableIdentifierCheck::ContextInfo *DC1) {
120
- if (!DC0->Bases .empty () && ND1->getAccess () != AS_private &&
121
- isMemberOf (DC1, DC0))
122
- return true ;
123
- if (!DC1->Bases .empty () && ND0->getAccess () != AS_private &&
124
- isMemberOf (DC0, DC1))
125
- return true ;
126
118
127
- return enclosesContext (DC0, DC1) &&
128
- (mayShadowImpl (ND0, ND1) || mayShadowImpl (DC0->NonTransparentContext ,
129
- DC1->NonTransparentContext ));
119
+ if (!DC0->Bases .empty () && !DC1->Bases .empty ()) {
120
+ // if any of the declaration is a non-private member of the other
121
+ // declaration, it's shadowed by the former
122
+
123
+ if (ND1->getAccess () != AS_private && isMemberOf (DC1, DC0))
124
+ return true ;
125
+
126
+ if (ND0->getAccess () != AS_private && isMemberOf (DC0, DC1))
127
+ return true ;
128
+ }
129
+
130
+ if (!mayShadowImpl (DC0->NonTransparentContext , DC1->NonTransparentContext ) &&
131
+ !mayShadowImpl (ND0, ND1))
132
+ return false ;
133
+
134
+ return enclosesContext (DC0, DC1);
130
135
}
131
136
132
137
const ConfusableIdentifierCheck::ContextInfo *
@@ -172,26 +177,41 @@ ConfusableIdentifierCheck::getContextInfo(const DeclContext *DC) {
172
177
173
178
void ConfusableIdentifierCheck::check (
174
179
const ast_matchers::MatchFinder::MatchResult &Result) {
175
- if (const auto *ND = Result.Nodes .getNodeAs <NamedDecl>(" nameddecl" )) {
176
- if (IdentifierInfo *NDII = ND->getIdentifier ()) {
177
- const ContextInfo *Info = getContextInfo (ND->getDeclContext ());
178
- StringRef NDName = NDII->getName ();
179
- llvm::SmallVector<Entry> &Mapped = Mapper[skeleton (NDName)];
180
- for (const Entry &E : Mapped) {
181
- const IdentifierInfo *ONDII = E.Declaration ->getIdentifier ();
182
- if (mayShadow (ND, Info, E.Declaration , E.Info )) {
183
- StringRef ONDName = ONDII->getName ();
184
- if (ONDName != NDName) {
185
- diag (ND->getLocation (), " %0 is confusable with %1" )
186
- << ND << E.Declaration ;
187
- diag (E.Declaration ->getLocation (), " other declaration found here" ,
188
- DiagnosticIDs::Note);
189
- }
190
- }
191
- }
192
- Mapped.push_back ({ND, Info});
193
- }
180
+ const auto *ND = Result.Nodes .getNodeAs <NamedDecl>(" nameddecl" );
181
+ if (!ND)
182
+ return ;
183
+
184
+ IdentifierInfo *NDII = ND->getIdentifier ();
185
+ if (!NDII)
186
+ return ;
187
+
188
+ StringRef NDName = NDII->getName ();
189
+ if (NDName.empty ())
190
+ return ;
191
+
192
+ const ContextInfo *Info = getContextInfo (ND->getDeclContext ());
193
+
194
+ llvm::SmallVector<Entry> &Mapped = Mapper[skeleton (NDName)];
195
+ for (const Entry &E : Mapped) {
196
+ if (!mayShadow (ND, Info, E.Declaration , E.Info ))
197
+ continue ;
198
+
199
+ const IdentifierInfo *ONDII = E.Declaration ->getIdentifier ();
200
+ StringRef ONDName = ONDII->getName ();
201
+ if (ONDName == NDName)
202
+ continue ;
203
+
204
+ diag (ND->getLocation (), " %0 is confusable with %1" ) << ND << E.Declaration ;
205
+ diag (E.Declaration ->getLocation (), " other declaration found here" ,
206
+ DiagnosticIDs::Note);
194
207
}
208
+
209
+ Mapped.push_back ({ND, Info});
210
+ }
211
+
212
+ void ConfusableIdentifierCheck::onEndOfTranslationUnit () {
213
+ Mapper.clear ();
214
+ ContextInfos.clear ();
195
215
}
196
216
197
217
void ConfusableIdentifierCheck::registerMatchers (
0 commit comments