Fix and stylize the emission of GC/ARC ivar and GC block layout strings.

Specifically, handle under-aligned object references (by explicitly
ignoring them, because this just isn't representable in the format;
yes, this means that GC silently ignores such references), descend
into anonymous structs and unions, stop classifying fields of
pointer-to-strong/weak type as strong/weak in ARC mode, and emit
skips to cover the entirety of block layouts in GC mode.  As a
cleanup, extract this code into a helper class, avoid a number of
unnecessary copies and layout queries, generate skips implicitly
instead of explicitly tracking them, and clarify the bitmap-creation
logic.

llvm-svn: 250919
This commit is contained in:
John McCall 2015-10-21 18:06:47 +00:00
parent b04ecb753a
commit 3fd13f0665
4 changed files with 470 additions and 415 deletions

File diff suppressed because it is too large Load Diff

View File

@ -159,7 +159,7 @@ void notifyBlock(id dependentBlock) {
void test_empty_block() {
// 01 00
// CHECK-LP64: block variable layout for block: 0x01, 0x00
// CHECK-LP64: block variable layout for block: 0x01, 0x30, 0x00
void (^wrapperBlock)() = ^() {
};
wrapperBlock();

View File

@ -112,3 +112,50 @@ typedef unsigned int FSCatalogInfoBitmap;
// CHECK: @OBJC_CLASS_NAME_{{.*}} = private global {{.*}} c"\02\10\00"
@implementation Foo @end
// GC layout strings aren't capable of expressing __strong ivars at
// non-word alignments.
struct __attribute__((packed)) PackedStruct {
char c;
__strong id x;
};
@interface Packed : NSObject {
struct PackedStruct _packed;
}
@end
@implementation Packed @end
// CHECK: @OBJC_CLASS_NAME_{{.*}} = private global {{.*}} c"Packed\00"
// CHECK: @OBJC_CLASS_NAME_{{.*}} = private global {{.*}} c"\01 \00"
// ' ' == 0x20
// Ensure that layout descends into anonymous unions and structs.
// Hilariously, anonymous unions and structs that appear directly as ivars
// are completely ignored by layout.
@interface AnonymousUnion : NSObject {
struct {
union {
id _object;
void *_ptr;
};
} a;
}
@end
@implementation AnonymousUnion @end
// CHECK: @OBJC_CLASS_NAME_{{.*}} = private global {{.*}} c"AnonymousUnion\00"
// CHECK: @OBJC_CLASS_NAME_{{.*}} = private global {{.*}} c"\02\00"
@interface AnonymousStruct : NSObject {
struct {
struct {
id _object;
__weak id _weakref;
};
} a;
}
@end
@implementation AnonymousStruct @end
// CHECK: @OBJC_CLASS_NAME_{{.*}} = private global {{.*}} c"AnonymousStruct\00"
// CHECK: @OBJC_CLASS_NAME_{{.*}} = private global {{.*}} c"\02\10\00"
// CHECK: @OBJC_CLASS_NAME_{{.*}} = private global {{.*}} c"!\00"
// '!' == 0x21

View File

@ -151,7 +151,7 @@ void notifyBlock(id dependentBlock) {
void test_empty_block() {
// 01 00
// CHECK: block variable layout for block: 0x01, 0x00
// CHECK: block variable layout for block: 0x01, 0x30, 0x00
void (^wrapperBlock)() = ^() {
};
wrapperBlock();