summaryrefslogtreecommitdiffstats
path: root/test/CodeGenObjC/block-var-layout.m
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenObjC/block-var-layout.m')
-rw-r--r--test/CodeGenObjC/block-var-layout.m101
1 files changed, 72 insertions, 29 deletions
diff --git a/test/CodeGenObjC/block-var-layout.m b/test/CodeGenObjC/block-var-layout.m
index bf9ba8d..466dee1 100644
--- a/test/CodeGenObjC/block-var-layout.m
+++ b/test/CodeGenObjC/block-var-layout.m
@@ -1,6 +1,4 @@
-// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -O0 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -O0 -S %s -o %t-64.s
+// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -O0 -emit-llvm %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
struct S {
@@ -18,19 +16,38 @@ __weak id wid;
void x(id y) {}
void y(int a) {}
+extern id opaque_id();
+
void f() {
__block int byref_int = 0;
char ch = 'a';
char ch1 = 'b';
char ch2 = 'c';
short sh = 2;
- const id bar = (id)0;
+ const id bar = (id) opaque_id();
id baz = 0;
__strong void *strong_void_sta;
__block id byref_bab = (id)0;
__block void *bl_var1;
int i; double dob;
+// The patterns here are a sequence of bytes, each saying first how
+// many sizeof(void*) chunks to skip (high nibble) and then how many
+// to scan (low nibble). A zero byte says that we've reached the end
+// of the pattern.
+//
+// All of these patterns start with 01 3x because the block header on
+// LP64 consists of an isa pointer (which we're supposed to scan for
+// some reason) followed by three words (2 ints, a function pointer,
+// and a descriptor pointer).
+
+// FIXME: do these really have to be named L_OBJC_CLASS_NAME_xxx?
+// FIXME: sequences should never end in x0 00 instead of just 00
+
+// 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"
void (^b)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -41,6 +58,9 @@ void f() {
b();
// 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"
void (^c)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
@@ -53,7 +73,11 @@ void f() {
c();
// Test 3
-void (^d)() = ^{
+// 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"
+ void (^d)() = ^{
byref_int = sh + ch+ch1+ch2 ;
x(bar);
x(baz);
@@ -64,7 +88,10 @@ void (^d)() = ^{
};
d();
-// Test4
+// Test 4
+// struct S (int, id, int, id, int, id)
+// 01 41 11 11
+// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\11\00"
struct S s2;
void (^e)() = ^{
x(s2.o1);
@@ -74,7 +101,7 @@ void (^d)() = ^{
// Test 5 (unions/structs and their nesting):
void Test5() {
-struct S5 {
+ struct S5 {
int i1;
id o1;
struct V {
@@ -88,36 +115,52 @@ struct S5 {
int i3;
id o3;
}ui;
-};
+ };
-union U {
+ union U {
void * i1;
id o1;
int i3;
id o3;
-}ui;
+ }ui;
-struct S5 s2;
-union U u2;
-void (^c)() = ^{
+ struct S5 s2;
+ union U u2;
+
+// struct s2 (int, id, int, id, int, id?), union u2 (id?)
+// 01 41 11 12 70 00
+// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [6 x i8] c"\01A\11\12p\00"
+ void (^c)() = ^{
x(s2.ui.o1);
x(u2.o1);
-};
-c();
-
+ };
+ c();
}
-// CHECK-LP64: L_OBJC_CLASS_NAME_:
-// CHECK-LP64-NEXT: .asciz "A\024"
-
-// CHECK-LP64: L_OBJC_CLASS_NAME_1:
-// CHECK-LP64-NEXT: .asciz "A\025"
-
-// CHECK-LP64: L_OBJC_CLASS_NAME_6:
-// CHECK-LP64-NEXT: .asciz "A\023!"
-
-// CHECK-LP64: L_OBJC_CLASS_NAME_11:
-// CHECK-LP64-NEXT: .asciz "Q\021\021"
+// rdar: //8417746
+void CFRelease(id);
+void notifyBlock(id dependentBlock) {
+ id singleObservationToken;
+ id token;
+ void (^b)();
+
+// id, id, void(^)()
+// 01 33 00
+// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\013\00"
+ void (^wrapperBlock)() = ^() {
+ CFRelease(singleObservationToken);
+ CFRelease(singleObservationToken);
+ CFRelease(token);
+ CFRelease(singleObservationToken);
+ b();
+ };
+ wrapperBlock();
+}
-// CHECK-LP64: L_OBJC_CLASS_NAME_14:
-// CHECK-LP64-NEXT: .asciz "Q\021\022p"
+void test_empty_block() {
+// 01 00
+// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"\01\00"
+ void (^wrapperBlock)() = ^() {
+ };
+ wrapperBlock();
+}
OpenPOWER on IntegriCloud