summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CodeGenObjC/direct-method.m175
-rw-r--r--clang/test/Misc/pragma-attribute-supported-attributes-list.test2
-rw-r--r--clang/test/SemaObjC/method-direct-properties.m126
-rw-r--r--clang/test/SemaObjC/method-direct.m148
4 files changed, 451 insertions, 0 deletions
diff --git a/clang/test/CodeGenObjC/direct-method.m b/clang/test/CodeGenObjC/direct-method.m
new file mode 100644
index 00000000000..dd9b670b3e4
--- /dev/null
+++ b/clang/test/CodeGenObjC/direct-method.m
@@ -0,0 +1,175 @@
+// RUN: %clang_cc1 -emit-llvm -fobjc-arc -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+
+struct my_complex_struct {
+ int a, b;
+};
+
+struct my_aggregate_struct {
+ int a, b;
+ char buf[128];
+};
+
+__attribute__((objc_root_class))
+@interface Root
+@end
+
+@implementation Root
+// CHECK-LABEL: define hidden i32 @"\01-[Root getInt]"(
+- (int)getInt __attribute__((objc_direct)) {
+ // loading parameters
+ // CHECK-LABEL: entry:
+ // CHECK-NEXT: [[RETVAL:%.*]] = alloca
+ // CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*,
+ // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*,
+ // CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]],
+ // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]],
+
+ // self nil-check
+ // CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]],
+ // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq %0* [[SELF]], null
+ // CHECK-NEXT: br i1 [[NILCHECK]],
+
+ // setting return value to nil
+ // CHECK-LABEL: objc_direct_method.self_is_nil:
+ // CHECK: [[RET0:%.*]] = bitcast{{.*}}[[RETVAL]]
+ // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RET0]], i8 0,
+ // CHECK-NEXT: br label
+
+ // set value
+ // CHECK-LABEL: objc_direct_method.cont:
+ // CHECK: store{{.*}}[[RETVAL]],
+ // CHECK-NEXT: br label
+
+ // return
+ // CHECK-LABEL: return:
+ // CHECK: {{%.*}} = load{{.*}}[[RETVAL]],
+ // CHECK-NEXT: ret
+ return 42;
+}
+
+// CHECK-LABEL: define hidden i32 @"\01+[Root classGetInt]"(
++ (int)classGetInt __attribute__((objc_direct)) {
+ // loading parameters
+ // CHECK-LABEL: entry:
+ // CHECK-NEXT: [[SELFADDR:%.*]] = alloca i8*,
+ // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*,
+ // CHECK-NEXT: store i8* %{{.*}}, i8** [[SELFADDR]],
+ // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]],
+
+ // [self self]
+ // CHECK-NEXT: [[SELF:%.*]] = load i8*, i8** [[SELFADDR]],
+ // CHECK-NEXT: [[SELFSEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
+ // CHECK-NEXT: [[SELF0:%.*]] = call {{.*}} @objc_msgSend
+ // CHECK-NEXT: store i8* [[SELF0]], i8** [[SELFADDR]],
+
+ // return
+ // CHECK-NEXT: ret
+ return 42;
+}
+
+// CHECK-LABEL: define hidden i64 @"\01-[Root getComplex]"(
+- (struct my_complex_struct)getComplex __attribute__((objc_direct)) {
+ // loading parameters
+ // CHECK-LABEL: entry:
+ // CHECK-NEXT: [[RETVAL:%.*]] = alloca
+ // CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*,
+ // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*,
+ // CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]],
+ // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]],
+
+ // self nil-check
+ // CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]],
+ // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq %0* [[SELF]], null
+ // CHECK-NEXT: br i1 [[NILCHECK]],
+
+ // setting return value to nil
+ // CHECK-LABEL: objc_direct_method.self_is_nil:
+ // CHECK: [[RET0:%.*]] = bitcast{{.*}}[[RETVAL]]
+ // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RET0]], i8 0,
+ // CHECK-NEXT: br label
+
+ // set value
+ // CHECK-LABEL: objc_direct_method.cont:
+ // CHECK: [[RET1:%.*]] = bitcast{{.*}}[[RETVAL]]
+ // CHECK-NEXT: call void @llvm.memcpy{{[^(]*}}({{[^,]*}}[[RET1]],
+ // CHECK-NEXT: br label
+
+ // return
+ // CHECK-LABEL: return:
+ // CHECK: [[RET2:%.*]] = bitcast{{.*}}[[RETVAL]]
+ // CHECK-NEXT: {{%.*}} = load{{.*}}[[RET2]],
+ // CHECK-NEXT: ret
+ struct my_complex_struct st = {.a = 42};
+ return st;
+}
+
+// CHECK-LABEL: define hidden i64 @"\01+[Root classGetComplex]"(
++ (struct my_complex_struct)classGetComplex __attribute__((objc_direct)) {
+ struct my_complex_struct st = {.a = 42};
+ return st;
+ // CHECK: ret i64
+}
+
+// CHECK-LABEL: define hidden void @"\01-[Root getAggregate]"(
+- (struct my_aggregate_struct)getAggregate __attribute__((objc_direct)) {
+ // CHECK: %struct.my_aggregate_struct* noalias sret [[RETVAL:%[^,]*]],
+
+ // loading parameters
+ // CHECK-LABEL: entry:
+ // CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*,
+ // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*,
+ // CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]],
+ // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]],
+
+ // self nil-check
+ // CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]],
+ // CHECK-NEXT: [[NILCHECK:%.*]] = icmp eq %0* [[SELF]], null
+ // CHECK-NEXT: br i1 [[NILCHECK]],
+
+ // setting return value to nil
+ // CHECK-LABEL: objc_direct_method.self_is_nil:
+ // CHECK: [[RET0:%.*]] = bitcast{{.*}}[[RETVAL]]
+ // CHECK-NEXT: call void @llvm.memset{{[^(]*}}({{[^,]*}}[[RET0]], i8 0,
+ // CHECK-NEXT: br label
+
+ // set value
+ // CHECK-LABEL: objc_direct_method.cont:
+ // CHECK: [[RET1:%.*]] = bitcast{{.*}}[[RETVAL]]
+ // CHECK: br label
+
+ // return
+ // CHECK-LABEL: return:
+ // CHECK: ret void
+ struct my_aggregate_struct st = {.a = 42};
+ return st;
+}
+
+// CHECK-LABEL: define hidden void @"\01+[Root classGetAggregate]"(
++ (struct my_aggregate_struct)classGetAggregate __attribute__((objc_direct)) {
+ struct my_aggregate_struct st = {.a = 42};
+ return st;
+ // CHECK: ret void
+}
+
+@end
+
+@interface Foo : Root {
+ id __strong _cause_cxx_destruct;
+}
+@property(nonatomic, readonly, direct) int getDirect_setDynamic;
+@property(nonatomic, readonly) int getDynamic_setDirect;
+@end
+
+@interface Foo ()
+@property(nonatomic, readwrite) int getDirect_setDynamic;
+@property(nonatomic, readwrite, direct) int getDynamic_setDirect;
+@end
+
+__attribute__((objc_direct_members))
+@implementation Foo
+// CHECK-LABEL: define hidden i32 @"\01-[Foo getDirect_setDynamic]"(
+// CHECK-LABEL: define internal void @"\01-[Foo setGetDirect_setDynamic:]"(
+// CHECK-LABEL: define internal i32 @"\01-[Foo getDynamic_setDirect]"(
+// CHECK-LABEL: define hidden void @"\01-[Foo setGetDynamic_setDirect:]"(
+// CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"(
+@end
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 877f6ee6f3f..2effc52eb98 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -105,6 +105,8 @@
// CHECK-NEXT: ObjCBridgeRelated (SubjectMatchRule_record)
// CHECK-NEXT: ObjCClassStub (SubjectMatchRule_objc_interface)
// CHECK-NEXT: ObjCDesignatedInitializer (SubjectMatchRule_objc_method)
+// CHECK-NEXT: ObjCDirect (SubjectMatchRule_objc_method)
+// CHECK-NEXT: ObjCDirectMembers (SubjectMatchRule_objc_implementation, SubjectMatchRule_objc_category)
// CHECK-NEXT: ObjCException (SubjectMatchRule_objc_interface)
// CHECK-NEXT: ObjCExplicitProtocolImpl (SubjectMatchRule_objc_protocol)
// CHECK-NEXT: ObjCExternallyRetained (SubjectMatchRule_variable_not_is_parameter, SubjectMatchRule_function, SubjectMatchRule_block, SubjectMatchRule_objc_method)
diff --git a/clang/test/SemaObjC/method-direct-properties.m b/clang/test/SemaObjC/method-direct-properties.m
new file mode 100644
index 00000000000..26d13010551
--- /dev/null
+++ b/clang/test/SemaObjC/method-direct-properties.m
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wselector-type-mismatch %s
+
+@protocol ProtoDirectFail
+@property(nonatomic, direct) int protoProperty; // expected-error {{'objc_direct' attribute cannot be applied to properties declared in an Objective-C protocol}}
+@end
+
+__attribute__((objc_root_class))
+@interface Root
+@property(nonatomic, direct) int propertyWithNonDirectGetter; // expected-note {{previous declaration is here}}
+- (int)propertyWithNonDirectGetter;
+- (int)propertyWithNonDirectGetter2;
+- (int)propertyWithNonDirectGetterInParent;
+- (int)propertyWithNonDirectGetterInParent2;
+
+@property(nonatomic, readonly, direct) int getDirect_setDynamic; // expected-note {{previous declaration is here}}
+@property(nonatomic, readonly, direct) int getDirect_setDirect; // expected-note {{previous declaration is here}}
+@property(nonatomic, readonly, direct) int getDirect_setDirectMembers; // expected-note {{previous declaration is here}}
+
+@property(nonatomic, readonly) int getDynamic_setDirect;
+@property(nonatomic, readonly) int getDynamic_setDirectMembers;
+
+@property(nonatomic, readonly) int dynamicProperty;
+@property(nonatomic, readonly) int synthDynamicProperty;
+
+@property(nonatomic, readonly, direct) int directProperty; // expected-note {{previous declaration is here}}
+@property(nonatomic, readonly, direct) int synthDirectProperty; // expected-note {{previous declaration is here}}
+@end
+
+__attribute__((objc_direct_members))
+@interface
+Root()
+@property(nonatomic) int propertyWithNonDirectGetter2; // expected-note {{previous declaration is here}}
+
+@property(nonatomic, readwrite) int getDirect_setDirectMembers; // expected-note {{previous declaration is here}}
+@property(nonatomic, readwrite) int getDynamic_setDirectMembers; // expected-note {{previous declaration is here}}
+@end
+
+@interface Root ()
+@property(nonatomic, readwrite) int getDirect_setDynamic;
+@property(nonatomic, readwrite, direct) int getDirect_setDirect; // expected-note {{previous declaration is here}}
+
+@property(nonatomic, readwrite, direct) int getDynamic_setDirect; // expected-note {{previous declaration is here}}
+@end
+
+@interface Sub : Root
+@property(nonatomic, direct) int propertyWithNonDirectGetterInParent; // expected-note {{previous declaration is here}}
+
+- (int)propertyWithNonDirectGetter; // no error: legal override
+- (int)propertyWithNonDirectGetter2; // no error: legal override
+- (int)propertyWithNonDirectGetterInParent; // no error: legal override
+- (int)propertyWithNonDirectGetterInParent2; // no error: legal override
+
+@end
+
+__attribute__((objc_direct_members))
+@interface Sub ()
+@property(nonatomic) int propertyWithNonDirectGetterInParent2; // expected-note {{previous declaration is here}}
+@end
+
+// make sure that the `directness` of methods stuck,
+// by observing errors trying to override the setter
+@interface SubWitness : Sub
+
+- (int)setPropertyWithNonDirectGetter:(int)value; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (int)setPropertyWithNonDirectGetter2:(int)value; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (int)setPropertyWithNonDirectGetterInParent:(int)value; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (int)setPropertyWithNonDirectGetterInParent2:(int)value; // expected-error {{cannot override a method that is declared direct by a superclass}}
+
+- (int)getDirect_setDynamic; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (int)setGetDirect_setDynamic:(int)value;
+- (int)getDirect_setDirect; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (int)setGetDirect_setDirect:(int)value; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (int)getDirect_setDirectMembers; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (int)setGetDirect_setDirectMembers:(int)value; // expected-error {{cannot override a method that is declared direct by a superclass}}
+
+- (int)getDynamic_setDirect;
+- (int)setGetDynamic_setDirect:(int)value; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (int)getDynamic_setDirectMembers;
+- (int)setGetDynamic_setDirectMembers:(int)value; // expected-error {{cannot override a method that is declared direct by a superclass}}
+@end
+
+__attribute__((objc_direct_members))
+@implementation Root
+- (int)propertyWithNonDirectGetter {
+ return 42;
+}
+- (int)propertyWithNonDirectGetter2 {
+ return 42;
+}
+- (int)propertyWithNonDirectGetterInParent {
+ return 42;
+}
+- (int)propertyWithNonDirectGetterInParent2 {
+ return 42;
+}
+
+- (int)dynamicProperty {
+ return 42;
+}
+- (int)directProperty {
+ return 42;
+}
+@end
+
+@implementation Sub
+- (int)propertyWithNonDirectGetter {
+ return 42;
+}
+- (int)propertyWithNonDirectGetter2 {
+ return 42;
+}
+
+- (int)dynamicProperty {
+ return 42;
+}
+- (int)synthDynamicProperty {
+ return 42;
+}
+
+- (int)directProperty { // expected-error {{cannot override a method that is declared direct by a superclass}}
+ return 42;
+}
+- (int)synthDirectProperty { // expected-error {{cannot override a method that is declared direct by a superclass}}
+ return 42;
+}
+@end
diff --git a/clang/test/SemaObjC/method-direct.m b/clang/test/SemaObjC/method-direct.m
new file mode 100644
index 00000000000..4829a67cd8a
--- /dev/null
+++ b/clang/test/SemaObjC/method-direct.m
@@ -0,0 +1,148 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wselector-type-mismatch %s
+
+@protocol Proto
+- (void)protoMethod; // expected-note {{previous declaration is here}}
++ (void)classProtoMethod; // expected-note {{previous declaration is here}}
+@end
+
+@protocol ProtoDirectFail
+- (void)protoMethod __attribute__((objc_direct)); // expected-error {{'objc_direct' attribute cannot be applied to methods declared in an Objective-C protocol}}
++ (void)classProtoMethod __attribute__((objc_direct)); // expected-error {{'objc_direct' attribute cannot be applied to methods declared in an Objective-C protocol}}
+@end
+
+__attribute__((objc_root_class))
+@interface Root
+- (void)rootRegular; // expected-note {{previous declaration is here}}
++ (void)classRootRegular; // expected-note {{previous declaration is here}}
+- (void)rootDirect __attribute__((objc_direct)); // expected-note {{previous declaration is here}};
++ (void)classRootDirect __attribute__((objc_direct)); // expected-note {{previous declaration is here}};
+- (void)otherRootDirect __attribute__((objc_direct)); // expected-note {{direct method 'otherRootDirect' declared here}}
++ (void)otherClassRootDirect __attribute__((objc_direct)); // expected-note {{direct method 'otherClassRootDirect' declared here}}
+- (void)notDirectInIface; // expected-note {{previous declaration is here}}
++ (void)classNotDirectInIface; // expected-note {{previous declaration is here}}
+@end
+
+__attribute__((objc_direct_members))
+@interface Root ()
+- (void)rootExtensionDirect; // expected-note {{previous declaration is here}}
++ (void)classRootExtensionDirect; // expected-note {{previous declaration is here}}
+@end
+
+__attribute__((objc_direct_members))
+@interface Root(Direct)
+- (void)rootCategoryDirect; // expected-note {{previous declaration is here}}
++ (void)classRootCategoryDirect; // expected-note {{previous declaration is here}}
+@end
+
+@interface Root ()
+- (void)rootExtensionRegular; // expected-note {{previous declaration is here}}
++ (void)classRootExtensionRegular; // expected-note {{previous declaration is here}}
+- (void)rootExtensionDirect2 __attribute__((objc_direct)); // expected-note {{previous declaration is here}}
++ (void)classRootExtensionDirect2 __attribute__((objc_direct)); // expected-note {{previous declaration is here}}
+@end
+
+@interface Root (Direct2)
+- (void)rootCategoryRegular; // expected-note {{previous declaration is here}}
++ (void)classRootCategoryRegular; // expected-note {{previous declaration is here}}
+- (void)rootCategoryDirect2 __attribute__((objc_direct)); // expected-note {{previous declaration is here}}
++ (void)classRootCategoryDirect2 __attribute__((objc_direct)); // expected-note {{previous declaration is here}}
+@end
+
+__attribute__((objc_root_class, objc_direct_members)) // expected-error {{'objc_direct_members' attribute only applies to Objective-C implementation declarations and Objective-C containers}}
+@interface SubDirectFail : Root
+- (instancetype)init;
+@end
+
+@interface Sub : Root <Proto>
+/* invalid overrides with directs */
+- (void)rootRegular __attribute__((objc_direct)); // expected-error {{methods that override superclass methods cannot be direct}}
++ (void)classRootRegular __attribute__((objc_direct)); // expected-error {{methods that override superclass methods cannot be direct}}
+- (void)protoMethod __attribute__((objc_direct)); // expected-error {{methods that implement protocol requirements cannot be direct}}
++ (void)classProtoMethod __attribute__((objc_direct)); // expected-error {{methods that implement protocol requirements cannot be direct}}
+- (void)rootExtensionRegular __attribute__((objc_direct)); // expected-error {{methods that override superclass methods cannot be direct}}
++ (void)classRootExtensionRegular __attribute__((objc_direct)); // expected-error {{methods that override superclass methods cannot be direct}}
+- (void)rootCategoryRegular __attribute__((objc_direct)); // expected-error {{methods that override superclass methods cannot be direct}}
++ (void)classRootCategoryRegular __attribute__((objc_direct)); // expected-error {{methods that override superclass methods cannot be direct}}
+
+/* invalid overrides of directs */
+- (void)rootDirect; // expected-error {{cannot override a method that is declared direct by a superclass}}
++ (void)classRootDirect; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (void)rootExtensionDirect; // expected-error {{cannot override a method that is declared direct by a superclass}}
++ (void)classRootExtensionDirect; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (void)rootExtensionDirect2; // expected-error {{cannot override a method that is declared direct by a superclass}}
++ (void)classRootExtensionDirect2; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (void)rootCategoryDirect; // expected-error {{cannot override a method that is declared direct by a superclass}}
++ (void)classRootCategoryDirect; // expected-error {{cannot override a method that is declared direct by a superclass}}
+- (void)rootCategoryDirect2; // expected-error {{cannot override a method that is declared direct by a superclass}}
++ (void)classRootCategoryDirect2; // expected-error {{cannot override a method that is declared direct by a superclass}}
+@end
+
+__attribute__((objc_direct_members))
+@implementation Root
+- (void)rootRegular {
+}
++ (void)classRootRegular {
+}
+- (void)rootDirect {
+}
++ (void)classRootDirect {
+}
+- (void)otherRootDirect {
+}
++ (void)otherClassRootDirect {
+}
+- (void)rootExtensionDirect {
+}
++ (void)classRootExtensionDirect {
+}
+- (void)rootExtensionRegular {
+}
++ (void)classRootExtensionRegular {
+}
+- (void)rootExtensionDirect2 {
+}
++ (void)classRootExtensionDirect2 {
+}
+- (void)notDirectInIface __attribute__((objc_direct)) // expected-error {{direct method implementation was previously declared not direct}}
+{
+}
++ (void)classNotDirectInIface __attribute__((objc_direct)) // expected-error {{direct method implementation was previously declared not direct}}
+{
+}
+- (void)direct1 { // expected-note {{direct method 'direct1' declared here}}
+}
+- (void)direct2 { // expected-note {{direct method 'direct2' declared here}}
+}
+@end
+
+@interface Foo : Root
+- (id)directMismatch1; // expected-note {{using}}
+- (id)directMismatch2; // expected-note {{method 'directMismatch2' declared here}}
+@end
+
+@interface Bar : Root
+- (void)directMismatch1 __attribute__((objc_direct)); // expected-note {{also found}}
+- (void)directMismatch2 __attribute__((objc_direct)); // expected-note {{method 'directMismatch2' declared here}}
+@end
+
+@interface ValidSub : Root
+@end
+
+@implementation ValidSub
+- (void)someValidSubMethod {
+ [super otherRootDirect]; // expected-error {{messaging super with a direct method}}
+}
+@end
+
+extern void callMethod(id obj, Class cls);
+extern void useSel(SEL sel);
+
+void callMethod(id obj, Class cls) {
+ [Root otherClassRootDirect];
+ [cls otherClassRootDirect]; // expected-error {{messaging a Class with a method that is possibly direct}}
+ [obj direct1]; // expected-error {{messaging unqualified id with a method that is possibly direct}}
+ [(Root *)obj direct1];
+ [obj directMismatch1]; // expected-warning {{multiple methods named 'directMismatch1' found}}
+ useSel(@selector(direct2)); // expected-error {{@selector expression formed with direct selector 'direct2'}}
+ useSel(@selector(directMismatch2)); // expected-warning {{several methods with selector 'directMismatch2' of mismatched types are found for the @selector expression}}
+}
OpenPOWER on IntegriCloud