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
35c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
41257bc6ee76b931e3f8e51a88298b95379963d24Rafael Espindola// X64: @.str = private unnamed_addr constant [6 x i8] c"v8@?0\00"
59cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner// X64: @__block_literal_global = internal constant {{.*}} { i8** @_NSConcreteGlobalBlock, i32 1342177280,
61257bc6ee76b931e3f8e51a88298b95379963d24Rafael Espindola// X64: @.str1 = private unnamed_addr constant [12 x i8] c"i16@?0c8f12\00"
75c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian// X64:   store i32 1073741824, i32*
85c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
96b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall// X32: [[STR1:@.*]] = private unnamed_addr constant [6 x i8] c"v4@?0\00"
109cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner// X32: @__block_descriptor_tmp = internal constant [[FULL_DESCRIPTOR_T:.*]] { i32 0, i32 20, i8* getelementptr inbounds ([6 x i8]* [[STR1]], i32 0, i32 0), i8* null }
119cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner// X32: @__block_literal_global = internal constant [[GLOBAL_LITERAL_T:.*]] { i8** @_NSConcreteGlobalBlock, i32 1342177280, i32 0, i8* bitcast (void (i8*)* @__block_global_{{.*}} to i8*), [[DESCRIPTOR_T:%.*]]* bitcast ([[FULL_DESCRIPTOR_T]]* @__block_descriptor_tmp to {{%.*}}*) }
126b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall// X32: [[STR2:@.*]] = private unnamed_addr constant [11 x i8] c"i12@?0c4f8\00"
136b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall// X32: @__block_descriptor_tmp{{.*}} = internal constant [[FULL_DESCRIPTOR_T]] { i32 0, i32 24, i8* getelementptr inbounds ([11 x i8]* [[STR2]], i32 0, i32 0), i8* null }
145c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian// X32:   store i32 1073741824, i32*
155c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
165c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian// rdar://7635294
175c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
185c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
195c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianint globalInt;
205c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianvoid (^global)(void) = ^{ ++globalInt; };
215c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
225c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
235c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianvoid foo(int param) {
245c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   extern int rand(void);
255c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   extern void rand_r(int (^b)(char x, float y));   // name a function present at runtime
265c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   while (param--)
275c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian      rand_r(^(char x, float y){ return x + (int)y + param + rand(); });  // generate a local block binding param
285c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian}
295c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
305c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian#if 0
315c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian#include <stdio.h>
325c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianenum {
335c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
345c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    BLOCK_HAS_CXX_OBJ =       (1 << 26),
355c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    BLOCK_IS_GLOBAL =         (1 << 28),
365c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    BLOCK_HAS_DESCRIPTOR =    (1 << 29),
375c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    BLOCK_HAS_OBJC_TYPE  =    (1 << 30)
385c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian};
395c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
405c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianstruct block_descriptor_big {
415c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    unsigned long int reserved;
425c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    unsigned long int size;
435c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE
445c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    void (*dispose)(void *);            // conditional on BLOCK_HAS_COPY_DISPOSE
455c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    const char *signature;                  // conditional on BLOCK_HAS_OBJC
465c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    const char *layout;                 // conditional on BLOCK_HAS_OBJC
475c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian};
485c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianstruct block_descriptor_small {
495c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    unsigned long int reserved;
505c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    unsigned long int size;
515c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    const char *signature;              // conditional on BLOCK_HAS_OBJC
525c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian    const char *layout;                 // conditional on BLOCK_HAS_OBJC
535c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian};
545c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
555c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianstruct block_layout_abi { // can't change
565c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian  void *isa;
575c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian  int flags;
585c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian  int reserved;
595c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian  void (*invoke)(void *, ...);
605c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian  struct block_descriptor_big *descriptor;
615c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian};
625c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
635c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianconst char *getBlockSignature(void *block) {
645c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   struct block_layout_abi *layout = (struct block_layout_abi *)block;
655c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   if ((layout->flags & BLOCK_HAS_OBJC_TYPE) != BLOCK_HAS_OBJC_TYPE) return NULL;
665c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   if (layout->flags & BLOCK_HAS_COPY_DISPOSE)
675c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian      return layout->descriptor->signature;
685c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   else
695c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian      return ((struct block_descriptor_small *)layout->descriptor)->signature;
705c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian}
715c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
725c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
735c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
745c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianint main(int argc, char *argv[]) {
755c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   printf("desired global flags: %d\n", BLOCK_IS_GLOBAL  | BLOCK_HAS_OBJC_TYPE);
765c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   printf("desired stack flags: %d\n",  BLOCK_HAS_OBJC_TYPE);
775c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
785c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   printf("types for global: %s\n", getBlockSignature(global));
795c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   printf("types for local: %s\n", getBlockSignature(^int(char x, float y) { return (int)(y + x); }));
805c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian   return 0;
815c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian}
825c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
835c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian/*
845c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanianx86_64
855c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniandesired global flags: 1342177280
865c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniandesired stack flags: 1073741824
875c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniantypes for global: v8@?0
885c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniantypes for local: i16@?0c8f12
895c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian
905c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniani386
915c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniandesired global flags: 1342177280
925c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniandesired stack flags: 1073741824
935c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniantypes for global: v4@?0
945c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahaniantypes for local: i12@?0c4f8
955c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian*/
965c8e13ffa8ab3d9d6f17717f9ce679382fc2ba5dFariborz Jahanian#endif
97