1 | // RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-macosx -emit-llvm -fobjc-arc -O2 -disable-llvm-passes -o - %s | FileCheck %s |
2 | |
3 | #import "nsvalue-boxed-expressions-support.h" |
4 | |
5 | // CHECK: [[CLASS:@.*]] = external global %struct._class_t |
6 | // CHECK: [[NSVALUE:@.*]] = {{.*}}[[CLASS]]{{.*}} |
7 | // CHECK: [[RANGE_STR:.*]] = {{.*}}_NSRange=QQ{{.*}} |
8 | // CHECK: [[METH:@.*]] = private unnamed_addr constant {{.*}}valueWithBytes:objCType:{{.*}} |
9 | // CHECK: [[VALUE_SEL:@.*]] = {{.*}}[[METH]]{{.*}} |
10 | // CHECK: [[POINT_STR:.*]] = {{.*}}_NSPoint=dd{{.*}} |
11 | // CHECK: [[SIZE_STR:.*]] = {{.*}}_NSSize=dd{{.*}} |
12 | // CHECK: [[RECT_STR:.*]] = {{.*}}_NSRect={_NSPoint=dd}{_NSSize=dd}}{{.*}} |
13 | // CHECK: [[EDGE_STR:.*]] = {{.*}}NSEdgeInsets=dddd{{.*}} |
14 | |
15 | // CHECK-LABEL: define void @doRange() |
16 | void doRange() { |
17 | // CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSRange{{.*}} |
18 | // CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSRange{{.*}} |
19 | // CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]] |
20 | // CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}} |
21 | // CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRange* [[LOCAL_VAR]]{{.*}} |
22 | // CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}} |
23 | // CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRange* [[TEMP_VAR]]{{.*}} |
24 | // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] |
25 | // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* |
26 | NSRange ns_range = { .location = 0, .length = 42 }; |
27 | // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) |
28 | // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue |
29 | NSValue *range = @(ns_range); |
30 | // CHECK: call void @llvm.objc.release |
31 | // CHECK: ret void |
32 | } |
33 | |
34 | // CHECK-LABEL: define void @doPoint() |
35 | void doPoint() { |
36 | // CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSPoint{{.*}} |
37 | // CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSPoint{{.*}} |
38 | // CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]] |
39 | // CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSPoint* [[TEMP_VAR]]{{.*}} |
40 | // CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSPoint* [[LOCAL_VAR]]{{.*}} |
41 | // CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}} |
42 | // CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSPoint* [[TEMP_VAR]]{{.*}} |
43 | // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] |
44 | // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* |
45 | NSPoint ns_point = { .x = 42, .y = 24 }; |
46 | // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[POINT_STR]]{{.*}}) |
47 | // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue |
48 | NSValue *point = @(ns_point); |
49 | // CHECK: call void @llvm.objc.release |
50 | // CHECK: ret void |
51 | } |
52 | |
53 | // CHECK-LABEL: define void @doSize() |
54 | void doSize() { |
55 | // CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSSize{{.*}} |
56 | // CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSSize{{.*}} |
57 | // CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]] |
58 | // CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSSize* [[TEMP_VAR]]{{.*}} |
59 | // CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSSize* [[LOCAL_VAR]]{{.*}} |
60 | // CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}} |
61 | // CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSSize* [[TEMP_VAR]]{{.*}} |
62 | // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] |
63 | // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* |
64 | NSSize ns_size = { .width = 42, .height = 24 }; |
65 | // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[SIZE_STR]]{{.*}}) |
66 | // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue |
67 | NSValue *size = @(ns_size); |
68 | // CHECK: call void @llvm.objc.release |
69 | // CHECK: ret void |
70 | } |
71 | |
72 | // CHECK-LABEL: define void @doRect() |
73 | void doRect() { |
74 | // CHECK: [[LOCAL_VAR:%.*]] = alloca %struct._NSRect{{.*}} |
75 | // CHECK: [[TEMP_VAR:%.*]] = alloca %struct._NSRect{{.*}} |
76 | // CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]] |
77 | // CHECK: [[TEMP_CAST:%.*]] = bitcast %struct._NSRect* [[TEMP_VAR]]{{.*}} |
78 | // CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct._NSRect* [[LOCAL_VAR]]{{.*}} |
79 | // CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}} |
80 | // CHECK: [[PARAM_CAST:%.*]] = bitcast %struct._NSRect* [[TEMP_VAR]]{{.*}} |
81 | // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] |
82 | // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* |
83 | NSPoint ns_point = { .x = 42, .y = 24 }; |
84 | NSSize ns_size = { .width = 42, .height = 24 }; |
85 | NSRect ns_rect = { .origin = ns_point, .size = ns_size }; |
86 | // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[RECT_STR]]{{.*}}) |
87 | // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue |
88 | NSValue *rect = @(ns_rect); |
89 | // CHECK: call void @llvm.objc.release |
90 | // CHECK: ret void |
91 | } |
92 | |
93 | // CHECK-LABEL: define void @doNSEdgeInsets() |
94 | void doNSEdgeInsets() { |
95 | // CHECK: [[LOCAL_VAR:%.*]] = alloca %struct.NSEdgeInsets{{.*}} |
96 | // CHECK: [[TEMP_VAR:%.*]] = alloca %struct.NSEdgeInsets{{.*}} |
97 | // CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]] |
98 | // CHECK: [[TEMP_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}} |
99 | // CHECK: [[LOCAL_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[LOCAL_VAR]]{{.*}} |
100 | // CHECK: call void @llvm.memcpy{{.*}} [[TEMP_CAST]]{{.*}} [[LOCAL_CAST]]{{.*}} |
101 | // CHECK: [[PARAM_CAST:%.*]] = bitcast %struct.NSEdgeInsets* [[TEMP_VAR]]{{.*}} |
102 | // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] |
103 | // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* |
104 | NSEdgeInsets ns_edge_insets; |
105 | // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}}) |
106 | // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue |
107 | NSValue *edge_insets = @(ns_edge_insets); |
108 | // CHECK: call void @llvm.objc.release |
109 | // CHECK: ret void |
110 | } |
111 | |
112 | // CHECK-LABEL: define void @doRangeRValue() |
113 | void doRangeRValue() { |
114 | // CHECK: [[COERCE:%.*]] = alloca %struct._NSRange{{.*}} |
115 | // CHECK: [[RECV_PTR:%.*]] = load {{.*}} [[NSVALUE]] |
116 | // CHECK: [[RVAL:%.*]] = call {{.*}} @getRange() |
117 | // CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}} |
118 | // CHECK: [[COERCE_CAST_PTR:%.*]] = getelementptr {{.*}} [[COERCE_CAST]], {{.*}} |
119 | // CHECK: [[EXTR_RVAL:%.*]] = extractvalue {{.*}} [[RVAL]]{{.*}} |
120 | // CHECK: store {{.*}}[[EXTR_RVAL]]{{.*}}[[COERCE_CAST_PTR]]{{.*}} |
121 | // CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}} |
122 | // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] |
123 | // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* |
124 | // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[COERCE_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) |
125 | // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue |
126 | NSValue *range_rvalue = @(getRange()); |
127 | // CHECK: call void @llvm.objc.release |
128 | // CHECK: ret void |
129 | } |
130 | |
131 | |