| // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s | 
 | // 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]]*, [[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]]*, [[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]; | 
 | } |