Index: lib/CodeGen/CGBlocks.cpp =================================================================== --- lib/CodeGen/CGBlocks.cpp +++ lib/CodeGen/CGBlocks.cpp @@ -725,12 +725,13 @@ llvm::Constant *blockFn = CodeGenFunction(CGM, true).GenerateBlockFunction(CurGD, blockInfo, LocalDeclMap, - isLambdaConv); + isLambdaConv, + blockInfo.CanBeGlobal); blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy); // If there is nothing to capture, we can emit this as a global block. if (blockInfo.CanBeGlobal) - return buildGlobalBlock(CGM, blockInfo, blockFn); + return CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression); // Otherwise, we have to emit this as a local block. @@ -1120,11 +1121,10 @@ blockFn = CodeGenFunction(*this).GenerateBlockFunction(GlobalDecl(), blockInfo, LocalDeclMap, - false); + false, true); } - blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy); - return buildGlobalBlock(*this, blockInfo, blockFn); + return getAddrOfGlobalBlockIfEmitted(BE); } static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, @@ -1226,7 +1226,8 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, const CGBlockInfo &blockInfo, const DeclMapTy &ldm, - bool IsLambdaConversionToBlock) { + bool IsLambdaConversionToBlock, + bool BuildGlobalBlock) { const BlockDecl *blockDecl = blockInfo.getBlockDecl(); CurGD = GD; @@ -1285,6 +1286,10 @@ fnLLVMType, llvm::GlobalValue::InternalLinkage, name, &CGM.getModule()); CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo); + if (BuildGlobalBlock) + buildGlobalBlock(CGM, blockInfo, + llvm::ConstantExpr::getBitCast(fn, VoidPtrTy)); + // Begin generating the function. StartFunction(blockDecl, fnType->getReturnType(), fn, fnInfo, args, blockDecl->getLocation(), Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -1586,7 +1586,8 @@ llvm::Function *GenerateBlockFunction(GlobalDecl GD, const CGBlockInfo &Info, const DeclMapTy &ldm, - bool IsLambdaConversionToBlock); + bool IsLambdaConversionToBlock, + bool BuildGlobalBlock); llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo); llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo); Index: test/CodeGen/mangle-blocks.c =================================================================== --- test/CodeGen/mangle-blocks.c +++ test/CodeGen/mangle-blocks.c @@ -12,12 +12,12 @@ } // CHECK: @__func__.__mangle_block_invoke_2 = private unnamed_addr constant [22 x i8] c"mangle_block_invoke_2\00", align 1 -// CHECK: @.str = private unnamed_addr constant {{.*}}, align 1 -// CHECK: @.str.1 = private unnamed_addr constant [7 x i8] c"mangle\00", align 1 +// CHECK: @.str{{.*}} = private unnamed_addr constant {{.*}}, align 1 +// CHECK: @.str[[STR1:.*]] = private unnamed_addr constant [7 x i8] c"mangle\00", align 1 // CHECK: define internal void @__mangle_block_invoke(i8* %.block_descriptor) // CHECK: define internal void @__mangle_block_invoke_2(i8* %.block_descriptor){{.*}}{ -// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @__func__.__mangle_block_invoke_2, i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 9, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i32 0, i32 0)) +// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @__func__.__mangle_block_invoke_2, i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 9, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str[[STR1]], i32 0, i32 0)) // CHECK: } Index: test/CodeGenObjC/local-static-block.m =================================================================== --- test/CodeGenObjC/local-static-block.m +++ test/CodeGenObjC/local-static-block.m @@ -46,6 +46,17 @@ } } +void FUNC2() { + static void (^const block1)(int) = ^(int a){ + if (a--) + block1(a); + }; +} + +// CHECK-LABEL-LP64: define void @FUNC2( +// CHECK: define internal void @_block_invoke{{.*}}( +// CHECK: call void %{{.*}}(i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global{{.*}} to i8*), i32 %{{.*}}) + void FUNC1() { static NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) { Index: test/CodeGenObjC/mangle-blocks.m =================================================================== --- test/CodeGenObjC/mangle-blocks.m +++ test/CodeGenObjC/mangle-blocks.m @@ -18,11 +18,11 @@ @end // CHECK: @"__func__.__14-[Test mangle]_block_invoke_2" = private unnamed_addr constant [30 x i8] c"-[Test mangle]_block_invoke_2\00", align 1 -// CHECK: @.str = private unnamed_addr constant {{.*}}, align 1 -// CHECK: @.str.1 = private unnamed_addr constant [7 x i8] c"mangle\00", align 1 +// CHECK: @.str{{.*}} = private unnamed_addr constant {{.*}}, align 1 +// CHECK: @.str[[STR1:.*]] = private unnamed_addr constant [7 x i8] c"mangle\00", align 1 // CHECK: define internal void @"__14-[Test mangle]_block_invoke"(i8* %.block_descriptor) // CHECK: define internal void @"__14-[Test mangle]_block_invoke_2"(i8* %.block_descriptor){{.*}}{ -// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @"__func__.__14-[Test mangle]_block_invoke_2", i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 14, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i32 0, i32 0)) +// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @"__func__.__14-[Test mangle]_block_invoke_2", i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 14, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str[[STR1]], i32 0, i32 0)) // CHECK: }