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 @@ -674,10 +674,14 @@ return refInDecl(D); if (auto *E = N.get()) return refInExpr(E); - if (auto *NNSL = N.get()) - return {ReferenceLoc{NNSL->getPrefix(), NNSL->getLocalBeginLoc(), false, - explicitReferenceTargets(DynTypedNode::create( - *NNSL->getNestedNameSpecifier()))}}; + if (auto *NNSL = N.get()) { + // (!) 'DeclRelation::Alias' ensures we do not loose namespace aliases. + return {ReferenceLoc{ + NNSL->getPrefix(), NNSL->getLocalBeginLoc(), false, + explicitReferenceTargets( + DynTypedNode::create(*NNSL->getNestedNameSpecifier()), + DeclRelation::Alias)}}; + } if (const TypeLoc *TL = N.get()) return refInTypeLoc(*TL); if (const CXXCtorInitializer *CCI = N.get()) { 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 @@ -882,6 +882,28 @@ "0: targets = {x}, decl\n" "1: targets = {fptr}, decl\n" "2: targets = {a}, decl\n"}, + // Namespace aliases should be handled properly. + { + R"cpp( + namespace ns { struct Type {} } + namespace alias = ns; + namespace rec_alias = alias; + + void foo() { + $0^ns::$1^Type $2^a; + $3^alias::$4^Type $5^b; + $6^rec_alias::$7^Type $8^c; + } + )cpp", + "0: targets = {ns}\n" + "1: targets = {ns::Type}, qualifier = 'ns::'\n" + "2: targets = {a}, decl\n" + "3: targets = {alias}\n" + "4: targets = {ns::Type}, qualifier = 'alias::'\n" + "5: targets = {b}, decl\n" + "6: targets = {rec_alias}\n" + "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n" + "8: targets = {c}, decl\n"}, }; for (const auto &C : Cases) {