summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2013-07-10 01:33:19 +0000
committerEli Friedman <eli.friedman@gmail.com>2013-07-10 01:33:19 +0000
commit0cd23357550d8a817d753c34b36320cff7deb92f (patch)
treec72c7ad9f0a3f37a8bed221c8f520267578365f9
parent3046e668301ec9df4ead087fdc906877b9dcbf82 (diff)
downloadbcm5719-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.cpp29
-rw-r--r--clang/test/CodeGenObjCXX/mangle-blocks.mm5
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
}
}
OpenPOWER on IntegriCloud