diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-10-14 17:20:14 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-10-14 17:20:14 +0000 |
commit | 64ab4de44339d84e8ecf578e260b68aeb142187b (patch) | |
tree | aefac88c2b2dfd33c1c368d59dec35b3a2944ede /clang/lib/AST/Mangle.cpp | |
parent | 24026502d5df709997d447a7babdc6b2983a4090 (diff) |
CodeGen: correct mangling for blocks
This addresses a regression introduced with SVN r219393. A block may be
contained within another block. In such a scenario, we would end up within a
BlockDecl, which is not a NamedDecl (as the names are synthesised). The cast to
a NamedDecl of the DeclContext would then assert as the types are unrelated.
Restore the mangling behaviour to that prior to SVN r219393. If the current
block is contained within a BlockDecl, walk up to the parent DeclContext,
recursively, until we have a non-BlockDecl. This is expected to be a NamedDecl.
Add in a couple of asserts to ensure that the assumption that we only encounter
a block within a NamedDecl or a BlockDecl.
llvm-svn: 219696
Diffstat (limited to 'clang/lib/AST/Mangle.cpp')
-rw-r--r-- | clang/lib/AST/Mangle.cpp | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp index fdc00e389350..fba835451e29 100644 --- a/clang/lib/AST/Mangle.cpp +++ b/clang/lib/AST/Mangle.cpp @@ -215,6 +215,12 @@ void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD, if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) { mangleObjCMethodName(Method, Stream); } else { + assert((isa<NamedDecl>(DC) || isa<BlockDecl>(DC)) && + "expected a NamedDecl or BlockDecl"); + if (isa<BlockDecl>(DC)) + for (; DC && isa<BlockDecl>(DC); DC = DC->getParent()) + (void) getBlockId(cast<BlockDecl>(DC), true); + assert(isa<NamedDecl>(DC) && "expected a NamedDecl"); const NamedDecl *ND = cast<NamedDecl>(DC); if (!shouldMangleDeclName(ND) && ND->getIdentifier()) Stream << ND->getIdentifier()->getName(); |