From 72952fc11f80c975492a2a1e0f6e3601c5252e0a Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 1 Mar 2010 23:36:21 +0000 Subject: [PATCH] More rewriter of nested blocks fun stuff. Radar 7696893. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97520 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Frontend/RewriteObjC.cpp | 47 ++++++++++++++---------- test/Rewriter/rewrite-nested-blocks-1.mm | 47 ++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 test/Rewriter/rewrite-nested-blocks-1.mm diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index 635280bf43..98dee264e9 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -26,6 +26,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/DenseSet.h" + using namespace clang; using llvm::utostr; @@ -390,7 +391,7 @@ namespace { void GetBlockDeclRefExprs(Stmt *S); void GetInnerBlockDeclRefExprs(Stmt *S, llvm::SmallVector &InnerBlockDeclRefs, - llvm::SmallPtrSet &InnerBlockValueDecls); + llvm::SmallPtrSet &InnerContexts); // We avoid calling Type::isBlockPointerType(), since it operates on the // canonical type. We only care if the top-level type is a closure pointer. @@ -4264,16 +4265,23 @@ void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, if (CurFunctionDeclToDeclareForBlock && !Blocks.empty()) RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); // Insert closures that were part of the function. - for (unsigned i = 0; i < Blocks.size(); i++) { + for (unsigned i = 0, count=0; i < Blocks.size(); i++) { + CollectBlockDeclRefInfo(Blocks[i]); // Need to copy-in the inner copied-in variables not actually used in this // block. - for (int j = 0; j < InnerDeclRefsCount[i]; j++) - BlockDeclRefs.push_back(InnerDeclRefs[j]); - CollectBlockDeclRefInfo(Blocks[i]); - llvm::SmallPtrSet InnerBlockValueDecls; - llvm::SmallVector InnerBlockDeclRefs; - GetInnerBlockDeclRefExprs(Blocks[i]->getBody(), - InnerBlockDeclRefs, InnerBlockValueDecls); + for (int j = 0; j < InnerDeclRefsCount[i]; j++) { + BlockDeclRefExpr *Exp = InnerDeclRefs[count++]; + ValueDecl *VD = Exp->getDecl(); + BlockDeclRefs.push_back(Exp); + if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) { + BlockByCopyDeclsPtrSet.insert(VD); + BlockByCopyDecls.push_back(VD); + } + if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) { + BlockByRefDeclsPtrSet.insert(VD); + BlockByRefDecls.push_back(VD); + } + } std::string ImplTag = "__" + std::string(FunName) + "_block_impl_" + utostr(i); std::string DescTag = "__" + std::string(FunName) + "_block_desc_" + utostr(i); @@ -4353,28 +4361,28 @@ void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, llvm::SmallVector &InnerBlockDeclRefs, - llvm::SmallPtrSet &InnerBlockValueDecls) { + llvm::SmallPtrSet &InnerContexts) { for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end(); CI != E; ++CI) if (*CI) { - if (BlockExpr *CBE = dyn_cast(*CI)) + if (BlockExpr *CBE = dyn_cast(*CI)) { + InnerContexts.insert(cast(CBE->getBlockDecl())); GetInnerBlockDeclRefExprs(CBE->getBody(), InnerBlockDeclRefs, - InnerBlockValueDecls); + InnerContexts); + } else GetInnerBlockDeclRefExprs(*CI, InnerBlockDeclRefs, - InnerBlockValueDecls); + InnerContexts); } // Handle specific things. if (BlockDeclRefExpr *CDRE = dyn_cast(S)) if (!isa(CDRE->getDecl()) && - !isa(CDRE->getDecl()) && - !InnerBlockValueDecls.count(CDRE->getDecl())) { - InnerBlockValueDecls.insert(CDRE->getDecl()); + !InnerContexts.count(CDRE->getDecl()->getDeclContext())) InnerBlockDeclRefs.push_back(CDRE); - } + return; } @@ -5166,10 +5174,11 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { } if (BlockExpr *BE = dyn_cast(S)) { - llvm::SmallPtrSet InnerBlockValueDecls; llvm::SmallVector InnerBlockDeclRefs; + llvm::SmallPtrSet InnerContexts; + InnerContexts.insert(BE->getBlockDecl()); GetInnerBlockDeclRefExprs(BE->getBody(), - InnerBlockDeclRefs, InnerBlockValueDecls); + InnerBlockDeclRefs, InnerContexts); // Rewrite the block body in place. RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); diff --git a/test/Rewriter/rewrite-nested-blocks-1.mm b/test/Rewriter/rewrite-nested-blocks-1.mm new file mode 100644 index 0000000000..582f5f4c0d --- /dev/null +++ b/test/Rewriter/rewrite-nested-blocks-1.mm @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp +// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp +// radar 7696893 + +void *sel_registerName(const char *); + +void f(void (^block)(void)); +void f2(id); +void f3(int); +char f4(id, id); + +@interface Baz +- (void)b:(void (^)(void))block; +@end + +@interface Bar +@end + +@interface Foo { + int _x; +} +@end + +@implementation Foo +- (void)method:(Bar *)up { + Baz *down; + int at; + id cq; + __block char didit = 'a'; + __block char upIsFinished = 'b'; + f(^{ + id old_cq; + f2(cq); + [down b:^{ + [down b:^{ + f(^{ + didit = f4(up, down); + upIsFinished = 'c'; + self->_x++; + }); + }]; + }]; + f2(old_cq); + f3(at); + }); +} +@end -- 2.40.0