[libclang] Introduce clang_Cursor_getObjCPropertyAttributes to query the written attributes in a property declaration.
rdar://13684512
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179803 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 3da42ab..fed12f4 100644
--- a/include/clang-c/Index.h
+++ b/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 17
+#define CINDEX_VERSION_MINOR 18
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -3360,6 +3360,35 @@
CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C);
/**
+ * \brief Property attributes for a \c CXCursor_ObjCPropertyDecl.
+ */
+typedef enum {
+ CXObjCPropertyAttr_noattr = 0x00,
+ CXObjCPropertyAttr_readonly = 0x01,
+ CXObjCPropertyAttr_getter = 0x02,
+ CXObjCPropertyAttr_assign = 0x04,
+ CXObjCPropertyAttr_readwrite = 0x08,
+ CXObjCPropertyAttr_retain = 0x10,
+ CXObjCPropertyAttr_copy = 0x20,
+ CXObjCPropertyAttr_nonatomic = 0x40,
+ CXObjCPropertyAttr_setter = 0x80,
+ CXObjCPropertyAttr_atomic = 0x100,
+ CXObjCPropertyAttr_weak = 0x200,
+ CXObjCPropertyAttr_strong = 0x400,
+ CXObjCPropertyAttr_unsafe_unretained = 0x800
+} CXObjCPropertyAttrKind;
+
+/**
+ * \brief Given a cursor that represents a property declaration, return the
+ * associated property attributes. The bits are formed from
+ * \c CXObjCPropertyAttrKind.
+ *
+ * \param reserved Reserved for future use, pass 0.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C,
+ unsigned reserved);
+
+/**
* \brief Given a cursor that represents a declaration, return the associated
* comment's source range. The range may include multiple consecutive comments
* with whitespace in between.
diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m
index b0fb71e..61d82a6 100644
--- a/test/Index/c-index-api-loadTU-test.m
+++ b/test/Index/c-index-api-loadTU-test.m
@@ -169,7 +169,7 @@
// CHECK: c-index-api-loadTU-test.m:71:8: StructDecl=X0:71:8 (Definition) Extent=[71:1 - 71:14]
// CHECK: c-index-api-loadTU-test.m:73:12: ObjCCategoryDecl=:73:12 Extent=[73:1 - 76:5]
// CHECK: c-index-api-loadTU-test.m:73:12: ObjCClassRef=TestAttributes:62:12 Extent=[73:12 - 73:26]
-// CHECK: c-index-api-loadTU-test.m:75:32: ObjCPropertyDecl=anotherOutlet:75:32 Extent=[75:1 - 75:45]
+// CHECK: c-index-api-loadTU-test.m:75:32: ObjCPropertyDecl=anotherOutlet:75:32 [retain,] Extent=[75:1 - 75:45]
// CHECK: <invalid loc>:0:0: attribute(iboutlet)= Extent=[75:20 - 75:28]
// CHECK: c-index-api-loadTU-test.m:75:29: TypeRef=id:0:0 Extent=[75:29 - 75:31]
// CHECK: c-index-api-loadTU-test.m:75:32: ObjCInstanceMethodDecl=anotherOutlet:75:32 Extent=[75:32 - 75:45]
diff --git a/test/Index/print-type.m b/test/Index/print-type.m
index 9325c3f..fce1637 100644
--- a/test/Index/print-type.m
+++ b/test/Index/print-type.m
@@ -5,6 +5,6 @@
@end
// RUN: c-index-test -test-print-type %s | FileCheck %s
-// CHECK: ObjCPropertyDecl=x:2:25 [type=id] [typekind=ObjCId] [canonicaltype=id] [canonicaltypekind=ObjCObjectPointer] [isPOD=1]
+// CHECK: ObjCPropertyDecl=x:2:25 [readonly,] [type=id] [typekind=ObjCId] [canonicaltype=id] [canonicaltypekind=ObjCObjectPointer] [isPOD=1]
// CHECK: ObjCInstanceMethodDecl=mymethod:3:8 [type=] [typekind=Invalid] [resulttype=int] [resulttypekind=Int] [isPOD=0]
// CHECK: ObjCInstanceMethodDecl=mymethod2:blah:boo::4:13 [type=] [typekind=Invalid] [resulttype=const id] [resulttypekind=ObjCId] [args= [id] [ObjCId] [Class] [ObjCClass] [SEL] [ObjCSel]] [isPOD=0]
diff --git a/test/Index/properties-class-extensions.m b/test/Index/properties-class-extensions.m
index aa99207..0fa0ecb 100644
--- a/test/Index/properties-class-extensions.m
+++ b/test/Index/properties-class-extensions.m
@@ -60,12 +60,12 @@
// CHECK: properties-class-extensions.m:9:15: ParmDecl=b:9:15 (Definition) Extent=[9:15 - 9:16]
// CHECK: properties-class-extensions.m:10:10: ObjCInstanceMethodDecl=bar:10:10 Extent=[10:1 - 10:14]
// CHECK: properties-class-extensions.m:15:12: ObjCInterfaceDecl=Bar:15:12 Extent=[15:1 - 17:5]
-// CHECK: properties-class-extensions.m:16:25: ObjCPropertyDecl=bar:16:25 Extent=[16:1 - 16:28]
+// CHECK: properties-class-extensions.m:16:25: ObjCPropertyDecl=bar:16:25 [readonly,] Extent=[16:1 - 16:28]
// CHECK: properties-class-extensions.m:16:22: TypeRef=id:0:0 Extent=[16:22 - 16:24]
// CHECK: properties-class-extensions.m:16:25: ObjCInstanceMethodDecl=bar:16:25 Extent=[16:25 - 16:28]
// CHECK: properties-class-extensions.m:18:12: ObjCCategoryDecl=:18:12 Extent=[18:1 - 20:5]
// CHECK: properties-class-extensions.m:18:12: ObjCClassRef=Bar:15:12 Extent=[18:12 - 18:15]
-// CHECK: properties-class-extensions.m:19:26: ObjCPropertyDecl=bar:19:26 Extent=[19:1 - 19:29]
+// CHECK: properties-class-extensions.m:19:26: ObjCPropertyDecl=bar:19:26 [readwrite,] Extent=[19:1 - 19:29]
// CHECK: properties-class-extensions.m:19:23: TypeRef=id:0:0 Extent=[19:23 - 19:25]
// CHECK-NOT: properties-class-extensions.m:16:25: ObjCInstanceMethodDecl=bar:16:25 Extent=[16:25 - 16:28]
// CHECK: properties-class-extensions.m:19:26: ObjCInstanceMethodDecl=setBar::19:26 Extent=[19:26 - 19:29]
@@ -73,7 +73,7 @@
// CHECK: properties-class-extensions.m:24:8: ObjCInterfaceDecl=Rdar8467189_Bar:24:8 Extent=[24:1 - 24:23]
// CHECK: properties-class-extensions.m:24:8: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[24:8 - 24:23]
// CHECK: properties-class-extensions.m:25:11: ObjCProtocolDecl=Rdar8467189_FooProtocol:25:11 (Definition) Extent=[25:1 - 27:5]
-// CHECK: properties-class-extensions.m:26:39: ObjCPropertyDecl=Rdar8467189_Bar:26:39 Extent=[26:1 - 26:54]
+// CHECK: properties-class-extensions.m:26:39: ObjCPropertyDecl=Rdar8467189_Bar:26:39 [readonly,] Extent=[26:1 - 26:54]
// CHECK: properties-class-extensions.m:26:22: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[26:22 - 26:37]
// CHECK: properties-class-extensions.m:26:39: ObjCInstanceMethodDecl=Rdar8467189_Bar:26:39 Extent=[26:39 - 26:54]
// CHECK: properties-class-extensions.m:28:12: ObjCInterfaceDecl=Rdar8467189_Foo:28:12 Extent=[28:1 - 29:5]
@@ -82,7 +82,7 @@
// CHECK-NOT: properties-class-extensions.m:31:23: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[31:23 - 31:38]
// CHECK: properties-class-extensions.m:30:12: ObjCCategoryDecl=:30:12 Extent=[30:1 - 32:5]
// CHECK: properties-class-extensions.m:30:12: ObjCClassRef=Rdar8467189_Foo:28:12 Extent=[30:12 - 30:27]
-// CHECK: properties-class-extensions.m:31:40: ObjCPropertyDecl=Rdar8467189_Bar:31:40 Extent=[31:1 - 31:55]
+// CHECK: properties-class-extensions.m:31:40: ObjCPropertyDecl=Rdar8467189_Bar:31:40 [readwrite,] Extent=[31:1 - 31:55]
// CHECK: properties-class-extensions.m:31:23: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[31:23 - 31:38]
// CHECK: properties-class-extensions.m:31:40: ObjCInstanceMethodDecl=Rdar8467189_Bar:31:40 [Overrides @26:39] Extent=[31:40 - 31:55]
// CHECK: properties-class-extensions.m:31:40: ObjCInstanceMethodDecl=setRdar8467189_Bar::31:40 Extent=[31:40 - 31:55]
@@ -90,7 +90,7 @@
// CHECK: properties-class-extensions.m:35:12: ObjCInterfaceDecl=Qux:35:12 Extent=[35:1 - 36:5]
// CHECK: properties-class-extensions.m:37:12: ObjCCategoryDecl=:37:12 Extent=[37:1 - 39:5]
// CHECK: properties-class-extensions.m:37:12: ObjCClassRef=Qux:35:12 Extent=[37:12 - 37:15]
-// CHECK: properties-class-extensions.m:38:34: ObjCPropertyDecl=qux:38:34 Extent=[38:1 - 38:37]
+// CHECK: properties-class-extensions.m:38:34: ObjCPropertyDecl=qux:38:34 [assign,readwrite,] Extent=[38:1 - 38:37]
// CHECK: properties-class-extensions.m:38:31: TypeRef=id:0:0 Extent=[38:31 - 38:33]
// CHECK: properties-class-extensions.m:38:34: ObjCInstanceMethodDecl=qux:38:34 Extent=[38:34 - 38:37]
// CHECK: properties-class-extensions.m:38:34: ObjCInstanceMethodDecl=setQux::38:34 Extent=[38:34 - 38:37]
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index b77c88d..ab022a9 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -787,6 +787,28 @@
}
PrintCursorComments(Cursor, ValidationData);
+
+ {
+ unsigned PropAttrs = clang_Cursor_getObjCPropertyAttributes(Cursor, 0);
+ if (PropAttrs != CXObjCPropertyAttr_noattr) {
+ printf(" [");
+ #define PRINT_PROP_ATTR(A) \
+ if (PropAttrs & CXObjCPropertyAttr_##A) printf(#A ",")
+ PRINT_PROP_ATTR(readonly);
+ PRINT_PROP_ATTR(getter);
+ PRINT_PROP_ATTR(assign);
+ PRINT_PROP_ATTR(readwrite);
+ PRINT_PROP_ATTR(retain);
+ PRINT_PROP_ATTR(copy);
+ PRINT_PROP_ATTR(nonatomic);
+ PRINT_PROP_ATTR(setter);
+ PRINT_PROP_ATTR(atomic);
+ PRINT_PROP_ATTR(weak);
+ PRINT_PROP_ATTR(strong);
+ PRINT_PROP_ATTR(unsafe_unretained);
+ printf("]");
+ }
+ }
}
}
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 95b49fc..fd13401 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -5919,6 +5919,35 @@
return const_cast<FileEntry *>(ID->getFile());
}
+unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
+ if (C.kind != CXCursor_ObjCPropertyDecl)
+ return CXObjCPropertyAttr_noattr;
+
+ unsigned Result = CXObjCPropertyAttr_noattr;
+ const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
+ ObjCPropertyDecl::PropertyAttributeKind Attr =
+ PD->getPropertyAttributesAsWritten();
+
+#define SET_CXOBJCPROP_ATTR(A) \
+ if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
+ Result |= CXObjCPropertyAttr_##A
+ SET_CXOBJCPROP_ATTR(readonly);
+ SET_CXOBJCPROP_ATTR(getter);
+ SET_CXOBJCPROP_ATTR(assign);
+ SET_CXOBJCPROP_ATTR(readwrite);
+ SET_CXOBJCPROP_ATTR(retain);
+ SET_CXOBJCPROP_ATTR(copy);
+ SET_CXOBJCPROP_ATTR(nonatomic);
+ SET_CXOBJCPROP_ATTR(setter);
+ SET_CXOBJCPROP_ATTR(atomic);
+ SET_CXOBJCPROP_ATTR(weak);
+ SET_CXOBJCPROP_ATTR(strong);
+ SET_CXOBJCPROP_ATTR(unsafe_unretained);
+#undef SET_CXOBJCPROP_ATTR
+
+ return Result;
+}
+
CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getNullRange();
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 16932a5..ad51812 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -10,6 +10,7 @@
clang_Cursor_getParsedComment
clang_Cursor_getRawCommentText
clang_Cursor_getNumArguments
+clang_Cursor_getObjCPropertyAttributes
clang_Cursor_getObjCSelectorIndex
clang_Cursor_getSpellingNameRange
clang_Cursor_getTranslationUnit