diff options
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 21 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 1 | ||||
-rw-r--r-- | test/CodeGen/blocks-1.c | 13 |
3 files changed, 32 insertions, 3 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index a876938c02..fcda90794e 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -155,7 +155,8 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { uint64_t subBlockSize, subBlockAlign; llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls; llvm::Function *Fn - = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, subBlockSize, + = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, LocalDeclMap, + subBlockSize, subBlockAlign, subBlockDeclRefDecls, BlockHasCopyDispose); @@ -558,8 +559,10 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) { uint64_t subBlockSize, subBlockAlign; llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls; bool subBlockHasCopyDispose = false; + llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap; llvm::Function *Fn - = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, subBlockSize, + = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, LocalDeclMap, + subBlockSize, subBlockAlign, subBlockDeclRefDecls, subBlockHasCopyDispose); @@ -602,10 +605,24 @@ llvm::Value *CodeGenFunction::LoadBlockStruct() { llvm::Function * CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, const BlockInfo& Info, + llvm::DenseMap<const Decl*, llvm::Value*> ldm, uint64_t &Size, uint64_t &Align, llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls, bool &subBlockHasCopyDispose) { + // Arrange for local static and local extern declarations to appear + // to be local to this function as well, as they are directly referenced + // in a block. + for (llvm::DenseMap<const Decl *, llvm::Value*>::iterator i = ldm.begin(); + i != ldm.end(); + ++i) { + const VarDecl *VD = dyn_cast<VarDecl>(i->first); + + if (VD->getStorageClass() == VarDecl::Static + || VD->getStorageClass() == VarDecl::Extern) + LocalDeclMap[VD] = i->second; + } + const FunctionProtoType *FTy = cast<FunctionProtoType>(BExpr->getFunctionType()); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 0b34d7a92d..7443e44916 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -272,6 +272,7 @@ public: llvm::Function *GenerateBlockFunction(const BlockExpr *BExpr, const BlockInfo& Info, + llvm::DenseMap<const Decl*, llvm::Value*> ldm, uint64_t &Size, uint64_t &Align, llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls, bool &subBlockHasCopyDispose); diff --git a/test/CodeGen/blocks-1.c b/test/CodeGen/blocks-1.c index df2a3fda6b..8572f8d6cf 100644 --- a/test/CodeGen/blocks-1.c +++ b/test/CodeGen/blocks-1.c @@ -41,9 +41,20 @@ void test3() { ^{j=0; k=0;}(); } +int test4() { + extern int g; + static int i = 1; + ^(int j){ i = j; g = 0; }(0); + return i + g; +} + +int g; + int main() { + int rv = 0; test1(); test2(); test3(); - return 0; + rv += test4(); + return rv; } |