diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -189,8 +189,8 @@ add(S->getUnderlyingDecl(), Flags); Flags |= Rel::Alias; // continue with the alias. } else if (const UsingEnumDecl *UED = dyn_cast(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(D)) { add(NAD->getUnderlyingDecl(), Flags | Rel::Underlying); Flags |= Rel::Alias; // continue with the alias @@ -207,9 +207,12 @@ // templates. Flags |= Rel::Alias; } else if (const UsingShadowDecl *USD = dyn_cast(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(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 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -279,6 +279,21 @@ )cpp"; EXPECT_DECLS("UnresolvedUsingTypeLoc", {"using typename Foo::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) {