diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp --- a/clang-tools-extra/clangd/AST.cpp +++ b/clang-tools-extra/clangd/AST.cpp @@ -119,14 +119,17 @@ (void)ReachedNS; NNS = NestedNameSpecifier::Create(Context, nullptr, false, TD->getTypeForDecl()); - } else { + } else if (auto *NSD = llvm::dyn_cast(CurContext)) { ReachedNS = true; - auto *NSD = llvm::cast(CurContext); NNS = NestedNameSpecifier::Create(Context, nullptr, NSD); - // Anonymous and inline namespace names are not spelled while qualifying a - // name, so skip those. + // Anonymous and inline namespace names are not spelled while qualifying + // a name, so skip those. if (NSD->isAnonymousNamespace() || NSD->isInlineNamespace()) continue; + } else { + // Other types of contexts cannot be spelled in code, just skip over + // them. + continue; } // Stop if this namespace is already visible at DestContext. if (IsVisible(NNS)) diff --git a/clang-tools-extra/clangd/unittests/ASTTests.cpp b/clang-tools-extra/clangd/unittests/ASTTests.cpp --- a/clang-tools-extra/clangd/unittests/ASTTests.cpp +++ b/clang-tools-extra/clangd/unittests/ASTTests.cpp @@ -259,6 +259,18 @@ {"ns2::", "ns2::", ""}, {"ns1::"}, }, + { + R"cpp( + namespace ns { + extern "C" { + typedef int Foo; + } + } + void insert(); // ns::Foo + )cpp", + {"ns::"}, + {}, + }, }; for (const auto &Case : Cases) { Annotations Test(Case.Test);