https://github.com/kadircet updated https://github.com/llvm/llvm-project/pull/106706
From 53b34977daa00abdad9bb6b3a351b05ae59cb2df Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya <kadir...@google.com> Date: Fri, 30 Aug 2024 12:28:02 +0200 Subject: [PATCH] [include-cleaner] Report refs for enum constants used through namespace aliases --- .../include-cleaner/lib/WalkAST.cpp | 27 ++++++++++++++++--- .../include-cleaner/unittests/WalkASTTest.cpp | 3 +++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index f7a2ebd5260681..aae3eda519ffdc 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -15,6 +15,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" @@ -23,9 +24,11 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" namespace clang::include_cleaner { namespace { @@ -125,6 +128,24 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> { return true; } + bool qualifierIsNamespaceOrNone(DeclRefExpr *DRE) { + const auto *Qual = DRE->getQualifier(); + if (!Qual) + return true; + switch (Qual->getKind()) { + case NestedNameSpecifier::Namespace: + case NestedNameSpecifier::NamespaceAlias: + case NestedNameSpecifier::Global: + return true; + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + case NestedNameSpecifier::Super: + case NestedNameSpecifier::Identifier: + return false; + } + llvm_unreachable("Unknown value for NestedNameSpecifierKind"); + } + bool VisitDeclRefExpr(DeclRefExpr *DRE) { auto *FD = DRE->getFoundDecl(); // Prefer the underlying decl if FoundDecl isn't a shadow decl, e.g: @@ -146,10 +167,8 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> { // // If it's an enum constant, it must be due to prior decl. Report references // to it when qualifier isn't a type. - if (llvm::isa<EnumConstantDecl>(FD)) { - if (!DRE->getQualifier() || DRE->getQualifier()->getAsNamespace()) - report(DRE->getLocation(), FD); - } + if (llvm::isa<EnumConstantDecl>(FD) && qualifierIsNamespaceOrNone(DRE)) + report(DRE->getLocation(), FD); return true; } diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index 9286758cab081c..e45ea36f7938ea 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -534,6 +534,9 @@ TEST(WalkAST, Enums) { testWalk(R"(namespace ns { enum E { A = 42 }; } struct S { using ns::E::A; };)", "int e = S::^A;"); + testWalk(R"(namespace ns { enum E { $explicit^A = 42 }; })", + "namespace z = ns; int e = z::^A;"); + testWalk(R"(enum E { $explicit^A = 42 };)", "int e = ::^A;"); } TEST(WalkAST, InitializerList) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits