[clang-tools-extra] ad9fd32 - [clangd] Fix SelectionTree behavior on constructor init-lists.
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 15 08:32:25 PST 2019
Author: Sam McCall
Date: 2019-11-15T17:32:13+01:00
New Revision: ad9fd320091d44d4b8782c28b72a7be21a2bd68d
URL: https://github.com/llvm/llvm-project/commit/ad9fd320091d44d4b8782c28b72a7be21a2bd68d
DIFF: https://github.com/llvm/llvm-project/commit/ad9fd320091d44d4b8782c28b72a7be21a2bd68d.diff
LOG: [clangd] Fix SelectionTree behavior on constructor init-lists.
Summary:
For the constructor Foo() : classmember(arg) {}
The AST looks like:
- CXXCtorInitializer classmember(arg)
- CXXConstructExpr classmember(arg)
- DeclRefExpr: arg
We want the 'classmember' to be associated with the CXXCtorInitializer, not the
CXXConstructExpr. (CXXConstructExpr is known to have bad ranges).
So just early-claim it.
Thanks @hokein for tracking down/reducing the bug.
Reviewers: hokein
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits, hokein
Tags: #clang
Differential Revision: https://reviews.llvm.org/D70312
Added:
Modified:
clang-tools-extra/clangd/Selection.cpp
clang-tools-extra/clangd/unittests/SelectionTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp
index 1424825d82bc..04076df0c39d 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -10,6 +10,7 @@
#include "Logger.h"
#include "SourceCode.h"
#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RecursiveASTVisitor.h"
@@ -397,6 +398,9 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
// int (*[[s]])();
else if (auto *VD = llvm::dyn_cast<VarDecl>(D))
return VD->getLocation();
+ } else if (const auto* CCI = N.get<CXXCtorInitializer>()) {
+ // : [[b_]](42)
+ return CCI->getMemberLocation();
}
return SourceRange();
}
diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
index 8895dd82262d..7b8b33d8a25b 100644
--- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -246,6 +246,17 @@ TEST(SelectionTest, CommonAncestor) {
// Tricky case: two VarDecls share a specifier.
{"[[int ^a]], b;", "VarDecl"},
{"[[int a, ^b]];", "VarDecl"},
+ // Tricky case: CXXConstructExpr wants to claim the whole init range.
+ {
+ R"cpp(
+ class X { X(int); };
+ class Y {
+ X x;
+ Y() : [[^x(4)]] {}
+ };
+ )cpp",
+ "CXXCtorInitializer", // Not the CXXConstructExpr!
+ },
// Tricky case: anonymous struct is a sibling of the VarDecl.
{"[[st^ruct {int x;}]] y;", "CXXRecordDecl"},
{"[[struct {int x;} ^y]];", "VarDecl"},
More information about the cfe-commits
mailing list