From: Argyrios Kyrtzidis Date: Mon, 27 Jun 2011 19:42:20 +0000 (+0000) Subject: [libclang] Avoid having the cursor of an expression "overwrite" the annotation of the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5517b89953e3c9276f161ce29831de388bb2573d;p=clang [libclang] 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. rdar://9124499. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133929 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Index/annotate-tokens.cpp b/test/Index/annotate-tokens.cpp index ccc9e96028..165420ab39 100644 --- a/test/Index/annotate-tokens.cpp +++ b/test/Index/annotate-tokens.cpp @@ -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= diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index f9cd40820d..3acf8908a0 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -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);