[clang-tools-extra] 2bb34cc - [clangd] FindTarget: UsingEnumDecl is not an alias

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 8 10:30:51 PDT 2022


Author: Sam McCall
Date: 2022-10-08T19:29:35+02:00
New Revision: 2bb34cc462ff857576a8145edc89ad2bdd1f4396

URL: https://github.com/llvm/llvm-project/commit/2bb34cc462ff857576a8145edc89ad2bdd1f4396
DIFF: https://github.com/llvm/llvm-project/commit/2bb34cc462ff857576a8145edc89ad2bdd1f4396.diff

LOG: [clangd] FindTarget: UsingEnumDecl is not an alias

Unlike UsingDecl it doesn't name the UsingShadowDecls it emits, so it doesn't
make sense to consider them the same thing. Don't consider the UsingEnumDecl
a target when the UsingShadowDecl is referenced.

Differential Revision: https://reviews.llvm.org/D135506

Added: 
    

Modified: 
    clang-tools-extra/clangd/FindTarget.cpp
    clang-tools-extra/clangd/unittests/FindTargetTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 17be646c7d7c5..dea5cb7f50288 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -189,8 +189,8 @@ struct TargetFinder {
         add(S->getUnderlyingDecl(), Flags);
       Flags |= Rel::Alias; // continue with the alias.
     } else if (const UsingEnumDecl *UED = dyn_cast<UsingEnumDecl>(D)) {
-      add(UED->getEnumDecl(), Flags);
-      Flags |= Rel::Alias; // continue with the alias.
+      // UsingEnumDecl is not an alias at all, just a reference.
+      D = UED->getEnumDecl();
     } else if (const auto *NAD = dyn_cast<NamespaceAliasDecl>(D)) {
       add(NAD->getUnderlyingDecl(), Flags | Rel::Underlying);
       Flags |= Rel::Alias; // continue with the alias
@@ -207,9 +207,12 @@ struct TargetFinder {
       // templates.
       Flags |= Rel::Alias;
     } else if (const UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) {
-      // Include the Introducing decl, but don't traverse it. This may end up
-      // including *all* shadows, which we don't want.
-      report(USD->getIntroducer(), Flags | Rel::Alias);
+      // Include the introducing UsingDecl, but don't traverse it. This may end
+      // up including *all* shadows, which we don't want.
+      // Don't apply this logic to UsingEnumDecl, which can't easily be
+      // conflated with the aliases it introduces.
+      if (llvm::isa<UsingDecl>(USD->getIntroducer()))
+        report(USD->getIntroducer(), Flags | Rel::Alias);
       // Shadow decls are synthetic and not themselves interesting.
       // Record the underlying decl instead, if allowed.
       D = USD->getTargetDecl();

diff  --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 6656ed9847233..fd25e8059e816 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -279,6 +279,21 @@ TEST_F(TargetDeclTest, UsingDecl) {
   )cpp";
   EXPECT_DECLS("UnresolvedUsingTypeLoc",
                {"using typename Foo<T>::foo", Rel::Alias});
+
+  // Using enum.
+  Flags.push_back("-std=c++20");
+  Code = R"cpp(
+    namespace ns { enum class A { X }; }
+    [[using enum ns::A]];
+  )cpp";
+  EXPECT_DECLS("UsingEnumDecl", "enum class A : int");
+
+  Code = R"cpp(
+    namespace ns { enum class A { X }; }
+    using enum ns::A;
+    auto m = [[X]];
+  )cpp";
+  EXPECT_DECLS("DeclRefExpr", "X");
 }
 
 TEST_F(TargetDeclTest, BaseSpecifier) {


        


More information about the cfe-commits mailing list