1111
1212#include " clang/Frontend/CompilerInstance.h"
1313#include " clang/Lex/Preprocessor.h"
14+ #include " llvm/ADT/SmallString.h"
1415#include " llvm/Support/ConvertUTF.h"
1516
1617namespace {
@@ -45,14 +46,13 @@ ConfusableIdentifierCheck::~ConfusableIdentifierCheck() = default;
4546// We're skipping 1. and 3. for the sake of simplicity, but this can lead to
4647// false positive.
4748
48- static std::string skeleton (StringRef Name) {
49+ static llvm::SmallString< 64U > skeleton (StringRef Name) {
4950 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 ());
5353
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 ();
5656 while (Curr < End) {
5757
5858 const char *Prev = Curr;
@@ -99,8 +99,6 @@ static bool mayShadowImpl(const NamedDecl *ND0, const NamedDecl *ND1) {
9999
100100static bool isMemberOf (const ConfusableIdentifierCheck::ContextInfo *DC0,
101101 const ConfusableIdentifierCheck::ContextInfo *DC1) {
102- if (DC0->Bases .empty ())
103- return false ;
104102 return llvm::is_contained (DC1->Bases , DC0->PrimaryContext );
105103}
106104
@@ -117,16 +115,23 @@ static bool mayShadow(const NamedDecl *ND0,
117115 const ConfusableIdentifierCheck::ContextInfo *DC0,
118116 const NamedDecl *ND1,
119117 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 ;
126118
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);
130135}
131136
132137const ConfusableIdentifierCheck::ContextInfo *
@@ -172,26 +177,41 @@ ConfusableIdentifierCheck::getContextInfo(const DeclContext *DC) {
172177
173178void ConfusableIdentifierCheck::check (
174179 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);
194207 }
208+
209+ Mapped.push_back ({ND, Info});
210+ }
211+
212+ void ConfusableIdentifierCheck::onEndOfTranslationUnit () {
213+ Mapper.clear ();
214+ ContextInfos.clear ();
195215}
196216
197217void ConfusableIdentifierCheck::registerMatchers (
0 commit comments