aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenObjCXX
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2013-04-08 18:45:10 +0000
committerDimitry Andric <dim@FreeBSD.org>2013-04-08 18:45:10 +0000
commit809500fc2c13c8173a16b052304d983864e4a1e1 (patch)
tree4fc2f184c499d106f29a386c452b49e5197bf63d /test/CodeGenObjCXX
parentbe7c9ec198dcdb5bf73a35bfbb00b3333cb87909 (diff)
downloadsrc-809500fc2c13c8173a16b052304d983864e4a1e1.tar.gz
src-809500fc2c13c8173a16b052304d983864e4a1e1.zip
Notes
Diffstat (limited to 'test/CodeGenObjCXX')
-rw-r--r--test/CodeGenObjCXX/address-safety-attr.mm17
-rw-r--r--test/CodeGenObjCXX/arc-attrs.mm48
-rw-r--r--test/CodeGenObjCXX/arc-blocks.mm49
-rw-r--r--test/CodeGenObjCXX/arc-exceptions.mm67
-rw-r--r--test/CodeGenObjCXX/arc-new-delete.mm5
-rw-r--r--test/CodeGenObjCXX/arc.mm9
-rw-r--r--test/CodeGenObjCXX/block-var-layout.mm21
-rw-r--r--test/CodeGenObjCXX/exceptions-legacy.mm80
-rw-r--r--test/CodeGenObjCXX/exceptions.mm20
-rw-r--r--test/CodeGenObjCXX/externally-initialized-selectors.mm8
-rw-r--r--test/CodeGenObjCXX/lambda-expressions.mm8
-rw-r--r--test/CodeGenObjCXX/message.mm24
-rw-r--r--test/CodeGenObjCXX/pr14474-gline-tables-only.mm25
-rw-r--r--test/CodeGenObjCXX/property-object-reference-2.mm4
-rw-r--r--test/CodeGenObjCXX/unknown-anytype.mm20
15 files changed, 368 insertions, 37 deletions
diff --git a/test/CodeGenObjCXX/address-safety-attr.mm b/test/CodeGenObjCXX/address-safety-attr.mm
index a3824b99aeff..1b6f0e807afd 100644
--- a/test/CodeGenObjCXX/address-safety-attr.mm
+++ b/test/CodeGenObjCXX/address-safety-attr.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=address | FileCheck -check-prefix ASAN %s
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=address | FileCheck -check-prefix=ASAN %s
@interface MyClass
+ (int) addressSafety:(int*)a;
@@ -7,14 +7,15 @@
@implementation MyClass
-// CHECK-NOT: +[MyClass load]{{.*}} address_safety
-// CHECK: +[MyClass load]{{.*}}
-// ASAN: +[MyClass load]{{.*}} address_safety
+// WITHOUT: +[MyClass load]{{.*}}#0
+// ASAN: +[MyClass load]{{.*}}#0
+(void) load { }
-// CHECK-NOT: +[MyClass addressSafety:]{{.*}} address_safety
-// CHECK: +[MyClass addressSafety:]{{.*}}
-// ASAN: +[MyClass addressSafety:]{{.*}} address_safety
+// WITHOUT: +[MyClass addressSafety:]{{.*}}#0
+// ASAN: +[MyClass addressSafety:]{{.*}}#0
+ (int) addressSafety:(int*)a { return *a; }
@end
+
+// ASAN: attributes #0 = {{.*}}sanitize_address
+// WITHOUT-NOT: attributes #0 = {{.*}}sanitize_address
diff --git a/test/CodeGenObjCXX/arc-attrs.mm b/test/CodeGenObjCXX/arc-attrs.mm
new file mode 100644
index 000000000000..57ccb6cdeae0
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-attrs.mm
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -emit-llvm -fobjc-arc -O0 -o - %s | FileCheck %s
+
+id makeObject1() __attribute__((ns_returns_retained));
+id makeObject2() __attribute__((ns_returns_retained));
+void releaseObject(__attribute__((ns_consumed)) id);
+
+// CHECK: define void @_Z10sanityTestv
+void sanityTest() {
+ // CHECK: [[X:%.*]] = alloca i8*, align 8
+ // CHECK-NEXT: [[OBJ1:%.*]] = call i8* @_Z11makeObject1v()
+ // CHECK-NEXT: store i8* [[OBJ1]], i8** [[X]], align 8
+ id x = makeObject1();
+
+ // CHECK-NEXT: [[OBJ2:%.*]] = call i8* @_Z11makeObject2v()
+ // CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(i8* [[OBJ2]])
+ releaseObject(makeObject2());
+
+ // CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null)
+ // CHECK-NEXT: ret void
+}
+
+
+template <typename T>
+T makeObjectT1() __attribute__((ns_returns_retained));
+template <typename T>
+T makeObjectT2() __attribute__((ns_returns_retained));
+
+template <typename T>
+void releaseObjectT(__attribute__((ns_consumed)) T);
+
+// CHECK: define void @_Z12templateTestv
+void templateTest() {
+ // CHECK: [[X:%.*]] = alloca i8*, align 8
+ // CHECK-NEXT: [[OBJ1:%.*]] = call i8* @_Z12makeObjectT1IU8__strongP11objc_objectET_v()
+ // CHECK-NEXT: store i8* [[OBJ1]], i8** [[X]], align 8
+ id x = makeObjectT1<id>();
+
+ // CHECK-NEXT: [[OBJ2:%.*]] = call i8* @_Z12makeObjectT2IU8__strongP11objc_objectET_v()
+ // CHECK-NEXT: call void @_Z13releaseObjectP11objc_object(i8* [[OBJ2]])
+ releaseObject(makeObjectT2<id>());
+
+ // CHECK-NEXT: [[OBJ3:%.*]] = call i8* @_Z11makeObject1v()
+ // CHECK-NEXT: call void @_Z14releaseObjectTIU8__strongP11objc_objectEvT_(i8* [[OBJ3]])
+ releaseObjectT(makeObject1());
+
+ // CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null)
+ // CHECK-NEXT: ret void
+}
diff --git a/test/CodeGenObjCXX/arc-blocks.mm b/test/CodeGenObjCXX/arc-blocks.mm
new file mode 100644
index 000000000000..810c0e09cc9d
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-blocks.mm
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -o - %s | FileCheck %s
+
+// CHECK: [[A:.*]] = type { i64, [10 x i8*] }
+
+// CHECK: [[LAYOUT0:@.*]] = internal global [3 x i8] c" 9\00"
+
+// rdar://13045269
+// If a __block variable requires extended layout information *and*
+// a copy/dispose helper, be sure to adjust the offsets used in copy/dispose.
+namespace test0 {
+ struct A {
+ unsigned long count;
+ id data[10];
+ };
+
+ void foo() {
+ __block A v;
+ }
+ // CHECK: define void @_ZN5test03fooEv()
+ // CHECK: [[V:%.*]] = alloca [[BYREF_A:%.*]], align 8
+ // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_A]]* [[V]], i32 0, i32 4
+ // CHECK-NEXT: store i8* bitcast (void (i8*, i8*)* [[COPY_HELPER:@.*]] to i8*), i8** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BYREF_A]]* [[V]], i32 0, i32 5
+ // CHECK-NEXT: store i8* bitcast (void (i8*)* [[DISPOSE_HELPER:@.*]] to i8*), i8** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BYREF_A]]* [[V]], i32 0, i32 6
+ // CHECK-NEXT: store i8* getelementptr inbounds ([3 x i8]* [[LAYOUT0]], i32 0, i32 0), i8** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BYREF_A]]* [[V]], i32 0, i32 7
+ // CHECK-NEXT: call void @_ZN5test01AC1Ev([[A]]* [[T0]])
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BYREF_A]]* [[V]], i32 0, i32 7
+ // CHECK-NEXT: [[T1:%.*]] = bitcast [[BYREF_A]]* [[V]] to i8*
+ // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T1]], i32 8)
+ // CHECK-NEXT: call void @_ZN5test01AD1Ev([[A]]* [[T0]])
+ // CHECK-NEXT: ret void
+
+ // CHECK: define internal void [[COPY_HELPER]](
+ // CHECK: [[T0:%.*]] = bitcast i8* {{.*}} to [[BYREF_A]]*
+ // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF_A]]* [[T0]], i32 0, i32 7
+ // CHECK-NEXT: load
+ // CHECK-NEXT: [[T2:%.*]] = bitcast i8* {{.*}} to [[BYREF_A]]*
+ // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[BYREF_A]]* [[T2]], i32 0, i32 7
+ // CHECK-NEXT: call void @_ZN5test01AC1ERKS0_([[A]]* [[T1]], [[A]]* [[T3]])
+ // CHECK-NEXT: ret void
+
+ // CHECK: define internal void [[DISPOSE_HELPER]](
+ // CHECK: [[T0:%.*]] = bitcast i8* {{.*}} to [[BYREF_A]]*
+ // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF_A]]* [[T0]], i32 0, i32 7
+ // CHECK-NEXT: call void @_ZN5test01AD1Ev([[A]]* [[T1]])
+ // CHECK-NEXT: ret void
+}
diff --git a/test/CodeGenObjCXX/arc-exceptions.mm b/test/CodeGenObjCXX/arc-exceptions.mm
index fb5300d15e4c..b5ed257e9485 100644
--- a/test/CodeGenObjCXX/arc-exceptions.mm
+++ b/test/CodeGenObjCXX/arc-exceptions.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-runtime-has-weak -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-runtime-has-weak -o - -fobjc-arc-exceptions %s | FileCheck %s
@class Ety;
@@ -17,12 +17,12 @@ void test0(void) {
// CHECK: [[T0:%.*]] = call i8* @objc_begin_catch(
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
-// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) nounwind
+// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) [[NUW:#[0-9]+]]
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
// CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
-// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) nounwind
-// CHECK-NEXT: call void @objc_end_catch() nounwind
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) [[NUW]]
+// CHECK-NEXT: call void @objc_end_catch() [[NUW]]
void test1_helper(void);
void test1(void) {
@@ -38,10 +38,10 @@ void test1(void) {
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
// CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
-// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) nounwind
+// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]]
// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
-// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) nounwind
-// CHECK-NEXT: call void @objc_end_catch() nounwind
+// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) [[NUW]]
+// CHECK-NEXT: call void @objc_end_catch() [[NUW]]
void test2_helper(void);
void test2(void) {
@@ -56,12 +56,12 @@ void test2(void) {
// CHECK: [[T0:%.*]] = call i8* @__cxa_begin_catch(
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
-// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) nounwind
+// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) [[NUW]]
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
// CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
-// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) nounwind
-// CHECK-NEXT: call void @__cxa_end_catch() nounwind
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) [[NUW]]
+// CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
void test3_helper(void);
void test3(void) {
@@ -77,7 +77,48 @@ void test3(void) {
// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
// CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
-// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) nounwind
+// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) [[NUW]]
// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
-// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) nounwind
-// CHECK-NEXT: call void @__cxa_end_catch() nounwind
+// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) [[NUW]]
+// CHECK-NEXT: call void @__cxa_end_catch() [[NUW]]
+
+namespace test4 {
+ struct A {
+ id single;
+ id array[2][3];
+
+ A();
+ };
+
+ A::A() {
+ throw 0;
+ }
+ // CHECK: define void @_ZN5test41AC2Ev(
+ // CHECK: [[THIS:%.*]] = load [[A:%.*]]** {{%.*}}
+ // Construct single.
+ // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 0
+ // CHECK-NEXT: store i8* null, i8** [[SINGLE]], align 8
+ // Construct array.
+ // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [2 x [3 x i8*]]* [[ARRAY]] to i8*
+ // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 48, i32 8, i1 false)
+ // throw 0;
+ // CHECK: invoke void @__cxa_throw(
+ // Landing pad from throw site:
+ // CHECK: landingpad
+ // - First, destroy all of array.
+ // CHECK: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x i8*]]* [[ARRAY]], i32 0, i32 0, i32 0
+ // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds i8** [[ARRAYBEGIN]], i64 6
+ // CHECK-NEXT: br label
+ // CHECK: [[AFTER:%.*]] = phi i8** [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[ELT]] = getelementptr inbounds i8** [[AFTER]], i64 -1
+ // CHECK-NEXT: call void @objc_storeStrong(i8** [[ELT]], i8* null) [[NUW]]
+ // CHECK-NEXT: [[DONE:%.*]] = icmp eq i8** [[ELT]], [[ARRAYBEGIN]]
+ // CHECK-NEXT: br i1 [[DONE]],
+ // - Next, destroy single.
+ // CHECK: call void @objc_storeStrong(i8** [[SINGLE]], i8* null) [[NUW]]
+ // CHECK: br label
+ // CHECK: resume
+}
+
+// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjCXX/arc-new-delete.mm b/test/CodeGenObjCXX/arc-new-delete.mm
index ce7eb3deb141..c061e5dbdff8 100644
--- a/test/CodeGenObjCXX/arc-new-delete.mm
+++ b/test/CodeGenObjCXX/arc-new-delete.mm
@@ -5,8 +5,9 @@ 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: [[INVALUEADDR:%.*]] = alloca i8*
+ // CHECK-NEXT: store i8* null, i8** [[INVALUEADDR]]
+ // CHECK-NEXT: call void @objc_storeStrong(i8** [[INVALUEADDR]], i8* [[INVALUE:%.*]])
// CHECK: call noalias i8* @_Znwm
// CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm
index f31b993946e8..1888dbe77d81 100644
--- a/test/CodeGenObjCXX/arc.mm
+++ b/test/CodeGenObjCXX/arc.mm
@@ -61,6 +61,8 @@ void test34(int cond) {
// CHECK-NEXT: [[WEAK:%.*]] = alloca i8*
// CHECK-NEXT: [[TEMP1:%.*]] = alloca i8*
// CHECK-NEXT: [[TEMP2:%.*]] = alloca i8*
+ // CHECK-NEXT: [[CONDCLEANUPSAVE:%.*]] = alloca i8*
+ // CHECK-NEXT: [[CONDCLEANUP:%.*]] = alloca i1
// CHECK-NEXT: store i32
// CHECK-NEXT: store i8* null, i8** [[STRONG]]
// CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAK]], i8* null)
@@ -74,11 +76,13 @@ void test34(int cond) {
// CHECK: [[T0:%.*]] = load i8** [[ARG]]
// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP1]]
// CHECK-NEXT: br label
+ // CHECK: [[W0:%.*]] = phi i8* [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ]
// 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: call void (...)* @clang.arc.use(i8* [[W0]])
// CHECK-NEXT: [[T2:%.*]] = load i8** [[ARG]]
// CHECK-NEXT: store i8* [[T1]], i8** [[ARG]]
// CHECK-NEXT: call void @objc_release(i8* [[T2]])
@@ -89,8 +93,11 @@ void test34(int cond) {
// CHECK: [[ARG:%.*]] = phi i8**
// CHECK-NEXT: [[T0:%.*]] = icmp eq i8** [[ARG]], null
// CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i8** null, i8** [[TEMP2]]
+ // CHECK-NEXT: store i1 false, i1* [[CONDCLEANUP]]
// CHECK-NEXT: br i1 [[T0]],
- // CHECK: [[T0:%.*]] = call i8* @objc_loadWeak(i8** [[ARG]])
+ // CHECK: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[ARG]])
+ // CHECK-NEXT: store i8* [[T0]], i8** [[CONDCLEANUPSAVE]]
+ // CHECK-NEXT: store i1 true, i1* [[CONDCLEANUP]]
// CHECK-NEXT: store i8* [[T0]], i8** [[TEMP2]]
// CHECK-NEXT: br label
// CHECK: call void @_Z11test34_sinkPU15__autoreleasingP11objc_object(i8** [[T1]])
diff --git a/test/CodeGenObjCXX/block-var-layout.mm b/test/CodeGenObjCXX/block-var-layout.mm
index f8b6b9c8868c..08dbc02affbd 100644
--- a/test/CodeGenObjCXX/block-var-layout.mm
+++ b/test/CodeGenObjCXX/block-var-layout.mm
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -emit-llvm %s -o %t-64.ll
-// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.ll %s
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
+// RUN: FileCheck --input-file=%t-64.layout %s
+// rdar://12184410
+// rdar://12752901
// See commentary in test/CodeGenObjC/block-var-layout.m, from which
// this is largely cloned.
@@ -37,7 +39,7 @@ void f() {
// Test 1
// byref int, short, char, char, char, id, id, strong void*, byref id
// 01 35 10 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\015\10\00"
+// CHECK: block variable layout for block: 0x01, 0x35, 0x10, 0x00
void (^b)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -50,7 +52,7 @@ void f() {
// Test 2
// byref int, short, char, char, char, id, id, strong void*, byref void*, byref id
// 01 36 10 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\016\10\00"
+// CHECK: 0x01, 0x36, 0x10, 0x00
void (^c)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -65,8 +67,7 @@ void f() {
// Test 3
// byref int, short, char, char, char, id, id, byref void*, int, double, byref id
// 01 34 11 30 00
-// FIXME: we'd get a better format here if we sorted by scannability, not just alignment
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\014\11 \00"
+// CHECK: block variable layout for block: 0x01, 0x35, 0x30, 0x00
void (^d)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -81,7 +82,7 @@ void (^d)() = ^{
// Test4
// struct S (int, id, int, id, int, id)
// 01 41 11 11 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\11\00"
+// CHECK: block variable layout for block: 0x01, 0x41, 0x11, 0x11, 0x00
struct S s2;
void (^e)() = ^{
x(s2.o1);
@@ -119,7 +120,7 @@ void Test5() {
// struct s2 (int, id, int, id, int, id?), union u2 (id?)
// 01 41 11 12 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\12\00"
+// CHECK: block variable layout for block: 0x01, 0x41, 0x11, 0x12, 0x00
void (^c)() = ^{
x(s2.ui.o1);
x(u2.o1);
@@ -137,7 +138,7 @@ void notifyBlock(id dependentBlock) {
// id, id, void(^)()
// 01 33 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\013\00"
+// CHECK: block variable layout for block: 0x01, 0x33, 0x00
void (^wrapperBlock)() = ^() {
CFRelease(singleObservationToken);
CFRelease(singleObservationToken);
@@ -150,7 +151,7 @@ void notifyBlock(id dependentBlock) {
void test_empty_block() {
// 01 00
-// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"\01\00"
+// CHECK: block variable layout for block: 0x01, 0x00
void (^wrapperBlock)() = ^() {
};
wrapperBlock();
diff --git a/test/CodeGenObjCXX/exceptions-legacy.mm b/test/CodeGenObjCXX/exceptions-legacy.mm
new file mode 100644
index 000000000000..a31ba36660ab
--- /dev/null
+++ b/test/CodeGenObjCXX/exceptions-legacy.mm
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fexceptions -fobjc-exceptions -O2 -o - %s | FileCheck %s
+
+// Test we maintain at least a basic amount of interoperation between
+// ObjC and C++ exceptions in the legacy runtime.
+
+// rdar://12364847
+
+void foo(void);
+
+void test0(id obj) {
+ @synchronized(obj) {
+ foo();
+ }
+}
+// CHECK: define void @_Z5test0P11objc_object(
+// Enter the @synchronized block.
+// CHECK: call i32 @objc_sync_enter(i8* [[OBJ:%.*]])
+// CHECK: call void @objc_exception_try_enter([[BUF_T:%.*]]* [[BUF:%.*]])
+// CHECK-NEXT: [[T0:%.*]] = getelementptr [[BUF_T]]* [[BUF]], i32 0, i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(i32* [[T0]])
+// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
+// CHECK-NEXT: br i1 [[T2]],
+
+// Body.
+// CHECK: invoke void @_Z3foov()
+
+// Leave the @synchronized. The reload of obj here is unnecessary.
+// CHECK: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]])
+// CHECK-NEXT: [[T0:%.*]] = load i8**
+// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]])
+// CHECK-NEXT: ret void
+
+// Real EH cleanup.
+// CHECK: [[T0:%.*]] = landingpad
+// CHECK-NEXT: cleanup
+// CHECK-NEXT: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]])
+// CHECK-NEXT: [[T0:%.*]] = load i8**
+// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]])
+// CHECK-NEXT: resume
+
+// ObjC EH "cleanup".
+// CHECK: [[T0:%.*]] = load i8**
+// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]])
+// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_exception_extract([[BUF_T]]* [[BUF]])
+// CHECK-NEXT: call void @objc_exception_throw(i8* [[T0]])
+// CHECK-NEXT: unreachable
+
+void test1(id obj, bool *failed) {
+ @try {
+ foo();
+ } @catch (...) {
+ *failed = true;
+ }
+}
+// CHECK: define void @_Z5test1P11objc_objectPb(
+// Enter the @try block.
+// CHECK: call void @objc_exception_try_enter([[BUF_T]]* [[BUF:%.*]])
+// CHECK-NEXT: [[T0:%.*]] = getelementptr [[BUF_T]]* [[BUF]], i32 0, i32 0, i32 0
+// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(i32* [[T0]])
+// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
+// CHECK-NEXT: br i1 [[T2]],
+
+// Body.
+// CHECK: invoke void @_Z3foov()
+
+// Leave the @try.
+// CHECK: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]])
+// CHECK-NEXT: br label
+// CHECK: ret void
+
+// Real EH cleanup.
+// CHECK: [[T0:%.*]] = landingpad
+// CHECK-NEXT: cleanup
+// CHECK-NEXT: call void @objc_exception_try_exit([[BUF_T]]* [[BUF]])
+// CHECK-NEXT: resume
+
+// Catch handler. Reload of 'failed' address is unnecessary.
+// CHECK: [[T0:%.*]] = load i8**
+// CHECK-NEXT: store i8 1, i8* [[T0]],
+// CHECK-NEXT: br label
diff --git a/test/CodeGenObjCXX/exceptions.mm b/test/CodeGenObjCXX/exceptions.mm
index ce6d20aa98b6..031c22204d8b 100644
--- a/test/CodeGenObjCXX/exceptions.mm
+++ b/test/CodeGenObjCXX/exceptions.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -fobjc-exceptions -o - %s | FileCheck %s
@interface OCType @end
void opaque();
@@ -16,3 +16,21 @@ namespace test0 {
}
}
}
+
+// rdar://12605907
+@interface NSException
+ + new;
+@end
+namespace test1 {
+
+ void bar() {
+ @try {
+ throw [NSException new];
+ } @catch (id i) {
+ }
+ }
+// CHECK: invoke void @objc_exception_throw(i8* [[CALL:%.*]]) [[NR:#[0-9]+]]
+// CHECK: to label [[INVOKECONT1:%.*]] unwind label [[LPAD:%.*]]
+}
+
+// CHECK: attributes [[NR]] = { noreturn }
diff --git a/test/CodeGenObjCXX/externally-initialized-selectors.mm b/test/CodeGenObjCXX/externally-initialized-selectors.mm
new file mode 100644
index 000000000000..87a7c04cf718
--- /dev/null
+++ b/test/CodeGenObjCXX/externally-initialized-selectors.mm
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -cc1 -fobjc-runtime=macosx-fragile-10.5 -o - -emit-llvm %s | FileCheck %s
+// RUN: %clang_cc1 -cc1 -o - -emit-llvm %s | FileCheck %s
+
+// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_" = internal externally_initialized global
+
+void test(id x) {
+ [x doSomething];
+}
diff --git a/test/CodeGenObjCXX/lambda-expressions.mm b/test/CodeGenObjCXX/lambda-expressions.mm
index ec3eb1fda50b..7c1e2e4f57ff 100644
--- a/test/CodeGenObjCXX/lambda-expressions.mm
+++ b/test/CodeGenObjCXX/lambda-expressions.mm
@@ -25,15 +25,19 @@ typedef int (^fp)();
fp global;
void f2() { global = []{ return 3; }; }
-// MRC: define void @_Z2f2v() nounwind {
+// MRC: define void @_Z2f2v() [[NUW:#[0-9]+]] {
// MRC: store i8* bitcast (i32 (i8*)* @___Z2f2v_block_invoke to i8*),
// MRC-NOT: call
// MRC: ret void
// ("global" contains a dangling pointer after this function runs.)
-// ARC: define void @_Z2f2v() nounwind {
+// ARC: define void @_Z2f2v() [[NUW:#[0-9]+]] {
// ARC: store i8* bitcast (i32 (i8*)* @___Z2f2v_block_invoke to i8*),
// ARC: call i8* @objc_retainBlock
// ARC: call void @objc_release
// ARC: define internal i32 @___Z2f2v_block_invoke
// ARC: call i32 @"_ZZ2f2vENK3$_1clEv
+
+// ARC: attributes [[NUW]] = { nounwind{{.*}} }
+
+// MRC: attributes [[NUW]] = { nounwind{{.*}} }
diff --git a/test/CodeGenObjCXX/message.mm b/test/CodeGenObjCXX/message.mm
new file mode 100644
index 000000000000..1268a79d63b7
--- /dev/null
+++ b/test/CodeGenObjCXX/message.mm
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-10.7 -emit-llvm -o - %s | FileCheck %s
+
+// Properly instantiate a non-dependent message expression which
+// requires a contextual conversion to ObjC pointer type.
+// <rdar://13305374>
+@interface Test0
+- (void) foo;
+@end
+namespace test0 {
+ struct A {
+ operator Test0*();
+ };
+ template <class T> void foo() {
+ A a;
+ [a foo];
+ }
+ template void foo<int>();
+ // CHECK: define weak_odr void @_ZN5test03fooIiEEvv()
+ // CHECK: [[T0:%.*]] = call [[TEST0:%.*]]* @_ZN5test01AcvP5Test0Ev(
+ // CHECK-NEXT: [[T1:%.*]] = load i8**
+ // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST0]]* [[T0]] to i8*
+ // CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* [[T2]], i8* [[T1]])
+ // CHECK-NEXT: ret void
+}
diff --git a/test/CodeGenObjCXX/pr14474-gline-tables-only.mm b/test/CodeGenObjCXX/pr14474-gline-tables-only.mm
new file mode 100644
index 000000000000..e927ab96f3c1
--- /dev/null
+++ b/test/CodeGenObjCXX/pr14474-gline-tables-only.mm
@@ -0,0 +1,25 @@
+// PR 14474
+// RUN: %clang_cc1 -triple i386-apple-macosx10.6.0 -emit-llvm \
+// RUN: -gline-tables-only -x objective-c++ -o /dev/null %s
+
+typedef signed char BOOL;
+@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object;
+@end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
+@end
+@interface NSObject <NSObject> { }
+@end
+@interface NSResponder : NSObject <NSCoding> { }
+@end
+@protocol NSValidatedUserInterfaceItem - (SEL)action;
+@end
+@protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id
+<NSValidatedUserInterfaceItem>)anItem;
+@end
+@interface NSRunningApplication : NSObject { }
+@end
+@interface NSApplication : NSResponder <NSUserInterfaceValidations> { }
+@end
+@implementation MockCrApp + (NSApplication*)sharedApplication { }
+@end
diff --git a/test/CodeGenObjCXX/property-object-reference-2.mm b/test/CodeGenObjCXX/property-object-reference-2.mm
index 2a380385bc9d..25bfdf848d3a 100644
--- a/test/CodeGenObjCXX/property-object-reference-2.mm
+++ b/test/CodeGenObjCXX/property-object-reference-2.mm
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-10.7 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple x86_64-unknown-freebsd -fobjc-runtime=gnustep-1.7 -emit-llvm -o - | FileCheck -check-prefix=CHECK-GNUSTEP %s
// rdar://6137845
extern int DEFAULT();
@@ -54,3 +55,6 @@ struct TCPPObject
// CHECK: [[THREE:%.*]] = bitcast %struct.TCPPObject* [[MYPROPERTY:%.*]] to i8*
// CHECK: call void @objc_copyCppObjectAtomic(i8* [[TWO]], i8* [[THREE]], i8* bitcast (void (%struct.TCPPObject*, %struct.TCPPObject*)* @__assign_helper_atomic_property_ to i8*))
// CHECK: ret void
+
+// CHECK-GNUSTEP: objc_getCppObjectAtomic
+// CHECK-GNUSTEP: objc_setCppObjectAtomic
diff --git a/test/CodeGenObjCXX/unknown-anytype.mm b/test/CodeGenObjCXX/unknown-anytype.mm
new file mode 100644
index 000000000000..0e146d42c9ee
--- /dev/null
+++ b/test/CodeGenObjCXX/unknown-anytype.mm
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fdebugger-support -funknown-anytype -emit-llvm -o - %s | FileCheck %s
+
+// rdar://13025708
+
+@interface A @end
+void test0(A *a) {
+ (void) [a test0: (float) 2.0];
+}
+// CHECK: define void @_Z5test0P1A(
+// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, float)*)(
+
+@interface B
+- (void) test1: (__unknown_anytype) x;
+@end
+void test1(B *b) {
+ (void) [b test1: (float) 2.0];
+}
+// CHECK: define void @_Z5test1P1B(
+// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, float)*)(
+