[cfe-commits] r117973 - in /cfe/trunk: test/Index/usrs.m tools/libclang/CIndex.cpp tools/libclang/CXCursor.cpp tools/libclang/CXCursor.h

Ted Kremenek kremenek at apple.com
Mon Nov 1 16:26:51 PDT 2010


Author: kremenek
Date: Mon Nov  1 18:26:51 2010
New Revision: 117973

URL: http://llvm.org/viewvc/llvm-project?rev=117973&view=rev
Log:
Encapsulate within CXCursor the notion of whether a VarDecl* is the first Decl in a DeclGroup.  We use this
to recover some context that is currently not modeled directly in the AST.  Currently VarDecl's cannot
properly determine their source range because they have no context on whether or not they appear in a DeclGroup.
For the meantime, this bandaid suffices in libclang since that is where the correct SourceRange is directly needed.

Fixes <rdar://problem/8595749>.

Modified:
    cfe/trunk/test/Index/usrs.m
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CXCursor.cpp
    cfe/trunk/tools/libclang/CXCursor.h

Modified: cfe/trunk/test/Index/usrs.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/usrs.m?rev=117973&r1=117972&r2=117973&view=diff
==============================================================================
--- cfe/trunk/test/Index/usrs.m (original)
+++ cfe/trunk/test/Index/usrs.m Mon Nov  1 18:26:51 2010
@@ -69,6 +69,13 @@
 - (id) meth4 { return 0; }
 @end
 
+void aux_1(int, int, int);
+int test_multi_declaration(void) {
+  int foo = 1, bar = 2, baz = 3;
+  aux_1(foo, bar, baz);
+  return 0;
+}
+
 // CHECK: usrs.m c:usrs.m at 85@F at my_helper Extent=[3:19 - 3:60]
 // CHECK: usrs.m c:usrs.m at 95@F at my_helper@x Extent=[3:29 - 3:34]
 // CHECK: usrs.m c:usrs.m at 102@F at my_helper@y Extent=[3:36 - 3:41]
@@ -119,4 +126,139 @@
 // CHECK: usrs.m c:objc(cs)CWithExt(im)meth3 Extent=[66:1 - 66:27]
 // CHECK: usrs.m c:objc(cy)CWithExt at Bar Extent=[68:1 - 70:2]
 // CHECK: usrs.m c:objc(cy)CWithExt at Bar(im)meth4 Extent=[69:1 - 69:27]
+// CHECK: usrs.m c:@F at aux_1 Extent=[72:6 - 72:26]
+// CHECK: usrs.m c:@F at test_multi_declaration Extent=[73:5 - 77:2]
+// CHECK: usrs.m c:usrs.m at 980@F at test_multi_declaration@foo Extent=[74:3 - 74:14]
+// CHECK: usrs.m c:usrs.m at 980@F at test_multi_declaration@bar Extent=[74:16 - 74:23]
+// CHECK: usrs.m c:usrs.m at 980@F at test_multi_declaration@baz Extent=[74:25 - 74:32]
+
+// RUN: c-index-test -test-load-source all %s | FileCheck -check-prefix=CHECK-source %s
+// CHECK-source: usrs.m:3:19: FunctionDecl=my_helper:3:19 (Definition) Extent=[3:19 - 3:60]
+// CHECK-source: usrs.m:3:33: ParmDecl=x:3:33 (Definition) Extent=[3:29 - 3:34]
+// CHECK-source: usrs.m:3:40: ParmDecl=y:3:40 (Definition) Extent=[3:36 - 3:41]
+// CHECK-source: usrs.m:3:43: UnexposedStmt= Extent=[3:43 - 3:60]
+// CHECK-source: usrs.m:3:45: UnexposedStmt= Extent=[3:45 - 3:57]
+// CHECK-source: usrs.m:3:52: UnexposedExpr= Extent=[3:52 - 3:57]
+// CHECK-source: usrs.m:3:52: DeclRefExpr=x:3:33 Extent=[3:52 - 3:53]
+// CHECK-source: usrs.m:3:56: DeclRefExpr=y:3:40 Extent=[3:56 - 3:57]
+// CHECK-source: usrs.m:5:1: EnumDecl=:5:1 (Definition) Extent=[5:1 - 8:2]
+// CHECK-source: usrs.m:6:3: EnumConstantDecl=ABA:6:3 (Definition) Extent=[6:3 - 6:6]
+// CHECK-source: usrs.m:7:3: EnumConstantDecl=CADABA:7:3 (Definition) Extent=[7:3 - 7:9]
+// CHECK-source: usrs.m:10:1: EnumDecl=:10:1 (Definition) Extent=[10:1 - 13:2]
+// CHECK-source: usrs.m:11:3: EnumConstantDecl=FOO:11:3 (Definition) Extent=[11:3 - 11:6]
+// CHECK-source: usrs.m:12:3: EnumConstantDecl=BAR:12:3 (Definition) Extent=[12:3 - 12:6]
+// CHECK-source: usrs.m:15:9: StructDecl=:15:9 (Definition) Extent=[15:9 - 18:2]
+// CHECK-source: usrs.m:16:7: FieldDecl=wa:16:7 (Definition) Extent=[16:7 - 16:9]
+// CHECK-source: usrs.m:17:7: FieldDecl=moo:17:7 (Definition) Extent=[17:7 - 17:10]
+// CHECK-source: usrs.m:18:3: TypedefDecl=MyStruct:18:3 (Definition) Extent=[18:3 - 18:11]
+// CHECK-source: usrs.m:15:9: TypeRef=MyStruct:15:9 Extent=[15:9 - 15:15]
+// CHECK-source: usrs.m:20:6: EnumDecl=Pizza:20:6 (Definition) Extent=[20:1 - 23:2]
+// CHECK-source: usrs.m:21:3: EnumConstantDecl=CHEESE:21:3 (Definition) Extent=[21:3 - 21:9]
+// CHECK-source: usrs.m:22:3: EnumConstantDecl=MUSHROOMS:22:3 (Definition) Extent=[22:3 - 22:12]
+// CHECK-source: usrs.m:25:12: ObjCInterfaceDecl=Foo:25:12 Extent=[25:1 - 32:5]
+// CHECK-source: usrs.m:26:6: ObjCIvarDecl=x:26:6 (Definition) Extent=[26:6 - 26:7]
+// CHECK-source: usrs.m:26:3: TypeRef=id:0:0 Extent=[26:3 - 26:5]
+// CHECK-source: usrs.m:27:6: ObjCIvarDecl=y:27:6 (Definition) Extent=[27:6 - 27:7]
+// CHECK-source: usrs.m:27:3: TypeRef=id:0:0 Extent=[27:3 - 27:5]
+// CHECK-source: usrs.m:31:15: ObjCPropertyDecl=d1:31:15 Extent=[31:15 - 31:17]
+// CHECK-source: usrs.m:29:1: ObjCInstanceMethodDecl=godzilla:29:1 Extent=[29:1 - 29:17]
+// CHECK-source: usrs.m:29:4: TypeRef=id:0:0 Extent=[29:4 - 29:6]
+// CHECK-source: usrs.m:30:1: ObjCClassMethodDecl=kingkong:30:1 Extent=[30:1 - 30:17]
+// CHECK-source: usrs.m:30:4: TypeRef=id:0:0 Extent=[30:4 - 30:6]
+// CHECK-source: usrs.m:31:15: ObjCInstanceMethodDecl=d1:31:15 Extent=[31:15 - 31:17]
+// CHECK-source: usrs.m:31:15: ObjCInstanceMethodDecl=setD1::31:15 Extent=[31:15 - 31:17]
+// CHECK-source: usrs.m:31:15: ParmDecl=d1:31:15 (Definition) Extent=[31:15 - 31:17]
+// CHECK-source: usrs.m:34:1: ObjCImplementationDecl=Foo:34:1 (Definition) Extent=[34:1 - 45:2]
+// CHECK-source: usrs.m:35:1: ObjCInstanceMethodDecl=godzilla:35:1 (Definition) [Overrides @29:1] Extent=[35:1 - 39:2]
+// CHECK-source: usrs.m:35:4: TypeRef=id:0:0 Extent=[35:4 - 35:6]
+// CHECK-source: usrs.m:35:17: UnexposedStmt= Extent=[35:17 - 39:2]
+// CHECK-source: usrs.m:36:3: UnexposedStmt= Extent=[36:3 - 36:20]
+// CHECK-source: usrs.m:36:14: VarDecl=a:36:14 (Definition) Extent=[36:10 - 36:19]
+// CHECK-source: usrs.m:36:18: UnexposedExpr= Extent=[36:18 - 36:19]
+// CHECK-source: usrs.m:37:3: UnexposedStmt= Extent=[37:3 - 37:16]
+// CHECK-source: usrs.m:37:14: VarDecl=z:37:14 Extent=[37:10 - 37:15]
+// CHECK-source: usrs.m:38:3: UnexposedStmt= Extent=[38:3 - 38:11]
+// CHECK-source: usrs.m:38:10: UnexposedExpr= Extent=[38:10 - 38:11]
+// CHECK-source: usrs.m:38:10: UnexposedExpr= Extent=[38:10 - 38:11]
+// CHECK-source: usrs.m:40:1: ObjCClassMethodDecl=kingkong:40:1 (Definition) [Overrides @30:1] Extent=[40:1 - 43:2]
+// CHECK-source: usrs.m:40:4: TypeRef=id:0:0 Extent=[40:4 - 40:6]
+// CHECK-source: usrs.m:40:17: UnexposedStmt= Extent=[40:17 - 43:2]
+// CHECK-source: usrs.m:41:3: UnexposedStmt= Extent=[41:3 - 41:17]
+// CHECK-source: usrs.m:41:7: VarDecl=local_var:41:7 (Definition) Extent=[41:3 - 41:16]
+// CHECK-source: usrs.m:42:3: UnexposedStmt= Extent=[42:3 - 42:11]
+// CHECK-source: usrs.m:42:10: UnexposedExpr= Extent=[42:10 - 42:11]
+// CHECK-source: usrs.m:42:10: UnexposedExpr= Extent=[42:10 - 42:11]
+// CHECK-source: usrs.m:44:13: ObjCIvarDecl=d1:44:13 (Definition) Extent=[44:13 - 44:15]
+// CHECK-source: usrs.m:44:13: UnexposedDecl=:44:13 (Definition) Extent=[44:1 - 44:15]
+// CHECK-source: usrs.m:47:5: VarDecl=z:47:5 Extent=[47:1 - 47:6]
+// CHECK-source: usrs.m:49:12: FunctionDecl=local_func:49:12 (Definition) Extent=[49:12 - 49:43]
+// CHECK-source: usrs.m:49:27: ParmDecl=x:49:27 (Definition) Extent=[49:23 - 49:28]
+// CHECK-source: usrs.m:49:30: UnexposedStmt= Extent=[49:30 - 49:43]
+// CHECK-source: usrs.m:49:32: UnexposedStmt= Extent=[49:32 - 49:40]
+// CHECK-source: usrs.m:49:39: DeclRefExpr=x:49:27 Extent=[49:39 - 49:40]
+// CHECK-source: usrs.m:51:12: ObjCInterfaceDecl=CWithExt:51:12 Extent=[51:1 - 53:5]
+// CHECK-source: usrs.m:52:1: ObjCInstanceMethodDecl=meth1:52:1 Extent=[52:1 - 52:14]
+// CHECK-source: usrs.m:52:4: TypeRef=id:0:0 Extent=[52:4 - 52:6]
+// CHECK-source: usrs.m:54:12: ObjCCategoryDecl=:54:12 Extent=[54:1 - 56:5]
+// CHECK-source: usrs.m:54:12: ObjCClassRef=CWithExt:51:12 Extent=[54:12 - 54:20]
+// CHECK-source: usrs.m:55:1: ObjCInstanceMethodDecl=meth2:55:1 Extent=[55:1 - 55:14]
+// CHECK-source: usrs.m:55:4: TypeRef=id:0:0 Extent=[55:4 - 55:6]
+// CHECK-source: usrs.m:57:12: ObjCCategoryDecl=:57:12 Extent=[57:1 - 59:5]
+// CHECK-source: usrs.m:57:12: ObjCClassRef=CWithExt:51:12 Extent=[57:12 - 57:20]
+// CHECK-source: usrs.m:58:1: ObjCInstanceMethodDecl=meth3:58:1 Extent=[58:1 - 58:14]
+// CHECK-source: usrs.m:58:4: TypeRef=id:0:0 Extent=[58:4 - 58:6]
+// CHECK-source: usrs.m:60:12: ObjCCategoryDecl=Bar:60:12 Extent=[60:1 - 62:5]
+// CHECK-source: usrs.m:60:12: ObjCClassRef=CWithExt:51:12 Extent=[60:12 - 60:20]
+// CHECK-source: usrs.m:61:1: ObjCInstanceMethodDecl=meth4:61:1 Extent=[61:1 - 61:14]
+// CHECK-source: usrs.m:61:4: TypeRef=id:0:0 Extent=[61:4 - 61:6]
+// CHECK-source: usrs.m:63:1: ObjCImplementationDecl=CWithExt:63:1 (Definition) Extent=[63:1 - 67:2]
+// CHECK-source: usrs.m:64:1: ObjCInstanceMethodDecl=meth1:64:1 (Definition) [Overrides @52:1] Extent=[64:1 - 64:27]
+// CHECK-source: usrs.m:64:4: TypeRef=id:0:0 Extent=[64:4 - 64:6]
+// CHECK-source: usrs.m:64:14: UnexposedStmt= Extent=[64:14 - 64:27]
+// CHECK-source: usrs.m:64:16: UnexposedStmt= Extent=[64:16 - 64:24]
+// CHECK-source: usrs.m:64:23: UnexposedExpr= Extent=[64:23 - 64:24]
+// CHECK-source: usrs.m:64:23: UnexposedExpr= Extent=[64:23 - 64:24]
+// CHECK-source: usrs.m:65:1: ObjCInstanceMethodDecl=meth2:65:1 (Definition) [Overrides @55:1] Extent=[65:1 - 65:27]
+// CHECK-source: usrs.m:65:4: TypeRef=id:0:0 Extent=[65:4 - 65:6]
+// CHECK-source: usrs.m:65:14: UnexposedStmt= Extent=[65:14 - 65:27]
+// CHECK-source: usrs.m:65:16: UnexposedStmt= Extent=[65:16 - 65:24]
+// CHECK-source: usrs.m:65:23: UnexposedExpr= Extent=[65:23 - 65:24]
+// CHECK-source: usrs.m:65:23: UnexposedExpr= Extent=[65:23 - 65:24]
+// CHECK-source: usrs.m:66:1: ObjCInstanceMethodDecl=meth3:66:1 (Definition) [Overrides @58:1] Extent=[66:1 - 66:27]
+// CHECK-source: usrs.m:66:4: TypeRef=id:0:0 Extent=[66:4 - 66:6]
+// CHECK-source: usrs.m:66:14: UnexposedStmt= Extent=[66:14 - 66:27]
+// CHECK-source: usrs.m:66:16: UnexposedStmt= Extent=[66:16 - 66:24]
+// CHECK-source: usrs.m:66:23: UnexposedExpr= Extent=[66:23 - 66:24]
+// CHECK-source: usrs.m:66:23: UnexposedExpr= Extent=[66:23 - 66:24]
+// CHECK-source: usrs.m:68:1: ObjCCategoryImplDecl=Bar:68:1 (Definition) Extent=[68:1 - 70:2]
+// CHECK-source: usrs.m:68:1: ObjCClassRef=CWithExt:51:12 Extent=[68:1 - 68:2]
+// CHECK-source: usrs.m:69:1: ObjCInstanceMethodDecl=meth4:69:1 (Definition) [Overrides @61:1] Extent=[69:1 - 69:27]
+// CHECK-source: usrs.m:69:4: TypeRef=id:0:0 Extent=[69:4 - 69:6]
+// CHECK-source: usrs.m:69:14: UnexposedStmt= Extent=[69:14 - 69:27]
+// CHECK-source: usrs.m:69:16: UnexposedStmt= Extent=[69:16 - 69:24]
+// CHECK-source: usrs.m:69:23: UnexposedExpr= Extent=[69:23 - 69:24]
+// CHECK-source: usrs.m:69:23: UnexposedExpr= Extent=[69:23 - 69:24]
+// CHECK-source: usrs.m:72:6: FunctionDecl=aux_1:72:6 Extent=[72:6 - 72:26]
+// CHECK-source: usrs.m:72:15: ParmDecl=:72:15 (Definition) Extent=[72:12 - 72:16]
+// CHECK-source: usrs.m:72:20: ParmDecl=:72:20 (Definition) Extent=[72:17 - 72:21]
+// CHECK-source: usrs.m:72:25: ParmDecl=:72:25 (Definition) Extent=[72:22 - 72:26]
+// CHECK-source: usrs.m:73:5: FunctionDecl=test_multi_declaration:73:5 (Definition) Extent=[73:5 - 77:2]
+// CHECK-source: usrs.m:73:34: UnexposedStmt= Extent=[73:34 - 77:2]
+// CHECK-source: usrs.m:74:3: UnexposedStmt= Extent=[74:3 - 74:33]
+// CHECK-source: usrs.m:74:7: VarDecl=foo:74:7 (Definition) Extent=[74:3 - 74:14]
+// CHECK-source: usrs.m:74:13: UnexposedExpr= Extent=[74:13 - 74:14]
+// CHECK-source: usrs.m:74:16: VarDecl=bar:74:16 Extent=[74:16 - 74:23]
+// CHECK-source: usrs.m:74:22: UnexposedExpr= Extent=[74:22 - 74:23]
+// CHECK-source: usrs.m:74:25: VarDecl=baz:74:25 Extent=[74:25 - 74:32]
+// CHECK-source: usrs.m:74:31: UnexposedExpr= Extent=[74:31 - 74:32]
+// CHECK-source: usrs.m:75:3: CallExpr=aux_1:72:6 Extent=[75:3 - 75:23]
+// CHECK-source: usrs.m:75:3: UnexposedExpr=aux_1:72:6 Extent=[75:3 - 75:8]
+// CHECK-source: usrs.m:75:3: DeclRefExpr=aux_1:72:6 Extent=[75:3 - 75:8]
+// CHECK-source: usrs.m:75:9: DeclRefExpr=foo:74:7 Extent=[75:9 - 75:12]
+// CHECK-source: usrs.m:75:14: DeclRefExpr=bar:74:16 Extent=[75:14 - 75:17]
+// CHECK-source: usrs.m:75:19: DeclRefExpr=baz:74:25 Extent=[75:19 - 75:22]
+// CHECK-source: usrs.m:76:3: UnexposedStmt= Extent=[76:3 - 76:11]
+// CHECK-source: usrs.m:76:10: UnexposedExpr= Extent=[76:10 - 76:11]
+
+
 

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=117973&r1=117972&r2=117973&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Mon Nov  1 18:26:51 2010
@@ -1357,10 +1357,12 @@
 }
 
 bool CursorVisitor::VisitDeclStmt(DeclStmt *S) {
+  bool isFirst = true;
   for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
        D != DEnd; ++D) {
-    if (*D && Visit(MakeCXCursor(*D, TU)))
+    if (*D && Visit(MakeCXCursor(*D, TU, isFirst)))
       return true;
+    isFirst = false;
   }
 
   return false;
@@ -2926,6 +2928,16 @@
   SourceLocation Loc = D->getLocation();
   if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
     Loc = Class->getClassLoc();
+  // FIXME: Multiple variables declared in a single declaration
+  // currently lack the information needed to correctly determine their
+  // ranges when accounting for the type-specifier.  We use context
+  // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
+  // and if so, whether it is the first decl.
+  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (!cxcursor::isFirstInDeclGroup(C))
+      Loc = VD->getLocation();
+  }
+
   return cxloc::translateSourceLocation(getCursorContext(C), Loc);
 }
 
@@ -2988,9 +3000,20 @@
   if (C.kind == CXCursor_InclusionDirective)
     return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
 
-  if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl)
-    return getCursorDecl(C)->getSourceRange();
-
+  if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
+    Decl *D = cxcursor::getCursorDecl(C);
+    SourceRange R = D->getSourceRange();
+    // FIXME: Multiple variables declared in a single declaration
+    // currently lack the information needed to correctly determine their
+    // ranges when accounting for the type-specifier.  We use context
+    // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
+    // and if so, whether it is the first decl.
+    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+      if (!cxcursor::isFirstInDeclGroup(C))
+        R.setBegin(VD->getLocation());
+    }
+    return R;
+  }
   return SourceRange();}
 
 extern "C" {

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=117973&r1=117972&r2=117973&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Mon Nov  1 18:26:51 2010
@@ -20,6 +20,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang-c/Index.h"
 #include "llvm/Support/ErrorHandling.h"
 
 using namespace clang;
@@ -49,9 +50,12 @@
   return C;
 }
 
-CXCursor cxcursor::MakeCXCursor(Decl *D, ASTUnit *TU) {
+CXCursor cxcursor::MakeCXCursor(Decl *D, ASTUnit *TU,
+                                bool FirstInDeclGroup) {
   assert(D && TU && "Invalid arguments!");
-  CXCursor C = { getCursorKindForDecl(D), { D, 0, TU } };
+  CXCursor C = { getCursorKindForDecl(D),
+                 { D, (void*) (FirstInDeclGroup ? 1 : 0), TU }
+               };
   return C;
 }
 
@@ -470,3 +474,11 @@
   return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
          X.data[2] == Y.data[2];
 }
+
+// FIXME: Remove once we can model DeclGroups and their appropriate ranges
+// properly in the ASTs.
+bool cxcursor::isFirstInDeclGroup(CXCursor C) {
+  assert(clang_isDeclaration(C.kind));
+  return ((uintptr_t) (C.data[1])) != 0;
+}
+

Modified: cfe/trunk/tools/libclang/CXCursor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.h?rev=117973&r1=117972&r2=117973&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.h (original)
+++ cfe/trunk/tools/libclang/CXCursor.h Mon Nov  1 18:26:51 2010
@@ -45,7 +45,8 @@
 namespace cxcursor {
   
 CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent, ASTUnit *TU);
-CXCursor MakeCXCursor(clang::Decl *D, ASTUnit *TU);
+CXCursor MakeCXCursor(clang::Decl *D, ASTUnit *TU,
+                      bool FirstInDeclGroup = true);
 CXCursor MakeCXCursor(clang::Stmt *S, clang::Decl *Parent, ASTUnit *TU);
 CXCursor MakeCXCursorInvalid(CXCursorKind K);
 
@@ -183,6 +184,10 @@
   return !(X == Y);
 }
 
+/// \brief Return true if the cursor represents a declaration that is the
+/// first in a declaration group.
+bool isFirstInDeclGroup(CXCursor C);
+
 }} // end namespace: clang::cxcursor
 
 #endif





More information about the cfe-commits mailing list