]> granicus.if.org Git - clang/commitdiff
[libclang] Avoid having the cursor of an expression "overwrite" the annotation of the
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 27 Jun 2011 19:42:20 +0000 (19:42 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 27 Jun 2011 19:42:20 +0000 (19:42 +0000)
variable declaration that it belongs to.

This can happen for C++ constructor expressions whose range generally
include the variable declaration, e.g.:

  MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.

rdar://9124499.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133929 91177308-0d34-0410-b5e6-96231b3b80d8

test/Index/annotate-tokens.cpp
tools/libclang/CIndex.cpp

index ccc9e960284390201ada79347df61e16111e06f4..165420ab39ceca3debdf482acbd1f3e1650e434f 100644 (file)
@@ -17,9 +17,10 @@ struct S1 { void f(); };
 struct S2 { S1 *operator->(); };
 void test3(S2 s2) {
   s2->f();
+  X foo;
 }
 
-// RUN: c-index-test -test-annotate-tokens=%s:1:1:20:1 %s | FileCheck %s
+// RUN: c-index-test -test-annotate-tokens=%s:1:1:21:1 %s | FileCheck %s
 // CHECK: Keyword: "struct" [1:1 - 1:7] StructDecl=bonk:1:8 (Definition)
 // CHECK: Identifier: "bonk" [1:8 - 1:12] StructDecl=bonk:1:8 (Definition)
 // CHECK: Punctuation: "{" [1:13 - 1:14] StructDecl=bonk:1:8 (Definition)
@@ -115,4 +116,7 @@ void test3(S2 s2) {
 // CHECK: Punctuation: "(" [19:8 - 19:9] CallExpr=f:16:18
 // CHECK: Punctuation: ")" [19:9 - 19:10] CallExpr=f:16:18
 // CHECK: Punctuation: ";" [19:10 - 19:11] UnexposedStmt=
-// CHECK: Punctuation: "}" [20:1 - 20:2] UnexposedStmt=
+// CHECK: Identifier: "X" [20:3 - 20:4] TypeRef=struct X:7:8
+// CHECK: Identifier: "foo" [20:5 - 20:8] VarDecl=foo:20:5 (Definition)
+// CHECK: Punctuation: ";" [20:8 - 20:9] UnexposedStmt=
+// CHECK: Punctuation: "}" [21:1 - 21:2] UnexposedStmt=
index f9cd40820d71512948ed7bc8fa127b6ae43f527d..3acf8908a0f106a9987c6e99dae899df3607ba31 100644 (file)
@@ -4627,6 +4627,24 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
     break;
   }
 
+  // Avoid having the cursor of an expression "overwrite" the annotation of the
+  // variable declaration that it belongs to.
+  // This can happen for C++ constructor expressions whose range generally
+  // include the variable declaration, e.g.:
+  //  MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
+  if (clang_isExpression(cursorK)) {
+    Expr *E = getCursorExpr(cursor);
+    if (Decl *D = getCursorDecl(cursor)) {
+      const unsigned I = NextToken();
+      if (E->getLocStart().isValid() && D->getLocation().isValid() &&
+          E->getLocStart() == D->getLocation() &&
+          E->getLocStart() == GetTokenLoc(I)) {
+        Cursors[I] = updateC;
+        AdvanceToken();
+      }
+    }
+  }
+
   // Visit children to get their cursor information.
   const unsigned BeforeChildren = NextToken();
   VisitChildren(cursor);