• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -debug-info-kind=limited -o - | FileCheck %s
2
3class S {
4public:
5	S& operator = (const S&);
6	S (const S&);
7	S ();
8};
9
10struct CGRect {
11	CGRect & operator = (const CGRect &);
12};
13
14@interface I {
15  S position;
16  CGRect bounds;
17}
18
19@property(assign, nonatomic) S position;
20@property CGRect bounds;
21@property CGRect frame;
22- (void)setFrame:(CGRect)frameRect;
23- (CGRect)frame;
24- (void) initWithOwner;
25- (CGRect)extent;
26- (void)dealloc;
27@end
28
29@implementation I
30@synthesize position;
31@synthesize bounds;
32@synthesize frame;
33
34// CHECK: define internal void @"\01-[I setPosition:]"
35// CHECK: call dereferenceable({{[0-9]+}}) %class.S* @_ZN1SaSERKS_
36// CHECK-NEXT: ret void
37
38// Don't attach debug locations to the prologue instructions. These were
39// leaking over from the previous function emission by accident.
40// CHECK: define internal void @"\01-[I setBounds:]"({{.*}} {
41// CHECK-NOT: !dbg
42// CHECK: call void @llvm.dbg.declare
43- (void)setFrame:(CGRect)frameRect {}
44- (CGRect)frame {return bounds;}
45
46- (void)initWithOwner {
47  I* _labelLayer;
48  CGRect labelLayerFrame = self.bounds;
49  labelLayerFrame = self.bounds;
50  _labelLayer.frame = labelLayerFrame;
51}
52
53// rdar://8366604
54- (void)dealloc
55  {
56      CGRect cgrect = self.extent;
57  }
58- (struct CGRect)extent {return bounds;}
59
60@end
61
62// CHECK-LABEL: define i32 @main
63// CHECK: call void @_ZN1SC1ERKS_(%class.S* [[AGGTMP:%[a-zA-Z0-9\.]+]], %class.S* dereferenceable({{[0-9]+}}) {{%[a-zA-Z0-9\.]+}})
64// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %class.S*)*)(i8* {{%[a-zA-Z0-9\.]+}}, i8* {{%[a-zA-Z0-9\.]+}}, %class.S* [[AGGTMP]])
65// CHECK-NEXT: ret i32 0
66int main() {
67  I *i;
68  S s1;
69  i.position = s1;
70  return 0;
71}
72
73// rdar://8379892
74// CHECK-LABEL: define void @_Z1fP1A
75// CHECK: call void @_ZN1XC1Ev(%struct.X* [[LVTEMP:%[a-zA-Z0-9\.]+]])
76// CHECK: call void @_ZN1XC1ERKS_(%struct.X* [[AGGTMP:%[a-zA-Z0-9\.]+]], %struct.X* dereferenceable({{[0-9]+}}) [[LVTEMP]])
77// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.X*)*)({{.*}} %struct.X* [[AGGTMP]])
78struct X {
79  X();
80  X(const X&);
81  ~X();
82};
83
84@interface A {
85  X xval;
86}
87- (X)x;
88- (void)setX:(X)x;
89@end
90
91void f(A* a) {
92  a.x = X();
93}
94
95// rdar://21801088
96//   Ensure that pseudo-objecet expressions that require the RHS to be
97//   rewritten don't result in crashes or redundant emission of code.
98struct B0 { long long x; };
99struct B1 { long long x; }; B1 operator+(B1, B1);
100struct B2 { B1 x; };
101struct B3 { B3(); B1 x; operator B1(); };
102@interface B
103@property B0 b0;
104@property B1 b1;
105@property B2 b2;
106@property B3 b3;
107@end
108
109int b_makeInt();
110
111// Note that there's a promotion from int to long long, so
112// the syntactic form of the RHS will be bogus.
113void testB0(B *b) {
114  b.b0 = { b_makeInt() };
115}
116void testB1(B *b) {
117  b.b1 += { b_makeInt() };
118}
119// CHECK:    define void @_Z6testB0P1B([[B:%.*]]*
120// CHECK:      [[BVAR:%.*]] = alloca [[B]]*, align 8
121// CHECK:      [[TEMP:%.*]] = alloca [[B0:%.*]], align 8
122// CHECK:      load [[B]]*, [[B]]** [[BVAR]]
123// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[B0]], [[B0]]* [[TEMP]], i32 0, i32 0
124// CHECK-NEXT: [[T0:%.*]] = call i32 @_Z9b_makeIntv()
125// CHECK-NEXT: [[T1:%.*]] = sext i32 [[T0]] to i64
126// CHECK-NEXT: store i64 [[T1]], i64* [[X]], align 8
127// CHECK-NOT:  call
128// CHECK:      call void @llvm.memcpy
129// CHECK-NOT:  call
130// CHECK:      call void bitcast {{.*}} @objc_msgSend
131// CHECK-NOT:  call
132// CHECK:      ret void
133
134// CHECK:    define void @_Z6testB1P1B([[B]]*
135// CHECK:      [[BVAR:%.*]] = alloca [[B]]*, align 8
136// CHECK:      load [[B]]*, [[B]]** [[BVAR]]
137// CHECK-NOT:  call
138// CHECK:      [[T0:%.*]] = call i64 bitcast {{.*}} @objc_msgSend
139// CHECK-NOT:  call
140// CHECK:      store i64 [[T0]],
141// CHECK-NOT:  call
142// CHECK:      [[T0:%.*]] = call i32 @_Z9b_makeIntv()
143// CHECK-NEXT: [[T1:%.*]] = sext i32 [[T0]] to i64
144// CHECK-NEXT: store i64 [[T1]], i64* {{.*}}, align 8
145// CHECK-NOT:  call
146// CHECK:      [[T0:%.*]] = call i64 @_Zpl2B1S_
147// CHECK-NOT:  call
148// CHECK:      store i64 [[T0]],
149// CHECK-NOT:  call
150// CHECK:      call void @llvm.memcpy
151// CHECK-NOT:  call
152// CHECK:      call void bitcast {{.*}} @objc_msgSend
153// CHECK-NOT:  call
154// CHECK:      ret void
155
156// Another example of a conversion that needs to be applied
157// in the semantic form.
158void testB2(B *b) {
159  b.b2 = { B3() };
160}
161
162// CHECK:    define void @_Z6testB2P1B([[B]]*
163// CHECK:      [[BVAR:%.*]] = alloca [[B]]*, align 8
164// CHECK:      load [[B]]*, [[B]]** [[BVAR]]
165// CHECK-NOT:  call
166// CHECK:      call void @_ZN2B3C1Ev(
167// CHECK-NEXT: [[T0:%.*]] = call i64 @_ZN2B3cv2B1Ev(
168// CHECK-NOT:  call
169// CHECK:      store i64 [[T0]],
170// CHECK-NOT:  call
171// CHECK:      call void @llvm.memcpy
172// CHECK-NOT:  call
173// CHECK:      call void bitcast {{.*}} @objc_msgSend
174// CHECK-NOT:  call
175// CHECK:      ret void
176
177// A similar test to B, but using overloaded function references.
178struct C1 {
179  int x;
180  friend C1 operator+(C1, void(&)());
181};
182@interface C
183@property void (*c0)();
184@property C1 c1;
185@end
186
187void c_helper();
188void c_helper(int);
189
190void testC0(C *c) {
191  c.c0 = c_helper;
192  c.c0 = &c_helper;
193}
194// CHECK:    define void @_Z6testC0P1C([[C:%.*]]*
195// CHECK:      [[CVAR:%.*]] = alloca [[C]]*, align 8
196// CHECK:      load [[C]]*, [[C]]** [[CVAR]]
197// CHECK-NOT:  call
198// CHECK:      call void bitcast {{.*}} @objc_msgSend {{.*}} @_Z8c_helperv
199// CHECK-NOT:  call
200// CHECK:      call void bitcast {{.*}} @objc_msgSend {{.*}} @_Z8c_helperv
201// CHECK-NOT:  call
202// CHECK:      ret void
203
204void testC1(C *c) {
205  c.c1 += c_helper;
206}
207// CHECK:    define void @_Z6testC1P1C([[C]]*
208// CHECK:      [[CVAR:%.*]] = alloca [[C]]*, align 8
209// CHECK:      load [[C]]*, [[C]]** [[CVAR]]
210// CHECK-NOT:  call
211// CHECK:      [[T0:%.*]] = call i32 bitcast {{.*}} @objc_msgSend
212// CHECK-NOT:  call
213// CHECK:      store i32 [[T0]],
214// CHECK-NOT:  call
215// CHECK:      [[T0:%.*]] = call i32 @_Zpl2C1RFvvE({{.*}} @_Z8c_helperv
216// CHECK-NOT:  call
217// CHECK:      store i32 [[T0]],
218// CHECK-NOT:  call
219// CHECK:      call void @llvm.memcpy
220// CHECK-NOT:  call
221// CHECK:      call void bitcast {{.*}} @objc_msgSend
222// CHECK-NOT:  call
223// CHECK:      ret void
224