diff options
author | John McCall <rjmccall@apple.com> | 2010-10-18 21:28:44 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-10-18 21:28:44 +0000 |
commit | 82b7d7bc723051d8db4e21883e9072fe3ad99305 (patch) | |
tree | e4aceef2e283819c38003faf9ac501d66e543e33 /lib/CodeGen/Mangle.cpp | |
parent | c7b7b7a8eda7a5316ad1062b7f81a339f5550bca (diff) |
Fix some bugs in local class mangling brought up in PR8355.
Patch by Richard Smith!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116752 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/Mangle.cpp')
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 36c908b099..e47d9cb43a 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -99,14 +99,14 @@ void MiscNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) { namespace { -static const DeclContext *GetLocalClassFunctionDeclContext( - const DeclContext *DC) { - if (isa<CXXRecordDecl>(DC)) { - while (!DC->isNamespace() && !DC->isTranslationUnit() && - !isa<FunctionDecl>(DC)) - DC = DC->getParent(); - if (isa<FunctionDecl>(DC)) - return DC; +static const CXXRecordDecl *GetLocalClassDecl(const NamedDecl *ND) { + const DeclContext *DC = dyn_cast<DeclContext>(ND); + if (!DC) + DC = ND->getDeclContext(); + while (!DC->isNamespace() && !DC->isTranslationUnit()) { + if (isa<FunctionDecl>(DC->getParent())) + return dyn_cast<CXXRecordDecl>(DC); + DC = DC->getParent(); } return 0; } @@ -433,16 +433,15 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) { // const DeclContext *DC = ND->getDeclContext(); - if (GetLocalClassFunctionDeclContext(DC)) { - mangleLocalName(ND); - return; - } - // If this is an extern variable declared locally, the relevant DeclContext // is that of the containing namespace, or the translation unit. if (isa<FunctionDecl>(DC) && ND->hasLinkage()) while (!DC->isNamespace() && !DC->isTranslationUnit()) DC = DC->getParent(); + else if (GetLocalClassDecl(ND)) { + mangleLocalName(ND); + return; + } while (isa<LinkageSpecDecl>(DC)) DC = DC->getParent(); @@ -853,15 +852,18 @@ void CXXNameMangler::mangleLocalName(const NamedDecl *ND) { if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) { mangleObjCMethodName(MD); - } - else if (const DeclContext *CDC = GetLocalClassFunctionDeclContext(DC)) { - mangleFunctionEncoding(cast<FunctionDecl>(CDC)); + } else if (const CXXRecordDecl *RD = GetLocalClassDecl(ND)) { + mangleFunctionEncoding(cast<FunctionDecl>(RD->getDeclContext())); Out << 'E'; - mangleNestedName(ND, DC, true /*NoFunction*/); - // FIXME. This still does not cover all cases. + // Mangle the name relative to the closest enclosing function. + if (ND == RD) // equality ok because RD derived from ND above + mangleUnqualifiedName(ND); + else + mangleNestedName(ND, DC, true /*NoFunction*/); + unsigned disc; - if (Context.getNextDiscriminator(ND, disc)) { + if (Context.getNextDiscriminator(RD, disc)) { if (disc < 10) Out << '_' << disc; else |