From: Eli Friedman Date: Wed, 10 Jul 2013 01:33:19 +0000 (+0000) Subject: Finish off mangling locals in block literals. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e79c9876aac0d933c9f97e8a36c97698b368daba;p=clang Finish off mangling locals in block literals. Specifically, handle the case where the block is in a default argument in a class method. The mangling here follows what we do for lambdas. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185991 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 2dc44eb355..76a8bf4ecc 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -56,6 +56,13 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) { = dyn_cast_or_null(RD->getLambdaContextDecl())) return ContextParam->getDeclContext(); } + + // Perform the same check for block literals. + if (const BlockDecl *BD = dyn_cast(D)) { + if (ParmVarDecl *ContextParam + = dyn_cast_or_null(BD->getBlockManglingContextDecl())) + return ContextParam->getDeclContext(); + } const DeclContext *DC = D->getDeclContext(); if (const CapturedDecl *CD = dyn_cast(DC)) @@ -1334,12 +1341,26 @@ void CXXNameMangler::mangleLocalName(const Decl *D) { const NamedDecl *ND = cast(D); mangleNestedName(ND, getEffectiveDeclContext(ND), true /*NoFunction*/); } + } else if (const BlockDecl *BD = dyn_cast(D)) { + // Mangle a block in a default parameter; see above explanation for + // lambdas. + if (const ParmVarDecl *Parm + = dyn_cast_or_null(BD->getBlockManglingContextDecl())) { + if (const FunctionDecl *Func + = dyn_cast(Parm->getDeclContext())) { + Out << 'd'; + unsigned Num = Func->getNumParams() - Parm->getFunctionScopeIndex(); + if (Num > 1) + mangleNumber(Num - 2); + Out << '_'; + } + } + + mangleUnqualifiedBlock(BD); } else { - if (const BlockDecl *BD = dyn_cast(D)) - mangleUnqualifiedBlock(BD); - else - mangleUnqualifiedName(cast(D)); + mangleUnqualifiedName(cast(D)); } + if (const NamedDecl *ND = dyn_cast(RD ? RD : D)) { unsigned disc; if (Context.getNextDiscriminator(ND, disc)) { diff --git a/test/CodeGenObjCXX/mangle-blocks.mm b/test/CodeGenObjCXX/mangle-blocks.mm index 9630c475bd..4c85229a0e 100644 --- a/test/CodeGenObjCXX/mangle-blocks.mm +++ b/test/CodeGenObjCXX/mangle-blocks.mm @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -emit-llvm -fblocks -o - -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck %s // CHECK: @_ZGVZZ3foovEUb_E5value = internal global i64 0 +// CHECK: @_ZZZN26externally_visible_statics1S3fooEiEd_Ub_E1k = linkonce_odr global i32 0 // CHECK: @_ZZ26externally_visible_statics1S1xMUb_E1j = linkonce_odr global i32 0 // CHECK: @_ZZZN26externally_visible_statics10inlinefuncEvEUb_E1i = linkonce_odr global i32 0 @@ -79,10 +80,6 @@ namespace externally_visible_statics { void g() { inlinefunc(); S s; -#if 0 - // FIXME: We know how to mangle k, but crash trying to mangle the - // block itself. s.foo(); -#endif } }