diff options
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CodeGenObjC/direct-method.m | 175 | ||||
-rw-r--r-- | clang/test/Misc/pragma-attribute-supported-attributes-list.test | 2 | ||||
-rw-r--r-- | clang/test/SemaObjC/method-direct-properties.m | 126 | ||||
-rw-r--r-- | clang/test/SemaObjC/method-direct.m | 148 |
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}} +} |