[cfe-commits] r108482 - in /cfe/trunk: include/clang/Basic/Builtins.def lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h test/CodeGen/block-decl-merging.c

Daniel Dunbar daniel at zuster.org
Thu Jul 15 17:00:19 PDT 2010


Author: ddunbar
Date: Thu Jul 15 19:00:19 2010
New Revision: 108482

URL: http://llvm.org/viewvc/llvm-project?rev=108482&view=rev
Log:
IRgen: Support user defined attributes on block runtime functions.
 - This issue here is that /usr/include/Blocks.h wants to define some of the
   block runtime globals as weak, depending on the target. This doesn't work in
   Clang because we aren't using the AST decl for these globals.

 - The fix is a pretty gross hack which just watches all the decls for the
   specific blocks globals we need to know about; if we see one we use it,
   otherwise we use the hand coded type.

   In time, I would like to clean this up by changing IRgen to ask Sema/AST for
   the decl, which would then be lazily loaded from the builtin table if
   necessary. This could be used in a whole host of places in IRgen and would
   get rid of a lot of grotty hand coding of LLVM IR; however, we need some
   extra Sema support for this as well as support for builtin global variables.

Added:
    cfe/trunk/test/CodeGen/block-decl-merging.c
Modified:
    cfe/trunk/include/clang/Basic/Builtins.def
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=108482&r1=108481&r2=108482&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Thu Jul 15 19:00:19 2010
@@ -560,5 +560,10 @@
 LIBBUILTIN(cosl, "LdLd", "fe", "math.h")
 LIBBUILTIN(cosf, "ff", "fe", "math.h")
 
+// Blocks runtime Builtin math library functions
+LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h")
+LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h")
+// FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock.
+
 #undef BUILTIN
 #undef LIBBUILTIN

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=108482&r1=108481&r2=108482&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu Jul 15 19:00:19 2010
@@ -52,7 +52,9 @@
     VTables(*this), Runtime(0), ABI(0),
     CFConstantStringClassRef(0), NSConstantStringClassRef(0),
     VMContext(M.getContext()),
+    NSConcreteGlobalBlockDecl(0), NSConcreteStackBlockDecl(0),
     NSConcreteGlobalBlock(0), NSConcreteStackBlock(0),
+    BlockObjectAssignDecl(0), BlockObjectDisposeDecl(0),
     BlockObjectAssign(0), BlockObjectDispose(0){
 
   if (!Features.ObjC1)
@@ -775,6 +777,15 @@
 
   // Ignore declarations, they will be emitted on their first use.
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
+    if (FD->getIdentifier()) {
+      llvm::StringRef Name = FD->getName();
+      if (Name == "_Block_object_assign") {
+        BlockObjectAssignDecl = FD;
+      } else if (Name == "_Block_object_dispose") {
+        BlockObjectDisposeDecl = FD;
+      }
+    }
+
     // Forward declarations are emitted lazily on first use.
     if (!FD->isThisDeclarationADefinition())
       return;
@@ -782,6 +793,16 @@
     const VarDecl *VD = cast<VarDecl>(Global);
     assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
 
+    if (VD->getIdentifier()) {
+      llvm::StringRef Name = VD->getName();
+      if (Name == "_NSConcreteGlobalBlock") {
+        NSConcreteGlobalBlockDecl = VD;
+      } else if (Name == "_NSConcreteStackBlock") {
+        NSConcreteStackBlockDecl = VD;
+      }
+    }
+
+
     if (VD->isThisDeclarationADefinition() != VarDecl::Definition)
       return;
   }
@@ -2144,6 +2165,14 @@
   if (BlockObjectDispose)
     return BlockObjectDispose;
 
+  // If we saw an explicit decl, use that.
+  if (BlockObjectDisposeDecl) {
+    return BlockObjectDispose = GetAddrOfFunction(
+      BlockObjectDisposeDecl,
+      getTypes().GetFunctionType(BlockObjectDisposeDecl));
+  }
+
+  // Otherwise construct the function by hand.
   const llvm::FunctionType *FTy;
   std::vector<const llvm::Type*> ArgTys;
   const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
@@ -2158,6 +2187,14 @@
   if (BlockObjectAssign)
     return BlockObjectAssign;
 
+  // If we saw an explicit decl, use that.
+  if (BlockObjectAssignDecl) {
+    return BlockObjectAssign = GetAddrOfFunction(
+      BlockObjectAssignDecl,
+      getTypes().GetFunctionType(BlockObjectAssignDecl));
+  }
+
+  // Otherwise construct the function by hand.
   const llvm::FunctionType *FTy;
   std::vector<const llvm::Type*> ArgTys;
   const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
@@ -2172,6 +2209,15 @@
 llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() {
   if (NSConcreteGlobalBlock)
     return NSConcreteGlobalBlock;
+
+  // If we saw an explicit decl, use that.
+  if (NSConcreteGlobalBlockDecl) {
+    return NSConcreteGlobalBlock = GetAddrOfGlobalVar(
+      NSConcreteGlobalBlockDecl,
+      getTypes().ConvertType(NSConcreteGlobalBlockDecl->getType()));
+  }
+
+  // Otherwise construct the variable by hand.
   return NSConcreteGlobalBlock = CreateRuntimeVariable(
     PtrToInt8Ty, "_NSConcreteGlobalBlock");
 }
@@ -2179,6 +2225,15 @@
 llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {
   if (NSConcreteStackBlock)
     return NSConcreteStackBlock;
+
+  // If we saw an explicit decl, use that.
+  if (NSConcreteStackBlockDecl) {
+    return NSConcreteStackBlock = GetAddrOfGlobalVar(
+      NSConcreteStackBlockDecl,
+      getTypes().ConvertType(NSConcreteStackBlockDecl->getType()));
+  }
+
+  // Otherwise construct the variable by hand.
   return NSConcreteStackBlock = CreateRuntimeVariable(
     PtrToInt8Ty, "_NSConcreteStackBlock");
 }

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=108482&r1=108481&r2=108482&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Thu Jul 15 19:00:19 2010
@@ -197,8 +197,13 @@
   /// @name Cache for Blocks Runtime Globals
   /// @{
 
+  const VarDecl *NSConcreteGlobalBlockDecl;
+  const VarDecl *NSConcreteStackBlockDecl;
   llvm::Constant *NSConcreteGlobalBlock;
   llvm::Constant *NSConcreteStackBlock;
+
+  const FunctionDecl *BlockObjectAssignDecl;
+  const FunctionDecl *BlockObjectDisposeDecl;
   llvm::Constant *BlockObjectAssign;
   llvm::Constant *BlockObjectDispose;
 

Added: cfe/trunk/test/CodeGen/block-decl-merging.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/block-decl-merging.c?rev=108482&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/block-decl-merging.c (added)
+++ cfe/trunk/test/CodeGen/block-decl-merging.c Thu Jul 15 19:00:19 2010
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -emit-llvm -o - %s | \
+// RUN:   FileCheck %s
+
+// CHECK: @_NSConcreteGlobalBlock = extern_weak global
+extern void * _NSConcreteStackBlock[32] __attribute__((weak_import));
+// CHECK: @_NSConcreteStackBlock = extern_weak global
+extern void * _NSConcreteGlobalBlock[32] __attribute__((weak_import));
+// CHECK: declare extern_weak void @_Block_object_dispose
+extern void _Block_object_dispose(const void *, const int) __attribute__((weak_import));
+// CHECK: declare extern_weak void @_Block_object_assign
+extern void _Block_object_assign(void *, const void *, const int) __attribute__((weak_import));
+
+void *x = ^(){};
+
+void f1(void (^a0)(void));
+
+void f0() {
+  __block int x;
+  f1(^(void){ x = 1; });
+}





More information about the cfe-commits mailing list