[cfe-commits] r133930 - in /cfe/trunk: test/Index/get-cursor.cpp tools/libclang/CIndex.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Mon Jun 27 12:42:23 PDT 2011


Author: akirtzidis
Date: Mon Jun 27 14:42:23 2011
New Revision: 133930

URL: http://llvm.org/viewvc/llvm-project?rev=133930&view=rev
Log:
[libclang] Avoid having the cursor of an expression replace the declaration cursor
when the expression source range overlaps the declaration range.

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

  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.

rdar://9124499.

Modified:
    cfe/trunk/test/Index/get-cursor.cpp
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/test/Index/get-cursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/get-cursor.cpp?rev=133930&r1=133929&r2=133930&view=diff
==============================================================================
--- cfe/trunk/test/Index/get-cursor.cpp (original)
+++ cfe/trunk/test/Index/get-cursor.cpp Mon Jun 27 14:42:23 2011
@@ -31,6 +31,10 @@
   X getAnotherX() { return member; }
 };
 
+void test() {
+  X foo;
+}
+
 // RUN: c-index-test -cursor-at=%s:12:20 %s | FileCheck -check-prefix=CHECK-VALUE-REF %s
 // RUN: c-index-test -cursor-at=%s:13:21 %s | FileCheck -check-prefix=CHECK-VALUE-REF %s
 // RUN: c-index-test -cursor-at=%s:13:28 %s | FileCheck -check-prefix=CHECK-VALUE-REF %s
@@ -61,3 +65,6 @@
 // RUN: c-index-test -cursor-at=%s:27:10 %s | FileCheck -check-prefix=CHECK-IMPLICIT-MEMREF %s
 // RUN: c-index-test -cursor-at=%s:31:28 %s | FileCheck -check-prefix=CHECK-IMPLICIT-MEMREF %s
 // CHECK-IMPLICIT-MEMREF: MemberRefExpr=member:21:7
+
+// RUN: c-index-test -cursor-at=%s:35:5 %s | FileCheck -check-prefix=CHECK-DECL %s
+// CHECK-DECL: VarDecl=foo:35:5

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=133930&r1=133929&r2=133930&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Mon Jun 27 14:42:23 2011
@@ -3393,11 +3393,34 @@
   return createCXString((const char*) 0);
 }
 
+struct GetCursorData {
+  SourceLocation TokenBeginLoc;
+  CXCursor &BestCursor;
+
+  GetCursorData(SourceLocation tokenBegin, CXCursor &outputCursor)
+    : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) { }
+};
+
 enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
                                          CXCursor parent,
                                          CXClientData client_data) {
-  CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
-  
+  GetCursorData *Data = static_cast<GetCursorData *>(client_data);
+  CXCursor *BestCursor = &Data->BestCursor;
+
+  if (clang_isExpression(cursor.kind) &&
+      clang_isDeclaration(BestCursor->kind)) {
+    Decl *D = getCursorDecl(*BestCursor);
+
+    // Avoid having the cursor of an expression replace the declaration cursor
+    // when the expression source range overlaps the declaration range.
+    // This can happen for C++ constructor expressions whose range generally
+    // include the variable declaration, e.g.:
+    //  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
+    if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
+        D->getLocation() == Data->TokenBeginLoc)
+      return CXChildVisit_Break;
+  }
+
   // If our current best cursor is the construction of a temporary object, 
   // don't replace that cursor with a type reference, because we want 
   // clang_getCursor() to point at the constructor.
@@ -3441,8 +3464,9 @@
     // FIXME: Would be great to have a "hint" cursor, then walk from that
     // hint cursor upward until we find a cursor whose source range encloses
     // the region of interest, rather than starting from the translation unit.
+    GetCursorData ResultData(SLoc, Result);
     CXCursor Parent = clang_getTranslationUnitCursor(TU);
-    CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
+    CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
                             Decl::MaxPCHLevel, true, SourceLocation(SLoc));
     CursorVis.VisitChildren(Parent);
   }





More information about the cfe-commits mailing list