From 514afc7255a2aaa88498b3374c944a2c497c1c55 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Fri, 5 Jul 2013 20:44:37 +0000 Subject: [PATCH] [libclang] Introduce clang_Cursor_isObjCOptional, which returns whether the declaration was affected by "@optional" rdar://14348525. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185722 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang-c/Index.h | 7 +++++++ test/Index/get-cursor.m | 24 ++++++++++++++++++++++++ tools/c-index-test/c-index-test.c | 4 +++- tools/libclang/CIndex.cpp | 13 +++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 21b7dba076..aa4b46f8df 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -3413,6 +3413,13 @@ typedef enum { */ CINDEX_LINKAGE unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C); +/** + * \brief Given a cursor that represents an ObjC method or property declaration, + * return non-zero if the declaration was affected by "@optional". + * Returns zero if the cursor is not such a declaration or it is "@required". + */ +CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C); + /** * \brief Returns non-zero if the given cursor is a variadic function or method. */ diff --git a/test/Index/get-cursor.m b/test/Index/get-cursor.m index 7eaa3a0a3c..f659fb1ff6 100644 --- a/test/Index/get-cursor.m +++ b/test/Index/get-cursor.m @@ -99,6 +99,20 @@ void foo3(Test3 *test3) { @synthesize prop1 = _prop1; @end +@protocol TestProt +-(void)protMeth1; +@property (retain) id propProp1; + +@optional +-(void)protMeth2; +@property (retain) id propProp2; + +@required +-(void)protMeth3; +@property (retain) id propProp3; +@end + + // RUN: c-index-test -cursor-at=%s:4:28 -cursor-at=%s:5:28 %s | FileCheck -check-prefix=CHECK-PROP %s // CHECK-PROP: ObjCPropertyDecl=foo1:4:26 // CHECK-PROP: ObjCPropertyDecl=foo2:5:27 @@ -146,3 +160,13 @@ void foo3(Test3 *test3) { // RUN: c-index-test -cursor-at=%s:86:7 -cursor-at=%s:89:7 %s | FileCheck -check-prefix=CHECK-SELECTORLOC %s // CHECK-SELECTORLOC: 86:6 ObjCInstanceMethodDecl=meth1:86:6 (Definition) Extent=[86:1 - 88:2] Spelling=meth1 ([86:6 - 86:11]) Selector index=0 // CHECK-SELECTORLOC: 89:6 ObjCInstanceMethodDecl=meth2:89:6 (Definition) Extent=[89:1 - 91:2] Spelling=meth2 ([89:6 - 89:11]) Selector index=0 + +// RUN: c-index-test -cursor-at=%s:103:10 -cursor-at=%s:104:10 \ +// RUN: -cursor-at=%s:107:10 -cursor-at=%s:108:10 \ +// RUN: -cursor-at=%s:111:10 -cursor-at=%s:112:10 %s | FileCheck -check-prefix=CHECK-OBJCOPTIONAL %s +// CHECK-OBJCOPTIONAL: 103:8 ObjCInstanceMethodDecl=protMeth1:103:8 Extent=[103:1 - 103:18] +// CHECK-OBJCOPTIONAL: 104:23 ObjCPropertyDecl=propProp1:104:23 [retain,] Extent=[104:1 - 104:32] +// CHECK-OBJCOPTIONAL: 107:8 ObjCInstanceMethodDecl=protMeth2:107:8 (@optional) Extent=[107:1 - 107:18] +// CHECK-OBJCOPTIONAL: 108:23 ObjCPropertyDecl=propProp2:108:23 (@optional) [retain,] Extent=[108:1 - 108:32] +// CHECK-OBJCOPTIONAL: 111:8 ObjCInstanceMethodDecl=protMeth3:111:8 Extent=[111:1 - 111:18] +// CHECK-OBJCOPTIONAL: 112:23 ObjCPropertyDecl=propProp3:112:23 [retain,] Extent=[112:1 - 112:32] diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index a824a9f041..2e8b58bff4 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -698,7 +698,9 @@ static void PrintCursor(CXCursor Cursor, printf(" (pure)"); if (clang_Cursor_isVariadic(Cursor)) printf(" (variadic)"); - + if (clang_Cursor_isObjCOptional(Cursor)) + printf(" (@optional)"); + if (Cursor.kind == CXCursor_IBOutletCollectionAttr) { CXType T = clang_getCanonicalType(clang_getIBOutletCollectionType(Cursor)); diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index eecb16a17e..ae131af333 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -5992,6 +5992,19 @@ unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) { return Result; } +unsigned clang_Cursor_isObjCOptional(CXCursor C) { + if (!clang_isDeclaration(C.kind)) + return 0; + + const Decl *D = getCursorDecl(C); + if (const ObjCPropertyDecl *PD = dyn_cast(D)) + return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional; + if (const ObjCMethodDecl *MD = dyn_cast(D)) + return MD->getImplementationControl() == ObjCMethodDecl::Optional; + + return 0; +} + unsigned clang_Cursor_isVariadic(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; -- 2.40.0