llvm-project/clang/test/CodeGenObjC/direct-method.m

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

238 lines
7.6 KiB
Mathematica
Raw Normal View History

Implement __attribute__((objc_direct)), __attribute__((objc_direct_members)) __attribute__((objc_direct)) is an attribute on methods declaration, and __attribute__((objc_direct_members)) on implementation, categories or extensions. A `direct` property specifier is added (@property(direct) type name) These attributes / specifiers cause the method to have no associated Objective-C metadata (for the property or the method itself), and the calling convention to be a direct C function call. The symbol for the method has enforced hidden visibility and such direct calls are hence unreachable cross image. An explicit C function must be made if so desired to wrap them. The implicit `self` and `_cmd` arguments are preserved, however to maintain compatibility with the usual `objc_msgSend` semantics, 3 fundamental precautions are taken: 1) for instance methods, `self` is nil-checked. On arm64 backends this typically adds a single instruction (cbz x0, <closest-ret>) to the codegen, for the vast majority of the cases when the return type is a scalar. 2) for class methods, because the class may not be realized/initialized yet, a call to `[self self]` is emitted. When the proper deployment target is used, this is optimized to `objc_opt_self(self)`. However, long term we might want to emit something better that the optimizer can reason about. When inlining kicks in, these calls aren't optimized away as the optimizer has no idea that a single call is really necessary. 3) the calling convention for the `_cmd` argument is changed: the caller leaves the second argument to the call undefined, and the selector is loaded inside the body when it's referenced only. As far as error reporting goes, the compiler refuses: - making any overloads direct, - making an overload of a direct method, - implementations marked as direct when the declaration in the interface isn't (the other way around is allowed, as the direct attribute is inherited from the declaration), - marking methods required for protocol conformance as direct, - messaging an unqualified `id` with a direct method, - forming any @selector() expression with only direct selectors. As warnings: - any inconsistency of direct-related calling convention when @selector() or messaging is used, - forming any @selector() expression with a possibly direct selector. Lastly an `objc_direct_members` attribute is added that can decorate `@implementation` blocks and causes methods only declared there (and in no `@interface`) to be automatically direct. When decorating an `@interface` then all methods and properties declared in this block are marked direct. Radar-ID: rdar://problem/2684889 Differential Revision: https://reviews.llvm.org/D69991 Reviewed-By: John McCall
2019-11-08 15:14:58 +08:00
// 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
- (int)getInt __attribute__((objc_direct));
@property(direct, readonly) int intProperty;
@property(direct, readonly) int intProperty2;
Implement __attribute__((objc_direct)), __attribute__((objc_direct_members)) __attribute__((objc_direct)) is an attribute on methods declaration, and __attribute__((objc_direct_members)) on implementation, categories or extensions. A `direct` property specifier is added (@property(direct) type name) These attributes / specifiers cause the method to have no associated Objective-C metadata (for the property or the method itself), and the calling convention to be a direct C function call. The symbol for the method has enforced hidden visibility and such direct calls are hence unreachable cross image. An explicit C function must be made if so desired to wrap them. The implicit `self` and `_cmd` arguments are preserved, however to maintain compatibility with the usual `objc_msgSend` semantics, 3 fundamental precautions are taken: 1) for instance methods, `self` is nil-checked. On arm64 backends this typically adds a single instruction (cbz x0, <closest-ret>) to the codegen, for the vast majority of the cases when the return type is a scalar. 2) for class methods, because the class may not be realized/initialized yet, a call to `[self self]` is emitted. When the proper deployment target is used, this is optimized to `objc_opt_self(self)`. However, long term we might want to emit something better that the optimizer can reason about. When inlining kicks in, these calls aren't optimized away as the optimizer has no idea that a single call is really necessary. 3) the calling convention for the `_cmd` argument is changed: the caller leaves the second argument to the call undefined, and the selector is loaded inside the body when it's referenced only. As far as error reporting goes, the compiler refuses: - making any overloads direct, - making an overload of a direct method, - implementations marked as direct when the declaration in the interface isn't (the other way around is allowed, as the direct attribute is inherited from the declaration), - marking methods required for protocol conformance as direct, - messaging an unqualified `id` with a direct method, - forming any @selector() expression with only direct selectors. As warnings: - any inconsistency of direct-related calling convention when @selector() or messaging is used, - forming any @selector() expression with a possibly direct selector. Lastly an `objc_direct_members` attribute is added that can decorate `@implementation` blocks and causes methods only declared there (and in no `@interface`) to be automatically direct. When decorating an `@interface` then all methods and properties declared in this block are marked direct. Radar-ID: rdar://problem/2684889 Differential Revision: https://reviews.llvm.org/D69991 Reviewed-By: John McCall
2019-11-08 15:14:58 +08:00
@end
@implementation Root
// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty2]"
- (int)intProperty2 {
return 42;
}
Implement __attribute__((objc_direct)), __attribute__((objc_direct_members)) __attribute__((objc_direct)) is an attribute on methods declaration, and __attribute__((objc_direct_members)) on implementation, categories or extensions. A `direct` property specifier is added (@property(direct) type name) These attributes / specifiers cause the method to have no associated Objective-C metadata (for the property or the method itself), and the calling convention to be a direct C function call. The symbol for the method has enforced hidden visibility and such direct calls are hence unreachable cross image. An explicit C function must be made if so desired to wrap them. The implicit `self` and `_cmd` arguments are preserved, however to maintain compatibility with the usual `objc_msgSend` semantics, 3 fundamental precautions are taken: 1) for instance methods, `self` is nil-checked. On arm64 backends this typically adds a single instruction (cbz x0, <closest-ret>) to the codegen, for the vast majority of the cases when the return type is a scalar. 2) for class methods, because the class may not be realized/initialized yet, a call to `[self self]` is emitted. When the proper deployment target is used, this is optimized to `objc_opt_self(self)`. However, long term we might want to emit something better that the optimizer can reason about. When inlining kicks in, these calls aren't optimized away as the optimizer has no idea that a single call is really necessary. 3) the calling convention for the `_cmd` argument is changed: the caller leaves the second argument to the call undefined, and the selector is loaded inside the body when it's referenced only. As far as error reporting goes, the compiler refuses: - making any overloads direct, - making an overload of a direct method, - implementations marked as direct when the declaration in the interface isn't (the other way around is allowed, as the direct attribute is inherited from the declaration), - marking methods required for protocol conformance as direct, - messaging an unqualified `id` with a direct method, - forming any @selector() expression with only direct selectors. As warnings: - any inconsistency of direct-related calling convention when @selector() or messaging is used, - forming any @selector() expression with a possibly direct selector. Lastly an `objc_direct_members` attribute is added that can decorate `@implementation` blocks and causes methods only declared there (and in no `@interface`) to be automatically direct. When decorating an `@interface` then all methods and properties declared in this block are marked direct. Radar-ID: rdar://problem/2684889 Differential Revision: https://reviews.llvm.org/D69991 Reviewed-By: John McCall
2019-11-08 15:14:58 +08:00
// 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 align 4 [[RETVAL:%[^,]*]],
Implement __attribute__((objc_direct)), __attribute__((objc_direct_members)) __attribute__((objc_direct)) is an attribute on methods declaration, and __attribute__((objc_direct_members)) on implementation, categories or extensions. A `direct` property specifier is added (@property(direct) type name) These attributes / specifiers cause the method to have no associated Objective-C metadata (for the property or the method itself), and the calling convention to be a direct C function call. The symbol for the method has enforced hidden visibility and such direct calls are hence unreachable cross image. An explicit C function must be made if so desired to wrap them. The implicit `self` and `_cmd` arguments are preserved, however to maintain compatibility with the usual `objc_msgSend` semantics, 3 fundamental precautions are taken: 1) for instance methods, `self` is nil-checked. On arm64 backends this typically adds a single instruction (cbz x0, <closest-ret>) to the codegen, for the vast majority of the cases when the return type is a scalar. 2) for class methods, because the class may not be realized/initialized yet, a call to `[self self]` is emitted. When the proper deployment target is used, this is optimized to `objc_opt_self(self)`. However, long term we might want to emit something better that the optimizer can reason about. When inlining kicks in, these calls aren't optimized away as the optimizer has no idea that a single call is really necessary. 3) the calling convention for the `_cmd` argument is changed: the caller leaves the second argument to the call undefined, and the selector is loaded inside the body when it's referenced only. As far as error reporting goes, the compiler refuses: - making any overloads direct, - making an overload of a direct method, - implementations marked as direct when the declaration in the interface isn't (the other way around is allowed, as the direct attribute is inherited from the declaration), - marking methods required for protocol conformance as direct, - messaging an unqualified `id` with a direct method, - forming any @selector() expression with only direct selectors. As warnings: - any inconsistency of direct-related calling convention when @selector() or messaging is used, - forming any @selector() expression with a possibly direct selector. Lastly an `objc_direct_members` attribute is added that can decorate `@implementation` blocks and causes methods only declared there (and in no `@interface`) to be automatically direct. When decorating an `@interface` then all methods and properties declared in this block are marked direct. Radar-ID: rdar://problem/2684889 Differential Revision: https://reviews.llvm.org/D69991 Reviewed-By: John McCall
2019-11-08 15:14:58 +08:00
// 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
// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty]"
Implement __attribute__((objc_direct)), __attribute__((objc_direct_members)) __attribute__((objc_direct)) is an attribute on methods declaration, and __attribute__((objc_direct_members)) on implementation, categories or extensions. A `direct` property specifier is added (@property(direct) type name) These attributes / specifiers cause the method to have no associated Objective-C metadata (for the property or the method itself), and the calling convention to be a direct C function call. The symbol for the method has enforced hidden visibility and such direct calls are hence unreachable cross image. An explicit C function must be made if so desired to wrap them. The implicit `self` and `_cmd` arguments are preserved, however to maintain compatibility with the usual `objc_msgSend` semantics, 3 fundamental precautions are taken: 1) for instance methods, `self` is nil-checked. On arm64 backends this typically adds a single instruction (cbz x0, <closest-ret>) to the codegen, for the vast majority of the cases when the return type is a scalar. 2) for class methods, because the class may not be realized/initialized yet, a call to `[self self]` is emitted. When the proper deployment target is used, this is optimized to `objc_opt_self(self)`. However, long term we might want to emit something better that the optimizer can reason about. When inlining kicks in, these calls aren't optimized away as the optimizer has no idea that a single call is really necessary. 3) the calling convention for the `_cmd` argument is changed: the caller leaves the second argument to the call undefined, and the selector is loaded inside the body when it's referenced only. As far as error reporting goes, the compiler refuses: - making any overloads direct, - making an overload of a direct method, - implementations marked as direct when the declaration in the interface isn't (the other way around is allowed, as the direct attribute is inherited from the declaration), - marking methods required for protocol conformance as direct, - messaging an unqualified `id` with a direct method, - forming any @selector() expression with only direct selectors. As warnings: - any inconsistency of direct-related calling convention when @selector() or messaging is used, - forming any @selector() expression with a possibly direct selector. Lastly an `objc_direct_members` attribute is added that can decorate `@implementation` blocks and causes methods only declared there (and in no `@interface`) to be automatically direct. When decorating an `@interface` then all methods and properties declared in this block are marked direct. Radar-ID: rdar://problem/2684889 Differential Revision: https://reviews.llvm.org/D69991 Reviewed-By: John McCall
2019-11-08 15:14:58 +08:00
@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;
- (int)directMethodInExtension __attribute__((objc_direct));
@end
@interface Foo (Cat)
- (int)directMethodInCategory __attribute__((objc_direct));
Implement __attribute__((objc_direct)), __attribute__((objc_direct_members)) __attribute__((objc_direct)) is an attribute on methods declaration, and __attribute__((objc_direct_members)) on implementation, categories or extensions. A `direct` property specifier is added (@property(direct) type name) These attributes / specifiers cause the method to have no associated Objective-C metadata (for the property or the method itself), and the calling convention to be a direct C function call. The symbol for the method has enforced hidden visibility and such direct calls are hence unreachable cross image. An explicit C function must be made if so desired to wrap them. The implicit `self` and `_cmd` arguments are preserved, however to maintain compatibility with the usual `objc_msgSend` semantics, 3 fundamental precautions are taken: 1) for instance methods, `self` is nil-checked. On arm64 backends this typically adds a single instruction (cbz x0, <closest-ret>) to the codegen, for the vast majority of the cases when the return type is a scalar. 2) for class methods, because the class may not be realized/initialized yet, a call to `[self self]` is emitted. When the proper deployment target is used, this is optimized to `objc_opt_self(self)`. However, long term we might want to emit something better that the optimizer can reason about. When inlining kicks in, these calls aren't optimized away as the optimizer has no idea that a single call is really necessary. 3) the calling convention for the `_cmd` argument is changed: the caller leaves the second argument to the call undefined, and the selector is loaded inside the body when it's referenced only. As far as error reporting goes, the compiler refuses: - making any overloads direct, - making an overload of a direct method, - implementations marked as direct when the declaration in the interface isn't (the other way around is allowed, as the direct attribute is inherited from the declaration), - marking methods required for protocol conformance as direct, - messaging an unqualified `id` with a direct method, - forming any @selector() expression with only direct selectors. As warnings: - any inconsistency of direct-related calling convention when @selector() or messaging is used, - forming any @selector() expression with a possibly direct selector. Lastly an `objc_direct_members` attribute is added that can decorate `@implementation` blocks and causes methods only declared there (and in no `@interface`) to be automatically direct. When decorating an `@interface` then all methods and properties declared in this block are marked direct. Radar-ID: rdar://problem/2684889 Differential Revision: https://reviews.llvm.org/D69991 Reviewed-By: John McCall
2019-11-08 15:14:58 +08:00
@end
__attribute__((objc_direct_members))
@implementation Foo
// CHECK-LABEL: define hidden i32 @"\01-[Foo directMethodInExtension]"(
- (int)directMethodInExtension {
return 42;
}
Implement __attribute__((objc_direct)), __attribute__((objc_direct_members)) __attribute__((objc_direct)) is an attribute on methods declaration, and __attribute__((objc_direct_members)) on implementation, categories or extensions. A `direct` property specifier is added (@property(direct) type name) These attributes / specifiers cause the method to have no associated Objective-C metadata (for the property or the method itself), and the calling convention to be a direct C function call. The symbol for the method has enforced hidden visibility and such direct calls are hence unreachable cross image. An explicit C function must be made if so desired to wrap them. The implicit `self` and `_cmd` arguments are preserved, however to maintain compatibility with the usual `objc_msgSend` semantics, 3 fundamental precautions are taken: 1) for instance methods, `self` is nil-checked. On arm64 backends this typically adds a single instruction (cbz x0, <closest-ret>) to the codegen, for the vast majority of the cases when the return type is a scalar. 2) for class methods, because the class may not be realized/initialized yet, a call to `[self self]` is emitted. When the proper deployment target is used, this is optimized to `objc_opt_self(self)`. However, long term we might want to emit something better that the optimizer can reason about. When inlining kicks in, these calls aren't optimized away as the optimizer has no idea that a single call is really necessary. 3) the calling convention for the `_cmd` argument is changed: the caller leaves the second argument to the call undefined, and the selector is loaded inside the body when it's referenced only. As far as error reporting goes, the compiler refuses: - making any overloads direct, - making an overload of a direct method, - implementations marked as direct when the declaration in the interface isn't (the other way around is allowed, as the direct attribute is inherited from the declaration), - marking methods required for protocol conformance as direct, - messaging an unqualified `id` with a direct method, - forming any @selector() expression with only direct selectors. As warnings: - any inconsistency of direct-related calling convention when @selector() or messaging is used, - forming any @selector() expression with a possibly direct selector. Lastly an `objc_direct_members` attribute is added that can decorate `@implementation` blocks and causes methods only declared there (and in no `@interface`) to be automatically direct. When decorating an `@interface` then all methods and properties declared in this block are marked direct. Radar-ID: rdar://problem/2684889 Differential Revision: https://reviews.llvm.org/D69991 Reviewed-By: John McCall
2019-11-08 15:14:58 +08:00
// 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
@implementation Foo (Cat)
// CHECK-LABEL: define hidden i32 @"\01-[Foo directMethodInCategory]"(
- (int)directMethodInCategory {
return 42;
}
// CHECK-LABEL: define hidden i32 @"\01-[Foo directMethodInCategoryNoDecl]"(
- (int)directMethodInCategoryNoDecl __attribute__((objc_direct)) {
return 42;
}
@end
int useRoot(Root *r) {
// CHECK-LABEL: define i32 @useRoot
// CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root getInt]"
// CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty]"
// CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty2]"
return [r getInt] + [r intProperty] + [r intProperty2];
}
int useFoo(Foo *f) {
// CHECK-LABEL: define i32 @useFoo
// CHECK: call void bitcast {{.*}} @"\01-[Foo setGetDynamic_setDirect:]"
// CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo getDirect_setDynamic]"
// CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInExtension]"
// CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInCategory]"
// CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInCategoryNoDecl]"
[f setGetDynamic_setDirect:1];
return [f getDirect_setDynamic] +
[f directMethodInExtension] +
[f directMethodInCategory] +
[f directMethodInCategoryNoDecl];
}
__attribute__((objc_root_class))
@interface RootDeclOnly
@property(direct, readonly) int intProperty;
@end
int useRootDeclOnly(RootDeclOnly *r) {
// CHECK-LABEL: define i32 @useRootDeclOnly
// CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[RootDeclOnly intProperty]"
return [r intProperty];
}