[clang-tools-extra] r366566 - [Clangd] Fixed SelectionTree bug for macros

Shaurya Gupta via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 19 04:41:03 PDT 2019


Author: sureyeaah
Date: Fri Jul 19 04:41:02 2019
New Revision: 366566

URL: http://llvm.org/viewvc/llvm-project?rev=366566&view=rev
Log:
[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

Modified:
    clang-tools-extra/trunk/clangd/Selection.cpp
    clang-tools-extra/trunk/clangd/unittests/SelectionTests.cpp
    clang-tools-extra/trunk/clangd/unittests/TweakTests.cpp

Modified: clang-tools-extra/trunk/clangd/Selection.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Selection.cpp?rev=366566&r1=366565&r2=366566&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Selection.cpp (original)
+++ clang-tools-extra/trunk/clangd/Selection.cpp Fri Jul 19 04:41:02 2019
@@ -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);

Modified: clang-tools-extra/trunk/clangd/unittests/SelectionTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/SelectionTests.cpp?rev=366566&r1=366565&r2=366566&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/SelectionTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/SelectionTests.cpp Fri Jul 19 04:41:02 2019
@@ -37,15 +37,15 @@ SelectionTree makeSelectionTree(const St
 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) {

Modified: clang-tools-extra/trunk/clangd/unittests/TweakTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/TweakTests.cpp?rev=366566&r1=366565&r2=366566&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/TweakTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/TweakTests.cpp Fri Jul 19 04:41:02 2019
@@ -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)




More information about the cfe-commits mailing list