diff options
author | Sam McCall <sam.mccall@gmail.com> | 2019-11-19 16:57:31 +0100 |
---|---|---|
committer | Sam McCall <sam.mccall@gmail.com> | 2019-11-20 13:06:57 +0100 |
commit | e18ab2a0b801e75ee39bb8ba30584c69b4c6e577 (patch) | |
tree | 51ec43ee77e296a801d60aabbac782392626143b | |
parent | ea8678d1c78ecf6c719b4a9ff1aa8db0087401ca (diff) | |
download | bcm5719-llvm-e18ab2a0b801e75ee39bb8ba30584c69b4c6e577.tar.gz bcm5719-llvm-e18ab2a0b801e75ee39bb8ba30584c69b4c6e577.zip |
[clangd] Treat UserDefinedLiteral as a leaf in SelectionTree, sidestepping tokenization issues
Summary: Fixes https://github.com/clangd/clangd/issues/203
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D70446
-rw-r--r-- | clang-tools-extra/clangd/Selection.cpp | 14 | ||||
-rw-r--r-- | clang-tools-extra/clangd/unittests/SelectionTests.cpp | 10 |
2 files changed, 24 insertions, 0 deletions
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp index 04076df0c39..c91cd24e2f2 100644 --- a/clang-tools-extra/clangd/Selection.cpp +++ b/clang-tools-extra/clangd/Selection.cpp @@ -12,6 +12,7 @@ #include "clang/AST/ASTTypeTraits.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TypeLoc.h" @@ -245,6 +246,10 @@ public: if (canSafelySkipNode(N)) return false; push(std::move(N)); + if (shouldSkipChildren(X)) { + pop(); + return false; + } return true; } bool dataTraverseStmtPost(Stmt *X) { @@ -355,6 +360,15 @@ private: return true; } + // There are certain nodes we want to treat as leaves in the SelectionTree, + // although they do have children. + bool shouldSkipChildren(const Stmt *X) const { + // UserDefinedLiteral (e.g. 12_i) has two children (12 and _i). + // Unfortunately TokenBuffer sees 12_i as one token and can't split it. + // So we treat UserDefinedLiteral as a leaf node, owning the token. + return llvm::isa<UserDefinedLiteral>(X); + } + // Pushes a node onto the ancestor stack. Pairs with pop(). // Performs early hit detection for some nodes (on the earlySourceRange). void push(DynTypedNode Node) { diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp index 7b8b33d8a25..2803aaaca1c 100644 --- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp @@ -304,6 +304,16 @@ TEST(SelectionTest, CommonAncestor) { } )cpp", "CallExpr"}, + + // User-defined literals are tricky: is 12_i one token or two? + // For now we treat it as one, and the UserDefinedLiteral as a leaf. + { + R"cpp( + struct Foo{}; + Foo operator""_ud(unsigned long long); + Foo x = [[^12_ud]]; + )cpp", + "UserDefinedLiteral"}, }; for (const Case &C : Cases) { Annotations Test(C.Code); |