diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 2dc44eb35559613182241949de4b709749212b47..76a8bf4ecc4ed45bd5ead6f75fd6ad5f6a762a5d 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<ParmVarDecl>(RD->getLambdaContextDecl())) return ContextParam->getDeclContext(); } + + // Perform the same check for block literals. + if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { + if (ParmVarDecl *ContextParam + = dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl())) + return ContextParam->getDeclContext(); + } const DeclContext *DC = D->getDeclContext(); if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(DC)) @@ -1334,12 +1341,26 @@ void CXXNameMangler::mangleLocalName(const Decl *D) { const NamedDecl *ND = cast<NamedDecl>(D); mangleNestedName(ND, getEffectiveDeclContext(ND), true /*NoFunction*/); } + } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { + // Mangle a block in a default parameter; see above explanation for + // lambdas. + if (const ParmVarDecl *Parm + = dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl())) { + if (const FunctionDecl *Func + = dyn_cast<FunctionDecl>(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<BlockDecl>(D)) - mangleUnqualifiedBlock(BD); - else - mangleUnqualifiedName(cast<NamedDecl>(D)); + mangleUnqualifiedName(cast<NamedDecl>(D)); } + if (const NamedDecl *ND = dyn_cast<NamedDecl>(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 9630c475bdb9cb86fd3586bcc1e7074c68d7d162..4c85229a0e02e6d3ac003a94817a59e36cdabd64 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 } }