aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenObjCXX
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
commit180abc3db9ae3b4fc63cd65b15697e6ffcc8a657 (patch)
tree2097d084eb235c0b12c0bff3445f4ec7bbaa8a12 /test/CodeGenObjCXX
parent29cafa66ad3878dbb9f82615f19fa0bded2e443c (diff)
downloadsrc-180abc3db9ae3b4fc63cd65b15697e6ffcc8a657.tar.gz
src-180abc3db9ae3b4fc63cd65b15697e6ffcc8a657.zip
Vendor import of clang trunk r135360:vendor/clang/clang-r135360
Notes
Notes: svn path=/vendor/clang/dist/; revision=224135 svn path=/vendor/clang/clang-r135360/; revision=224136; tag=vendor/clang/clang-r135360
Diffstat (limited to 'test/CodeGenObjCXX')
-rw-r--r--test/CodeGenObjCXX/arc-globals.mm27
-rw-r--r--test/CodeGenObjCXX/arc-mangle.mm25
-rw-r--r--test/CodeGenObjCXX/arc-move.mm75
-rw-r--r--test/CodeGenObjCXX/arc-new-delete.mm95
-rw-r--r--test/CodeGenObjCXX/arc-pseudo-destructors.mm21
-rw-r--r--test/CodeGenObjCXX/arc-references.mm83
-rw-r--r--test/CodeGenObjCXX/arc-special-member-functions.mm161
-rw-r--r--test/CodeGenObjCXX/arc.mm166
-rw-r--r--test/CodeGenObjCXX/catch-id-type.mm48
-rw-r--r--test/CodeGenObjCXX/copy.mm26
-rw-r--r--test/CodeGenObjCXX/encode.mm14
-rw-r--r--test/CodeGenObjCXX/gc.mm20
-rw-r--r--test/CodeGenObjCXX/property-object-conditional-exp.mm7
-rw-r--r--test/CodeGenObjCXX/property-objects.mm2
14 files changed, 766 insertions, 4 deletions
diff --git a/test/CodeGenObjCXX/arc-globals.mm b/test/CodeGenObjCXX/arc-globals.mm
new file mode 100644
index 000000000000..7167dbc366d0
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-globals.mm
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-nonfragile-abi -fblocks -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+
+// Test that we're properly retaining lifetime-qualified pointers
+// initialized statically and wrapping up those initialization in an
+// autorelease pool.
+id getObject();
+
+// CHECK: define internal void @__cxx_global_var_init
+// CHECK: call i8* @_Z9getObjectv
+// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue
+// CHECK-NEXT: {{store i8*.*@global_obj}}
+// CHECK-NEXT: ret void
+id global_obj = getObject();
+
+// CHECK: define internal void @__cxx_global_var_init
+// CHECK: call i8* @_Z9getObjectv
+// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue
+// CHECK-NEXT: {{store i8*.*@global_obj2}}
+// CHECK-NEXT: ret void
+id global_obj2 = getObject();
+
+// CHECK: define internal void @_GLOBAL__I_a
+// CHECK: call i8* @objc_autoreleasePoolPush()
+// CHECK-NEXT: call void @__cxx_global_var_init
+// CHECK-NEXT: call void @__cxx_global_var_init1
+// CHECK-NEXT: call void @objc_autoreleasePoolPop(
+// CHECK-NEXT: ret void
diff --git a/test/CodeGenObjCXX/arc-mangle.mm b/test/CodeGenObjCXX/arc-mangle.mm
new file mode 100644
index 000000000000..1955348f1c32
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-mangle.mm
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-arc -fobjc-runtime-has-weak -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: define void @_Z1fPU8__strongP11objc_object(i8**)
+void f(__strong id *) {}
+// CHECK: define void @_Z1fPU6__weakP11objc_object(i8**)
+void f(__weak id *) {}
+// CHECK: define void @_Z1fPU15__autoreleasingP11objc_object(i8**)
+void f(__autoreleasing id *) {}
+// CHECK: define void @_Z1fPP11objc_object(i8**)
+void f(__unsafe_unretained id *) {}
+// CHECK: define void @_Z1fPKU8__strongP11objc_object(i8**)
+void f(const __strong id *) {}
+// CHECK: define void @_Z1fPKU6__weakP11objc_object(i8**)
+void f(const __weak id *) {}
+// CHECK: define void @_Z1fPKU15__autoreleasingP11objc_object(i8**)
+void f(const __autoreleasing id *) {}
+// CHECK: define void @_Z1fPKP11objc_object(i8**)
+void f(const __unsafe_unretained id *) {}
+
+
+template<unsigned N> struct unsigned_c { };
+
+// CHECK: define weak_odr void @_Z1gIKvEvP10unsigned_cIXplszv1U8__bridgecvPT_v1U8__bridgecvP11objc_objectcvS3_Li0ELi1EEE
+template<typename T>void g(unsigned_c<sizeof((__bridge T*)(__bridge id)(T*)0) + 1>*) {}
+template void g<const void>(unsigned_c<sizeof(id) + 1> *);
diff --git a/test/CodeGenObjCXX/arc-move.mm b/test/CodeGenObjCXX/arc-move.mm
new file mode 100644
index 000000000000..70469e6a8586
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-move.mm
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-nonfragile-abi -fblocks -fobjc-arc -O2 -std=c++0x -disable-llvm-optzns -o - %s | FileCheck %s
+
+// define void @_Z11simple_moveRU8__strongP11objc_objectS2_
+void simple_move(__strong id &x, __strong id &y) {
+ // CHECK: = load i8**
+ // CHECK: store i8* null
+ // CHECK: = load i8**
+ // CHECK: store i8*
+ // CHECK-NEXT: call void @objc_release
+ x = static_cast<__strong id&&>(y);
+ // CHECK-NEXT: ret void
+}
+
+template<typename T>
+struct remove_reference {
+ typedef T type;
+};
+
+template<typename T>
+struct remove_reference<T&> {
+ typedef T type;
+};
+
+template<typename T>
+struct remove_reference<T&&> {
+ typedef T type;
+};
+
+template<typename T>
+typename remove_reference<T>::type&& move(T &&x) {
+ return static_cast<typename remove_reference<T>::type&&>(x);
+}
+
+// CHECK: define void @_Z12library_moveRU8__strongP11objc_objectS2_
+void library_move(__strong id &x, __strong id &y) {
+ // CHECK: call i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
+ // CHECK: load i8**
+ // CHECK: store i8* null, i8**
+ // CHECK: load i8***
+ // CHECK-NEXT: load i8**
+ // CHECK-NEXT: store i8*
+ // CHECK-NEXT: call void @objc_release
+ // CHECK-NEXT: ret void
+ x = move(y);
+}
+
+// CHECK: define void @_Z12library_moveRU8__strongP11objc_object
+void library_move(__strong id &y) {
+ // CHECK: [[Y:%[a-zA-Z0-9]+]] = call i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
+ // Load the object
+ // CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8** [[Y]]
+ // Null out y
+ // CHECK-NEXT: store i8* null, i8** [[Y]]
+ // Initialize x with the object
+ // CHECK-NEXT: store i8* [[OBJ]], i8** [[X:%[a-zA-Z0-9]+]]
+ id x = move(y);
+
+ // CHECK-NEXT: store i32 17
+ int i = 17;
+ // CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8** [[X]]
+ // CHECK-NEXT: call void @objc_release(i8* [[OBJ]])
+ // CHECK-NEXT: ret void
+}
+
+// CHECK: define void @_Z10const_moveRKU8__strongP11objc_object(
+void const_move(const __strong id &x) {
+ // CHECK: [[Y:%.*]] = alloca i8*,
+ // CHECK: [[X:%.*]] = call i8** @_Z4moveIRKU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_(
+ // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]]
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+ // CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
+ // CHECK-NEXT: [[T0:%.*]] = load i8** [[Y]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]])
+ id y = move(x);
+}
diff --git a/test/CodeGenObjCXX/arc-new-delete.mm b/test/CodeGenObjCXX/arc-new-delete.mm
new file mode 100644
index 000000000000..4597985f8dfe
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-new-delete.mm
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s
+
+typedef __strong id strong_id;
+typedef __weak id weak_id;
+
+// CHECK: define void @_Z8test_newP11objc_object
+void test_new(id invalue) {
+ // CHECK: alloca i8*
+ // CHECK-NEXT: call i8* @objc_retain
+
+ // CHECK: call noalias i8* @_Znwm
+ // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
+ // CHECK-NEXT: store i8* null, i8**
+ new strong_id;
+ // CHECK: call noalias i8* @_Znwm
+ // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
+ // CHECK-NEXT: store i8* null, i8**
+ new weak_id;
+
+ // CHECK: call noalias i8* @_Znwm
+ // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
+ // CHECK-NEXT: store i8* null, i8**
+ new __strong id;
+ // CHECK: call noalias i8* @_Znwm
+ // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
+ // CHECK-NEXT: store i8* null, i8**
+ new __weak id;
+
+ // CHECK: call noalias i8* @_Znwm
+ // CHECK: call i8* @objc_retain
+ // CHECK: store i8*
+ new __strong id(invalue);
+
+ // CHECK: call noalias i8* @_Znwm
+ // CHECK: call i8* @objc_initWeak
+ new __weak id(invalue);
+
+ // CHECK: call void @objc_release
+ // CHECK: ret void
+}
+
+// CHECK: define void @_Z14test_array_new
+void test_array_new() {
+ // CHECK: call noalias i8* @_Znam
+ // CHECK: store i64 17, i64*
+ // CHECK: call void @llvm.memset.p0i8.i64
+ new strong_id[17];
+
+ // CHECK: call noalias i8* @_Znam
+ // CHECK: store i64 17, i64*
+ // CHECK: call void @llvm.memset.p0i8.i64
+ new weak_id[17];
+ // CHECK: ret void
+}
+
+// CHECK: define void @_Z11test_deletePU8__strongP11objc_objectPU6__weakS0_
+void test_delete(__strong id *sptr, __weak id *wptr) {
+ // CHECK: br i1
+ // CHECK: load i8**
+ // CHECK-NEXT: call void @objc_release
+ // CHECK: call void @_ZdlPv
+ delete sptr;
+
+ // CHECK: call void @objc_destroyWeak
+ // CHECK: call void @_ZdlPv
+ delete wptr;
+
+ // CHECK: ret void
+}
+
+// CHECK: define void @_Z17test_array_deletePU8__strongP11objc_objectPU6__weakS0_
+void test_array_delete(__strong id *sptr, __weak id *wptr) {
+ // CHECK: icmp eq i8** [[BEGIN:%.*]], null
+ // CHECK: [[LEN:%.*]] = load i64* {{%.*}}
+ // CHECK: [[END:%.*]] = getelementptr inbounds i8** [[BEGIN]], i64 [[LEN]]
+ // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]]
+ // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]],
+ // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8** [[PAST]], i64 -1
+ // CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T0]])
+ // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]]
+ // CHECK: call void @_ZdaPv
+ delete [] sptr;
+
+ // CHECK: icmp eq i8** [[BEGIN:%.*]], null
+ // CHECK: [[LEN:%.*]] = load i64* {{%.*}}
+ // CHECK: [[END:%.*]] = getelementptr inbounds i8** [[BEGIN]], i64 [[LEN]]
+ // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]]
+ // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]],
+ // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8** [[PAST]], i64 -1
+ // CHECK-NEXT: call void @objc_destroyWeak(i8** [[CUR]])
+ // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]]
+ // CHECK: call void @_ZdaPv
+ delete [] wptr;
+}
diff --git a/test/CodeGenObjCXX/arc-pseudo-destructors.mm b/test/CodeGenObjCXX/arc-pseudo-destructors.mm
new file mode 100644
index 000000000000..4023e90b7dc7
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-pseudo-destructors.mm
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: define void @_Z28test_objc_object_pseudo_dtorPU8__strongP11objc_objectPU6__weakS0_
+void test_objc_object_pseudo_dtor(__strong id *ptr, __weak id *wptr) {
+ // CHECK: load i8***
+ // CHECK-NEXT: load i8**
+ // CHECK-NEXT: call void @objc_release
+ ptr->~id();
+
+ // CHECK: call void @objc_destroyWeak(i8** {{%.*}})
+ wptr->~id();
+
+ // CHECK: load i8***
+ // CHECK-NEXT: load i8**
+ // CHECK-NEXT: call void @objc_release
+ (*ptr).~id();
+
+ // CHECK: call void @objc_destroyWeak(i8** {{%.*}})
+ (*wptr).~id();
+ // CHECK: ret void
+}
diff --git a/test/CodeGenObjCXX/arc-references.mm b/test/CodeGenObjCXX/arc-references.mm
new file mode 100644
index 000000000000..3d0313d13ac8
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-references.mm
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-nonfragile-abi -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+
+@interface A
+@end
+
+id getObject();
+void callee();
+
+// Lifetime extension for binding a reference to an rvalue
+// CHECK: define void @_Z5test0v()
+void test0() {
+ // CHECK: call i8* @_Z9getObjectv
+ // CHECK-NEXT:: call i8* @objc_retainAutoreleasedReturnValue
+ const __strong id &ref1 = getObject();
+ // CHECK: call void @_Z6calleev
+ callee();
+ // CHECK: call i8* @_Z9getObjectv
+ // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue
+ // CHECK-NEXT: call i8* @objc_autorelease
+ const __autoreleasing id &ref2 = getObject();
+ // CHECK: call void @_Z6calleev
+ callee();
+ // CHECK: call void @objc_release
+ // CHECK-NEXT: ret
+}
+
+// No lifetime extension when we're binding a reference to an lvalue.
+// CHECK: define void @_Z5test1RU8__strongP11objc_objectRU6__weakS0_
+void test1(__strong id &x, __weak id &y) {
+ // CHECK-NOT: release
+ const __strong id &ref1 = x;
+ const __autoreleasing id &ref2 = x;
+ const __weak id &ref3 = y;
+ // CHECK: ret void
+}
+
+typedef __strong id strong_id;
+
+//CHECK: define void @_Z5test3v
+void test3() {
+ // CHECK: call i8* @objc_initWeak
+ // CHECK-NEXT: store i8**
+ const __weak id &ref = strong_id();
+ // CHECK-NEXT: call void @_Z6calleev()
+ callee();
+ // CHECK-NEXT: call void @objc_destroyWeak
+ // CHECK-NEXT: ret void
+}
+
+// CHECK: define void @_Z5test4RU8__strongP11objc_object
+void test4(__strong id &x) {
+ // CHECK: call i8* @objc_retain
+ __strong A* const &ar = x;
+ // CHECK: store i32 17, i32*
+ int i = 17;
+ // CHECK: call void @objc_release(
+ // CHECK: ret void
+}
+
+void sink(__strong A* &&);
+
+// CHECK: define void @_Z5test5RU8__strongP11objc_object
+void test5(__strong id &x) {
+ // CHECK: [[OBJ_ID:%[a-zA-Z0-9]+]] = call i8* @objc_retain
+ // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = bitcast i8* [[OBJ_ID]] to [[A:%[a-zA-Z0-9]+]]*
+ // CHECK-NEXT: store [[A]]* [[OBJ_A]], [[A]]** [[REFTMP:%[a-zA-Z0-9]+]]
+ // CHECK-NEXT: call void @_Z4sinkOU8__strongP1A
+ sink(x);
+ // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load [[A]]** [[REFTMP]]
+ // CHECK-NEXT: [[OBJ_ID:%[a-zA-Z0-9]+]] = bitcast [[A]]* [[OBJ_A]] to i8*
+ // CHECK-NEXT: call void @objc_release
+ // CHECK-NEXT: store i32 17, i32
+ int i = 17;
+ // CHECK-NEXT: ret void
+}
+
+// CHECK: define internal void @__cxx_global_var_init(
+// CHECK: call i8* @_Z9getObjectv
+// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue
+const __strong id &global_ref = getObject();
+
+// Note: we intentionally don't release the object.
+
diff --git a/test/CodeGenObjCXX/arc-special-member-functions.mm b/test/CodeGenObjCXX/arc-special-member-functions.mm
new file mode 100644
index 000000000000..d88a2bd62ffc
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-special-member-functions.mm
@@ -0,0 +1,161 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fobjc-arc -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s
+
+struct ObjCMember {
+ id member;
+};
+
+struct ObjCArrayMember {
+ id member[2][3];
+};
+
+struct ObjCBlockMember {
+ int (^bp)(int);
+};
+
+// CHECK: define void @_Z42test_ObjCMember_default_construct_destructv(
+void test_ObjCMember_default_construct_destruct() {
+ // CHECK: call void @_ZN10ObjCMemberC1Ev
+ // CHECK: call void @_ZN10ObjCMemberD1Ev
+ ObjCMember m1;
+}
+
+// CHECK: define void @_Z39test_ObjCMember_copy_construct_destruct10ObjCMember
+void test_ObjCMember_copy_construct_destruct(ObjCMember m1) {
+ // CHECK: call void @_ZN10ObjCMemberC1ERKS_
+ // CHECK: call void @_ZN10ObjCMemberD1Ev
+ ObjCMember m2 = m1;
+ // CHECK: ret void
+}
+
+// CHECK: define void @_Z27test_ObjCMember_copy_assign10ObjCMemberS_
+void test_ObjCMember_copy_assign(ObjCMember m1, ObjCMember m2) {
+ // CHECK: {{call.*_ZN10ObjCMemberaSERKS_}}
+ m1 = m2;
+ // CHECK-NEXT: ret void
+}
+
+// Implicitly-generated copy assignment operator for ObjCMember
+// CHECK: {{define linkonce_odr.*@_ZN10ObjCMemberaSERKS_}}
+// CHECK: call void @objc_storeStrong
+// CHECK: ret
+
+// CHECK: define void @_Z47test_ObjCArrayMember_default_construct_destructv
+void test_ObjCArrayMember_default_construct_destruct() {
+ // CHECK: call void @_ZN15ObjCArrayMemberC1Ev
+ ObjCArrayMember m1;
+ // CHECK: call void @_ZN15ObjCArrayMemberD1Ev
+ // CHECK: ret void
+}
+
+// CHECK: define void @_Z44test_ObjCArrayMember_copy_construct_destruct15ObjCArrayMember
+void test_ObjCArrayMember_copy_construct_destruct(ObjCArrayMember m1) {
+ // CHECK: call void @_ZN15ObjCArrayMemberC1ERKS_
+ ObjCArrayMember m2 = m1;
+ // CHECK: call void @_ZN15ObjCArrayMemberD1Ev
+ // CHECK: ret void
+}
+
+void test_ObjCArrayMember_copy_assign(ObjCArrayMember m1, ObjCArrayMember m2) {
+ // CHECK: {{call.*@_ZN15ObjCArrayMemberaSERKS_}}
+ m1 = m2;
+ // CHECK-NEXT: ret void
+}
+
+// Implicitly-generated copy assignment operator for ObjCArrayMember
+// CHECK: {{define linkonce_odr.*@_ZN15ObjCArrayMemberaSERKS_}}
+// CHECK: call void @objc_storeStrong
+// CHECK-NEXT: br label
+// CHECK: ret
+
+// CHECK: define void @_Z47test_ObjCBlockMember_default_construct_destructv
+void test_ObjCBlockMember_default_construct_destruct() {
+ // CHECK: call void @_ZN15ObjCBlockMemberC1Ev
+ ObjCBlockMember m;
+ // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev
+ // CHECK-NEXT: ret void
+}
+
+// CHECK: define void @_Z44test_ObjCBlockMember_copy_construct_destruct15ObjCBlockMember
+void test_ObjCBlockMember_copy_construct_destruct(ObjCBlockMember m1) {
+ // CHECK: call void @_ZN15ObjCBlockMemberC1ERKS_
+ ObjCBlockMember m2 = m1;
+ // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev
+ // CHECK-NEXT: ret void
+}
+
+// CHECK: define void @_Z32test_ObjCBlockMember_copy_assign15ObjCBlockMemberS_
+void test_ObjCBlockMember_copy_assign(ObjCBlockMember m1, ObjCBlockMember m2) {
+ // CHECK: {{call.*_ZN15ObjCBlockMemberaSERKS_}}
+ m1 = m2;
+ // CHECK-NEXT: ret void
+}
+
+// Implicitly-generated copy assignment operator for ObjCBlockMember
+// CHECK: define linkonce_odr {{%.*}}* @_ZN15ObjCBlockMemberaSERKS_(
+// CHECK: [[T0:%.*]] = call i8* @objc_retainBlock(
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i32 (i32)*
+// CHECK-NEXT: [[T2:%.*]] = load {{.*}} [[SLOT:%.*]],
+// CHECK: store
+// CHECK-NEXT: [[T3:%.*]] = bitcast
+// CHECK-NEXT: call void @objc_release(i8* [[T3]])
+// CHECK-NEXT: ret
+
+// Implicitly-generated copy constructor for ObjCBlockMember
+// CHECK: define linkonce_odr void @_ZN15ObjCBlockMemberC2ERKS_
+// CHECK: call i8* @objc_retainBlock
+// CHECK: ret
+
+// Implicitly-generated destructor for ObjCBlockMember
+// CHECK: define linkonce_odr void @_ZN15ObjCBlockMemberD2Ev
+// CHECK: call void @objc_release(i8*
+// CHECK: ret
+
+// Implicitly-generated default constructor for ObjCBlockMember
+// CHECK: define linkonce_odr void @_ZN15ObjCBlockMemberC2Ev
+// CHECK: store {{.*}} null,
+// CHECK-NEXT: ret void
+
+// Implicitly-generated copy constructor for ObjCArrayMember
+// CHECK: define linkonce_odr void @_ZN15ObjCArrayMemberC2ERKS_
+// CHECK: br i1
+// CHECK: call i8* @objc_retain
+// CHECK-NEXT: store i8*
+// CHECK-NEXT: br label
+// CHECK: ret
+
+// Implicitly-generated destructor for ObjCArrayMember
+// CHECK: define linkonce_odr void @_ZN15ObjCArrayMemberD2Ev
+// CHECK: [[BEGIN:%.*]] = getelementptr inbounds [2 x [3 x i8*]]*
+// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[BEGIN]], i64 6
+// CHECK-NEXT: br label
+// CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+// CHECK-NEXT: [[CUR]] = getelementptr inbounds i8** [[PAST]], i64 -1
+// CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]]
+// CHECK-NEXT: call void @objc_release(i8* [[T0]])
+// CHECK-NEXT: [[T1:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]]
+// CHECK-NEXT: br i1 [[T1]],
+// CHECK: ret void
+
+// Implicitly-generated default constructor for ObjCArrayMember
+// CHECK: define linkonce_odr void @_ZN15ObjCArrayMemberC2Ev
+// CHECK: call void @llvm.memset.p0i8.i64
+// CHECK: ret
+
+// Implicitly-generated copy constructor for ObjCMember
+// CHECK: define linkonce_odr void @_ZN10ObjCMemberC2ERKS_
+// CHECK-NOT: objc_release
+// CHECK: call i8* @objc_retain
+// CHECK-NEXT: store i8*
+// CHECK-NEXT: ret void
+
+// Implicitly-generated destructor for ObjCMember
+// CHECK: define linkonce_odr void @_ZN10ObjCMemberD2Ev
+// CHECK: call void @objc_release
+// CHECK: ret void
+
+// Implicitly-generated default constructor for ObjCMember
+// CHECK: define linkonce_odr void @_ZN10ObjCMemberC2Ev
+// CHECK-NOT: objc_release
+// CHECK: store i8* null
+// CHECK-NEXT: ret void
+
diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm
new file mode 100644
index 000000000000..0c5466a4cea3
--- /dev/null
+++ b/test/CodeGenObjCXX/arc.mm
@@ -0,0 +1,166 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-nonfragile-abi -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+
+// rdar://problem/9315552
+// The analogous ObjC testcase test46 in arr.m.
+void test0(__weak id *wp, __weak volatile id *wvp) {
+ extern id test0_helper(void);
+
+ // TODO: this is sub-optimal, we should retain at the actual call site.
+ // TODO: in the non-volatile case, we do not need to be reloading.
+
+ // CHECK: [[T0:%.*]] = call i8* @_Z12test0_helperv()
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T2:%.*]] = load i8*** {{%.*}}, align 8
+ // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]])
+ // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_retain(i8* [[T3]])
+ // CHECK-NEXT: store i8* [[T4]], i8**
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]])
+ id x = *wp = test0_helper();
+
+ // CHECK: [[T0:%.*]] = call i8* @_Z12test0_helperv()
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T2:%.*]] = load i8*** {{%.*}}, align 8
+ // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]])
+ // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_loadWeakRetained(i8** [[T2]])
+ // CHECK-NEXT: store i8* [[T4]], i8**
+ // CHECK-NEXT: call void @objc_release(i8* [[T1]])
+ id y = *wvp = test0_helper();
+}
+
+// rdar://problem/9320648
+struct Test1_helper { Test1_helper(); };
+@interface Test1 @end
+@implementation Test1 { Test1_helper x; } @end
+// CHECK: define internal i8* @"\01-[Test1 .cxx_construct]"(
+// CHECK: call void @_ZN12Test1_helperC1Ev(
+// CHECK-NEXT: load
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: ret i8*
+
+void test34(int cond) {
+ __strong id strong;
+ __weak id weak;
+ extern void test34_sink(id *);
+ test34_sink(cond ? &strong : 0);
+ test34_sink(cond ? &weak : 0);
+
+ // CHECK: define void @_Z6test34i(
+ // CHECK: [[COND:%.*]] = alloca i32
+ // CHECK-NEXT: [[STRONG:%.*]] = alloca i8*
+ // CHECK-NEXT: [[WEAK:%.*]] = alloca i8*
+ // CHECK-NEXT: [[TEMP1:%.*]] = alloca i8*
+ // CHECK-NEXT: [[TEMP2:%.*]] = alloca i8*
+ // CHECK-NEXT: store i32
+ // CHECK-NEXT: store i8* null, i8** [[STRONG]]
+ // CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAK]], i8* null)
+
+ // CHECK-NEXT: [[T0:%.*]] = load i32* [[COND]]
+ // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0
+ // CHECK: [[ARG:%.*]] = phi i8**
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
+ // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP1]]
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: [[T0:%.*]] = load i8** [[ARG]]
+ // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]]
+ // CHECK-NEXT: br label
+ // CHECK: call void @_Z11test34_sinkPU15__autoreleasingP11objc_object(i8** [[T1]])
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: [[T0:%.*]] = load i8** [[TEMP1]]
+ // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+ // CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]]
+ // CHECK-NEXT: store i8* [[T1]], i8** [[ARG]]
+ // CHECK-NEXT: call void @objc_release(i8* [[T2]])
+ // CHECK-NEXT: br label
+
+ // CHECK: [[T0:%.*]] = load i32* [[COND]]
+ // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0
+ // CHECK: [[ARG:%.*]] = phi i8**
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
+ // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP2]]
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: [[T0:%.*]] = call i8* @objc_loadWeak(i8** [[ARG]])
+ // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP2]]
+ // CHECK-NEXT: br label
+ // CHECK: call void @_Z11test34_sinkPU15__autoreleasingP11objc_object(i8** [[T1]])
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
+ // CHECK-NEXT: br i1 [[T0]],
+ // CHECK: [[T0:%.*]] = load i8** [[TEMP2]]
+ // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[ARG]], i8* [[T0]])
+ // CHECK-NEXT: br label
+
+ // CHECK: call void @objc_destroyWeak(i8** [[WEAK]])
+ // CHECK: ret void
+}
+
+struct Test35_Helper {
+ static id makeObject1() __attribute__((ns_returns_retained));
+ id makeObject2() __attribute__((ns_returns_retained));
+ static id makeObject3();
+ id makeObject4();
+};
+
+// CHECK: define void @_Z6test3513Test35_HelperPS_
+void test35(Test35_Helper x0, Test35_Helper *x0p) {
+ // CHECK: call i8* @_ZN13Test35_Helper11makeObject1Ev
+ // CHECK-NOT: call i8* @objc_retain
+ id obj1 = Test35_Helper::makeObject1();
+ // CHECK: call i8* @_ZN13Test35_Helper11makeObject2Ev
+ // CHECK-NOT: call i8* @objc_retain
+ id obj2 = x0.makeObject2();
+ // CHECK: call i8* @_ZN13Test35_Helper11makeObject2Ev
+ // CHECK-NOT: call i8* @objc_retain
+ id obj3 = x0p->makeObject2();
+ id (Test35_Helper::*pmf)() __attribute__((ns_returns_retained))
+ = &Test35_Helper::makeObject2;
+ // CHECK: call i8* %
+ // CHECK-NOT: call i8* @objc_retain
+ id obj4 = (x0.*pmf)();
+ // CHECK: call i8* %
+ // CHECK-NOT: call i8* @objc_retain
+ id obj5 = (x0p->*pmf)();
+
+ // CHECK: call void @objc_release
+ // CHECK: call void @objc_release
+ // CHECK: call void @objc_release
+ // CHECK: call void @objc_release
+ // CHECK: call void @objc_release
+ // CHECK-NEXT: ret void
+}
+
+// CHECK: define void @_Z7test35b13Test35_HelperPS_
+void test35b(Test35_Helper x0, Test35_Helper *x0p) {
+ // CHECK: call i8* @_ZN13Test35_Helper11makeObject3Ev
+ // CHECK: call i8* @objc_retain
+ id obj1 = Test35_Helper::makeObject3();
+ // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev
+ // CHECK: call i8* @objc_retain
+ id obj2 = x0.makeObject4();
+ // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev
+ // CHECK: call i8* @objc_retain
+ id obj3 = x0p->makeObject4();
+ id (Test35_Helper::*pmf)() = &Test35_Helper::makeObject4;
+ // CHECK: call i8* %
+ // CHECK: call i8* @objc_retain
+ id obj4 = (x0.*pmf)();
+ // CHECK: call i8* %
+ // CHECK: call i8* @objc_retain
+ id obj5 = (x0p->*pmf)();
+
+ // CHECK: call void @objc_release
+ // CHECK: call void @objc_release
+ // CHECK: call void @objc_release
+ // CHECK: call void @objc_release
+ // CHECK: call void @objc_release
+ // CHECK-NEXT: ret void
+}
+
+// rdar://problem/9603128
+// CHECK: define i8* @_Z6test36P11objc_object(
+id test36(id z) {
+ // CHECK: objc_retain
+ // CHECK: objc_retain
+ // CHECK: objc_release
+ // CHECK: objc_autoreleaseReturnValue
+ return z;
+}
diff --git a/test/CodeGenObjCXX/catch-id-type.mm b/test/CodeGenObjCXX/catch-id-type.mm
new file mode 100644
index 000000000000..ece342bb8720
--- /dev/null
+++ b/test/CodeGenObjCXX/catch-id-type.mm
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -triple i386-apple-macosx10.6.6 -emit-llvm -fobjc-exceptions -fcxx-exceptions -fexceptions -o - %s | FileCheck %s
+// rdar://8940528
+
+@interface ns_array
++ (id) array;
+@end
+
+@implementation ns_array
++ (id) array { return 0; }
+@end
+
+id Groups();
+
+@protocol P @end;
+
+@interface INTF<P> {
+ double dd;
+}
+@end
+
+id FUNC() {
+ id groups;
+ try
+ {
+ groups = Groups(); // throws on errors.
+ }
+ catch( INTF<P>* error )
+ {
+ Groups();
+ }
+ catch( id error )
+ {
+ // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__gxx_personality_v0 {{.*}} @_ZTIP4INTF {{.*}} @_ZTIP11objc_object {{.*}} @_ZTIP10objc_class
+ error = error;
+ groups = [ns_array array];
+ }
+ catch (Class cl) {
+ cl = cl;
+ groups = [ns_array array];
+ }
+ return groups;
+
+}
+
+int main() {
+ FUNC();
+ return 0;
+}
diff --git a/test/CodeGenObjCXX/copy.mm b/test/CodeGenObjCXX/copy.mm
new file mode 100644
index 000000000000..133910f25dcf
--- /dev/null
+++ b/test/CodeGenObjCXX/copy.mm
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+// rdar://problem/9158302
+// This should not use a memmove_collectable in non-GC mode.
+namespace test0 {
+ struct A {
+ id x;
+ };
+
+ // CHECK: define [[A:%.*]]* @_ZN5test04testENS_1AE(
+ // CHECK: alloca
+ // CHECK-NEXT: getelementptr
+ // CHECK-NEXT: store
+ // CHECK-NEXT: call noalias i8* @_Znwm(
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: call void @llvm.memset.p0i8.i64(
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(
+ // CHECK-NEXT: ret
+ A *test(A a) {
+ return new A(a);
+ }
+}
+
diff --git a/test/CodeGenObjCXX/encode.mm b/test/CodeGenObjCXX/encode.mm
index dce3d70665de..2c10fbcb9753 100644
--- a/test/CodeGenObjCXX/encode.mm
+++ b/test/CodeGenObjCXX/encode.mm
@@ -91,6 +91,20 @@ namespace rdar9357400 {
const char gg[] = @encode(vector4f);
}
+// rdar://9624314
+namespace rdar9624314 {
+ struct B2 { int x; };
+ struct B3 {};
+ struct S : B2, B3 {};
+
+ // CHECK: @_ZN11rdar9624314L2ggE = internal constant [6 x i8] c"{S=i}\00"
+ const char gg[] = @encode(S);
+
+ struct S2 { unsigned : 0; int x; unsigned : 0; };
+ // CHECK: @_ZN11rdar9624314L2g2E = internal constant [11 x i8] c"{S2=b0ib0}\00"
+ const char g2[] = @encode(S2);
+}
+
struct Base1 {
char x;
};
diff --git a/test/CodeGenObjCXX/gc.mm b/test/CodeGenObjCXX/gc.mm
new file mode 100644
index 000000000000..aa293dacf3a7
--- /dev/null
+++ b/test/CodeGenObjCXX/gc.mm
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fobjc-gc -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+namespace test0 {
+ extern id x;
+
+ struct A {
+ id x;
+ A();
+ };
+ A::A() : x(test0::x) {}
+
+// CHECK: define void @_ZN5test01AC2Ev(
+// CHECK: [[THIS:%.*]] = alloca [[TEST0:%.*]]*, align 8
+// CHECK-NEXT: store
+// CHECK-NEXT: [[T0:%.*]] = load [[TEST0]]** [[THIS]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[TEST0]]* [[T0]], i32 0, i32 0
+// CHECK-NEXT: [[T2:%.*]] = load i8** @_ZN5test01xE
+// CHECK-NEXT: call i8* @objc_assign_strongCast(i8* [[T2]], i8** [[T1]])
+// CHECK-NEXT: ret void
+}
diff --git a/test/CodeGenObjCXX/property-object-conditional-exp.mm b/test/CodeGenObjCXX/property-object-conditional-exp.mm
index a3c1027ed709..5d8a8826355c 100644
--- a/test/CodeGenObjCXX/property-object-conditional-exp.mm
+++ b/test/CodeGenObjCXX/property-object-conditional-exp.mm
@@ -22,11 +22,12 @@ extern "C" bool CGRectIsEmpty(CGRect);
CGRect dataRect;
CGRect virtualBounds;
-// CHECK: [[SRC:%.*]] = call %struct.CGRect bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-// CHECK-NEXT:getelementptr %struct.CGRect* [[SRC:%.*]]
+// CHECK: [[SRC:%.*]] = call { i8*, i32 } bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK-NEXT: bitcast
+// CHECK-NEXT:getelementptr { i8*, i32 }* [[SRC:%.*]]
// CHECK-NEXT:extractvalue
// CHECK-NEXT:store
-// CHECK-NEXT:getelementptr %struct.CGRect* [[SRC:%.*]]
+// CHECK-NEXT:getelementptr { i8*, i32 }* [[SRC:%.*]]
// CHECK-NEXT:extractvalue
// CHECK-NEXT:store
dataRect = CGRectIsEmpty(virtualBounds) ? self.bounds : virtualBounds;
diff --git a/test/CodeGenObjCXX/property-objects.mm b/test/CodeGenObjCXX/property-objects.mm
index 8e98b0dae7e4..1f4311763595 100644
--- a/test/CodeGenObjCXX/property-objects.mm
+++ b/test/CodeGenObjCXX/property-objects.mm
@@ -2,7 +2,7 @@
// CHECK-NOT: callq _objc_msgSend_stret
// CHECK: call void @_ZN1SC1ERKS_
// CHECK: call %class.S* @_ZN1SaSERKS_
-// CHECK: call %class.S* @_ZN6CGRectaSERKS_
+// CHECK: call %struct.CGRect* @_ZN6CGRectaSERKS_
class S {
public: