block literal irgen: several improvements on naming block
literal helper functions. All helper functions (global
and locals) use block_invoke as their prefix. Local literal
helper names are prefixed by their enclosing mangled function
names. Blocks in non-local initializers (e.g. a global variable 
or a C++11 field) are prefixed by their mangled variable name. 
The descriminator number added to end of the name starts off 
with blank (for first block) and _<N> (for the N+2-th block).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159206 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index ca22ed6..a0dffb9 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -121,6 +121,7 @@
                              raw_ostream &) = 0;
 
   void mangleGlobalBlock(const BlockDecl *BD,
+                         const NamedDecl *ID,
                          raw_ostream &Out);
   void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
                        const BlockDecl *BD, raw_ostream &Out);
@@ -129,7 +130,8 @@
   void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
                    raw_ostream &Out);
   // Do the right thing.
-  void mangleBlock(const BlockDecl *BD, raw_ostream &Out);
+  void mangleBlock(const BlockDecl *BD, raw_ostream &Out,
+                   const NamedDecl *ID=0);
 
   void mangleObjCMethodName(const ObjCMethodDecl *MD,
                             raw_ostream &);
diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp
index 73c9f57..d5f8371 100644
--- a/lib/AST/Mangle.cpp
+++ b/lib/AST/Mangle.cpp
@@ -40,7 +40,11 @@
                                 StringRef Outer,
                                 const BlockDecl *BD,
                                 raw_ostream &Out) {
-  Out << "__" << Outer << "_block_invoke_" << Context.getBlockId(BD, true);
+  unsigned discriminator = Context.getBlockId(BD, true);
+  if (discriminator == 0)
+    Out << "__" << Outer << "_block_invoke";
+  else
+    Out << "__" << Outer << "_block_invoke_" << discriminator+1; 
 }
 
 static void checkMangleDC(const DeclContext *DC, const BlockDecl *BD) {
@@ -62,8 +66,20 @@
 void MangleContext::anchor() { }
 
 void MangleContext::mangleGlobalBlock(const BlockDecl *BD,
+                                      const NamedDecl *ID,
                                       raw_ostream &Out) {
-  Out << "__block_global_" << getBlockId(BD, false);
+  unsigned discriminator = getBlockId(BD, false);
+  if (ID) {
+    if (shouldMangleDeclName(ID))
+      mangleName(ID, Out);
+    else {
+      Out << ID->getIdentifier()->getName();
+    }
+  }
+  if (discriminator == 0)
+    Out << "_block_invoke";
+  else
+    Out << "_block_invoke_" << discriminator+1;
 }
 
 void MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD,
@@ -99,8 +115,8 @@
     mangleObjCMethodName(Method, Stream);
   } else {
     const NamedDecl *ND = cast<NamedDecl>(DC);
-    if (IdentifierInfo *II = ND->getIdentifier())
-      Stream << II->getName();
+    if (!shouldMangleDeclName(ND) && ND->getIdentifier())
+      Stream << ND->getIdentifier()->getName();
     else {
       // FIXME: We were doing a mangleUnqualifiedName() before, but that's
       // a private member of a class that will soon itself be private to the
@@ -131,12 +147,13 @@
 }
 
 void MangleContext::mangleBlock(const BlockDecl *BD,
-                                raw_ostream &Out) {
+                                raw_ostream &Out,
+                                const NamedDecl *ID) {
   const DeclContext *DC = BD->getDeclContext();
   while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC))
     DC = DC->getParent();
   if (DC->isFunctionOrMethod())
     mangleBlock(DC, BD, Out);
   else
-    mangleGlobalBlock(BD, Out);
+    mangleGlobalBlock(BD, ID, Out);
 }
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 47c6c48..e89841c 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -630,7 +630,7 @@
   // Using the computed layout, generate the actual block function.
   bool isLambdaConv = blockInfo.getBlockDecl()->isConversionFromLambda();
   llvm::Constant *blockFn
-    = CodeGenFunction(CGM).GenerateBlockFunction(CurGD, blockInfo,
+    = CodeGenFunction(CGM, true).GenerateBlockFunction(CurGD, blockInfo,
                                                  CurFuncDecl, LocalDeclMap,
                                                  isLambdaConv);
   blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy);
@@ -1003,7 +1003,8 @@
   // Check if we should generate debug info for this block function.
   if (CGM.getModuleDebugInfo())
     DebugInfo = CGM.getModuleDebugInfo();
-
+  CurGD = GD;
+  
   BlockInfo = &blockInfo;
 
   // Arrange for local static and local extern declarations to appear
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index ceffbd4..6859394 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -28,7 +28,7 @@
 using namespace clang;
 using namespace CodeGen;
 
-CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
+CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
   : CodeGenTypeCache(cgm), CGM(cgm),
     Target(CGM.getContext().getTargetInfo()),
     Builder(cgm.getModule().getContext()),
@@ -42,7 +42,8 @@
     TerminateHandler(0), TrapBB(0) {
 
   CatchUndefined = getContext().getLangOpts().CatchUndefined;
-  CGM.getCXXABI().getMangleContext().startNewFunction();
+  if (!suppressNewContext)
+    CGM.getCXXABI().getMangleContext().startNewFunction();
 }
 
 CodeGenFunction::~CodeGenFunction() {
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index a6d77e3..b26d174 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -1198,7 +1198,7 @@
   llvm::BasicBlock *TrapBB;
 
 public:
-  CodeGenFunction(CodeGenModule &cgm);
+  CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext=false);
   ~CodeGenFunction();
 
   CodeGenTypes &getTypes() const { return CGM.getTypes(); }
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 8c1588b..8f769d9 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -347,7 +347,8 @@
   else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
     getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Out);
   else if (const BlockDecl *BD = dyn_cast<BlockDecl>(ND))
-    getCXXABI().getMangleContext().mangleBlock(BD, Out);
+    getCXXABI().getMangleContext().mangleBlock(BD, Out,
+      dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()));
   else
     getCXXABI().getMangleContext().mangleName(ND, Out);
 
@@ -368,7 +369,8 @@
   const Decl *D = GD.getDecl();
   llvm::raw_svector_ostream Out(Buffer.getBuffer());
   if (D == 0)
-    MangleCtx.mangleGlobalBlock(BD, Out);
+    MangleCtx.mangleGlobalBlock(BD, 
+      dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()), Out);
   else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
     MangleCtx.mangleCtorBlock(CD, GD.getCtorType(), BD, Out);
   else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D))
@@ -1551,8 +1553,10 @@
     // FIXME: It does so in a global constructor, which is *not* what we
     // want.
 
-    if (!Init)
+    if (!Init) {
+      initializedGlobalDecl = GlobalDecl(D);
       Init = EmitConstantInit(*InitDecl);
+    }
     if (!Init) {
       QualType T = InitExpr->getType();
       if (D->getType()->isReferenceType())
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index d1ecfec..a742d84 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -351,6 +351,8 @@
   struct {
     int GlobalUniqueCount;
   } Block;
+  
+  GlobalDecl initializedGlobalDecl;
 
   /// @}
 public:
@@ -596,7 +598,7 @@
 
   /// getUniqueBlockCount - Fetches the global unique block count.
   int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; }
-
+  
   /// getBlockDescriptorType - Fetches the type of a generic block
   /// descriptor.
   llvm::Type *getBlockDescriptorType();
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
index 9adecd0..9f98671 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
@@ -3,7 +3,7 @@
 namespace PR12746 {
   // CHECK: define zeroext i1 @_ZN7PR127462f1EPi
   bool f1(int *x) {
-    // CHECK: store i8* bitcast (i1 (i8*)* @__f1_block_invoke_0 to i8*)
+    // CHECK: store i8* bitcast (i1 (i8*)* @___ZN7PR127462f1EPi_block_invoke to i8*)
     bool (^outer)() = ^ {
       auto inner = [&]() -> bool {
 	return x == 0;
@@ -13,8 +13,8 @@
     return outer();
   }
 
-  // CHECK: define internal zeroext i1 @__f1_block_invoke_0
-  // CHECK: call zeroext i1 @"_ZNK7PR127462f119__f1_block_invoke_03$_0clEv"
+  // CHECK: define internal zeroext i1 @___ZN7PR127462f1EPi_block_invoke
+  // CHECK: call zeroext i1 @"_ZNK7PR127462f132___ZN7PR127462f1EPi_block_invoke3$_0clEv"
 
   bool f2(int *x) {
     auto outer = [&]() -> bool {
diff --git a/test/CodeGen/blocks.c b/test/CodeGen/blocks.c
index 40bab5f..71f7171 100644
--- a/test/CodeGen/blocks.c
+++ b/test/CodeGen/blocks.c
@@ -12,7 +12,7 @@
   int a[64];
 };
 
-// CHECK: define internal void @__f2_block_invoke_0(%struct.s0* noalias sret {{%.*}}, i8* {{%.*}}, %struct.s0* byval align 4 {{.*}})
+// CHECK: define internal void @__f2_block_invoke(%struct.s0* noalias sret {{%.*}}, i8* {{%.*}}, %struct.s0* byval align 4 {{.*}})
 struct s0 f2(struct s0 a0) {
   return ^(struct s0 a1){ return a1; }(a0);
 }
diff --git a/test/CodeGen/blocksignature.c b/test/CodeGen/blocksignature.c
index 63fe124..fd586eb 100644
--- a/test/CodeGen/blocksignature.c
+++ b/test/CodeGen/blocksignature.c
@@ -8,7 +8,7 @@
 
 // X32: [[STR1:@.*]] = private unnamed_addr constant [6 x i8] c"v4@?0\00" 
 // X32: @__block_descriptor_tmp = internal constant [[FULL_DESCRIPTOR_T:.*]] { i32 0, i32 20, i8* getelementptr inbounds ([6 x i8]* [[STR1]], i32 0, i32 0), i8* null }
-// X32: @__block_literal_global = internal constant [[GLOBAL_LITERAL_T:.*]] { i8** @_NSConcreteGlobalBlock, i32 1342177280, i32 0, i8* bitcast (void (i8*)* @__block_global_{{.*}} to i8*), [[DESCRIPTOR_T:%.*]]* bitcast ([[FULL_DESCRIPTOR_T]]* @__block_descriptor_tmp to {{%.*}}*) }
+// X32: @__block_literal_global = internal constant [[GLOBAL_LITERAL_T:.*]] { i8** @_NSConcreteGlobalBlock, i32 1342177280, i32 0, i8* bitcast (void (i8*)* @global_block_invoke{{.*}} to i8*), [[DESCRIPTOR_T:%.*]]* bitcast ([[FULL_DESCRIPTOR_T]]* @__block_descriptor_tmp to {{%.*}}*) }
 // X32: [[STR2:@.*]] = private unnamed_addr constant [11 x i8] c"i12@?0c4f8\00"
 // X32: @__block_descriptor_tmp{{.*}} = internal constant [[FULL_DESCRIPTOR_T]] { i32 0, i32 24, i8* getelementptr inbounds ([11 x i8]* [[STR2]], i32 0, i32 0), i8* null }
 // X32:   store i32 1073741824, i32*
diff --git a/test/CodeGen/blockwithlocalstatic.c b/test/CodeGen/blockwithlocalstatic.c
index 1fdaaf3..8b4210e 100644
--- a/test/CodeGen/blockwithlocalstatic.c
+++ b/test/CodeGen/blockwithlocalstatic.c
@@ -1,17 +1,17 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -emit-llvm -o - %s | FileCheck %s
 // pr8707
 
-// CHECK: @__block_global_0.test = internal global i32
+// CHECK: @block_block_invoke.test = internal global i32
 int (^block)(void) = ^ {
 	static int test=0;
 	return test;
 };
-// CHECK: @__block_global_1.test = internal global i32
+// CHECK: @block1_block_invoke_2.test = internal global i32
 void (^block1)(void) = ^ {
 	static int test = 2;
 	return;
 };
-// CHECK: @__block_global_2.test = internal global i32
+// CHECK: @block2_block_invoke_3.test = internal global i32
 int (^block2)(void) = ^ {
 	static int test = 5;
 	return test;
diff --git a/test/CodeGen/capture-complex-expr-in-block.c b/test/CodeGen/capture-complex-expr-in-block.c
index 9ce7570..86c93d0 100644
--- a/test/CodeGen/capture-complex-expr-in-block.c
+++ b/test/CodeGen/capture-complex-expr-in-block.c
@@ -12,7 +12,7 @@
     b();
 }
 
-// CHECK: define internal void @__main_block_invoke_0
+// CHECK: define internal void @__main_block_invoke
 // CHECK:  [[C1:%.*]] = alloca { double, double }, align 8
 // CHECK:  [[RP:%.*]] = getelementptr inbounds { double, double }* [[C1]], i32 0, i32 0
 // CHECK-NEXT:  [[R:%.*]] = load double* [[RP]]
diff --git a/test/CodeGen/func-in-block.c b/test/CodeGen/func-in-block.c
index 1900135..503695f 100644
--- a/test/CodeGen/func-in-block.c
+++ b/test/CodeGen/func-in-block.c
@@ -15,5 +15,5 @@
     return 0; // not reached
 }
 
-// CHECK: @__func__.__main_block_invoke_0 = private unnamed_addr constant [22 x i8] c"__main_block_invoke_0\00"
-// CHECK: call void @PRINTF({{.*}}@__func__.__main_block_invoke_ 
+// CHECK: @__func__.__main_block_invoke = private unnamed_addr constant [20 x i8] c"__main_block_invoke\00"
+// CHECK: call void @PRINTF({{.*}}@__func__.__main_block_invoke 
diff --git a/test/CodeGenCXX/block-in-ctor-dtor.cpp b/test/CodeGenCXX/block-in-ctor-dtor.cpp
index e4389a4..4ee6b1c 100644
--- a/test/CodeGenCXX/block-in-ctor-dtor.cpp
+++ b/test/CodeGenCXX/block-in-ctor-dtor.cpp
@@ -36,13 +36,13 @@
 };
 
 
+// CHECK: define internal void @___ZN4ZoneC2Ev_block_invoke
 // CHECK: define internal void @___ZN4ZoneC2Ev_block_invoke_
-// CHECK: define internal void @___ZN4ZoneC2Ev_block_invoke_
+// CHECK: define internal void @___ZN4ZoneD2Ev_block_invoke
 // CHECK: define internal void @___ZN4ZoneD2Ev_block_invoke_
-// CHECK: define internal void @___ZN4ZoneD2Ev_block_invoke_
+// CHECK: define internal void @___ZN1XC1Ev_block_invoke
 // CHECK: define internal void @___ZN1XC1Ev_block_invoke_
-// CHECK: define internal void @___ZN1XC1Ev_block_invoke_
+// CHECK: define internal void @___ZN1XC2Ev_block_invoke
 // CHECK: define internal void @___ZN1XC2Ev_block_invoke_
-// CHECK: define internal void @___ZN1XC2Ev_block_invoke_
-// CHECK: define internal void @___ZN1XD2Ev_block_invoke_
+// CHECK: define internal void @___ZN1XD2Ev_block_invoke
 // CHECK: define internal void @___ZN1XD2Ev_block_invoke_
diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp
index eb54478..1500c0d 100644
--- a/test/CodeGenCXX/blocks.cpp
+++ b/test/CodeGenCXX/blocks.cpp
@@ -2,8 +2,8 @@
 
 namespace test0 {
   // CHECK: define void @_ZN5test04testEi(
-  // CHECK: define internal void @__test_block_invoke_{{.*}}(
-  // CHECK: define internal void @__block_global_{{.*}}(
+  // CHECK: define internal void @___ZN5test04testEi_block_invoke{{.*}}(
+  // CHECK: define internal void @___ZN5test04testEi_block_invoke_2{{.*}}(
   void test(int x) {
     ^{ ^{ (void) x; }; };
   }
@@ -119,7 +119,7 @@
     consume(^{ return foo(A()); });
   }
   // CHECK: define void @_ZN5test44testEv()
-  // CHECK: define internal void @__test_block_invoke
+  // CHECK: define internal void @___ZN5test44testEv_block_invoke
   // CHECK:      [[TMP:%.*]] = alloca [[A:%.*]], align 1
   // CHECK-NEXT: bitcast i8*
   // CHECK-NEXT: call void @_ZN5test41AC1Ev([[A]]* [[TMP]])
diff --git a/test/CodeGenCXX/global-block-literal-helpers.cpp b/test/CodeGenCXX/global-block-literal-helpers.cpp
new file mode 100644
index 0000000..350ea54
--- /dev/null
+++ b/test/CodeGenCXX/global-block-literal-helpers.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -fblocks -o - -triple x86_64-apple-darwin10 %s | FileCheck %s
+// rdar://11343499
+
+namespace N {
+  typedef void (^BL)();
+  int func(BL, BL, BL);
+
+// CHECK: define internal void @_ZN1N8ArrBlockE_block_invoke(
+// CHECK: define internal void @_ZN1N8ArrBlockE_block_invoke_2(
+// CHECK: define internal void @_ZN1N8ArrBlockE_block_invoke_3
+  BL ArrBlock [] = { ^{}, ^{}, ^{} };
+
+// CHECK: define internal void @_ZN1N4ivalE_block_invoke_4(
+// CHECK: define internal void @_ZN1N4ivalE_block_invoke_5(
+// CHECK: define internal void @_ZN1N4ivalE_block_invoke_6(
+  int ival = func(^{}, ^{}, ^{});
+
+// CHECK: define internal void @_ZN1N9gvarlobalE_block_invoke_7(
+  void (^gvarlobal)(void) = ^{};
+
+  struct S {
+    BL field = ^{};
+  };
+
+// CHECK: define internal void @_ZN1N3blfE_block_invoke_8(
+  S blf;
+};
diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m
index 1092a87..2326bce 100644
--- a/test/CodeGenObjC/arc-blocks.m
+++ b/test/CodeGenObjC/arc-blocks.m
@@ -124,7 +124,7 @@
   // CHECK-NEXT: [[T1:%.*]] = load i8** [[T0]]
   // CHECK-NEXT: call void @objc_release(i8* [[T1]])
 
-  // CHECK:    define internal void @__test4_block_invoke_
+  // CHECK:    define internal void @__test4_block_invoke
   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 6
   // CHECK-NEXT: [[T0:%.*]] = load i8** [[SLOT]], align 8
   // CHECK-NEXT: store i8* null, i8** [[SLOT]],
@@ -200,7 +200,7 @@
   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
   // CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]])
 
-  // CHECK:    define internal void @__test6_block_invoke_
+  // CHECK:    define internal void @__test6_block_invoke
   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds {{.*}}, i32 0, i32 6
   // CHECK-NEXT: call i8* @objc_storeWeak(i8** [[SLOT]], i8* null)
   // CHECK-NEXT: ret void
@@ -238,7 +238,7 @@
   // CHECK-NEXT: call void @objc_destroyWeak(i8** [[VAR]])
   // CHECK-NEXT: ret void
 
-  // CHECK:    define internal void @__test7_block_invoke_
+  // CHECK:    define internal void @__test7_block_invoke
   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* {{%.*}}, i32 0, i32 5
   // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeak(i8** [[SLOT]])
   // CHECK-NEXT: call void @test7_consume(i8* [[T0]])
diff --git a/test/CodeGenObjC/blocks-2.m b/test/CodeGenObjC/blocks-2.m
index 8345f7c..b04fa00 100644
--- a/test/CodeGenObjC/blocks-2.m
+++ b/test/CodeGenObjC/blocks-2.m
@@ -4,7 +4,7 @@
 
 
 // CHECK: define i8* @{{.*}}test0
-// CHECK: define internal void @__test0_block_invoke_0(
+// CHECK: define internal void @{{.*}}_block_invoke(
 // CHECK:      call i8* @objc_assign_strongCast(
 // CHECK-NEXT: ret void
 id test0(id x) {
diff --git a/test/CodeGenObjC/blocks.m b/test/CodeGenObjC/blocks.m
index 490f4a0..6c85da9 100644
--- a/test/CodeGenObjC/blocks.m
+++ b/test/CodeGenObjC/blocks.m
@@ -18,7 +18,7 @@
 -(void) im0;
 @end
 
-// CHECK: define internal i32 @"__8-[A im0]_block_invoke_0"(
+// CHECK: define internal i32 @"__8-[A im0]_block_invoke"(
 @implementation A
 -(void) im0 {
   (void) ^{ return 1; }();
@@ -91,7 +91,7 @@
 // rdar://problem/9124263
 // In the test above, check that the use in the invocation function
 // doesn't require a read barrier.
-// CHECK:    define internal void @__test2_block_invoke_
+// CHECK:    define internal void @__test2_block_invoke
 // CHECK:      [[BLOCK:%.*]] = bitcast i8* {{%.*}} to [[BLOCK_T]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
 // CHECK-NEXT: [[T1:%.*]] = load i8** [[T0]]
diff --git a/test/CodeGenObjCXX/lambda-expressions.mm b/test/CodeGenObjCXX/lambda-expressions.mm
index 858cb74..ec3eb1f 100644
--- a/test/CodeGenObjCXX/lambda-expressions.mm
+++ b/test/CodeGenObjCXX/lambda-expressions.mm
@@ -9,7 +9,7 @@
 // MRC: define i32 ()* @_Z1fv(
 // MRC: define internal i32 ()* @"_ZZ1fvENK3$_0cvU13block_pointerFivEEv"
 // MRC: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*)
-// MRC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke_0" to i8*)
+// MRC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke" to i8*)
 // MRC: call i32 ()* (i8*, i8*)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 ()* (i8*, i8*)*)
 // MRC: call i32 ()* (i8*, i8*)* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 ()* (i8*, i8*)*)
 // MRC: ret i32 ()*
@@ -17,7 +17,7 @@
 // ARC: define i32 ()* @_Z1fv(
 // ARC: define internal i32 ()* @"_ZZ1fvENK3$_0cvU13block_pointerFivEEv"
 // ARC: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*)
-// ARC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke_0" to i8*)
+// ARC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke" to i8*)
 // ARC: call i8* @objc_retainBlock
 // ARC: call i8* @objc_autoreleaseReturnValue
 
@@ -26,14 +26,14 @@
 void f2() { global = []{ return 3; }; }
 
 // MRC: define void @_Z2f2v() nounwind {
-// MRC: store i8* bitcast (i32 (i8*)* @__f2_block_invoke_0 to i8*),
+// MRC: store i8* bitcast (i32 (i8*)* @___Z2f2v_block_invoke to i8*),
 // MRC-NOT: call
 // MRC: ret void
 // ("global" contains a dangling pointer after this function runs.)
 
 // ARC: define void @_Z2f2v() nounwind {
-// ARC: store i8* bitcast (i32 (i8*)* @__f2_block_invoke_0 to i8*),
+// ARC: store i8* bitcast (i32 (i8*)* @___Z2f2v_block_invoke to i8*),
 // ARC: call i8* @objc_retainBlock
 // ARC: call void @objc_release
-// ARC: define internal i32 @__f2_block_invoke_0
+// ARC: define internal i32 @___Z2f2v_block_invoke
 // ARC: call i32 @"_ZZ2f2vENK3$_1clEv
diff --git a/test/CodeGenObjCXX/mangle-blocks.mm b/test/CodeGenObjCXX/mangle-blocks.mm
index 22ca223..892c8af 100644
--- a/test/CodeGenObjCXX/mangle-blocks.mm
+++ b/test/CodeGenObjCXX/mangle-blocks.mm
@@ -1,19 +1,19 @@
 // RUN: %clang_cc1 -emit-llvm -fblocks -o - -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck %s
 
-// CHECK: @_ZGVN3foo20__foo_block_invoke_05valueE = internal global i64 0
+// CHECK: @_ZGVN3foo22___Z3foov_block_invoke5valueE = internal global i64 0
 
 int f();
 
 void foo() {
-  // CHECK: define internal i32 @__foo_block_invoke_0
-  // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVN3foo20__foo_block_invoke_05value
+  // CHECK: define internal i32 @___Z3foov_block_invoke
+  // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVN3foo22___Z3foov_block_invoke5valueE
   (void)^(int x) { 
     static int value = f();
     return x + value;
   };
 }
 
-// CHECK: define internal i32 @__block_global_0
+// CHECK: define internal i32 @i_block_invoke
 int i = ^(int x) { return x;}(i);
 
 @interface A
@@ -22,9 +22,9 @@
 
 @implementation A
 - (void)method { 
-  // CHECK: define internal signext i8 @"__11-[A method]_block_invoke_0"
+  // CHECK: define internal signext i8 @"__11-[A method]_block_invoke"
   (void)^(int x) {
-    // CHECK: @"_ZN11-[A method]30__11-[A method]_block_invoke_04nameE"
+    // CHECK: @"_ZN11-[A method]28__11-[A method]_block_invoke4nameE"
     static const char *name = "hello";
     return name[x];
   };
@@ -39,10 +39,10 @@
 }
 
 namespace N {
-  // CHECK: define internal signext i8 @__bar_block_invoke_0
+  // CHECK: define internal signext i8 @___Z3fooi_block_invoke
   void bar() {
     (void)^(int x) { 
-      // CHECK: @_ZN1N3bar20__bar_block_invoke_04nameE
+      // CHECK: @_ZN1N3bar26___ZN1N3barEv_block_invoke4nameE
       static const char *name = "hello";
       return name[x];
     };
diff --git a/test/CodeGenObjCXX/nrvo.mm b/test/CodeGenObjCXX/nrvo.mm
index 765101d..47460c2 100644
--- a/test/CodeGenObjCXX/nrvo.mm
+++ b/test/CodeGenObjCXX/nrvo.mm
@@ -22,7 +22,7 @@
 
 X blocksNRVO() {
   return ^{
-    // CHECK: define internal void @__blocksNRVO_block_invoke_0
+    // CHECK: define internal void @___Z10blocksNRVOv_block_invoke
     X x;
     // CHECK: tail call void @_ZN1XC1Ev
     // CHECK-NEXT: ret void