| // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-fragile-abi -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK |
| // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NF |
| |
| // Most of this test is apparently just verifying that we don't crash. |
| |
| int printf(const char *, ...); |
| |
| @interface Root |
| @end |
| |
| typedef struct { |
| int x, y, z[10]; |
| } MyPoint; |
| typedef struct { |
| float width, height; |
| } MySize; |
| |
| @interface A : Root |
| +(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3; |
| +(float) returnAFloat; |
| +(double) returnADouble; |
| +(MyPoint) returnAPoint; |
| +(void) printThisSize: (MySize) arg0; |
| +(MySize) returnASize; |
| |
| -(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3; |
| -(float) returnAFloat; |
| -(double) returnADouble; |
| -(MyPoint) returnAPoint; |
| -(void) printThisSize: (MySize) arg0; |
| -(MySize) returnASize; |
| @end |
| @interface B : A |
| @end |
| |
| @implementation A |
| +(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 { |
| printf("(CLASS) theInt: %d, theFloat: %f, theDouble: %f, thePoint: { %d, %d }\n", |
| arg0, arg1, arg2, arg3.x, arg3.y); |
| } |
| +(float) returnAFloat { |
| return 15.; |
| } |
| +(double) returnADouble { |
| return 25.; |
| } |
| +(MyPoint) returnAPoint { |
| MyPoint x = { 35, 45 }; |
| return x; |
| } |
| +(void) printThisSize: (MySize) arg0 { |
| printf("(CLASS) theSize: { %f, %f }\n", |
| arg0.width, arg0.height); |
| } |
| +(MySize) returnASize { |
| MySize x = { 32, 44 }; |
| return x; |
| } |
| |
| -(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 { |
| printf("theInt: %d, theFloat: %f, theDouble: %f, thePoint: { %d, %d }\n", |
| arg0, arg1, arg2, arg3.x, arg3.y); |
| } |
| -(float) returnAFloat { |
| return 10.; |
| } |
| -(double) returnADouble { |
| return 20.; |
| } |
| -(MyPoint) returnAPoint { |
| MyPoint x = { 30, 40 }; |
| return x; |
| } |
| -(void) printThisSize: (MySize) arg0 { |
| printf("theSize: { %f, %f }\n", |
| arg0.width, arg0.height); |
| } |
| -(MySize) returnASize { |
| MySize x = { 22, 34 }; |
| return x; |
| } |
| @end |
| |
| @implementation B |
| +(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 { |
| arg3.x *= 2; |
| arg3.y *= 2; |
| [ super printThisInt: arg0*2 andThatFloat: arg1*2 andADouble: arg2*2 andAPoint: arg3 ]; |
| } |
| +(void) printThisSize: (MySize) arg0 { |
| arg0.width *= 2; |
| arg0.height *= 2; |
| [ super printThisSize: arg0 ]; |
| } |
| +(float) returnAFloat { |
| return [ super returnAFloat ]*2; |
| } |
| +(double) returnADouble { |
| return [ super returnADouble ]*2; |
| } |
| +(MyPoint) returnAPoint { |
| MyPoint x = [ super returnAPoint ]; |
| x.x *= 2; |
| x.y *= 2; |
| return x; |
| } |
| +(MySize) returnASize { |
| MySize x = [ super returnASize ]; |
| x.width *= 2; |
| x.height *= 2; |
| return x; |
| } |
| |
| -(void) printThisInt: (int) arg0 andThatFloat: (float) arg1 andADouble: (double) arg2 andAPoint: (MyPoint) arg3 { |
| arg3.x *= 2; |
| arg3.y *= 2; |
| [ super printThisInt: arg0*2 andThatFloat: arg1*2 andADouble: arg2*2 andAPoint: arg3 ]; |
| } |
| -(void) printThisSize: (MySize) arg0 { |
| arg0.width *= 2; |
| arg0.height *= 2; |
| [ super printThisSize: arg0 ]; |
| } |
| -(float) returnAFloat { |
| return [ super returnAFloat ]*2; |
| } |
| -(double) returnADouble { |
| return [ super returnADouble ]*2; |
| } |
| -(MyPoint) returnAPoint { |
| MyPoint x = [ super returnAPoint ]; |
| x.x *= 2; |
| x.y *= 2; |
| return x; |
| } |
| -(MySize) returnASize { |
| MySize x = [ super returnASize ]; |
| x.width *= 2; |
| x.height *= 2; |
| return x; |
| } |
| -(const float) returnAConstFloat { |
| return 5; |
| } |
| @end |
| |
| // rdar://problem/7854674 |
| // CHECK: define void @test0([[A:%.*]]* |
| // CHECK-NF: define void @test0([[A:%.*]]* |
| void test0(A *x) { |
| // CHECK: [[X:%.*]] = alloca [[A]]* |
| // CHECK-NEXT: [[POINT:%.*]] = alloca [[POINT_T:%.*]], |
| // CHECK: [[T0:%.*]] = load [[A]]** [[X]] |
| // CHECK: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* |
| // CHECK-NEXT: icmp eq i8* [[T1]], null |
| // CHECK-NEXT: br i1 |
| // CHECK: call {{.*}} @objc_msgSend_stret to |
| // CHECK-NEXT: br label |
| // CHECK: [[T0:%.*]] = bitcast [[POINT_T]]* [[POINT]] to i8* |
| // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 48, i32 4, i1 false) |
| // CHECK-NEXT: br label |
| |
| // CHECK-NF: [[X:%.*]] = alloca [[A]]* |
| // CHECK-NF-NEXT: [[POINT:%.*]] = alloca [[POINT_T:%.*]], |
| // CHECK-NF: [[T0:%.*]] = load [[A]]** [[X]] |
| // CHECK-NF: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* |
| // CHECK-NF-NEXT: icmp eq i8* [[T1]], null |
| // CHECK-NF-NEXT: br i1 |
| // CHECK-NF: call {{.*}} @objc_msgSend_stret to |
| // CHECK-NF-NEXT: br label |
| // CHECK-NF: [[T0:%.*]] = bitcast [[POINT_T]]* [[POINT]] to i8* |
| // CHECK-NF-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 48, i32 4, i1 false) |
| // CHECK-NF-NEXT: br label |
| MyPoint point = [x returnAPoint]; |
| } |