Unconditionally support block introspection data in a new field at the end
of the block descriptor field.  This field is the ObjC style @encode
signature of the implementation function, and was to this point
conditionally provided in the block literal data structure.  That
provisional support is removed.

Additionally, eliminate unused enumerations for the block literal flags field.
The first shipping ABI unconditionally set (1<<29) but this bit is unused
by the runtime, so the second ABI will unconditionally have (1<<30) set so
that the runtime can in fact distinguish whether the additional data is
present or not.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96989 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index c6c5d5a..7076067 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -24,7 +24,7 @@
 using namespace CodeGen;
 
 llvm::Constant *CodeGenFunction::
-BuildDescriptorBlockDecl(bool BlockHasCopyDispose, CharUnits Size,
+BuildDescriptorBlockDecl(const BlockExpr *BE, bool BlockHasCopyDispose, CharUnits Size,
                          const llvm::StructType* Ty,
                          std::vector<HelperInfo> *NoteForHelper) {
   const llvm::Type *UnsignedLongTy
@@ -43,6 +43,7 @@
   C = llvm::ConstantInt::get(UnsignedLongTy, Size.getQuantity());
   Elts.push_back(C);
 
+  // optional copy/dispose helpers
   if (BlockHasCopyDispose) {
     // copy_func_helper_decl
     Elts.push_back(BuildCopyHelper(Ty, NoteForHelper));
@@ -51,6 +52,17 @@
     Elts.push_back(BuildDestroyHelper(Ty, NoteForHelper));
   }
 
+  // Signature.  non-optional ObjC-style method descriptor @encode sequence
+  std::string BlockTypeEncoding;
+  CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding);
+
+  Elts.push_back(llvm::ConstantExpr::getBitCast(
+          CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty));
+  
+  // Layout.
+  C = llvm::ConstantInt::get(UnsignedLongTy, 0);
+  Elts.push_back(C);
+
   C = llvm::ConstantStruct::get(VMContext, Elts, false);
 
   C = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
@@ -135,30 +147,14 @@
 
   size_t BlockFields = 5;
 
-  bool hasIntrospection  = CGM.getContext().getLangOptions().BlockIntrospection;
-
-  if (hasIntrospection) {
-    BlockFields++;
-  }
   std::vector<llvm::Constant*> Elts(BlockFields);
 
-  if (hasIntrospection) {
-    std::string BlockTypeEncoding;
-    CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding);
-
-    Elts[5] = llvm::ConstantExpr::getBitCast(
-            CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty);
-  }
-
   llvm::Constant *C;
   llvm::Value *V;
 
   {
     // C = BuildBlockStructInitlist();
-    unsigned int flags = BLOCK_HAS_DESCRIPTOR;
-
-    if (hasIntrospection)
-      flags |= BLOCK_HAS_OBJC_TYPE;
+    unsigned int flags = BLOCK_HAS_OBJC_TYPE;
 
     // We run this first so that we set BlockHasCopyDispose from the entire
     // block literal.
@@ -199,7 +195,7 @@
 
     if (subBlockDeclRefDecls.size() == 0) {
       // __descriptor
-      Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize,
+      Elts[4] = BuildDescriptorBlockDecl(BE, subBlockHasCopyDispose, subBlockSize,
                                          0, 0);
 
       // Optimize to being a global block.
@@ -221,8 +217,6 @@
     for (int i=0; i<4; ++i)
       Types[i] = Elts[i]->getType();
     Types[4] = PtrToInt8Ty;
-    if (hasIntrospection)
-      Types[5] = PtrToInt8Ty;
 
     for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i) {
       const Expr *E = subBlockDeclRefDecls[i];
@@ -245,8 +239,6 @@
 
     for (unsigned i=0; i<4; ++i)
       Builder.CreateStore(Elts[i], Builder.CreateStructGEP(V, i, "block.tmp"));
-    if (hasIntrospection)
-      Builder.CreateStore(Elts[5], Builder.CreateStructGEP(V, 5, "block.tmp"));
 
     for (unsigned i=0; i < subBlockDeclRefDecls.size(); ++i)
       {
@@ -335,7 +327,8 @@
     NoteForHelper.resize(helpersize);
 
     // __descriptor
-    llvm::Value *Descriptor = BuildDescriptorBlockDecl(subBlockHasCopyDispose,
+    llvm::Value *Descriptor = BuildDescriptorBlockDecl(BE,
+                                                       subBlockHasCopyDispose,
                                                        subBlockSize, Ty,
                                                        &NoteForHelper);
     Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty);
@@ -371,6 +364,16 @@
   // struct __block_descriptor {
   //   unsigned long reserved;
   //   unsigned long block_size;
+  //
+  //   // later, the following will be added
+  //
+  //   struct {
+  //     void (*copyHelper)();
+  //     void (*copyHelper)();
+  //   } helpers;                // !!! optional
+  //
+  //   const char *signature;   // the block signature
+  //   const char *layout;      // reserved
   // };
   BlockDescriptorType = llvm::StructType::get(UnsignedLongTy->getContext(),
                                               UnsignedLongTy,
@@ -399,20 +402,8 @@
   //   int __reserved;
   //   void (*__invoke)(void *);
   //   struct __block_descriptor *__descriptor;
-  //   // GNU runtime only:
-  //   const char *types;
   // };
-  if (CGM.getContext().getLangOptions().BlockIntrospection)
-    GenericBlockLiteralType = llvm::StructType::get(IntTy->getContext(),
-                                                  PtrToInt8Ty,
-                                                  IntTy,
-                                                  IntTy,
-                                                  PtrToInt8Ty,
-                                                  BlockDescPtrTy,
-                                                  PtrToInt8Ty,
-                                                  NULL);
-  else
-    GenericBlockLiteralType = llvm::StructType::get(IntTy->getContext(),
+  GenericBlockLiteralType = llvm::StructType::get(IntTy->getContext(),
                                                   PtrToInt8Ty,
                                                   IntTy,
                                                   IntTy,
@@ -556,7 +547,7 @@
   const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
     getTypes().ConvertType(getContext().IntTy));
 
-  llvm::Constant *DescriptorFields[2];
+  llvm::Constant *DescriptorFields[4];
 
   // Reserved
   DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy);
@@ -567,9 +558,21 @@
     CGM.GetTargetTypeStoreSize(getGenericBlockLiteralType());
   DescriptorFields[1] =
     llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize.getQuantity());
+  
+  // signature.  non-optional ObjC-style method descriptor @encode sequence
+  std::string BlockTypeEncoding;
+  CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding);
 
+  DescriptorFields[2] = llvm::ConstantExpr::getBitCast(
+          CGM.GetAddrOfConstantCString(BlockTypeEncoding), PtrToInt8Ty);
+  
+  // layout
+  DescriptorFields[3] =
+    llvm::ConstantInt::get(UnsignedLongTy,0);
+
+  // build the structure from the 4 elements
   llvm::Constant *DescriptorStruct =
-    llvm::ConstantStruct::get(VMContext, &DescriptorFields[0], 2, false);
+    llvm::ConstantStruct::get(VMContext, &DescriptorFields[0], 4, false);
 
   llvm::GlobalVariable *Descriptor =
     new llvm::GlobalVariable(getModule(), DescriptorStruct->getType(), true,
@@ -578,8 +581,6 @@
 
   int FieldCount = 5;
   // Generate the constants for the block literal.
-  if (CGM.getContext().getLangOptions().BlockIntrospection)
-    FieldCount = 6;
 
   std::vector<llvm::Constant*> LiteralFields(FieldCount);
 
@@ -602,10 +603,8 @@
   LiteralFields[0] = getNSConcreteGlobalBlock();
 
   // Flags
-  LiteralFields[1] = CGM.getContext().getLangOptions().BlockIntrospection ?
-    llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_DESCRIPTOR |
-            BLOCK_HAS_OBJC_TYPE) :
-    llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_DESCRIPTOR);
+  LiteralFields[1] =
+    llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL | BLOCK_HAS_OBJC_TYPE);
 
   // Reserved
   LiteralFields[2] = llvm::Constant::getNullValue(IntTy);
@@ -616,14 +615,6 @@
   // Descriptor
   LiteralFields[4] = Descriptor;
   
-  // Type encoding
-  if (CGM.getContext().getLangOptions().BlockIntrospection) {
-    std::string BlockTypeEncoding;
-    CGM.getContext().getObjCEncodingForBlock(BE, BlockTypeEncoding);
-
-    LiteralFields[5] = CGM.GetAddrOfConstantCString(BlockTypeEncoding);
-  }
-
   llvm::Constant *BlockLiteralStruct =
     llvm::ConstantStruct::get(VMContext, LiteralFields, false);