[cfe-commits] r92501 - /cfe/trunk/lib/Frontend/RewriteObjC.cpp

Fariborz Jahanian fjahanian at apple.com
Mon Jan 4 11:50:07 PST 2010


Author: fjahanian
Date: Mon Jan  4 13:50:07 2010
New Revision: 92501

URL: http://llvm.org/viewvc/llvm-project?rev=92501&view=rev
Log:
More rewriting of __block declared objective-c/block pointers.
This is wip.


Modified:
    cfe/trunk/lib/Frontend/RewriteObjC.cpp

Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=92501&r1=92500&r2=92501&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Mon Jan  4 13:50:07 2010
@@ -347,7 +347,7 @@
     void RewriteBlockCall(CallExpr *Exp);
     void RewriteBlockPointerDecl(NamedDecl *VD);
     void RewriteByRefVar(VarDecl *VD);
-    Stmt *RewriteBlockDeclRefExpr(BlockDeclRefExpr *VD);
+    Stmt *RewriteBlockDeclRefExpr(Expr *VD);
     void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
 
     std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
@@ -4192,29 +4192,40 @@
 //        i = 77;
 //    };
 //}
-Stmt *RewriteObjC::RewriteBlockDeclRefExpr(BlockDeclRefExpr *BDRE) {
+Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) {
   // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
-  // for each BDRE where BYREFVAR is name of the variable.
+  // for each DeclRefExp where BYREFVAR is name of the variable.
+  ValueDecl *VD;
+  bool isArrow = true;
+  if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(DeclRefExp))
+    VD = BDRE->getDecl();
+  else {
+    VD = cast<DeclRefExpr>(DeclRefExp)->getDecl();
+    isArrow = false;
+  }
+  
   FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
                                     &Context->Idents.get("__forwarding"), 
                                     Context->VoidPtrTy, 0,
                                     /*BitWidth=*/0, /*Mutable=*/true);
-  MemberExpr *ME = new (Context) MemberExpr(BDRE, true, FD, SourceLocation(),
+  MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
+                                            FD, SourceLocation(),
                                             FD->getType());
-  const char *Name = BDRE->getDecl()->getNameAsCString();
+
+  const char *Name = VD->getNameAsCString();
   FD = FieldDecl::Create(*Context, 0, SourceLocation(),
                          &Context->Idents.get(Name), 
                          Context->VoidPtrTy, 0,
                          /*BitWidth=*/0, /*Mutable=*/true);
   ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
-                                BDRE->getType());
+                                DeclRefExp->getType());
   
   
   
   // Need parens to enforce precedence.
   ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
                                           ME);
-  ReplaceStmt(BDRE, PE);
+  ReplaceStmt(DeclRefExp, PE);
   return PE;
 }
 
@@ -4376,8 +4387,8 @@
 /// struct __Block_byref_ND *__forwarding;
 /// int32_t __flags;
 /// int32_t __size;
-/// void *__ByrefKeepFuncPtr;    // Only if variable is __block ObjC object
-/// void *__ByrefDestroyFuncPtr; // Only if variable is __block ObjC object
+/// void *__copy_helper;    // Only if variable is __block ObjC object
+/// void *__destroy_helper; // Only if variable is __block ObjC object
 /// typex ND;
 /// };
 ///
@@ -4401,9 +4412,15 @@
   ByrefType += " struct __Block_byref_" + Name + " *__forwarding;\n";
   ByrefType += " int __flags;\n";
   ByrefType += " int __size;\n";
-  // FIXME. Add  void *__ByrefKeepFuncPtr; void *__ByrefDestroyFuncPtr; 
-  // if needed.
-  ND->getType().getAsStringInternal(Name, Context->PrintingPolicy);
+  // Add void *__copy_helper; void *__destroy_helper; if needed.
+  QualType Ty = ND->getType();
+  bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty);
+  if (HasCopyAndDispose) {
+    ByrefType += " void *__copy_helper;\n";
+    ByrefType += " void *__destroy_helper;\n";
+  }
+  
+  Ty.getAsStringInternal(Name, Context->PrintingPolicy);
   ByrefType += " " + Name + ";\n";
   ByrefType += "};\n";
   // Insert this type in global scope. It is needed by helper function.
@@ -4420,8 +4437,11 @@
   if (!hasInit) {
     ByrefType += " " + Name + " = ";
     ByrefType += "{0, &" + Name + ", ";
-    // FIXME. Compute the flag.
-    ByrefType += "0, ";
+    unsigned flag = 0;
+    if (HasCopyAndDispose)
+      flag |= BLOCK_HAS_COPY_DISPOSE;
+    ByrefType += utostr(flag);
+    ByrefType += ", ";
     ByrefType += "sizeof(struct __Block_byref_" + Name + ")";
     ByrefType += "};\n";
     ReplaceText(DeclLoc, endBuf-startBuf+Name.size(), 
@@ -4433,8 +4453,11 @@
     ReplaceText(DeclLoc, endBuf-startBuf, 
                 ByrefType.c_str(), ByrefType.size());
     ByrefType = " = {0, &" + Name + ", ";
-    // FIXME. Compute the flag.
-    ByrefType += "0, ";
+    unsigned flag = 0;
+    if (HasCopyAndDispose)
+      flag |= BLOCK_HAS_COPY_DISPOSE;
+    ByrefType += utostr(flag);
+    ByrefType += ", ";
     ByrefType += "sizeof(struct __Block_byref_" + Name + "), ";
     InsertText(startLoc, ByrefType.c_str(), ByrefType.size());
     
@@ -4829,6 +4852,12 @@
     if (BDRE->isByRef())
       return RewriteBlockDeclRefExpr(BDRE);
   }
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    ValueDecl *VD = DRE->getDecl(); 
+    if (VD->hasAttr<BlocksAttr>())
+      return RewriteBlockDeclRefExpr(DRE);
+  }
+  
   if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
     if (CE->getCallee()->getType()->isBlockPointerType()) {
       Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());





More information about the cfe-commits mailing list