From fd035e6496665b1f1197868e21cb0a4594e8db6e Mon Sep 17 00:00:00 2001 From: rdivacky Date: Tue, 16 Feb 2010 09:31:36 +0000 Subject: Update clang to r96341. --- lib/CodeGen/Mangle.cpp | 320 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 287 insertions(+), 33 deletions(-) (limited to 'lib/CodeGen/Mangle.cpp') diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index d873cfe..a302225 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -26,6 +26,13 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/ErrorHandling.h" #include "CGVtable.h" + +#define MANGLE_CHECKER 0 + +#if MANGLE_CHECKER +#include +#endif + using namespace clang; using namespace CodeGen; @@ -44,6 +51,8 @@ static const CXXMethodDecl *getStructor(const CXXMethodDecl *MD) { return MD; } + +static const unsigned UnknownArity = ~0U; /// CXXNameMangler - Manage the mangling of a single name. class CXXNameMangler { @@ -55,6 +64,8 @@ class CXXNameMangler { llvm::DenseMap Substitutions; + ASTContext &getASTContext() const { return Context.getASTContext(); } + public: CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl &Res) : Context(C), Out(Res), Structor(0), StructorType(0) { } @@ -65,6 +76,17 @@ public: const CXXDestructorDecl *D, CXXDtorType Type) : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type) { } +#if MANGLE_CHECKER + ~CXXNameMangler() { + if (Out.str()[0] == '\01') + return; + + int status = 0; + char *result = abi::__cxa_demangle(Out.str().str().c_str(), 0, 0, &status); + assert(status == 0 && "Could not demangle mangled name!"); + free(result); + } +#endif llvm::raw_svector_ostream &getStream() { return Out; } void mangle(const NamedDecl *D, llvm::StringRef Prefix = "_Z"); @@ -89,10 +111,19 @@ private: void addSubstitution(QualType T); void addSubstitution(uintptr_t Ptr); + void mangleUnresolvedScope(NestedNameSpecifier *Qualifier); + void mangleUnresolvedName(NestedNameSpecifier *Qualifier, + DeclarationName Name, + unsigned KnownArity = UnknownArity); + void mangleName(const TemplateDecl *TD, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs); - void mangleUnqualifiedName(const NamedDecl *ND); + void mangleUnqualifiedName(const NamedDecl *ND) { + mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity); + } + void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, + unsigned KnownArity); void mangleUnscopedName(const NamedDecl *ND); void mangleUnscopedTemplateName(const TemplateDecl *ND); void mangleSourceName(const IdentifierInfo *II); @@ -119,6 +150,11 @@ private: bool MangleReturnType); void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value); + void mangleMemberExpr(const Expr *Base, bool IsArrow, + NestedNameSpecifier *Qualifier, + DeclarationName Name, + unsigned KnownArity); + void mangleCalledExpression(const Expr *E, unsigned KnownArity); void mangleExpression(const Expr *E); void mangleCXXCtorType(CXXCtorType T); void mangleCXXDtorType(CXXDtorType T); @@ -171,14 +207,14 @@ bool MangleContext::shouldMangleDeclName(const NamedDecl *D) { isInExternCSystemHeader(D->getLocation())) return false; - // Variables at global scope are not mangled. + // Variables at global scope with non-internal linkage are not mangled if (!FD) { const DeclContext *DC = D->getDeclContext(); // Check for extern variable declared locally. if (isa(DC) && D->hasLinkage()) while (!DC->isNamespace() && !DC->isTranslationUnit()) DC = DC->getParent(); - if (DC->isTranslationUnit()) + if (DC->isTranslationUnit() && D->getLinkage() != InternalLinkage) return false; } @@ -199,13 +235,10 @@ void CXXNameMangler::mangle(const NamedDecl *D, llvm::StringRef Prefix) { return; } - // ::= _Z [L] + // ::= _Z // ::= // ::= Out << Prefix; - if (D->getLinkage() == NamedDecl::InternalLinkage) // match gcc behavior - Out << 'L'; - if (const FunctionDecl *FD = dyn_cast(D)) mangleFunctionEncoding(FD); else @@ -367,6 +400,13 @@ void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) { if (mangleSubstitution(ND)) return; + // ::= + if (const TemplateTemplateParmDecl *TTP + = dyn_cast(ND)) { + mangleTemplateParameter(TTP->getIndex()); + return; + } + mangleUnscopedName(ND->getTemplatedDecl()); addSubstitution(ND); } @@ -401,28 +441,69 @@ void CXXNameMangler::mangleCallOffset(const ThunkAdjustment &Adjustment) { Out << '_'; } -void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) { +void CXXNameMangler::mangleUnresolvedScope(NestedNameSpecifier *Qualifier) { + Qualifier = getASTContext().getCanonicalNestedNameSpecifier(Qualifier); + switch (Qualifier->getKind()) { + case NestedNameSpecifier::Global: + // nothing + break; + case NestedNameSpecifier::Namespace: + mangleName(Qualifier->getAsNamespace()); + break; + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + mangleType(QualType(Qualifier->getAsType(), 0)); + break; + case NestedNameSpecifier::Identifier: + mangleUnresolvedScope(Qualifier->getPrefix()); + mangleSourceName(Qualifier->getAsIdentifier()); + break; + } +} + +/// Mangles a name which was not resolved to a specific entity. +void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *Qualifier, + DeclarationName Name, + unsigned KnownArity) { + if (Qualifier) + mangleUnresolvedScope(Qualifier); + // FIXME: ambiguity of unqualified lookup with :: + + mangleUnqualifiedName(0, Name, KnownArity); +} + +void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, + DeclarationName Name, + unsigned KnownArity) { // ::= // ::= // ::= - DeclarationName Name = ND->getDeclName(); switch (Name.getNameKind()) { case DeclarationName::Identifier: { + if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) { + // We must avoid conflicts between internally- and externally- + // linked variable declaration names in the same TU. + // This naming convention is the same as that followed by GCC, though it + // shouldn't actually matter. + if (ND && isa(ND) && ND->getLinkage() == InternalLinkage && + ND->getDeclContext()->isFileContext()) + Out << 'L'; + + mangleSourceName(II); + break; + } + + // Otherwise, an anonymous entity. We must have a declaration. + assert(ND && "mangling empty name without declaration"); + if (const NamespaceDecl *NS = dyn_cast(ND)) { if (NS->isAnonymousNamespace()) { - // This is how gcc mangles these names. It's apparently - // always '1', no matter how many different anonymous - // namespaces appear in a context. + // This is how gcc mangles these names. Out << "12_GLOBAL__N_1"; break; } } - if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) { - mangleSourceName(II); - break; - } - // We must have an anonymous struct. const TagDecl *TD = cast(ND); if (const TypedefDecl *D = TD->getTypedefForAnonDecl()) { @@ -484,13 +565,18 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) { break; case DeclarationName::CXXOperatorName: { - unsigned Arity = cast(ND)->getNumParams(); + unsigned Arity; + if (ND) { + Arity = cast(ND)->getNumParams(); - // If we have a C++ member function, we need to include the 'this' pointer. - // FIXME: This does not make sense for operators that are static, but their - // names stay the same regardless of the arity (operator new for instance). - if (isa(ND)) - Arity++; + // If we have a C++ member function, we need to include the 'this' pointer. + // FIXME: This does not make sense for operators that are static, but their + // names stay the same regardless of the arity (operator new for instance). + if (isa(ND)) + Arity++; + } else + Arity = KnownArity; + mangleOperatorName(Name.getCXXOverloadedOperator(), Arity); break; } @@ -596,15 +682,21 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND) { // ::=