[cfe-commits] r64390 - /cfe/trunk/lib/CodeGen/CGExprScalar.cpp

Mike Stump mrs at apple.com
Thu Feb 12 10:29:16 PST 2009


Author: mrs
Date: Thu Feb 12 12:29:15 2009
New Revision: 64390

URL: http://llvm.org/viewvc/llvm-project?rev=64390&view=rev
Log:
Initial codegen for block literals.  This is a work in progress.  I've
tried to put FIXMEs on the most important things to fix up.  Lots left
to do including more codegen, more documentation and cleaning code and
style cleanups.

Modified:
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=64390&r1=64389&r2=64390&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Thu Feb 12 12:29:15 2009
@@ -85,7 +85,10 @@
   /// type is an LLVM scalar type.
   Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
                                        QualType SrcTy, QualType DstTy);
-    
+
+  llvm::Constant *BuildBlockLiteralTmp ();
+  llvm::Constant *BuildDescriptorBlockDecl();
+
   //===--------------------------------------------------------------------===//
   //                            Visitor Methods
   //===--------------------------------------------------------------------===//
@@ -319,11 +322,7 @@
   Value *VisitBinComma      (const BinaryOperator *E);
 
   // Other Operators.
-  Value *VisitBlockExpr(const BlockExpr *BE) {
-    CGF.ErrorUnsupported(BE, "block expression");
-    return llvm::UndefValue::get(CGF.ConvertType(BE->getType()));
-  }
-
+  Value *VisitBlockExpr(const BlockExpr *BE);
   Value *VisitConditionalOperator(const ConditionalOperator *CO);
   Value *VisitChooseExpr(ChooseExpr *CE);
   Value *VisitOverloadExpr(OverloadExpr *OE);
@@ -1361,6 +1360,143 @@
   return C;
 }
 
+enum {
+  BLOCK_NEEDS_FREE =        (1 << 24),
+  BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+  BLOCK_HAS_CXX_OBJ =       (1 << 26),
+  BLOCK_IS_GC =             (1 << 27),
+  BLOCK_IS_GLOBAL =         (1 << 28),
+  BLOCK_HAS_DESCRIPTOR =    (1 << 29)
+};
+
+llvm::Constant *ScalarExprEmitter::BuildDescriptorBlockDecl() {
+  // FIXME: Push up.
+  bool BlockHasCopyDispose = false;
+
+  const llvm::PointerType *PtrToInt8Ty
+    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+  llvm::Constant *C;
+  std::vector<llvm::Constant*> Elts;
+
+  // reserved
+  const llvm::IntegerType *LongTy
+    = cast<llvm::IntegerType>(
+        CGF.CGM.getTypes().ConvertType(CGF.CGM.getContext().LongTy));
+  C = llvm::ConstantInt::get(LongTy, 0);
+  Elts.push_back(C);
+
+  // Size
+  // FIXME: This should be the size of BlockStructType
+  C = llvm::ConstantInt::get(LongTy, 20);
+  Elts.push_back(C);
+
+  if (BlockHasCopyDispose) {
+    // copy_func_helper_decl
+    C = llvm::ConstantInt::get(LongTy, 0);
+    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
+    Elts.push_back(C);
+
+    // destroy_func_decl
+    C = llvm::ConstantInt::get(LongTy, 0);
+    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
+    Elts.push_back(C);
+  }
+
+  C = llvm::ConstantStruct::get(Elts);
+
+  // FIXME: Should be in module?
+  static int desc_unique_count;
+  char Name[32];
+  sprintf(Name, "__block_descriptor_tmp_%d", ++desc_unique_count);
+  C = new llvm::GlobalVariable(C->getType(), true,
+                               llvm::GlobalValue::InternalLinkage,
+                               C, Name, &CGF.CGM.getModule());
+  return C;
+}
+
+llvm::Constant *ScalarExprEmitter::BuildBlockLiteralTmp() {
+  // FIXME: Push up
+  bool BlockHasCopyDispose = false;
+  bool insideFunction = false;
+  bool BlockRefDeclList = false;
+  bool BlockByrefDeclList = false;
+
+  std::vector<llvm::Constant*> Elts;
+  llvm::Constant *C;
+
+  bool staticBlockTmp = (BlockRefDeclList == 0
+                         && BlockByrefDeclList == 0);
+
+  {
+    // C = BuildBlockStructInitlist();
+    unsigned int flags = BLOCK_HAS_DESCRIPTOR;
+
+    if (BlockHasCopyDispose)
+      flags |= BLOCK_HAS_COPY_DISPOSE;
+
+    const llvm::PointerType *PtrToInt8Ty
+      = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+    // FIXME: static?  What if we start up a new, unrelated module?
+    // logically we want 1 per module.
+    static llvm::Constant *NSConcreteGlobalBlock_decl
+      = new llvm::GlobalVariable(PtrToInt8Ty, false, 
+                                 llvm::GlobalValue::ExternalLinkage,
+                                 0, "_NSConcreteGlobalBlock",
+                                 &CGF.CGM.getModule());
+    static llvm::Constant *NSConcreteStackBlock_decl
+      = new llvm::GlobalVariable(PtrToInt8Ty, false, 
+                                 llvm::GlobalValue::ExternalLinkage,
+                                 0, "_NSConcreteStackBlock",
+                                 &CGF.CGM.getModule());
+    C = NSConcreteStackBlock_decl;
+    if (!insideFunction ||
+        (!BlockRefDeclList && !BlockByrefDeclList)) {
+      C = NSConcreteGlobalBlock_decl;
+      flags |= BLOCK_IS_GLOBAL;
+    }
+    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
+    Elts.push_back(C);
+
+    // __flags
+    const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
+      CGF.CGM.getTypes().ConvertType(CGF.CGM.getContext().IntTy));
+    C = llvm::ConstantInt::get(IntTy, flags);
+    Elts.push_back(C);
+
+    // __reserved
+    C = llvm::ConstantInt::get(IntTy, 0);
+    Elts.push_back(C);
+
+    // __FuncPtr
+    // FIXME: Build this up.
+    Elts.push_back(C);
+
+    // __descriptor
+    Elts.push_back(BuildDescriptorBlockDecl());
+
+    // FIXME: Add block_original_ref_decl_list and block_byref_decl_list.
+  }
+  
+  C = llvm::ConstantStruct::get(Elts);
+
+  char Name[32];
+  // FIXME: Boost in CGM?
+  static int global_unique_count;
+  sprintf(Name, "__block_holder_tmp_%d", ++global_unique_count);
+  C = new llvm::GlobalVariable(C->getType(), true,
+                               llvm::GlobalValue::InternalLinkage,
+                               C, Name, &CGF.CGM.getModule());
+  return C;
+}
+
+Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *BE) {
+  llvm::Constant *C = BuildBlockLiteralTmp();
+
+  const llvm::PointerType *PtrToInt8Ty
+    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+  return llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
+}
+
 //===----------------------------------------------------------------------===//
 //                         Entry Point into this File
 //===----------------------------------------------------------------------===//





More information about the cfe-commits mailing list