]> granicus.if.org Git - clang/commitdiff
More codegen for blocks. The type of block literals should be better.
authorMike Stump <mrs@apple.com>
Thu, 19 Feb 2009 01:01:04 +0000 (01:01 +0000)
committerMike Stump <mrs@apple.com>
Thu, 19 Feb 2009 01:01:04 +0000 (01:01 +0000)
The size calculation is improved.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64994 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
lib/CodeGen/CGBlocks.cpp
lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CodeGenModule.h

index ee698d6c93fb07df747482012559b4fda12dff07..d573236783eaf1155fda5ef08291f8c5fef30668 100644 (file)
@@ -260,6 +260,7 @@ public:
   APValue VisitAddrLabelExpr(AddrLabelExpr *E)
       { return APValue(E, 0); }
   APValue VisitCallExpr(CallExpr *E);
+  APValue VisitBlockExpr(BlockExpr *E) { return APValue(E, 0); }
   APValue VisitConditionalOperator(ConditionalOperator *E);
 };
 } // end anonymous namespace
index 4a940960730e5778c916607021e9d17dd241de4b..9a130d7bc0e0fd7c2c1160bf97281b8f500c0796 100644 (file)
@@ -46,8 +46,13 @@ llvm::Constant *CodeGenFunction::BuildDescriptorBlockDecl() {
   Elts.push_back(C);
 
   // Size
-  int sz = CGM.getTargetData()
-    .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8;
+  int sz;
+  if (!BlockHasCopyDispose)
+    sz = CGM.getTargetData()
+      .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8;
+  else
+    sz = CGM.getTargetData()
+      .getTypeStoreSizeInBits(CGM.getGenericExtendedBlockLiteralType()) / 8;
   C = llvm::ConstantInt::get(UnsignedLongTy, sz);
   Elts.push_back(C);
 
@@ -107,6 +112,8 @@ llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {
   return NSConcreteStackBlock;
 }
 
+// FIXME: Push most into CGM, passing down a few bits, like current
+// function name.
 llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
   // FIXME: Push up
   bool BlockHasCopyDispose = false;
@@ -146,7 +153,7 @@ llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
     C = llvm::ConstantInt::get(IntTy, 0);
     Elts.push_back(C);
 
-    // __FuncPtr
+    // __invoke
     const char *Name = "";
     if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurFuncDecl))
       if (ND->getIdentifier())
@@ -168,6 +175,8 @@ llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
   C = new llvm::GlobalVariable(C->getType(), true,
                                llvm::GlobalValue::InternalLinkage,
                                C, Name, &CGM.getModule());
+  QualType BPT = BE->getType();
+  C = llvm::ConstantExpr::getBitCast(C, ConvertType(BPT));
   return C;
 }
 
@@ -210,11 +219,11 @@ CodeGenModule::getGenericBlockLiteralType() {
     getTypes().ConvertType(getContext().IntTy));
 
   // struct __block_literal_generic {
-  //   void *isa;
-  //   int flags;
-  //   int reserved;
-  //   void (*invoke)(void *);
-  //   struct __block_descriptor *descriptor;
+  //   void *__isa;
+  //   int __flags;
+  //   int __reserved;
+  //   void (*__invoke)(void *);
+  //   struct __block_descriptor *__descriptor;
   // };
   GenericBlockLiteralType = llvm::StructType::get(Int8PtrTy,
                                                   IntTy,
@@ -229,6 +238,44 @@ CodeGenModule::getGenericBlockLiteralType() {
   return GenericBlockLiteralType;
 }
 
+const llvm::Type *
+CodeGenModule::getGenericExtendedBlockLiteralType() {
+  if (GenericExtendedBlockLiteralType)
+    return GenericExtendedBlockLiteralType;
+
+  const llvm::Type *Int8PtrTy =
+    llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+
+  const llvm::Type *BlockDescPtrTy =
+    llvm::PointerType::getUnqual(getBlockDescriptorType());
+
+  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
+    getTypes().ConvertType(getContext().IntTy));
+
+  // struct __block_literal_generic {
+  //   void *__isa;
+  //   int __flags;
+  //   int __reserved;
+  //   void (*__invoke)(void *);
+  //   struct __block_descriptor *__descriptor;
+  //   void *__copy_func_helper_decl;
+  //   void *__destroy_func_decl;
+  // };
+  GenericExtendedBlockLiteralType = llvm::StructType::get(Int8PtrTy,
+                                                          IntTy,
+                                                          IntTy,
+                                                          Int8PtrTy,
+                                                          BlockDescPtrTy,
+                                                          Int8PtrTy,
+                                                          Int8PtrTy,
+                                                          NULL);
+
+  getModule().addTypeName("struct.__block_literal_extended_generic",
+                          GenericExtendedBlockLiteralType);
+
+  return GenericExtendedBlockLiteralType;
+}
+
 /// getBlockFunctionType - Given a BlockPointerType, will return the
 /// function type for the block, including the first block literal argument.
 static QualType getBlockFunctionType(ASTContext &Ctx,
index 15dab8faf7bfa487af1c94123f967ede23769900..651a283baa898135b4512932f38d6a2cef76c7c3 100644 (file)
@@ -614,6 +614,9 @@ public:
       std::string S(Literal->getStrData(), Literal->getByteLength());
       return CGM.GetAddrOfConstantCFString(S);
     }
+    case Expr::BlockExprClass: {
+      return CGF->BuildBlockLiteralTmp(cast<BlockExpr>(E));
+    }
     }
 
     return 0;
index 4b185f61018aea9136669477a2105a09fc919716..eb1345737292f6955fdd8281a2cb767cdeac205d 100644 (file)
@@ -1364,10 +1364,7 @@ Value *ScalarExprEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
 
 Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *BE) {
   llvm::Constant *C = CGF.BuildBlockLiteralTmp(BE);
-
-  const llvm::PointerType *PtrToInt8Ty
-    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
-  return llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
+  return C;
 }
 
 //===----------------------------------------------------------------------===//
index 24453ccadc7669dfecb62d6858943992c694f9e0..b7d3aa9f38eff0e610a2106edd8fcae605112cf7 100644 (file)
@@ -145,6 +145,7 @@ class CodeGenModule {
   
   const llvm::Type *BlockDescriptorType;
   const llvm::Type *GenericBlockLiteralType;
+  const llvm::Type *GenericExtendedBlockLiteralType;
   struct {
     int GlobalUniqueCount;
   } Block;
@@ -166,6 +167,7 @@ public:
   const llvm::Type *getBlockDescriptorType();
 
   const llvm::Type *getGenericBlockLiteralType();
+  const llvm::Type *getGenericExtendedBlockLiteralType();
 
   /// getObjCRuntime() - Return a reference to the configured
   /// Objective-C runtime.