15
15
#include " clang/AST/DeclTemplate.h"
16
16
#include " clang/AST/Expr.h"
17
17
#include " clang/AST/ExprCXX.h"
18
+ #include " clang/AST/NestedNameSpecifier.h"
18
19
#include " clang/AST/RecursiveASTVisitor.h"
19
20
#include " clang/AST/TemplateBase.h"
20
21
#include " clang/AST/TemplateName.h"
23
24
#include " clang/Basic/IdentifierTable.h"
24
25
#include " clang/Basic/SourceLocation.h"
25
26
#include " clang/Basic/Specifiers.h"
27
+ #include " llvm/ADT/STLExtras.h"
26
28
#include " llvm/ADT/STLFunctionalExtras.h"
27
29
#include " llvm/ADT/SmallVector.h"
28
30
#include " llvm/Support/Casting.h"
31
+ #include " llvm/Support/ErrorHandling.h"
29
32
30
33
namespace clang ::include_cleaner {
31
34
namespace {
@@ -125,6 +128,24 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
125
128
return true ;
126
129
}
127
130
131
+ bool qualifierIsNamespaceOrNone (DeclRefExpr *DRE) {
132
+ const auto *Qual = DRE->getQualifier ();
133
+ if (!Qual)
134
+ return true ;
135
+ switch (Qual->getKind ()) {
136
+ case NestedNameSpecifier::Namespace:
137
+ case NestedNameSpecifier::NamespaceAlias:
138
+ case NestedNameSpecifier::Global:
139
+ return true ;
140
+ case NestedNameSpecifier::TypeSpec:
141
+ case NestedNameSpecifier::TypeSpecWithTemplate:
142
+ case NestedNameSpecifier::Super:
143
+ case NestedNameSpecifier::Identifier:
144
+ return false ;
145
+ }
146
+ llvm_unreachable (" Unknown value for NestedNameSpecifierKind" );
147
+ }
148
+
128
149
bool VisitDeclRefExpr (DeclRefExpr *DRE) {
129
150
auto *FD = DRE->getFoundDecl ();
130
151
// Prefer the underlying decl if FoundDecl isn't a shadow decl, e.g:
@@ -146,10 +167,8 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
146
167
//
147
168
// If it's an enum constant, it must be due to prior decl. Report references
148
169
// to it when qualifier isn't a type.
149
- if (llvm::isa<EnumConstantDecl>(FD)) {
150
- if (!DRE->getQualifier () || DRE->getQualifier ()->getAsNamespace ())
151
- report (DRE->getLocation (), FD);
152
- }
170
+ if (llvm::isa<EnumConstantDecl>(FD) && qualifierIsNamespaceOrNone (DRE))
171
+ report (DRE->getLocation (), FD);
153
172
return true ;
154
173
}
155
174
0 commit comments