forked from OSchip/llvm-project
objC block layout: Patch reorders block layout to
produce more inline layout metadata. // rdar://12752901 llvm-svn: 172683
This commit is contained in:
parent
e9fe5308ca
commit
c889205567
|
@ -182,13 +182,16 @@ namespace {
|
|||
struct BlockLayoutChunk {
|
||||
CharUnits Alignment;
|
||||
CharUnits Size;
|
||||
Qualifiers::ObjCLifetime Lifetime;
|
||||
const BlockDecl::Capture *Capture; // null for 'this'
|
||||
llvm::Type *Type;
|
||||
|
||||
BlockLayoutChunk(CharUnits align, CharUnits size,
|
||||
Qualifiers::ObjCLifetime lifetime,
|
||||
const BlockDecl::Capture *capture,
|
||||
llvm::Type *type)
|
||||
: Alignment(align), Size(size), Capture(capture), Type(type) {}
|
||||
: Alignment(align), Size(size), Lifetime(lifetime),
|
||||
Capture(capture), Type(type) {}
|
||||
|
||||
/// Tell the block info that this chunk has the given field index.
|
||||
void setIndex(CGBlockInfo &info, unsigned index) {
|
||||
|
@ -200,9 +203,35 @@ namespace {
|
|||
}
|
||||
};
|
||||
|
||||
/// Order by descending alignment.
|
||||
/// Order by 1) all __strong together 2) next, all byfref together 3) next,
|
||||
/// all __weak together. Preserve descending alignment in all situations.
|
||||
bool operator<(const BlockLayoutChunk &left, const BlockLayoutChunk &right) {
|
||||
return left.Alignment > right.Alignment;
|
||||
CharUnits LeftValue, RightValue;
|
||||
bool LeftByref = left.Capture ? left.Capture->isByRef() : false;
|
||||
bool RightByref = right.Capture ? right.Capture->isByRef() : false;
|
||||
|
||||
if (left.Lifetime == Qualifiers::OCL_Strong &&
|
||||
left.Alignment >= right.Alignment)
|
||||
LeftValue = CharUnits::fromQuantity(64);
|
||||
else if (LeftByref && left.Alignment >= right.Alignment)
|
||||
LeftValue = CharUnits::fromQuantity(32);
|
||||
else if (left.Lifetime == Qualifiers::OCL_Weak &&
|
||||
left.Alignment >= right.Alignment)
|
||||
LeftValue = CharUnits::fromQuantity(16);
|
||||
else
|
||||
LeftValue = left.Alignment;
|
||||
if (right.Lifetime == Qualifiers::OCL_Strong &&
|
||||
right.Alignment >= left.Alignment)
|
||||
RightValue = CharUnits::fromQuantity(64);
|
||||
else if (RightByref && right.Alignment >= left.Alignment)
|
||||
RightValue = CharUnits::fromQuantity(32);
|
||||
else if (right.Lifetime == Qualifiers::OCL_Weak &&
|
||||
right.Alignment >= left.Alignment)
|
||||
RightValue = CharUnits::fromQuantity(16);
|
||||
else
|
||||
RightValue = right.Alignment;
|
||||
|
||||
return LeftValue > RightValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,7 +366,9 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
|
|||
= CGM.getContext().getTypeInfoInChars(thisType);
|
||||
maxFieldAlign = std::max(maxFieldAlign, tinfo.second);
|
||||
|
||||
layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first, 0, llvmType));
|
||||
layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
|
||||
Qualifiers::OCL_None,
|
||||
0, llvmType));
|
||||
}
|
||||
|
||||
// Next, all the block captures.
|
||||
|
@ -358,6 +389,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
|
|||
maxFieldAlign = std::max(maxFieldAlign, tinfo.second);
|
||||
|
||||
layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
|
||||
Qualifiers::OCL_None,
|
||||
&*ci, llvmType));
|
||||
continue;
|
||||
}
|
||||
|
@ -371,8 +403,9 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
|
|||
|
||||
// If we have a lifetime qualifier, honor it for capture purposes.
|
||||
// That includes *not* copying it if it's __unsafe_unretained.
|
||||
if (Qualifiers::ObjCLifetime lifetime
|
||||
= variable->getType().getObjCLifetime()) {
|
||||
Qualifiers::ObjCLifetime lifetime =
|
||||
variable->getType().getObjCLifetime();
|
||||
if (lifetime) {
|
||||
switch (lifetime) {
|
||||
case Qualifiers::OCL_None: llvm_unreachable("impossible");
|
||||
case Qualifiers::OCL_ExplicitNone:
|
||||
|
@ -387,6 +420,8 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
|
|||
// Block pointers require copy/dispose. So do Objective-C pointers.
|
||||
} else if (variable->getType()->isObjCRetainableType()) {
|
||||
info.NeedsCopyDispose = true;
|
||||
// used for mrr below.
|
||||
lifetime = Qualifiers::OCL_Strong;
|
||||
|
||||
// So do types that require non-trivial copy construction.
|
||||
} else if (ci->hasCopyExpr()) {
|
||||
|
@ -413,7 +448,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
|
|||
llvm::Type *llvmType =
|
||||
CGM.getTypes().ConvertTypeForMem(VT);
|
||||
|
||||
layout.push_back(BlockLayoutChunk(align, size, &*ci, llvmType));
|
||||
layout.push_back(BlockLayoutChunk(align, size, lifetime, &*ci, llvmType));
|
||||
}
|
||||
|
||||
// If that was everything, we're done here.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -emit-llvm %s -o %t-64.s
|
||||
// RUN: FileCheck --input-file=%t-64.s %s
|
||||
// rdar://12773256
|
||||
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
|
||||
// RUN: FileCheck --input-file=%t-32.layout %s
|
||||
// rdar://12184410
|
||||
// rdar://12752901
|
||||
|
||||
@class NSString;
|
||||
extern void NSLog(NSString *format, ...);
|
||||
|
@ -10,43 +11,32 @@ int main() {
|
|||
NSString *strong;
|
||||
unsigned long long eightByte = 0x8001800181818181ull;
|
||||
// Test1
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\220\00"
|
||||
// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
|
||||
void (^block1)() = ^{ printf("%#llx", eightByte); NSLog(@"%@", strong); };
|
||||
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0*, i64, %0* }>, align 8
|
||||
// block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
|
||||
|
||||
// Test2
|
||||
int i = 1;
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"#0\00"
|
||||
// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
|
||||
void (^block2)() = ^{ printf("%#llx, %d", eightByte, i); NSLog(@"%@", strong); };
|
||||
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32, i64, i32, %0* }>, align 8
|
||||
// block variable layout: BL_NON_OBJECT_WORD:4, BL_STRONG:1, BL_OPERATOR:0
|
||||
|
||||
// Test3
|
||||
char ch = 'a';
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\220\00"
|
||||
// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
|
||||
void (^block3)() = ^{ printf("%c %#llx", ch, eightByte); NSLog(@"%@", strong); };
|
||||
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0*, i64, %0*, i8 }>, align 8
|
||||
// block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
|
||||
|
||||
// Test4
|
||||
unsigned long fourByte = 0x8001ul;
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c" 0\00"
|
||||
void (^block4)() = ^{ printf("%c %#lx", ch, fourByte); NSLog(@"%@", strong); };
|
||||
// block variable layout: BL_NON_OBJECT_WORD:1, BL_STRONG:1, BL_OPERATOR:0
|
||||
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32, %0*, i8 }>, align 4
|
||||
// CHECK: Inline instruction for block variable layout: 0x0100
|
||||
void (^block4)() = ^{ printf("%c %#lx", ch, fourByte); NSLog(@"%@", strong); };
|
||||
|
||||
// Test5
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\220\00"
|
||||
// CHECK: block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
|
||||
void (^block5)() = ^{ NSLog(@"%@", strong); printf("%c %#llx", ch, eightByte); };
|
||||
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0*, i64, %0*, i8 }>, align 8
|
||||
// block variable layout: BL_NON_OBJECT_WORD:3, BL_STRONG:1, BL_OPERATOR:0
|
||||
|
||||
// Test6
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK: block variable layout: BL_OPERATOR:0
|
||||
void (^block6)() = ^{ printf("%#llx", eightByte); };
|
||||
// %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [4 x i8], i64 }>, align 8
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -emit-llvm %s -o %t-64.s
|
||||
// RUN: FileCheck --input-file=%t-64.s %s
|
||||
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
|
||||
// RUN: FileCheck --input-file=%t-32.layout %s
|
||||
// rdar://12184410
|
||||
// rdar://12752901
|
||||
|
||||
void x(id y) {}
|
||||
void y(int a) {}
|
||||
|
@ -32,8 +33,7 @@ void f() {
|
|||
// and a descriptor pointer).
|
||||
|
||||
// Test 1
|
||||
// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_BYREF:1, BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"@2@\00"
|
||||
// CHECK: Inline instruction for block variable layout: 0x0320
|
||||
void (^b)() = ^{
|
||||
byref_int = sh + ch+ch1+ch2 ;
|
||||
x(bar);
|
||||
|
@ -44,8 +44,7 @@ void f() {
|
|||
b();
|
||||
|
||||
// Test 2
|
||||
// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_WEAK:1, BL_BYREF:2, BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"@2PA\00"
|
||||
// CHECK: Inline instruction for block variable layout: 0x0331
|
||||
void (^c)() = ^{
|
||||
byref_int = sh + ch+ch1+ch2 ;
|
||||
x(bar);
|
||||
|
@ -66,8 +65,7 @@ void g() {
|
|||
unsigned int i;
|
||||
NSString *y;
|
||||
NSString *z;
|
||||
// block variable layout: BL_STRONG:2, BL_WEAK:1, BL_STRONG:2, BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"!1P1\00"
|
||||
// CHECK: Inline instruction for block variable layout: 0x0401
|
||||
void (^c)() = ^{
|
||||
int j = i + bletch;
|
||||
x(foo);
|
||||
|
@ -112,7 +110,7 @@ void h() {
|
|||
block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1, BL_NON_OBJECT_WORD:1,
|
||||
BL_UNRETAINE:1, BL_NON_OBJECT_WORD:3, BL_BYREF:1, BL_OPERATOR:0
|
||||
*/
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [7 x i8] c" ` `\22@\00"
|
||||
// CHECK: block variable layout: BL_BYREF:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
|
||||
void (^c)() = ^{
|
||||
x(s2.ui.o1);
|
||||
x(u2.o1);
|
||||
|
@ -127,8 +125,7 @@ void arr1() {
|
|||
__unsafe_unretained id unsafe_unretained_var[4];
|
||||
} imported_s;
|
||||
|
||||
// block variable layout: BL_UNRETAINE:4, BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"c\00"
|
||||
// CHECK: block variable layout: BL_UNRETAINED:4, BL_OPERATOR:0
|
||||
void (^c)() = ^{
|
||||
x(imported_s.unsafe_unretained_var[2]);
|
||||
};
|
||||
|
@ -143,8 +140,7 @@ void arr2() {
|
|||
__unsafe_unretained id unsafe_unretained_var[4];
|
||||
} imported_s;
|
||||
|
||||
// block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:4, BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c" c\00"
|
||||
// CHECK: block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINED:4, BL_OPERATOR:0
|
||||
void (^c)() = ^{
|
||||
x(imported_s.unsafe_unretained_var[2]);
|
||||
};
|
||||
|
@ -159,8 +155,7 @@ void arr3() {
|
|||
__unsafe_unretained id unsafe_unretained_var[0];
|
||||
} imported_s;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK: block variable layout: BL_OPERATOR:0
|
||||
void (^c)() = ^{
|
||||
int i = imported_s.a;
|
||||
};
|
||||
|
@ -186,15 +181,7 @@ void arr4() {
|
|||
} f4[2][2];
|
||||
} captured_s;
|
||||
|
||||
/**
|
||||
block variable layout: BL_UNRETAINE:3,
|
||||
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
|
||||
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
|
||||
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
|
||||
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
|
||||
BL_OPERATOR:0
|
||||
*/
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [10 x i8]
|
||||
// CHECK: block variable layout: BL_UNRETAINED:3, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
|
||||
void (^c)() = ^{
|
||||
id i = captured_s.f0.s_f1;
|
||||
};
|
||||
|
@ -212,8 +199,7 @@ void bf1() {
|
|||
int flag4: 24;
|
||||
} s;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK: block variable layout: BL_OPERATOR:0
|
||||
int (^c)() = ^{
|
||||
return s.flag;
|
||||
};
|
||||
|
@ -226,8 +212,7 @@ void bf2() {
|
|||
int flag : 1;
|
||||
} s;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK: block variable layout: BL_OPERATOR:0
|
||||
int (^c)() = ^{
|
||||
return s.flag;
|
||||
};
|
||||
|
@ -258,8 +243,7 @@ void bf3() {
|
|||
unsigned int _filler : 32;
|
||||
} _flags;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK: block variable layout: BL_OPERATOR:0
|
||||
unsigned char (^c)() = ^{
|
||||
return _flags._draggedNodesAreDeletable;
|
||||
};
|
||||
|
@ -294,8 +278,7 @@ void bf4() {
|
|||
unsigned int _filler : 32;
|
||||
} _flags;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK: block variable layout: BL_OPERATOR:0
|
||||
unsigned char (^c)() = ^{
|
||||
return _flags._draggedNodesAreDeletable;
|
||||
};
|
||||
|
@ -313,8 +296,7 @@ void bf5() {
|
|||
unsigned char flag1 : 1;
|
||||
} _flags;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK: block variable layout: BL_OPERATOR:0
|
||||
unsigned char (^c)() = ^{
|
||||
return _flags.flag;
|
||||
};
|
||||
|
@ -331,8 +313,7 @@ void bf6() {
|
|||
unsigned char flag1 : 1;
|
||||
} _flags;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK: block variable layout: BL_OPERATOR:0
|
||||
unsigned char (^c)() = ^{
|
||||
return _flags.flag;
|
||||
};
|
||||
|
@ -348,8 +329,7 @@ void Test7() {
|
|||
__weak id wid9, wid10, wid11, wid12;
|
||||
__weak id wid13, wid14, wid15, wid16;
|
||||
const id bar = (id) opaque_id();
|
||||
//block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"0_\00"
|
||||
// CHECK: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
|
||||
void (^b)() = ^{
|
||||
x(bar);
|
||||
x(wid1);
|
||||
|
@ -384,8 +364,7 @@ __weak id wid;
|
|||
__weak id w9, w10, w11, w12;
|
||||
__weak id w13, w14, w15, w16;
|
||||
const id bar = (id) opaque_id();
|
||||
// block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
|
||||
// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8]
|
||||
// CHECK: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
|
||||
void (^b)() = ^{
|
||||
x(bar);
|
||||
x(wid1);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-i386 %s
|
||||
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
|
||||
// RUN: FileCheck --input-file=%t-64.layout %s
|
||||
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
|
||||
// RUN: FileCheck -check-prefix=CHECK-i386 --input-file=%t-32.layout %s
|
||||
// rdar://12184410
|
||||
|
||||
void x(id y) {}
|
||||
|
@ -15,25 +17,22 @@ void f() {
|
|||
__block id byref_bab = (id)0;
|
||||
__block id bl_var1;
|
||||
|
||||
// Inline instruction for block variable layout: 0x0100
|
||||
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 256 }
|
||||
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 256 }
|
||||
// CHECK: Inline instruction for block variable layout: 0x0100
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x0100
|
||||
void (^b)() = ^{
|
||||
x(bar);
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x0210
|
||||
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 528 }
|
||||
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 528 }
|
||||
// CHECK: Inline instruction for block variable layout: 0x0210
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x0210
|
||||
void (^c)() = ^{
|
||||
x(bar);
|
||||
x(baz);
|
||||
byref_int = 1;
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x0230
|
||||
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 560 }
|
||||
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 560 }
|
||||
// CHECK: Inline instruction for block variable layout: 0x0230
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x0230
|
||||
void (^d)() = ^{
|
||||
x(bar);
|
||||
x(baz);
|
||||
|
@ -42,9 +41,8 @@ void f() {
|
|||
byref_bab = 0;
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x0231
|
||||
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 561 }
|
||||
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 561 }
|
||||
// CHECK: Inline instruction for block variable layout: 0x0231
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x0231
|
||||
__weak id wid;
|
||||
id (^e)() = ^{
|
||||
x(bar);
|
||||
|
@ -55,9 +53,8 @@ void f() {
|
|||
return wid;
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x0235
|
||||
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 565 }
|
||||
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 565 }
|
||||
// CHECK: Inline instruction for block variable layout: 0x0235
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x0235
|
||||
__weak id wid1, wid2, wid3, wid4;
|
||||
id (^f)() = ^{
|
||||
x(bar);
|
||||
|
@ -72,9 +69,8 @@ void f() {
|
|||
return wid;
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x035
|
||||
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 53 }
|
||||
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 53 }
|
||||
// CHECK: Inline instruction for block variable layout: 0x035
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x035
|
||||
id (^g)() = ^{
|
||||
byref_int = 1;
|
||||
bl_var1 = 0;
|
||||
|
@ -86,27 +82,41 @@ void f() {
|
|||
return wid;
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x01
|
||||
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 1 }
|
||||
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 1 }
|
||||
// CHECK: Inline instruction for block variable layout: 0x01
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x01
|
||||
id (^h)() = ^{
|
||||
return wid;
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x020
|
||||
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 32 }
|
||||
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 32 }
|
||||
// CHECK: Inline instruction for block variable layout: 0x020
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x020
|
||||
void (^ii)() = ^{
|
||||
byref_int = 1;
|
||||
byref_bab = 0;
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x0102
|
||||
// CHECK: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i64 258 }
|
||||
// CHECK-i386: i8* getelementptr inbounds ([6 x i8]* {{@.*}}, i32 0, i32 0), i32 258 }
|
||||
// CHECK: Inline instruction for block variable layout: 0x0102
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x0102
|
||||
void (^jj)() = ^{
|
||||
x(bar);
|
||||
x(wid1);
|
||||
x(wid2);
|
||||
};
|
||||
}
|
||||
|
||||
// rdar://12752901
|
||||
@class NSString;
|
||||
extern void NSLog(NSString *format, ...);
|
||||
typedef void (^dispatch_block_t)(void);
|
||||
int main() {
|
||||
__strong NSString *s1 = 0;
|
||||
__strong NSString *s2 = 0;
|
||||
__weak NSString *w1 = 0;
|
||||
|
||||
|
||||
// CHECK: Inline instruction for block variable layout: 0x0201
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x0201
|
||||
dispatch_block_t block2 = ^{
|
||||
NSLog(@"%@, %@, %@", s1, w1, s2);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -emit-llvm %s -o %t-64.s
|
||||
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
|
||||
// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
|
||||
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.layout %s
|
||||
// rdar://12184410
|
||||
// rdar://12752901
|
||||
|
||||
void x(id y) {}
|
||||
void y(int a) {}
|
||||
|
@ -32,8 +33,8 @@ void f() {
|
|||
// and a descriptor pointer).
|
||||
|
||||
// Test 1
|
||||
// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_BYREF:1, BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"@2@\00"
|
||||
// Inline instruction for block variable layout: 0x0320 (3 strong 2 byref)
|
||||
// CHECK-LP64: Inline instruction for block variable layout: 0x0320
|
||||
void (^b)() = ^{
|
||||
byref_int = sh + ch+ch1+ch2 ;
|
||||
x(bar);
|
||||
|
@ -44,8 +45,8 @@ void f() {
|
|||
b();
|
||||
|
||||
// Test 2
|
||||
// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_WEAK:1, BL_BYREF:2, BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"@2PA\00"
|
||||
// Inline instruction for block variable layout: 0x0331 (3 strong 3 byref 1 weak)
|
||||
// CHECK-LP64: Inline instruction for block variable layout: 0x0331
|
||||
void (^c)() = ^{
|
||||
byref_int = sh + ch+ch1+ch2 ;
|
||||
x(bar);
|
||||
|
@ -66,8 +67,8 @@ void g() {
|
|||
unsigned int i;
|
||||
NSString *y;
|
||||
NSString *z;
|
||||
// block variable layout: BL_STRONG:2, BL_WEAK:1, BL_STRONG:2, BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"1P1\00"
|
||||
// Inline instruction for block variable layout: 0x0401 (4 strong 0 byref 1 weak)
|
||||
// CHECK-LP64: Inline instruction for block variable layout: 0x0401
|
||||
void (^c)() = ^{
|
||||
int j = i + bletch;
|
||||
x(foo);
|
||||
|
@ -108,11 +109,7 @@ void h() {
|
|||
union U u2;
|
||||
__block id block_id;
|
||||
|
||||
/**
|
||||
block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1, BL_NON_OBJECT_WORD:1,
|
||||
BL_UNRETAINE:1, BL_NON_OBJECT_WORD:3, BL_BYREF:1, BL_OPERATOR:0
|
||||
*/
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [7 x i8] c" ` `\22@\00"
|
||||
// CHECK-LP64: block variable layout: BL_BYREF:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
|
||||
void (^c)() = ^{
|
||||
x(s2.ui.o1);
|
||||
x(u2.o1);
|
||||
|
@ -127,8 +124,7 @@ void arr1() {
|
|||
__unsafe_unretained id unsafe_unretained_var[4];
|
||||
} imported_s;
|
||||
|
||||
// block variable layout: BL_UNRETAINE:4, BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"c\00"
|
||||
// CHECK-LP64: block variable layout: BL_UNRETAINED:4, BL_OPERATOR:0
|
||||
void (^c)() = ^{
|
||||
x(imported_s.unsafe_unretained_var[2]);
|
||||
};
|
||||
|
@ -143,8 +139,7 @@ void arr2() {
|
|||
__unsafe_unretained id unsafe_unretained_var[4];
|
||||
} imported_s;
|
||||
|
||||
// block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:4, BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c" c\00"
|
||||
// CHECK-LP64: block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINED:4, BL_OPERATOR:0
|
||||
void (^c)() = ^{
|
||||
x(imported_s.unsafe_unretained_var[2]);
|
||||
};
|
||||
|
@ -159,8 +154,7 @@ void arr3() {
|
|||
__unsafe_unretained id unsafe_unretained_var[0];
|
||||
} imported_s;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK-LP64: block variable layout: BL_OPERATOR:0
|
||||
void (^c)() = ^{
|
||||
int i = imported_s.a;
|
||||
};
|
||||
|
@ -186,15 +180,7 @@ void arr4() {
|
|||
} f4[2][2];
|
||||
} captured_s;
|
||||
|
||||
/**
|
||||
block variable layout: BL_UNRETAINE:3,
|
||||
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
|
||||
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
|
||||
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
|
||||
BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
|
||||
BL_OPERATOR:0
|
||||
*/
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [10 x i8]
|
||||
// CHECK-LP64: block variable layout: BL_UNRETAINED:3, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_NON_OBJECT_WORD:1, BL_UNRETAINED:1, BL_OPERATOR:0
|
||||
void (^c)() = ^{
|
||||
id i = captured_s.f0.s_f1;
|
||||
};
|
||||
|
@ -212,8 +198,7 @@ void bf1() {
|
|||
int flag4: 24;
|
||||
} s;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK-LP64: block variable layout: BL_OPERATOR:0
|
||||
int (^c)() = ^{
|
||||
return s.flag;
|
||||
};
|
||||
|
@ -226,8 +211,7 @@ void bf2() {
|
|||
int flag : 1;
|
||||
} s;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK-LP64: block variable layout: BL_OPERATOR:0
|
||||
int (^c)() = ^{
|
||||
return s.flag;
|
||||
};
|
||||
|
@ -258,8 +242,7 @@ void bf3() {
|
|||
unsigned int _filler : 32;
|
||||
} _flags;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK-LP64: block variable layout: BL_OPERATOR:0
|
||||
unsigned char (^c)() = ^{
|
||||
return _flags._draggedNodesAreDeletable;
|
||||
};
|
||||
|
@ -294,8 +277,7 @@ void bf4() {
|
|||
unsigned int _filler : 32;
|
||||
} _flags;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK-LP64: block variable layout: BL_OPERATOR:0
|
||||
unsigned char (^c)() = ^{
|
||||
return _flags._draggedNodesAreDeletable;
|
||||
};
|
||||
|
@ -313,8 +295,7 @@ void bf5() {
|
|||
unsigned char flag1 : 1;
|
||||
} _flags;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK-LP64: block variable layout: BL_OPERATOR:0
|
||||
unsigned char (^c)() = ^{
|
||||
return _flags.flag;
|
||||
};
|
||||
|
@ -331,8 +312,7 @@ void bf6() {
|
|||
unsigned char flag1 : 1;
|
||||
} _flags;
|
||||
|
||||
// block variable layout: BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
|
||||
// CHECK-LP64: block variable layout: BL_OPERATOR:0
|
||||
unsigned char (^c)() = ^{
|
||||
return _flags.flag;
|
||||
};
|
||||
|
@ -348,8 +328,7 @@ void Test7() {
|
|||
__weak id wid9, wid10, wid11, wid12;
|
||||
__weak id wid13, wid14, wid15, wid16;
|
||||
const id bar = (id) opaque_id();
|
||||
//block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"0_\00"
|
||||
// CHECK-LP64: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
|
||||
void (^b)() = ^{
|
||||
x(bar);
|
||||
x(wid1);
|
||||
|
@ -384,8 +363,7 @@ __weak id wid;
|
|||
__weak id w9, w10, w11, w12;
|
||||
__weak id w13, w14, w15, w16;
|
||||
const id bar = (id) opaque_id();
|
||||
// block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
|
||||
// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8]
|
||||
// CHECK-LP64: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
|
||||
void (^b)() = ^{
|
||||
x(bar);
|
||||
x(wid1);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -O0 -emit-llvm %s -o %t-64.s
|
||||
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
|
||||
// RUN: %clang_cc1 -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 -check-prefix LP64 --input-file=%t-64.layout %s
|
||||
// rdar://12752901
|
||||
|
||||
struct S {
|
||||
int i1;
|
||||
|
@ -46,8 +47,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-LP64: block variable layout for block: 0x01, 0x35, 0x10, 0x00
|
||||
void (^b)() = ^{
|
||||
byref_int = sh + ch+ch1+ch2 ;
|
||||
x(bar);
|
||||
|
@ -60,7 +60,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-LP64: block variable layout for block: 0x01, 0x36, 0x10, 0x00
|
||||
void (^c)() = ^{
|
||||
byref_int = sh + ch+ch1+ch2 ;
|
||||
x(bar);
|
||||
|
@ -76,7 +76,7 @@ void f() {
|
|||
// 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-LP64: block variable layout for block: 0x01, 0x35, 0x30, 0x00
|
||||
void (^d)() = ^{
|
||||
byref_int = sh + ch+ch1+ch2 ;
|
||||
x(bar);
|
||||
|
@ -91,7 +91,7 @@ void f() {
|
|||
// Test 4
|
||||
// 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-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x11, 0x00
|
||||
struct S s2;
|
||||
void (^e)() = ^{
|
||||
x(s2.o1);
|
||||
|
@ -129,7 +129,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-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x12, 0x00
|
||||
void (^c)() = ^{
|
||||
x(s2.ui.o1);
|
||||
x(u2.o1);
|
||||
|
@ -146,7 +146,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-LP64: block variable layout for block: 0x01, 0x33, 0x00
|
||||
void (^wrapperBlock)() = ^() {
|
||||
CFRelease(singleObservationToken);
|
||||
CFRelease(singleObservationToken);
|
||||
|
@ -159,7 +159,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-LP64: block variable layout for block: 0x01, 0x00
|
||||
void (^wrapperBlock)() = ^() {
|
||||
};
|
||||
wrapperBlock();
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -O0 -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -fblocks -triple i386-apple-darwin -O0 -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-i386 %s
|
||||
// RUN: %clang_cc1 -fblocks -fobjc-runtime-has-weak -triple x86_64-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
|
||||
// RUN: FileCheck --input-file=%t-64.layout %s
|
||||
// RUN: %clang_cc1 -fblocks -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-32.layout
|
||||
// RUN: FileCheck -check-prefix=CHECK-i386 --input-file=%t-32.layout %s
|
||||
// rdar://12184410
|
||||
// rdar://12184410
|
||||
|
||||
void x(id y) {}
|
||||
|
@ -17,17 +20,15 @@ void f() {
|
|||
__block id bl_var1;
|
||||
|
||||
// block variable layout: BL_STRONG:1, BL_OPERATOR:0
|
||||
// Inline instruction for block variable layout: 0x0100
|
||||
// CHECK: internal constant{{.*}}i64 256
|
||||
// CHECK-i386: internal constant{{.*}}i32 256
|
||||
// CHECK: Inline instruction for block variable layout: 0x0100
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x0100
|
||||
void (^b)() = ^{
|
||||
x(bar);
|
||||
};
|
||||
|
||||
// block variable layout: BL_STRONG:2, BL_BYREF:1, BL_OPERATOR:0
|
||||
// Inline instruction for block variable layout: 0x0210
|
||||
// CHECK: internal constant{{.*}}i64 528
|
||||
// CHECK-i386: internal constant{{.*}}i32 528
|
||||
// CHECK: Inline instruction for block variable layout: 0x0210
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x0210
|
||||
void (^c)() = ^{
|
||||
x(bar);
|
||||
x(baz);
|
||||
|
@ -35,9 +36,8 @@ void f() {
|
|||
};
|
||||
|
||||
// block variable layout: BL_STRONG:2, BL_BYREF:3, BL_OPERATOR:0
|
||||
// Inline instruction for block variable layout: 0x0230
|
||||
// CHECK: internal constant{{.*}}i64 560
|
||||
// CHECK-i386: internal constant{{.*}}i32 560
|
||||
// CHECK: Inline instruction for block variable layout: 0x0230
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x0230
|
||||
void (^d)() = ^{
|
||||
x(bar);
|
||||
x(baz);
|
||||
|
@ -47,9 +47,8 @@ void f() {
|
|||
};
|
||||
|
||||
// block variable layout: BL_STRONG:2, BL_BYREF:3, BL_OPERATOR:0
|
||||
// Inline instruction for block variable layout: 0x0230
|
||||
// CHECK: internal constant{{.*}}i64 560
|
||||
// CHECK-i386: internal constant{{.*}}i32 560
|
||||
// CHECK: Inline instruction for block variable layout: 0x0230
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x0230
|
||||
id (^e)() = ^{
|
||||
x(bar);
|
||||
x(baz);
|
||||
|
@ -59,9 +58,8 @@ void f() {
|
|||
return wid;
|
||||
};
|
||||
|
||||
// Inline instruction for block variable layout: 0x020
|
||||
// CHECK: internal constant{{.*}}i64 32
|
||||
// CHECK-i386: internal constant{{.*}}i32 32
|
||||
// CHECK: Inline instruction for block variable layout: 0x020
|
||||
// CHECK-i386: Inline instruction for block variable layout: 0x020
|
||||
void (^ii)() = ^{
|
||||
byref_int = 1;
|
||||
byref_bab = 0;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue