[clangd] Include expression in DecltypeTypeLoc sourcerange while building SelectionTree

Summary:
Currently AST only contains the location for `decltype` keyword,
therefore we were skipping expressions inside decltype while building selection
tree.

This patch extends source range in such cases to contain the expression as well.
A proper fix would require changes to Sema and DecltypeTypeLoc to contain these
location information.

Fixes https://github.com/clangd/clangd/issues/250.

Reviewers: sammccall

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D72594
This commit is contained in:
Kadir Cetinkaya 2020-01-13 12:09:30 +01:00
parent 15078d7202
commit f5465e74ef
No known key found for this signature in database
GPG Key ID: E39E36B8D2057ED6
2 changed files with 19 additions and 0 deletions

View File

@ -527,6 +527,19 @@ private:
// don't intersect the selection may be recursively skipped.
bool canSafelySkipNode(const DynTypedNode &N) {
SourceRange S = N.getSourceRange();
if (auto *TL = N.get<TypeLoc>()) {
// DeclTypeTypeLoc::getSourceRange() is incomplete, which would lead to
// failing
// to descend into the child expression.
// decltype(2+2);
// ~~~~~~~~~~~~~ <-- correct range
// ~~~~~~~~ <-- range reported by getSourceRange()
// ~~~~~~~~~~~~ <-- range with this hack(i.e, missing closing paren)
// FIXME: Alter DecltypeTypeLoc to contain parentheses locations and get
// rid of this patch.
if (auto DT = TL->getAs<DecltypeTypeLoc>())
S.setEnd(DT.getUnderlyingExpr()->getEndLoc());
}
if (!SelChecker.mayHit(S)) {
dlog("{1}skip: {0}", printNodeToString(N, PrintPolicy), indent());
dlog("{1}skipped range = {0}", S.printToString(SM), indent(1));

View File

@ -323,6 +323,12 @@ TEST(SelectionTest, CommonAncestor) {
Foo x = [[^12_ud]];
)cpp",
"UserDefinedLiteral"},
{
R"cpp(
int a;
decltype([[^a]] + a) b;
)cpp",
"DeclRefExpr"},
};
for (const Case &C : Cases) {
Annotations Test(C.Code);