[cfe-commits] r91435 - in /cfe/trunk: lib/Frontend/RewriteObjC.cpp test/Rewriter/rewrite-block-literal.c

Fariborz Jahanian fjahanian at apple.com
Tue Dec 15 09:30:20 PST 2009


Author: fjahanian
Date: Tue Dec 15 11:30:20 2009
New Revision: 91435

URL: http://llvm.org/viewvc/llvm-project?rev=91435&view=rev
Log:
Implement conditional block invocation rewrite
and some clean up and a block rewriter test.

Added:
    cfe/trunk/test/Rewriter/rewrite-block-literal.c
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=91435&r1=91434&r2=91435&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Tue Dec 15 11:30:20 2009
@@ -337,7 +337,7 @@
                                           std::string ImplTag,
                                           int i, const char *funcName,
                                           unsigned hasCopy);
-    Stmt *SynthesizeBlockCall(CallExpr *Exp);
+    Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
     void SynthesizeBlockLiterals(SourceLocation FunLocStart,
                                    const char *FunName);
     void RewriteRecordBody(RecordDecl *RD);
@@ -4030,20 +4030,36 @@
   return;
 }
 
-Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp) {
+Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
   // Navigate to relevant type information.
-  const char *closureName = 0;
   const BlockPointerType *CPT = 0;
 
-  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp->getCallee())) {
-    closureName = DRE->getDecl()->getNameAsCString();
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
     CPT = DRE->getType()->getAs<BlockPointerType>();
-  } else if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(Exp->getCallee())) {
-    closureName = CDRE->getDecl()->getNameAsCString();
+  } else if (const BlockDeclRefExpr *CDRE = 
+              dyn_cast<BlockDeclRefExpr>(BlockExp)) {
     CPT = CDRE->getType()->getAs<BlockPointerType>();
-  } else if (MemberExpr *MExpr = dyn_cast<MemberExpr>(Exp->getCallee())) {
-    closureName = MExpr->getMemberDecl()->getNameAsCString();
+  } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
     CPT = MExpr->getType()->getAs<BlockPointerType>();
+  } 
+  else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
+    return SynthesizeBlockCall(Exp, PRE->getSubExpr());
+  }
+  else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 
+    CPT = IEXPR->getType()->getAs<BlockPointerType>();
+  else if (const ConditionalOperator *CEXPR = 
+            dyn_cast<ConditionalOperator>(BlockExp)) {
+    Expr *LHSExp = CEXPR->getLHS();
+    Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
+    Expr *RHSExp = CEXPR->getRHS();
+    Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
+    Expr *CONDExp = CEXPR->getCond();
+    ConditionalOperator *CondExpr =
+      new (Context) ConditionalOperator(CONDExp,
+                                      SourceLocation(), cast<Expr>(LHSStmt),
+                                      SourceLocation(), cast<Expr>(RHSStmt), 
+                                      Exp->getType());
+    return CondExpr;
   } else {
     assert(1 && "RewriteBlockClass: Bad type");
   }
@@ -4083,7 +4099,7 @@
 
   CastExpr *BlkCast = new (Context) CStyleCastExpr(PtrBlock,
                                                    CastExpr::CK_Unknown,
-                                                   Exp->getCallee(),
+                                                   const_cast<Expr*>(BlockExp),
                                                    PtrBlock, SourceLocation(),
                                                    SourceLocation());
   // Don't forget the parens to enforce the proper binding.
@@ -4119,7 +4135,7 @@
 }
 
 void RewriteObjC::RewriteBlockCall(CallExpr *Exp) {
-  Stmt *BlockCall = SynthesizeBlockCall(Exp);
+  Stmt *BlockCall = SynthesizeBlockCall(Exp, Exp->getCallee());
   ReplaceStmt(Exp, BlockCall);
 }
 
@@ -4668,7 +4684,7 @@
   }
   if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
     if (CE->getCallee()->getType()->isBlockPointerType()) {
-      Stmt *BlockCall = SynthesizeBlockCall(CE);
+      Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
       ReplaceStmt(S, BlockCall);
       return BlockCall;
     }

Added: cfe/trunk/test/Rewriter/rewrite-block-literal.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-block-literal.c?rev=91435&view=auto

==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-block-literal.c (added)
+++ cfe/trunk/test/Rewriter/rewrite-block-literal.c Tue Dec 15 11:30:20 2009
@@ -0,0 +1,80 @@
+// RUN: clang -cc1 -rewrite-objc %s -fblocks -o -
+
+void I( void (^)(void));
+void (^noop)(void);
+
+void nothing();
+int printf(const char*, ...);
+
+typedef void (^T) (void);
+
+void takeblock(T);
+int takeintint(int (^C)(int)) { return C(4); }
+
+T somefunction() {
+  if (^{ })
+    nothing();
+
+  noop = ^{};
+
+  noop = ^{printf("\nClosure\n"); };
+
+  I(^{ });
+
+  return ^{printf("\nClosure\n"); };
+}
+void test2() {
+  int x = 4;
+
+  takeblock(^{ printf("%d\n", x); });
+
+  while (1) {
+    takeblock(^{ 
+        while(1) break;  // ok
+      });
+    break;
+  }
+}
+
+
+void (^test3())(void) { 
+  return ^{};
+}
+
+void test4() {
+  void (^noop)(void) = ^{};
+  void (*noop2)() = 0;
+}
+
+void myfunc(int (^block)(int)) {}
+
+void myfunc3(const int *x);
+
+void test5() {
+  int a;
+
+  myfunc(^(int abcd) {
+      myfunc3(&a);
+      return 1;
+    });
+}
+
+void *X;
+
+void test_arguments() {
+  int y;
+  int (^c)(char);
+  (1 ? c : 0)('x');
+  (1 ? 0 : c)('x');
+
+  (1 ? c : c)('x');
+}
+
+static int global_x = 10;
+void (^global_block)(void) = ^{ printf("global x is %d\n", global_x); };
+
+typedef void (^void_block_t)(void);
+
+static const void_block_t myBlock = ^{ };
+
+static const void_block_t myBlock2 = ^ void(void) { }; 





More information about the cfe-commits mailing list