[clangd] Fix the crash in getQualification

Happens when DestContext is LinkageSpecDecl and hense CurContext happens to be
both not TagDecl and NamespaceDecl.

Minimal reproducer: trigger define outline in

```
namespace ns {
extern "C" {
typedef int foo;
}
foo Fo^o(int id) { return id; }
}
```

Reviewed By: kadircet

Differential Revision: https://reviews.llvm.org/D107047
This commit is contained in:
Kirill Bobyrev 2021-08-02 09:08:09 +02:00
parent bd19ba9d6d
commit e0f2d4af03
No known key found for this signature in database
GPG Key ID: 2307C055C8384FA0
2 changed files with 19 additions and 4 deletions

View File

@ -119,14 +119,17 @@ getQualification(ASTContext &Context, const DeclContext *DestContext,
(void)ReachedNS;
NNS = NestedNameSpecifier::Create(Context, nullptr, false,
TD->getTypeForDecl());
} else {
} else if (auto *NSD = llvm::dyn_cast<NamespaceDecl>(CurContext)) {
ReachedNS = true;
auto *NSD = llvm::cast<NamespaceDecl>(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))

View File

@ -259,6 +259,18 @@ TEST(ClangdAST, GetQualification) {
{"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);