diff options
author | Sam McCall <sam.mccall@gmail.com> | 2019-08-28 12:05:12 +0000 |
---|---|---|
committer | Sam McCall <sam.mccall@gmail.com> | 2019-08-28 12:05:12 +0000 |
commit | ab6594575a221debb2a02f6b0e277c6cc86e9154 (patch) | |
tree | 8e381f2ba72efba83706d161482e5d7deef343e9 | |
parent | 4f4387dd123cc980b8a81bbd86d06055b32bd7d5 (diff) | |
download | bcm5719-llvm-ab6594575a221debb2a02f6b0e277c6cc86e9154.tar.gz bcm5719-llvm-ab6594575a221debb2a02f6b0e277c6cc86e9154.zip |
[clangd] Fix SelectionTree to allow selection range expression in foreach loops.
Reviewers: hokein
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66869
llvm-svn: 370191
-rw-r--r-- | clang-tools-extra/clangd/Selection.cpp | 10 | ||||
-rw-r--r-- | clang-tools-extra/clangd/unittests/SelectionTests.cpp | 16 |
2 files changed, 26 insertions, 0 deletions
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp index 96b10f5358c..cd1c84b43c7 100644 --- a/clang-tools-extra/clangd/Selection.cpp +++ b/clang-tools-extra/clangd/Selection.cpp @@ -228,6 +228,16 @@ public: bool TraverseNestedNameSpecifier(NestedNameSpecifier *) { return true; } bool TraverseType(QualType) { return true; } + // The DeclStmt for the loop variable claims to cover the whole range + // inside the parens, this causes the range-init expression to not be hit. + // Traverse the loop VarDecl instead, which has the right source range. + bool TraverseCXXForRangeStmt(CXXForRangeStmt *S) { + return traverseNode(S, [&] { + return TraverseStmt(S->getInit()) && TraverseDecl(S->getLoopVariable()) && + TraverseStmt(S->getRangeInit()) && TraverseStmt(S->getBody()); + }); + } + private: using Base = RecursiveASTVisitor<SelectionVisitor>; diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp index a8ca324adb3..e1a103e8a2b 100644 --- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp @@ -261,6 +261,22 @@ TEST(SelectionTest, CommonAncestor) { struct Foo<U<int>*> {}; )cpp", "TemplateTemplateParmDecl"}, + + // Foreach has a weird AST, ensure we can select parts of the range init. + // This used to fail, because the DeclStmt for C claimed the whole range. + { + R"cpp( + struct Str { + const char *begin(); + const char *end(); + }; + Str makeStr(const char*); + void loop() { + for (const char* C : [[mak^eStr("foo"^)]]) + ; + } + )cpp", + "CallExpr"}, }; for (const Case &C : Cases) { Annotations Test(C.Code); |