CodeGen: correct mangling for blocks

This addresses a regression introduced with SVN r219393.  A block may be
contained within another block.  In such a scenario, we would end up within a
BlockDecl, which is not a NamedDecl (as the names are synthesised).  The cast to
a NamedDecl of the DeclContext would then assert as the types are unrelated.

Restore the mangling behaviour to that prior to SVN r219393.  If the current
block is contained within a BlockDecl, walk up to the parent DeclContext,
recursively, until we have a non-BlockDecl.  This is expected to be a NamedDecl.
Add in a couple of asserts to ensure that the assumption that we only encounter
a block within a NamedDecl or a BlockDecl.

llvm-svn: 219696
This commit is contained in:
Saleem Abdulrasool 2014-10-14 17:20:14 +00:00
parent 24026502d5
commit 64ab4de443
2 changed files with 26 additions and 0 deletions

View File

@ -215,6 +215,12 @@ void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD,
if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
mangleObjCMethodName(Method, Stream);
} else {
assert((isa<NamedDecl>(DC) || isa<BlockDecl>(DC)) &&
"expected a NamedDecl or BlockDecl");
if (isa<BlockDecl>(DC))
for (; DC && isa<BlockDecl>(DC); DC = DC->getParent())
(void) getBlockId(cast<BlockDecl>(DC), true);
assert(isa<NamedDecl>(DC) && "expected a NamedDecl");
const NamedDecl *ND = cast<NamedDecl>(DC);
if (!shouldMangleDeclName(ND) && ND->getIdentifier())
Stream << ND->getIdentifier()->getName();

View File

@ -0,0 +1,20 @@
// RUN: %clang_cc1 -triple i386-apple-ios -fblocks -emit-llvm -o - %s | FileCheck %s
void __assert_rtn(const char *, const char *, int, const char *)
__attribute__ (( noreturn ));
void invoke(void (^)(void));
void mangle(void) {
invoke(^{ invoke(^{ __assert_rtn(__func__, __FILE__, __LINE__, "mangle"); }); });
}
// CHECK: @__func__.__mangle_block_invoke_2 = private unnamed_addr constant [24 x i8] c"__mangle_block_invoke_2\00", align 1
// CHECK: @.str = private unnamed_addr constant {{.*}}, align 1
// CHECK: @.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 ([24 x i8]* @__func__.__mangle_block_invoke_2, i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 8, i8* getelementptr inbounds ([7 x i8]* @.str1, i32 0, i32 0))
// CHECK: }