diff options
author | Mike Stump <mrs@apple.com> | 2009-10-21 22:01:24 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-10-21 22:01:24 +0000 |
commit | 38e1627e895cd276186ebf177f75ba5d229c3fd7 (patch) | |
tree | ac3c56058b6b87919f1e8424c2d66a4f3c091010 | |
parent | 87f9fd90ca08348d2a058c526760688e17208daa (diff) |
Refine collection of BlockDeclRefExprs. WIP.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84787 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/ASTContext.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 25 |
2 files changed, 18 insertions, 11 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 4a0df6bf02..42a6704d8a 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2757,8 +2757,8 @@ QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) { // struct __Block_byref_1_X *__forwarding; // unsigned int __flags; // unsigned int __size; - // void *__copy_helper; - // void *__destroy_helper; + // void *__copy_helper; // as needed + // void *__destroy_help // as needed // int X; // } * diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index af64fd5546..08c45874a3 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -73,24 +73,29 @@ llvm::Constant *BlockModule::getNSConcreteStackBlock() { return NSConcreteStackBlock; } -static void CollectBlockDeclRefInfo(const Stmt *S, - CodeGenFunction::BlockInfo &Info) { +static void CollectBlockDeclRefInfo( + const Stmt *S, CodeGenFunction::BlockInfo &Info, + llvm::SmallSet<const DeclContext *, 16> &InnerContexts) { for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end(); I != E; ++I) if (*I) - CollectBlockDeclRefInfo(*I, Info); + CollectBlockDeclRefInfo(*I, Info, InnerContexts); // We want to ensure we walk down into block literals so we can find // all nested BlockDeclRefExprs. - if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) - CollectBlockDeclRefInfo(BE->getBody(), Info); + if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) { + InnerContexts.insert(cast<DeclContext>(BE->getBlockDecl())); + CollectBlockDeclRefInfo(BE->getBody(), Info, InnerContexts); + } - if (const BlockDeclRefExpr *DE = dyn_cast<BlockDeclRefExpr>(S)) { + if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) { // FIXME: Handle enums. - if (isa<FunctionDecl>(DE->getDecl())) + if (isa<FunctionDecl>(BDRE->getDecl())) return; - Info.DeclRefs.push_back(DE); + // Only Decls that escape are added. + if (!InnerContexts.count(BDRE->getDecl()->getDeclContext())) + Info.DeclRefs.push_back(BDRE); } } @@ -130,7 +135,9 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { std::string Name = CurFn->getName(); CodeGenFunction::BlockInfo Info(0, Name.c_str()); - CollectBlockDeclRefInfo(BE->getBody(), Info); + llvm::SmallSet<const DeclContext *, 16> InnerContexts; + InnerContexts.insert(BE->getBlockDecl()); + CollectBlockDeclRefInfo(BE->getBody(), Info, InnerContexts); // Check if the block can be global. // FIXME: This test doesn't work for nested blocks yet. Longer term, I'd like |