Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -32,7 +32,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 47 +#define CINDEX_VERSION_MINOR 48 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ @@ -6091,7 +6091,9 @@ } CXIdxCXXClassDeclInfo; /** - * \brief Data for IndexerCallbacks#indexEntityReference. + * \brief DEPRECATED: Data for IndexerCallbacks#indexEntityReference. + * + * Use CXSymbolRole_Implicit instead. */ typedef enum { /** @@ -6105,6 +6107,22 @@ CXIdxEntityRef_Implicit = 2 } CXIdxEntityRefKind; +/** + * \brief Roles that are attributed to symbol occurrences. + */ +typedef enum { + CXSymbolRole_None = 0, + CXSymbolRole_Declaration = 1 << 0, + CXSymbolRole_Definition = 1 << 1, + CXSymbolRole_Reference = 1 << 2, + CXSymbolRole_Read = 1 << 3, + CXSymbolRole_Write = 1 << 4, + CXSymbolRole_Call = 1 << 5, + CXSymbolRole_Dynamic = 1 << 6, + CXSymbolRole_AddressOf = 1 << 7, + CXSymbolRole_Implicit = 1 << 8 +} CXSymbolRole; + /** * \brief Data for IndexerCallbacks#indexEntityReference. */ @@ -6135,6 +6153,10 @@ * \brief Lexical container context of the reference. */ const CXIdxContainerInfo *container; + /** + * \brief Sets of symbol roles of the reference. + */ + CXSymbolRole role; } CXIdxEntityRefInfo; /** Index: test/Index/index-decls.m =================================================================== --- test/Index/index-decls.m +++ test/Index/index-decls.m @@ -78,7 +78,7 @@ // CHECK: [indexEntityReference]: kind: function | name: extfn | {{.*}} | loc: 33:10 // CHECK: [indexDeclaration]: kind: objc-class | name: I4 | {{.*}} | loc: 36:12 -// CHECK: [indexEntityReference]: kind: objc-property | name: prop | {{.*}} | cursor: ObjCSynthesizeDecl=prop:37:34 (Definition) | loc: 43:13 | :: kind: objc-class | name: I4 | {{.*}} | container: [I4:42:17] | refkind: direct +// CHECK: [indexEntityReference]: kind: objc-property | name: prop | {{.*}} | cursor: ObjCSynthesizeDecl=prop:37:34 (Definition) | loc: 43:13 | :: kind: objc-class | name: I4 | {{.*}} | container: [I4:42:17] // CHECK-NOT: [indexDeclaration]: kind: objc-instance-method {{.*}} loc: 37: // CHECK-NOT: [indexDeclaration]: kind: objc-instance-method {{.*}} loc: 43: Index: test/Index/index-refs.cpp =================================================================== --- test/Index/index-refs.cpp +++ test/Index/index-refs.cpp @@ -67,6 +67,9 @@ void foo5() { struct S2 s = { .y = 1, .x = 4}; + s.y = s.x + 1; + (void)&foo3; + foo4(s.y); } int ginitlist[] = {EnumVal}; @@ -105,7 +108,7 @@ // CHECK: [indexDeclaration]: kind: c++-class-template | name: TS | {{.*}} | loc: 47:8 // CHECK-NEXT: [indexDeclaration]: kind: struct-template-partial-spec | name: TS | USR: c:@SP>1#T@TS>#t0.0#I | {{.*}} | loc: 50:8 // CHECK-NEXT: [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp@SP>1#T@TS>#t0.0#I@T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8] -// CHECK-NEXT: [indexEntityReference]: kind: c++-class-template | name: TS | USR: c:@ST>2#T#T@TS | lang: C++ | cursor: TemplateRef=TS:47:8 | loc: 50:8 | :: <> | container: [TU] | refkind: direct +// CHECK-NEXT: [indexEntityReference]: kind: c++-class-template | name: TS | USR: c:@ST>2#T#T@TS | lang: C++ | cursor: TemplateRef=TS:47:8 | loc: 50:8 | :: <> | container: [TU] | role: ref /* when indexing implicit instantiations [indexDeclaration]: kind: struct-template-spec | name: TS | USR: c:@S@TS>#I | {{.*}} | loc: 50:8 [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp@593@S@TS>#I@T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8] @@ -117,7 +120,7 @@ // CHECK-NEXT: [indexEntityReference]: kind: c++-class-template | name: TS | USR: c:@ST>2#T#T@TS | {{.*}} | loc: 55:3 // CHECK: [indexEntityReference]: kind: variable | name: array_size | {{.*}} | loc: 59:22 -// CHECK: [indexEntityReference]: kind: variable | name: default_param | {{.*}} | loc: 62:19 +// CHECK: [indexEntityReference]: kind: variable | name: default_param | {{.*}} | loc: 62:19 | {{.*}} | role: ref read // CHECK-NOT: [indexEntityReference]: kind: variable | name: default_param | {{.*}} | loc: 62:19 // CHECK: [indexEntityReference]: kind: field | name: y | {{.*}} | loc: 69:20 @@ -125,6 +128,11 @@ // CHECK-NOT: [indexEntityReference]: kind: field | name: y | {{.*}} | loc: 69:20 // CHECK-NOT: [indexEntityReference]: kind: field | name: x | {{.*}} | loc: 69:28 +// CHECK: [indexEntityReference]: kind: field | name: y | {{.*}} | loc: 70:5 | {{.*}} | role: ref write +// CHECK: [indexEntityReference]: kind: field | name: x | {{.*}} | loc: 70:11 | {{.*}} | role: ref read +// CHECK: [indexEntityReference]: kind: function | name: foo3 | {{.*}} | loc: 71:10 | {{.*}} | role: ref addressof +// CHECK: [indexEntityReference]: kind: function | name: foo4 | {{.*}} | loc: 72:3 | {{.*}} | role: ref call + // CHECK: [indexDeclaration]: kind: variable | name: ginitlist | -// CHECK: [indexEntityReference]: kind: enumerator | name: EnumVal | {{.*}} | loc: 72:20 -// CHECK-NOT: [indexEntityReference]: kind: enumerator | name: EnumVal | {{.*}} | loc: 72:20 +// CHECK: [indexEntityReference]: kind: enumerator | name: EnumVal | {{.*}} | loc: 75:20 +// CHECK-NOT: [indexEntityReference]: kind: enumerator | name: EnumVal | {{.*}} | loc: 75:20 Index: test/Index/index-subscripting-literals.m =================================================================== --- test/Index/index-subscripting-literals.m +++ test/Index/index-subscripting-literals.m @@ -42,7 +42,7 @@ // RUN: c-index-test -index-file -target x86_64-apple-macosx10.7 %s | FileCheck %s // CHECK: [indexEntityReference]: kind: variable | name: idx | USR: c:@idx | lang: C | cursor: DeclRefExpr=idx:22:5 | loc: 27:9 -// CHECK-NEXT: [indexEntityReference]: kind: variable | name: p | USR: c:@p | lang: C | cursor: DeclRefExpr=p:23:4 | loc: 27:16 | :: kind: function | name: testArray | USR: c:@F@testArray | lang: C | container: [testArray:25:4] | refkind: direct +// CHECK-NEXT: [indexEntityReference]: kind: variable | name: p | USR: c:@p | lang: C | cursor: DeclRefExpr=p:23:4 | loc: 27:16 | :: kind: function | name: testArray | USR: c:@F@testArray | lang: C | container: [testArray:25:4] | role: ref // CHECK-NEXT: [indexEntityReference]: kind: objc-instance-method | name: setObject:atIndexedSubscript: // CHECK-NEXT: [indexEntityReference]: kind: objc-class | name: NSArray // CHECK-NEXT: [indexEntityReference]: kind: objc-class-method | name: arrayWithObjects:count: Index: tools/c-index-test/c-index-test.c =================================================================== --- tools/c-index-test/c-index-test.c +++ tools/c-index-test/c-index-test.c @@ -3326,6 +3326,27 @@ } } +static void printSymbolRole(CXSymbolRole role) { + if (role & CXSymbolRole_Declaration) + printf(" decl"); + if (role & CXSymbolRole_Definition) + printf(" def"); + if (role & CXSymbolRole_Reference) + printf(" ref"); + if (role & CXSymbolRole_Read) + printf(" read"); + if (role & CXSymbolRole_Write) + printf(" write"); + if (role & CXSymbolRole_Call) + printf(" call"); + if (role & CXSymbolRole_Dynamic) + printf(" dyn"); + if (role & CXSymbolRole_AddressOf) + printf(" addr"); + if (role & CXSymbolRole_Implicit) + printf(" implicit"); +} + static void index_diagnostic(CXClientData client_data, CXDiagnosticSet diagSet, void *reserved) { CXString str; @@ -3542,11 +3563,8 @@ printEntityInfo(" | :", client_data, info->parentEntity); printf(" | container: "); printCXIndexContainer(info->container); - printf(" | refkind: "); - switch (info->kind) { - case CXIdxEntityRef_Direct: printf("direct"); break; - case CXIdxEntityRef_Implicit: printf("implicit"); break; - } + printf(" | role:"); + printSymbolRole(info->role); printf("\n"); } Index: tools/libclang/CXIndexDataConsumer.h =================================================================== --- tools/libclang/CXIndexDataConsumer.h +++ tools/libclang/CXIndexDataConsumer.h @@ -436,13 +436,15 @@ const NamedDecl *Parent, const DeclContext *DC, const Expr *E = nullptr, - CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct); + CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct, + CXSymbolRole Role = CXSymbolRole_None); bool handleReference(const NamedDecl *D, SourceLocation Loc, const NamedDecl *Parent, const DeclContext *DC, const Expr *E = nullptr, - CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct); + CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct, + CXSymbolRole Role = CXSymbolRole_None); bool isNotFromSourceFile(SourceLocation Loc) const; Index: tools/libclang/CXIndexDataConsumer.cpp =================================================================== --- tools/libclang/CXIndexDataConsumer.cpp +++ tools/libclang/CXIndexDataConsumer.cpp @@ -148,6 +148,11 @@ return true; } }; + +CXSymbolRole getSymbolRole(SymbolRoleSet Role) { + // CXSymbolRole is synchronized with clang::index::SymbolRole. + return CXSymbolRole(static_cast(Role)); +} } bool CXIndexDataConsumer::handleDeclOccurence(const Decl *D, @@ -184,6 +189,7 @@ if (Roles & (unsigned)SymbolRole::Implicit) { Kind = CXIdxEntityRef_Implicit; } + CXSymbolRole CXRole = getSymbolRole(Roles); CXCursor Cursor; if (ASTNode.OrigE) { @@ -202,7 +208,7 @@ } handleReference(ND, Loc, Cursor, dyn_cast_or_null(ASTNode.Parent), - ASTNode.ContainerDC, ASTNode.OrigE, Kind); + ASTNode.ContainerDC, ASTNode.OrigE, Kind, CXRole); } else { const DeclContext *LexicalDC = ASTNode.ContainerDC; @@ -889,13 +895,14 @@ const NamedDecl *Parent, const DeclContext *DC, const Expr *E, - CXIdxEntityRefKind Kind) { + CXIdxEntityRefKind Kind, + CXSymbolRole Role) { if (!D || !DC) return false; CXCursor Cursor = E ? MakeCXCursor(E, cast(DC), CXTU) : getRefCursor(D, Loc); - return handleReference(D, Loc, Cursor, Parent, DC, E, Kind); + return handleReference(D, Loc, Cursor, Parent, DC, E, Kind, Role); } bool CXIndexDataConsumer::handleReference(const NamedDecl *D, SourceLocation Loc, @@ -903,7 +910,8 @@ const NamedDecl *Parent, const DeclContext *DC, const Expr *E, - CXIdxEntityRefKind Kind) { + CXIdxEntityRefKind Kind, + CXSymbolRole Role) { if (!CB.indexEntityReference) return false; @@ -939,7 +947,8 @@ getIndexLoc(Loc), &RefEntity, Parent ? &ParentEntity : nullptr, - &Container }; + &Container, + Role }; CB.indexEntityReference(ClientData, &Info); return true; }