[llvm-commits] [llvm-gcc-4.2] r109702 - in /llvm-gcc-4.2/trunk/gcc: c-common.h c-decl.c c-parser.c cp/parser.c testsuite/g++.apple/blockstret.C testsuite/gcc.apple/blockstret.c

Bill Wendling isanbard at gmail.com
Wed Jul 28 16:54:15 PDT 2010


Author: void
Date: Wed Jul 28 18:54:15 2010
New Revision: 109702

URL: http://llvm.org/viewvc/llvm-project?rev=109702&view=rev
Log:
Title: BLOCKS: Need flag to indicate structure return semantics

This patch allows seamless integration of BLOCK_HAS_STRET in gcc/llvmgcc
while binaries produced by clang do the real work. libclosure will have the corresponding
changes to ignore the new fields.

Patch does:
1. Sets BLOCK_HAS_SIGNATURE always.
2. Include the `const char *signature` and `const char *layout` fields in the block descriptor.
3. Set signature=NULL and layout=NULL.

2010-07-28 Fariborz Jahanian <fjahanian at apple.com>

       Radar 8143947
       * c-decl.c (build_block_descriptor_type): Two new fields
       for 'struct __block_descriptor' type.
       * c-parser.c (build_descriptor_block_decl): Initialize new fields to 0.
       * c-common.h (BLOCK_HAS_SIGNATURE): New block flag.

       * parser.c (build_block_descriptor_type): Two new fields
       for 'struct __block_descriptor' type.
       (build_descriptor_block_decl): Initialize new fields to 0.

       gcc.apple/blockstret.c: New
       g++.apple/blockstret.C: New


Added:
    llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/blockstret.C
    llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/blockstret.c
Modified:
    llvm-gcc-4.2/trunk/gcc/c-common.h
    llvm-gcc-4.2/trunk/gcc/c-decl.c
    llvm-gcc-4.2/trunk/gcc/c-parser.c
    llvm-gcc-4.2/trunk/gcc/cp/parser.c

Modified: llvm-gcc-4.2/trunk/gcc/c-common.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-common.h?rev=109702&r1=109701&r2=109702&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/c-common.h (original)
+++ llvm-gcc-4.2/trunk/gcc/c-common.h Wed Jul 28 18:54:15 2010
@@ -1157,7 +1157,9 @@
      /* APPLE LOCAL radar 5822844 */
      BLOCK_IS_GLOBAL = 	       (1 << 28),
      /* APPLE LOCAL radar 7735196 */
-     BLOCK_USE_STRET =    (1 << 29)
+     BLOCK_USE_STRET =    (1 << 29),
+     /* APPLE LOCAL radar 8143947 */
+     BLOCK_HAS_SIGNATURE  =    (1 << 30)
 };
 
 struct block_sema_info {

Modified: llvm-gcc-4.2/trunk/gcc/c-decl.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-decl.c?rev=109702&r1=109701&r2=109702&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/c-decl.c (original)
+++ llvm-gcc-4.2/trunk/gcc/c-decl.c Wed Jul 28 18:54:15 2010
@@ -8136,6 +8136,11 @@
  // optional helper functions
  void *CopyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE is set (withCopyDispose true)
  void *DestroyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE is set (withCopyDispose true)
+
+ // APPLE LOCAL begin radar 8143947
+ const char *signature;   // the block signature
+ const char *layout;      // reserved
+ // APPLE LOCAL end radar 8143947
 } *descriptor_ptr_type;
 
 Objects of this type will always be static. This is one main component of abi change.
@@ -8174,6 +8179,16 @@
     chainon (field_decl_chain, field_decl);
   }
   
+
+  /* APPLE LOCAL begin radar 8143947 */
+  /* char * signature */
+  field_decl = build_decl (FIELD_DECL, get_identifier ("signature"), build_pointer_type (char_type_node));
+  chainon (field_decl_chain, field_decl);
+  /* char * layout */
+  field_decl = build_decl (FIELD_DECL, get_identifier ("layout"), build_pointer_type (char_type_node));
+  chainon (field_decl_chain, field_decl);
+  /* APPLE LOCAL end radar 8143947 */
+
    /* Mark this struct as being a block struct rather than a 'normal'
       struct.  */
   TYPE_BLOCK_IMPL_STRUCT (main_type) = 1;

Modified: llvm-gcc-4.2/trunk/gcc/c-parser.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-parser.c?rev=109702&r1=109701&r2=109702&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/c-parser.c (original)
+++ llvm-gcc-4.2/trunk/gcc/c-parser.c Wed Jul 28 18:54:15 2010
@@ -9428,6 +9428,10 @@
         {
           unsigned long int reserved;
 	  unsigned long int Size;
+          // APPLE LOCAL begin radar 8143927
+          const char *signature;   // the block signature
+          const char *layout;      // reserved
+          // APPLE LOCAL end radar 8143927
 	} *__descriptor;
    };
 
@@ -9488,6 +9492,10 @@
     // optional helper functions
     void *CopyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE
     void *DestroyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE 
+    // APPLE LOCAL begin radar 8143927
+    const char *signature;   // the block signature
+    const char *layout;      // reserved
+    // APPLE LOCAL end radar 8143927
  } *__descriptor;
  
  // imported variables
@@ -9590,6 +9598,10 @@
   {0, sizeof(struct literal_block_n), 
    copy_helper_block_1, // only if block BLOCK_HAS_COPY_DISPOSE
    destroy_helper_block_1, // only if block BLOCK_HAS_COPY_DISPOSE
+   // APPLE LOCAL begin radar 8143947
+   // const char *signature;   // the block signature set to 0
+   // const char *layout;      // reserved set to 0
+   // APPLE LOCAL end radar 8143947 
   }
 */
 static tree
@@ -9638,6 +9650,19 @@
       helper_addr = convert (ptr_type_node, helper_addr);
       initlist = tree_cons (fields, helper_addr, initlist);
     }
+  /* APPLE LOCAL begin radar 8143947 */
+  /* signature field is set to 0 */
+  fields = TREE_CHAIN (fields);
+  initlist = tree_cons (fields,
+                        build_int_cst (build_pointer_type (char_type_node), 0),
+                        initlist);
+  /* layout field is set to 0 */
+  fields = TREE_CHAIN (fields);
+  initlist = tree_cons (fields,
+                        build_int_cst (build_pointer_type (char_type_node), 0),
+                        initlist);
+  /* APPLE LOCAL end radar 8143947 */
+  
   constructor = build_constructor_from_list (descriptor_type,
                                              nreverse (initlist));
   TREE_CONSTANT (constructor) = 1;
@@ -9658,6 +9683,7 @@
  build_block_struct_initlist - builds the initializer list:
  { &_NSConcreteStackBlock or &_NSConcreteGlobalBlock // __isa,
    BLOCK_USE_STRET | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags,
+   | BLOCK_HAS_SIGNATURE // __flags
    0, // __reserved
    &helper_1, // __FuncPtr,
    &static_descriptor_variable // __descriptor,
@@ -9673,7 +9699,7 @@
   tree initlist, helper_addr;
   tree chain, fields;
   /* APPLE LOCAL radar 7735196 */
-  unsigned int flags = 0;
+  unsigned int flags = BLOCK_HAS_SIGNATURE;
   static tree NSConcreteStackBlock_decl = NULL_TREE;
   static tree NSConcreteGlobalBlock_decl = NULL_TREE;
   tree descriptor_block_decl = build_descriptor_block_decl (block_struct_type, block_impl);
@@ -9819,6 +9845,10 @@
     // optional helper functions
     void *CopyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE
     void *DestroyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE
+    // APPLE LOCAL begin radar 8143927
+    const char *signature;   // the block signature
+    const char *layout;      // reserved
+    // APPLE LOCAL end radar 8143927
  } *__descriptor;
 
  // imported variables
@@ -9833,6 +9863,7 @@
  struct __block_literal_n I = {
    &_NSConcreteStackBlock or &_NSConcreteGlobalBlock // __isa,
    BLOCK_USE_STRET | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags,
+   | BLOCK_HAS_SIGNATURE // __flags
    0, // __reserved
    &helper_1, // __FuncPtr 
    &static_descriptor_variable // __descriptor,

Modified: llvm-gcc-4.2/trunk/gcc/cp/parser.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/parser.c?rev=109702&r1=109701&r2=109702&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/cp/parser.c (original)
+++ llvm-gcc-4.2/trunk/gcc/cp/parser.c Wed Jul 28 18:54:15 2010
@@ -20599,6 +20599,10 @@
   {0, sizeof(struct literal_block_n), 
    copy_helper_block_1, // only if block BLOCK_HAS_COPY_DISPOSE
    destroy_helper_block_1, // only if block BLOCK_HAS_COPY_DISPOSE
+   // APPLE LOCAL begin radar 8143947
+   // const char *signature;   // the block signature set to 0
+   // const char *layout;      // reserved set to 0
+   // APPLE LOCAL end radar 8143947
   }
 */
 static tree
@@ -20641,6 +20645,15 @@
       helper_addr = convert (ptr_type_node, helper_addr);
       CONSTRUCTOR_APPEND_ELT(impl_v, NULL_TREE, helper_addr);
     }
+  /* APPLE LOCAL begin radar 8143947 */
+  /* signature field is set to 0 */
+  CONSTRUCTOR_APPEND_ELT(impl_v, NULL_TREE, 
+                         build_int_cst (build_pointer_type (char_type_node), 0));
+  /* layout field is set to 0 */
+  CONSTRUCTOR_APPEND_ELT(impl_v, NULL_TREE, 
+                         build_int_cst (build_pointer_type (char_type_node), 0));
+  /* APPLE LOCAL end radar 8143947 */
+
   /* Create a CONSTRUCTOR to represent the braced-initializer.  */
   constructor = make_node (CONSTRUCTOR);
   CONSTRUCTOR_ELTS (constructor) = impl_v;
@@ -20673,6 +20686,10 @@
         {
           unsigned long int reserved;
 	  unsigned long int Size;
+          // APPLE LOCAL begin radar 8143927
+          const char *signature;   // the block signature
+          const char *layout;      // reserved
+          // APPLE LOCAL end radar 8143927
 	} *__descriptor;
    };
 
@@ -20872,6 +20889,7 @@
  build_block_struct_initlist - builds the initializer list:
  { &_NSConcreteStackBlock or &_NSConcreteGlobalBlock // __isa,
    BLOCK_USE_STRET | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags,
+   | BLOCK_HAS_SIGNATURE // __flags
    0, // __reserved,
    &helper_1, // __FuncPtr,
    &static_descriptor_variable // __descriptor,
@@ -20889,7 +20907,7 @@
 {
   tree expr, chain, helper_addr;
   /* APPLE LOCAL radar 7735196 */
-  unsigned flags = 0;
+  unsigned flags = BLOCK_HAS_SIGNATURE;
   static tree NSConcreteStackBlock_decl = NULL_TREE;
   static tree NSConcreteGlobalBlock_decl = NULL_TREE;
   VEC(constructor_elt,gc) *impl_v = NULL;
@@ -21882,6 +21900,10 @@
  // optional helper functions
  void *CopyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE is set (withCopyDispose true)
  void *DestroyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE is set (withCopyDispose true)
+ // APPLE LOCAL begin radar 8143947
+ const char *signature;   // the block signature
+ const char *layout;      // reserved
+ // APPLE LOCAL end radar 8143947
 } *descriptor_ptr_type;
 
 Objects of this type will always be static. This is one main component of abi change.
@@ -21922,6 +21944,17 @@
     field_decl_chain = field_decl;
   }
 
+  /* APPLE LOCAL begin radar 8143947 */
+  /* char * signature */
+  field_decl = build_decl (FIELD_DECL, get_identifier ("signature"), build_pointer_type (char_type_node));
+  TREE_CHAIN (field_decl) = field_decl_chain;
+  field_decl_chain = field_decl;
+  /* char * layout */
+  field_decl = build_decl (FIELD_DECL, get_identifier ("layout"), build_pointer_type (char_type_node));
+  TREE_CHAIN (field_decl) = field_decl_chain;
+  field_decl_chain = field_decl;
+  /* APPLE LOCAL end radar 8143947 */
+
    /* Mark this struct as being a block struct rather than a 'normal'
       struct.  */
   TYPE_BLOCK_IMPL_STRUCT (main_type) = 1;

Added: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/blockstret.C
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/blockstret.C?rev=109702&view=auto
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/blockstret.C (added)
+++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/blockstret.C Wed Jul 28 18:54:15 2010
@@ -0,0 +1,102 @@
+/* APPLE LOCAL file radar 8241648 */
+/* { dg-do run { target *-*-darwin[1-2][0-9]* } } */
+/* { dg-options "-mmacosx-version-min=10.6 -fblocks" { target *-*-darwin* } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } } */
+
+// rdar://8241648
+extern "C" void *malloc(__SIZE_TYPE__ size);
+extern "C" void abort (void);
+
+typedef struct bigbig {
+   int array[512];
+   char more[32];
+} BigStruct_t;
+
+BigStruct_t (^global)(void) = ^{ return *(BigStruct_t *)malloc(sizeof(struct bigbig)); };
+
+const char * getBlockSignature(void *);
+ 
+BigStruct_t foo(int param) {
+   BigStruct_t x;
+   BigStruct_t (^f)(int) = ^(int param) {
+     BigStruct_t *result = (BigStruct_t *)malloc(sizeof(BigStruct_t));
+     result->array[23] = param;
+     return *result;
+   };
+   getBlockSignature(f);
+   return x;
+}
+
+enum {
+    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+    BLOCK_HAS_CXX_OBJ =       (1 << 26),
+    BLOCK_IS_GLOBAL =         (1 << 28),
+    BLOCK_USE_STRET =    (1 << 29),
+    BLOCK_HAS_OBJC_TYPE  =    (1 << 30)
+};
+
+struct block_descriptor_big {
+    unsigned long int reserved;
+    unsigned long int size;
+    void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE
+    void (*dispose)(void *);            // conditional on BLOCK_HAS_COPY_DISPOSE
+    const char *signature;                  // conditional on BLOCK_HAS_OBJC
+    const char *layout;                 // conditional on BLOCK_HAS_OBJC
+};
+struct block_descriptor_small {
+    unsigned long int reserved;
+    unsigned long int size;
+    const char *signature;              // conditional on BLOCK_HAS_OBJC
+    const char *layout;                 // conditional on BLOCK_HAS_OBJC
+};
+
+struct block_layout_abi { // can't change
+  void *isa;
+  int flags;
+  int reserved; 
+  void (*invoke)(void *, ...);
+  struct block_descriptor_big *descriptor;
+};
+
+const char *getBlockSignature(void *block) {
+   struct block_layout_abi *layout = (struct block_layout_abi *)block;
+   if ((layout->flags & BLOCK_HAS_OBJC_TYPE) != BLOCK_HAS_OBJC_TYPE) return 0;
+   if (layout->flags & BLOCK_HAS_COPY_DISPOSE) 
+      return layout->descriptor->signature;
+   else
+      return ((struct block_descriptor_small *)layout->descriptor)->signature;
+}
+
+int usesStruct(void *block) {
+   struct block_layout_abi *layout = (struct block_layout_abi *)block;
+   int want = BLOCK_HAS_OBJC_TYPE | BLOCK_USE_STRET;
+   return (layout->flags & want) == want;
+}
+
+int main(int argc, char *argv[]) {
+   if (!usesStruct(global))
+     abort();
+   BigStruct_t x;
+   BigStruct_t (^local)(int) = ^(int param) {
+     BigStruct_t *result = (BigStruct_t *)malloc(sizeof(BigStruct_t));
+     result->array[23] = argc;
+     return *result;
+   };
+   if (!usesStruct(global))
+     abort();
+   if (!usesStruct(local))
+     abort();
+   if (usesStruct(^void(int x){ }))
+     abort();
+   return 0;
+}
+
+/*
+desired global flags: 1879048192
+desired stack flags: 1610612736
+should be non-zero: 1
+should be non-zero: 1
+should be non-zero: 1
+should be zero: 0
+
+*/

Added: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/blockstret.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/blockstret.c?rev=109702&view=auto
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/blockstret.c (added)
+++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/blockstret.c Wed Jul 28 18:54:15 2010
@@ -0,0 +1,102 @@
+/* APPLE LOCAL file radar 8241648 */
+/* { dg-do run { target *-*-darwin[1-2][0-9]* } } */
+/* { dg-options "-mmacosx-version-min=10.6 -fblocks" { target *-*-darwin* } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } } */
+
+// rdar://8241648
+void *malloc(__SIZE_TYPE__ size);
+extern void abort (void);
+
+typedef struct bigbig {
+   int array[512];
+   char more[32];
+} BigStruct_t;
+
+BigStruct_t (^global)(void) = ^{ return *(BigStruct_t *)malloc(sizeof(struct bigbig)); };
+
+const char * getBlockSignature(void *);
+ 
+BigStruct_t foo(int param) {
+   BigStruct_t x;
+   BigStruct_t (^f)(int) = ^(int param) {
+     BigStruct_t *result = (BigStruct_t *)malloc(sizeof(BigStruct_t));
+     result->array[23] = param;
+     return *result;
+   };
+   getBlockSignature(f);
+   return x;
+}
+
+enum {
+    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+    BLOCK_HAS_CXX_OBJ =       (1 << 26),
+    BLOCK_IS_GLOBAL =         (1 << 28),
+    BLOCK_USE_STRET =    (1 << 29),
+    BLOCK_HAS_OBJC_TYPE  =    (1 << 30)
+};
+
+struct block_descriptor_big {
+    unsigned long int reserved;
+    unsigned long int size;
+    void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE
+    void (*dispose)(void *);            // conditional on BLOCK_HAS_COPY_DISPOSE
+    const char *signature;                  // conditional on BLOCK_HAS_OBJC
+    const char *layout;                 // conditional on BLOCK_HAS_OBJC
+};
+struct block_descriptor_small {
+    unsigned long int reserved;
+    unsigned long int size;
+    const char *signature;              // conditional on BLOCK_HAS_OBJC
+    const char *layout;                 // conditional on BLOCK_HAS_OBJC
+};
+
+struct block_layout_abi { // can't change
+  void *isa;
+  int flags;
+  int reserved; 
+  void (*invoke)(void *, ...);
+  struct block_descriptor_big *descriptor;
+};
+
+const char *getBlockSignature(void *block) {
+   struct block_layout_abi *layout = (struct block_layout_abi *)block;
+   if ((layout->flags & BLOCK_HAS_OBJC_TYPE) != BLOCK_HAS_OBJC_TYPE) return 0;
+   if (layout->flags & BLOCK_HAS_COPY_DISPOSE) 
+      return layout->descriptor->signature;
+   else
+      return ((struct block_descriptor_small *)layout->descriptor)->signature;
+}
+
+int usesStruct(void *block) {
+   struct block_layout_abi *layout = (struct block_layout_abi *)block;
+   int want = BLOCK_HAS_OBJC_TYPE | BLOCK_USE_STRET;
+   return (layout->flags & want) == want;
+}
+
+int main(int argc, char *argv[]) {
+   if (!usesStruct(global))
+     abort();
+   BigStruct_t x;
+   BigStruct_t (^local)(int) = ^(int param) {
+     BigStruct_t *result = (BigStruct_t *)malloc(sizeof(BigStruct_t));
+     result->array[23] = argc;
+     return *result;
+   };
+   if (!usesStruct(global))
+     abort();
+   if (!usesStruct(local))
+     abort();
+   if (usesStruct(^void(int x){ }))
+     abort();
+   return 0;
+}
+
+/*
+desired global flags: 1879048192
+desired stack flags: 1610612736
+should be non-zero: 1
+should be non-zero: 1
+should be non-zero: 1
+should be zero: 0
+
+*/





More information about the llvm-commits mailing list