summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShaurya Gupta <shauryab98@gmail.com>2019-07-19 11:41:02 +0000
committerShaurya Gupta <shauryab98@gmail.com>2019-07-19 11:41:02 +0000
commit06841eab009445ee455d85dc9eee17d3a214bb7d (patch)
tree65062066995e0daf8e8617a80004389107471f2a
parent9998585c47b97b31a5811ee0528029629937c063 (diff)
downloadbcm5719-llvm-06841eab009445ee455d85dc9eee17d3a214bb7d.tar.gz
bcm5719-llvm-06841eab009445ee455d85dc9eee17d3a214bb7d.zip
[Clangd] Fixed SelectionTree bug for macros
Summary: Fixed SelectionTree bug for macros - Fixed SelectionTree claimRange for macros and template instantiations - Fixed SelectionTree unit tests - Changed a breaking test in TweakTests Reviewers: sammccall, kadircet Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D64329 llvm-svn: 366566
-rw-r--r--clang-tools-extra/clangd/Selection.cpp22
-rw-r--r--clang-tools-extra/clangd/unittests/SelectionTests.cpp34
-rw-r--r--clang-tools-extra/clangd/unittests/TweakTests.cpp15
3 files changed, 45 insertions, 26 deletions
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp
index d3e8fcf91f8..4ca038a8453 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -8,10 +8,13 @@
#include "Selection.h"
#include "ClangdUnit.h"
+#include "SourceCode.h"
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
#include "llvm/ADT/STLExtras.h"
#include <algorithm>
@@ -239,26 +242,23 @@ private:
SelectionTree::Selection claimRange(SourceRange S) {
if (!S.isValid())
return SelectionTree::Unselected;
- // getTopMacroCallerLoc() allows selection of constructs in macro args. e.g:
+ // toHalfOpenFileRange() allows selection of constructs in macro args. e.g:
// #define LOOP_FOREVER(Body) for(;;) { Body }
// void IncrementLots(int &x) {
// LOOP_FOREVER( ++x; )
// }
// Selecting "++x" or "x" will do the right thing.
- auto B = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getBegin()));
- auto E = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getEnd()));
+ auto Range = toHalfOpenFileRange(SM, LangOpts, S);
+ assert(Range && "We should be able to get the File Range");
+ auto B = SM.getDecomposedLoc(Range->getBegin());
+ auto E = SM.getDecomposedLoc(Range->getEnd());
// Otherwise, nodes in macro expansions can't be selected.
if (B.first != SelFile || E.first != SelFile)
return SelectionTree::Unselected;
- // Cheap test: is there any overlap at all between the selection and range?
- // Note that E.second is the *start* of the last token, which is why we
- // compare against the "rounded-down" SelBegin.
- if (B.second >= SelEnd || E.second < SelBeginTokenStart)
+ // Is there any overlap at all between the selection and range?
+ if (B.second >= SelEnd || E.second < SelBegin)
return SelectionTree::Unselected;
-
- // We may have hit something, need some more precise checks.
- // Adjust [B, E) to be a half-open character range.
- E.second += Lexer::MeasureTokenLength(S.getEnd(), SM, LangOpts);
+ // We may have hit something.
auto PreciseBounds = std::make_pair(B.second, E.second);
// Trim range using the selection, drop it if empty.
B.second = std::max(B.second, SelBegin);
diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
index 205ca529381..9d3b1fcb601 100644
--- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -37,15 +37,15 @@ SelectionTree makeSelectionTree(const StringRef MarkedCode, ParsedAST &AST) {
Range nodeRange(const SelectionTree::Node *N, ParsedAST &AST) {
if (!N)
return Range{};
- SourceManager &SM = AST.getSourceManager();
+ const SourceManager &SM = AST.getSourceManager();
+ const LangOptions &LangOpts = AST.getASTContext().getLangOpts();
StringRef Buffer = SM.getBufferData(SM.getMainFileID());
- SourceRange SR = N->ASTNode.getSourceRange();
- SR.setBegin(SM.getFileLoc(SR.getBegin()));
- SR.setEnd(SM.getFileLoc(SR.getEnd()));
- CharSourceRange R =
- Lexer::getAsCharRange(SR, SM, AST.getASTContext().getLangOpts());
- return Range{offsetToPosition(Buffer, SM.getFileOffset(R.getBegin())),
- offsetToPosition(Buffer, SM.getFileOffset(R.getEnd()))};
+ auto FileRange =
+ toHalfOpenFileRange(SM, LangOpts, N->ASTNode.getSourceRange());
+ assert(FileRange && "We should be able to get the File Range");
+ return Range{
+ offsetToPosition(Buffer, SM.getFileOffset(FileRange->getBegin())),
+ offsetToPosition(Buffer, SM.getFileOffset(FileRange->getEnd()))};
}
std::string nodeKind(const SelectionTree::Node *N) {
@@ -144,17 +144,17 @@ TEST(SelectionTest, CommonAncestor) {
R"cpp(
void foo();
#define CALL_FUNCTION(X) X()
- void bar() [[{ CALL_FUNC^TION(fo^o); }]]
+ void bar() { [[CALL_FUNC^TION(fo^o)]]; }
)cpp",
- "CompoundStmt",
+ "CallExpr",
},
{
R"cpp(
void foo();
#define CALL_FUNCTION(X) X()
- void bar() [[{ C^ALL_FUNC^TION(foo); }]]
+ void bar() { [[C^ALL_FUNC^TION(foo)]]; }
)cpp",
- "CompoundStmt",
+ "CallExpr",
},
{
R"cpp(
@@ -289,6 +289,9 @@ TEST(SelectionTest, InjectedClassName) {
EXPECT_FALSE(D->isInjectedClassName());
}
+// FIXME: Doesn't select the binary operator node in
+// #define FOO(X) X + 1
+// int a, b = [[FOO(a)]];
TEST(SelectionTest, Selected) {
// Selection with ^marks^.
// Partially selected nodes marked with a [[range]].
@@ -308,7 +311,12 @@ TEST(SelectionTest, Selected) {
R"cpp(
template <class T>
struct unique_ptr {};
- void foo(^$C[[unique_ptr<unique_ptr<$C[[int]]>>]]^ a) {}
+ void foo(^$C[[unique_ptr<$C[[unique_ptr<$C[[int]]>]]>]]^ a) {}
+ )cpp",
+ R"cpp(int a = [[5 >^> 1]];)cpp",
+ R"cpp(
+ #define ECHO(X) X
+ ECHO(EC^HO([[$C[[int]]) EC^HO(a]]));
)cpp",
};
for (const char *C : Cases) {
diff --git a/clang-tools-extra/clangd/unittests/TweakTests.cpp b/clang-tools-extra/clangd/unittests/TweakTests.cpp
index 1c5c3a89eb7..f918b731ba6 100644
--- a/clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ b/clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -398,12 +398,23 @@ TEST(TweakTest, ExtractVariable) {
}
})cpp"},*/
// ensure InsertionPoint isn't inside a macro
- {R"cpp(#define LOOP(x) {int a = x + 1;}
+ // FIXME: SelectionTree needs to be fixed for macros
+ /*{R"cpp(#define LOOP(x) while (1) {a = x;}
void f(int a) {
if(1)
LOOP(5 + [[3]])
})cpp",
- R"cpp(#define LOOP(x) {int a = x + 1;}
+ R"cpp(#define LOOP(x) while (1) {a = x;}
+ void f(int a) {
+ auto dummy = 3; if(1)
+ LOOP(5 + dummy)
+ })cpp"},*/
+ {R"cpp(#define LOOP(x) do {x;} while(1);
+ void f(int a) {
+ if(1)
+ LOOP(5 + [[3]])
+ })cpp",
+ R"cpp(#define LOOP(x) do {x;} while(1);
void f(int a) {
auto dummy = 3; if(1)
LOOP(5 + dummy)
OpenPOWER on IntegriCloud