diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2013-07-10 01:33:19 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2013-07-10 01:33:19 +0000 |
commit | 0cd23357550d8a817d753c34b36320cff7deb92f (patch) | |
tree | c72c7ad9f0a3f37a8bed221c8f520267578365f9 | |
parent | 3046e668301ec9df4ead087fdc906877b9dcbf82 (diff) | |
download | bcm5719-llvm-0cd23357550d8a817d753c34b36320cff7deb92f.tar.gz bcm5719-llvm-0cd23357550d8a817d753c34b36320cff7deb92f.zip |
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.
llvm-svn: 185991
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 29 | ||||
-rw-r--r-- | clang/test/CodeGenObjCXX/mangle-blocks.mm | 5 |
2 files changed, 26 insertions, 8 deletions
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 2dc44eb3555..76a8bf4ecc4 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/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/clang/test/CodeGenObjCXX/mangle-blocks.mm b/clang/test/CodeGenObjCXX/mangle-blocks.mm index 9630c475bdb..4c85229a0e0 100644 --- a/clang/test/CodeGenObjCXX/mangle-blocks.mm +++ b/clang/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 } } |