15c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X64 25c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian// RUN: %clang_cc1 -fblocks -triple i686-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X32 3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -fblocks -triple arm64-apple-darwin %s -emit-llvm -o - | FileCheck %s -check-prefix=ARM64 45c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 59cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner// X64: internal constant {{.*}} { i8** @_NSConcreteGlobalBlock, i32 1879048192 6651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// X64: store i32 1610612736, i32* %want 75c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 85c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian// X32: @_NSConcreteGlobalBlock, i32 1879048192, i32 0, 95c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian// X32: store i32 1610612736, i32* %want 105c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 115c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian// rdar://7677537 12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// ARM64: @_NSConcreteGlobalBlock, i32 1342177280, i32 0, 14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// ARM64: store i32 1610612736, i32* %want 15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// rdar://9757126 17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 185c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianint printf(const char *, ...); 195c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianvoid *malloc(__SIZE_TYPE__ size); 205c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 215c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniantypedef struct bigbig { 225c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian int array[512]; 235c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian char more[32]; 245c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian} BigStruct_t; 255c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 265c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz JahanianBigStruct_t (^global)(void) = ^{ return *(BigStruct_t *)malloc(sizeof(struct bigbig)); }; 275c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 285c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianconst char * getBlockSignature(void *); 295c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 305c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz JahanianBigStruct_t foo(int param) { 315c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian BigStruct_t x; 325c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian BigStruct_t (^f)(int) = ^(int param) { 335c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian BigStruct_t *result = malloc(sizeof(BigStruct_t)); 345c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian result->array[23] = param; 355c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian return *result; 365c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian }; 375c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian getBlockSignature(f); 385c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian return x; 395c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian} 405c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 415c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianenum { 425c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian BLOCK_HAS_COPY_DISPOSE = (1 << 25), 435c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian BLOCK_HAS_CXX_OBJ = (1 << 26), 445c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian BLOCK_IS_GLOBAL = (1 << 28), 455c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian BLOCK_USE_STRET = (1 << 29), 465c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian BLOCK_HAS_OBJC_TYPE = (1 << 30) 475c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian}; 485c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 495c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianstruct block_descriptor_big { 505c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian unsigned long int reserved; 515c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian unsigned long int size; 525c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE 535c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian void (*dispose)(void *); // conditional on BLOCK_HAS_COPY_DISPOSE 545c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian const char *signature; // conditional on BLOCK_HAS_OBJC 555c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian const char *layout; // conditional on BLOCK_HAS_OBJC 565c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian}; 575c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianstruct block_descriptor_small { 585c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian unsigned long int reserved; 595c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian unsigned long int size; 605c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian const char *signature; // conditional on BLOCK_HAS_OBJC 615c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian const char *layout; // conditional on BLOCK_HAS_OBJC 625c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian}; 635c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 645c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianstruct block_layout_abi { // can't change 655c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian void *isa; 665c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian int flags; 675c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian int reserved; 685c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian void (*invoke)(void *, ...); 695c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian struct block_descriptor_big *descriptor; 705c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian}; 715c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 725c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianconst char *getBlockSignature(void *block) { 735c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian struct block_layout_abi *layout = (struct block_layout_abi *)block; 745c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian if ((layout->flags & BLOCK_HAS_OBJC_TYPE) != BLOCK_HAS_OBJC_TYPE) return 0; 755c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian if (layout->flags & BLOCK_HAS_COPY_DISPOSE) 765c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian return layout->descriptor->signature; 775c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian else 785c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian return ((struct block_descriptor_small *)layout->descriptor)->signature; 795c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian} 805c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 815c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianint usesStruct(void *block) { 825c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian struct block_layout_abi *layout = (struct block_layout_abi *)block; 835c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian int want = BLOCK_HAS_OBJC_TYPE | BLOCK_USE_STRET; 845c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian return (layout->flags & want) == want; 855c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian} 865c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 875c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 885c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianint main(int argc, char *argv[]) { 895c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian printf("desired global flags: %d\n", BLOCK_USE_STRET | BLOCK_IS_GLOBAL | BLOCK_HAS_OBJC_TYPE); 905c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian printf("desired stack flags: %d\n", BLOCK_USE_STRET | BLOCK_HAS_OBJC_TYPE); 915c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 925c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian printf("should be non-zero: %d\n", usesStruct(global)); 935c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian BigStruct_t x; 945c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian BigStruct_t (^local)(int) = ^(int param) { 955c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian BigStruct_t *result = (BigStruct_t *)malloc(sizeof(BigStruct_t)); 965c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian result->array[23] = argc; 975c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian return *result; 985c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian }; 995c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian printf("should be non-zero: %d\n", usesStruct(global)); 1005c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian printf("should be non-zero: %d\n", usesStruct(local)); 1015c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian printf("should be zero: %d\n", usesStruct(^void(int x){ })); 1025c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian return 0; 1035c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian} 1045c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 1055c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian/* 1065c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniandesired global flags: 1879048192 1075c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniandesired stack flags: 1610612736 1085c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianshould be non-zero: 1 1095c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianshould be non-zero: 1 1105c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianshould be non-zero: 1 1115c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianshould be zero: 0 1125c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian 1135c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian*/ 114