summaryrefslogtreecommitdiffstats
path: root/clang/lib
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 /clang/lib
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
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp29
1 files changed, 25 insertions, 4 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)) {
OpenPOWER on IntegriCloud