diff options
-rw-r--r-- | test/Index/usrs.m | 142 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 31 | ||||
-rw-r--r-- | tools/libclang/CXCursor.cpp | 16 | ||||
-rw-r--r-- | tools/libclang/CXCursor.h | 7 |
4 files changed, 189 insertions, 7 deletions
diff --git a/test/Index/usrs.m b/test/Index/usrs.m index 4b3de5c480..03ddfd31ee 100644 --- a/test/Index/usrs.m +++ b/test/Index/usrs.m @@ -69,6 +69,13 @@ static int local_func(int x) { return x; } - (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@85@F@my_helper Extent=[3:19 - 3:60] // CHECK: usrs.m c:usrs.m@95@F@my_helper@x Extent=[3:29 - 3:34] // CHECK: usrs.m c:usrs.m@102@F@my_helper@y Extent=[3:36 - 3:41] @@ -119,4 +126,139 @@ static int local_func(int x) { return x; } // CHECK: usrs.m c:objc(cs)CWithExt(im)meth3 Extent=[66:1 - 66:27] // CHECK: usrs.m c:objc(cy)CWithExt@Bar Extent=[68:1 - 70:2] // CHECK: usrs.m c:objc(cy)CWithExt@Bar(im)meth4 Extent=[69:1 - 69:27] +// CHECK: usrs.m c:@F@aux_1 Extent=[72:6 - 72:26] +// CHECK: usrs.m c:@F@test_multi_declaration Extent=[73:5 - 77:2] +// CHECK: usrs.m c:usrs.m@980@F@test_multi_declaration@foo Extent=[74:3 - 74:14] +// CHECK: usrs.m c:usrs.m@980@F@test_multi_declaration@bar Extent=[74:16 - 74:23] +// CHECK: usrs.m c:usrs.m@980@F@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] + + diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 44493497bd..4413766b02 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -1357,10 +1357,12 @@ bool CursorVisitor::VisitCaseStmt(CaseStmt *S) { } 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 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { 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 @@ static SourceRange getRawCursorExtent(CXCursor C) { 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" { diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index d506400407..9dd94f972e 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -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 @@ CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent, ASTUnit *TU) { 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 @@ bool cxcursor::operator==(CXCursor X, CXCursor Y) { 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; +} + diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h index a31a322076..7e518edef9 100644 --- a/tools/libclang/CXCursor.h +++ b/tools/libclang/CXCursor.h @@ -45,7 +45,8 @@ class TypeDecl; 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 @@ inline bool operator!=(CXCursor X, CXCursor Y) { 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 |