diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-03-03 19:41:08 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-03-03 19:41:08 +0000 |
commit | 570585307ef1e33490883b26b807cd2a5f88e99d (patch) | |
tree | ac38f6b8b36ad68a7aa3463f4c621af6c450ba44 /lib/CodeGen/Mangle.cpp | |
parent | 2752c0137d95aa2f4ee1cdff4b564bac842e041b (diff) |
Implements mangling of local class names to
fix a code gen crash. This is WIP as not
all ABI cases are covered (there is a FIXME to
this effect). Fixes radar 7696748.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97658 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/Mangle.cpp')
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index 64743c7696..e053f78008 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -37,7 +37,19 @@ using namespace clang; using namespace CodeGen; 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; + } + return 0; +} + static const CXXMethodDecl *getStructor(const CXXMethodDecl *MD) { assert((isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) && "Passed in decl is not a ctor or dtor!"); @@ -53,6 +65,8 @@ static const CXXMethodDecl *getStructor(const CXXMethodDecl *MD) { } static const unsigned UnknownArity = ~0U; +static unsigned Discriminator = 0; +static llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier; /// CXXNameMangler - Manage the mangling of a single name. class CXXNameMangler { @@ -61,7 +75,7 @@ class CXXNameMangler { const CXXMethodDecl *Structor; unsigned StructorType; - + llvm::DenseMap<uintptr_t, unsigned> Substitutions; ASTContext &getASTContext() const { return Context.getASTContext(); } @@ -128,11 +142,12 @@ private: void mangleUnscopedTemplateName(const TemplateDecl *ND); void mangleSourceName(const IdentifierInfo *II); void mangleLocalName(const NamedDecl *ND); - void mangleNestedName(const NamedDecl *ND, const DeclContext *DC); + void mangleNestedName(const NamedDecl *ND, const DeclContext *DC, + bool NoFunction=false); void mangleNestedName(const TemplateDecl *TD, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs); - void manglePrefix(const DeclContext *DC); + void manglePrefix(const DeclContext *DC, bool NoFunction=false); void mangleTemplatePrefix(const TemplateDecl *ND); void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity); void mangleQualifiers(Qualifiers Quals); @@ -342,7 +357,12 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) { // ::= <local-name> // 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()) @@ -603,7 +623,8 @@ void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) { } void CXXNameMangler::mangleNestedName(const NamedDecl *ND, - const DeclContext *DC) { + const DeclContext *DC, + bool NoFunction) { // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E // ::= N [<CV-qualifiers>] <template-prefix> <template-args> E @@ -616,8 +637,9 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND, if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { mangleTemplatePrefix(TD); mangleTemplateArgs(*TemplateArgs); - } else { - manglePrefix(DC); + } + else { + manglePrefix(DC, NoFunction); mangleUnqualifiedName(ND); } @@ -640,18 +662,38 @@ void CXXNameMangler::mangleLocalName(const NamedDecl *ND) { // <local-name> := Z <function encoding> E <entity name> [<discriminator>] // := Z <function encoding> E s [<discriminator>] // <discriminator> := _ <non-negative number> + const DeclContext *DC = ND->getDeclContext(); Out << 'Z'; - if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ND->getDeclContext())) + if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) mangleObjCMethodName(MD); + else if (const DeclContext *CDC = GetLocalClassFunctionDeclContext(DC)) { + mangleFunctionEncoding(cast<FunctionDecl>(CDC)); + Out << 'E'; + mangleNestedName(ND, DC, true /*NoFunction*/); + + // FIXME. This still does not conform to ABI and does not cover all cases. + unsigned &discriminator = Uniquifier[ND]; + if (!discriminator) + discriminator = ++Discriminator; + if (discriminator == 1) + return; + unsigned disc = discriminator-2; + if (disc < 10) + Out << '_' << disc; + else + Out << "__" << disc << '_'; + + return; + } else - mangleFunctionEncoding(cast<FunctionDecl>(ND->getDeclContext())); + mangleFunctionEncoding(cast<FunctionDecl>(DC)); Out << 'E'; mangleUnqualifiedName(ND); } -void CXXNameMangler::manglePrefix(const DeclContext *DC) { +void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) { // <prefix> ::= <prefix> <unqualified-name> // ::= <template-prefix> <template-args> // ::= <template-param> @@ -672,8 +714,11 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC) { if (const TemplateDecl *TD = isTemplate(cast<NamedDecl>(DC), TemplateArgs)) { mangleTemplatePrefix(TD); mangleTemplateArgs(*TemplateArgs); - } else { - manglePrefix(DC->getParent()); + } + else if(NoFunction && isa<FunctionDecl>(DC)) + return; + else { + manglePrefix(DC->getParent(), NoFunction); mangleUnqualifiedName(cast<NamedDecl>(DC)); } |