Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -4449,6 +4449,18 @@ unsigned reserved); /** + * Given a cursor that represents a property declaration, return the + * name of the method that implements the getter. + */ +CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C); + +/** + * Given a cursor that represents a property declaration, return the + * name of the method that implements the setter, if any. + */ +CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertySetterName(CXCursor C); + +/** * 'Qualifiers' written next to the return and parameter types in * Objective-C method declarations. */ Index: test/Index/property-getter-setter.m =================================================================== --- test/Index/property-getter-setter.m +++ test/Index/property-getter-setter.m @@ -0,0 +1,10 @@ +@interface Foo +@property (assign,readwrite,getter=b,setter=c:) id a; +@property (assign,readonly,getter=e) id d; +@property (assign,readwrite) id f; +@end + +// RUN: c-index-test -test-print-type-declaration %s | FileCheck %s +// CHECK: ObjCPropertyDecl=a:2:52 [getter,assign,readwrite,setter,] (getter=b) (setter=c:) [typedeclaration=id] [typekind=ObjCId] +// CHECK: ObjCPropertyDecl=d:3:41 [readonly,getter,assign,] (getter=e) [typedeclaration=id] [typekind=ObjCId] +// CHECK: ObjCPropertyDecl=f:4:33 [assign,readwrite,] [typedeclaration=id] [typekind=ObjCId] 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 @@ -1103,6 +1103,34 @@ } } + if (Cursor.kind == CXCursor_ObjCPropertyDecl) { + CXString Name = clang_Cursor_getObjCPropertyGetterName(Cursor); + CXString Spelling = clang_getCursorSpelling(Cursor); + const char *CName = clang_getCString(Name); + const char *CSpelling = clang_getCString(Spelling); + if (CName && strcmp(CName, CSpelling)) { + printf(" (getter=%s)", CName); + } + clang_disposeString(Spelling); + clang_disposeString(Name); + } + + if (Cursor.kind == CXCursor_ObjCPropertyDecl) { + CXString Name = clang_Cursor_getObjCPropertySetterName(Cursor); + CXString Spelling = clang_getCursorSpelling(Cursor); + const char *CName = clang_getCString(Name); + const char *CSpelling = clang_getCString(Spelling); + char *DefaultSetter = malloc(strlen(CSpelling) + 5); + sprintf(DefaultSetter, "set%s:", CSpelling); + DefaultSetter[3] &= ~(1 << 5); /* Make uppercase */ + if (CName && strcmp(CName, DefaultSetter)) { + printf(" (setter=%s)", CName); + } + free(DefaultSetter); + clang_disposeString(Spelling); + clang_disposeString(Name); + } + { unsigned QT = clang_Cursor_getObjCDeclQualifiers(Cursor); if (QT != CXObjCDeclQualifier_None) { Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -7913,6 +7913,30 @@ return Result; } +CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) { + if (C.kind != CXCursor_ObjCPropertyDecl) + return cxstring::createNull(); + + const ObjCPropertyDecl *PD = dyn_cast(getCursorDecl(C)); + Selector sel = PD->getGetterName(); + if (sel.isNull()) + return cxstring::createNull(); + + return cxstring::createDup(sel.getAsString()); +} + +CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) { + if (C.kind != CXCursor_ObjCPropertyDecl) + return cxstring::createNull(); + + const ObjCPropertyDecl *PD = dyn_cast(getCursorDecl(C)); + Selector sel = PD->getSetterName(); + if (sel.isNull()) + return cxstring::createNull(); + + return cxstring::createDup(sel.getAsString()); +} + unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) { if (!clang_isDeclaration(C.kind)) return CXObjCDeclQualifier_None; Index: tools/libclang/libclang.exports =================================================================== --- tools/libclang/libclang.exports +++ tools/libclang/libclang.exports @@ -31,6 +31,8 @@ clang_Cursor_getNumArguments clang_Cursor_getObjCDeclQualifiers clang_Cursor_getObjCPropertyAttributes +clang_Cursor_getObjCPropertyGetterName +clang_Cursor_getObjCPropertySetterName clang_Cursor_getObjCSelectorIndex clang_Cursor_getOffsetOfField clang_Cursor_getSpellingNameRange