aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/Mangle.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-10-18 21:28:44 +0000
committerJohn McCall <rjmccall@apple.com>2010-10-18 21:28:44 +0000
commit82b7d7bc723051d8db4e21883e9072fe3ad99305 (patch)
treee4aceef2e283819c38003faf9ac501d66e543e33 /lib/CodeGen/Mangle.cpp
parentc7b7b7a8eda7a5316ad1062b7f81a339f5550bca (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.cpp40
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