diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-02-19 02:16:16 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-02-19 02:16:16 +0000 |
commit | b8014dd7c074d4058c962e426332fc8e9babdda1 (patch) | |
tree | a31062d685489781ea2273a68d3c626c90a62a7a /clang/lib/AST/ItaniumMangle.cpp | |
parent | 0a52cd7937f2bd1ad97cc35e5dae74bfb949f2d5 (diff) | |
download | bcm5719-llvm-b8014dd7c074d4058c962e426332fc8e9babdda1.tar.gz bcm5719-llvm-b8014dd7c074d4058c962e426332fc8e9babdda1.zip |
Itanium ABI: Properly qualify the destructor-name
We didn't have enough qualificaiton before the scope specifier and we
had too much qualification in the destructor name itself.
llvm-svn: 229809
Diffstat (limited to 'clang/lib/AST/ItaniumMangle.cpp')
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 375 |
1 files changed, 169 insertions, 206 deletions
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 9e9f8660def..89bf8d0970a 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -327,10 +327,8 @@ private: void addSubstitution(uintptr_t Ptr); void mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, - NamedDecl *firstQualifierLookup, bool recursive = false); void mangleUnresolvedName(NestedNameSpecifier *qualifier, - NamedDecl *firstQualifierLookup, DeclarationName name, unsigned KnownArity = UnknownArity); @@ -360,7 +358,8 @@ private: void manglePrefix(QualType type); void mangleTemplatePrefix(const TemplateDecl *ND, bool NoFunction=false); void mangleTemplatePrefix(TemplateName Template); - void mangleDestructorName(QualType DestroyedType); + bool mangleUnresolvedTypeOrSimpleId(QualType DestroyedType, + StringRef Prefix = ""); void mangleOperatorName(DeclarationName Name, unsigned Arity); void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity); void mangleQualifiers(Qualifiers Quals); @@ -799,7 +798,6 @@ void CXXNameMangler::manglePrefix(QualType type) { /// \param recursive - true if this is being called recursively, /// i.e. if there is more prefix "to the right". void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, - NamedDecl *firstQualifierLookup, bool recursive) { // x, ::x @@ -832,7 +830,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, case NestedNameSpecifier::Namespace: if (qualifier->getPrefix()) - mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup, + mangleUnresolvedPrefix(qualifier->getPrefix(), /*recursive*/ true); else Out << "sr"; @@ -840,7 +838,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, break; case NestedNameSpecifier::NamespaceAlias: if (qualifier->getPrefix()) - mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup, + mangleUnresolvedPrefix(qualifier->getPrefix(), /*recursive*/ true); else Out << "sr"; @@ -857,193 +855,26 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, // - a template template parameter with arguments // In all of these cases, we should have no prefix. if (qualifier->getPrefix()) { - mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup, + mangleUnresolvedPrefix(qualifier->getPrefix(), /*recursive*/ true); } else { // Otherwise, all the cases want this. Out << "sr"; } - // Only certain other types are valid as prefixes; enumerate them. - switch (type->getTypeClass()) { - case Type::Builtin: - case Type::Complex: - case Type::Adjusted: - case Type::Decayed: - case Type::Pointer: - case Type::BlockPointer: - case Type::LValueReference: - case Type::RValueReference: - case Type::MemberPointer: - case Type::ConstantArray: - case Type::IncompleteArray: - case Type::VariableArray: - case Type::DependentSizedArray: - case Type::DependentSizedExtVector: - case Type::Vector: - case Type::ExtVector: - case Type::FunctionProto: - case Type::FunctionNoProto: - case Type::Enum: - case Type::Paren: - case Type::Elaborated: - case Type::Attributed: - case Type::Auto: - case Type::PackExpansion: - case Type::ObjCObject: - case Type::ObjCInterface: - case Type::ObjCObjectPointer: - case Type::Atomic: - llvm_unreachable("type is illegal as a nested name specifier"); - - case Type::SubstTemplateTypeParmPack: - // FIXME: not clear how to mangle this! - // template <class T...> class A { - // template <class U...> void foo(decltype(T::foo(U())) x...); - // }; - Out << "_SUBSTPACK_"; - break; - - // <unresolved-type> ::= <template-param> - // ::= <decltype> - // ::= <template-template-param> <template-args> - // (this last is not official yet) - case Type::TypeOfExpr: - case Type::TypeOf: - case Type::Decltype: - case Type::TemplateTypeParm: - case Type::UnaryTransform: - case Type::SubstTemplateTypeParm: - unresolvedType: - assert(!qualifier->getPrefix()); - - // We only get here recursively if we're followed by identifiers. - if (recursive) Out << 'N'; - - // This seems to do everything we want. It's not really - // sanctioned for a substituted template parameter, though. - mangleType(QualType(type, 0)); - - // We never want to print 'E' directly after an unresolved-type, - // so we return directly. + if (mangleUnresolvedTypeOrSimpleId(QualType(type, 0), recursive ? "N" : "")) return; - case Type::Typedef: - mangleSourceName(cast<TypedefType>(type)->getDecl()->getIdentifier()); - break; - - case Type::UnresolvedUsing: - mangleSourceName(cast<UnresolvedUsingType>(type)->getDecl() - ->getIdentifier()); - break; - - case Type::Record: - mangleSourceName(cast<RecordType>(type)->getDecl()->getIdentifier()); - break; - - case Type::TemplateSpecialization: { - const TemplateSpecializationType *tst - = cast<TemplateSpecializationType>(type); - TemplateName name = tst->getTemplateName(); - switch (name.getKind()) { - case TemplateName::Template: - case TemplateName::QualifiedTemplate: { - TemplateDecl *temp = name.getAsTemplateDecl(); - - // If the base is a template template parameter, this is an - // unresolved type. - assert(temp && "no template for template specialization type"); - if (isa<TemplateTemplateParmDecl>(temp)) goto unresolvedType; - - mangleSourceName(temp->getIdentifier()); - break; - } - - case TemplateName::OverloadedTemplate: - case TemplateName::DependentTemplate: - llvm_unreachable("invalid base for a template specialization type"); - - case TemplateName::SubstTemplateTemplateParm: { - SubstTemplateTemplateParmStorage *subst - = name.getAsSubstTemplateTemplateParm(); - mangleExistingSubstitution(subst->getReplacement()); - break; - } - - case TemplateName::SubstTemplateTemplateParmPack: { - // FIXME: not clear how to mangle this! - // template <template <class U> class T...> class A { - // template <class U...> void foo(decltype(T<U>::foo) x...); - // }; - Out << "_SUBSTPACK_"; - break; - } - } - - mangleTemplateArgs(tst->getArgs(), tst->getNumArgs()); - break; - } - - case Type::InjectedClassName: - mangleSourceName(cast<InjectedClassNameType>(type)->getDecl() - ->getIdentifier()); - break; - - case Type::DependentName: - mangleSourceName(cast<DependentNameType>(type)->getIdentifier()); - break; - - case Type::DependentTemplateSpecialization: { - const DependentTemplateSpecializationType *tst - = cast<DependentTemplateSpecializationType>(type); - mangleSourceName(tst->getIdentifier()); - mangleTemplateArgs(tst->getArgs(), tst->getNumArgs()); - break; - } - } break; } case NestedNameSpecifier::Identifier: // Member expressions can have these without prefixes. - if (qualifier->getPrefix()) { - mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup, + if (qualifier->getPrefix()) + mangleUnresolvedPrefix(qualifier->getPrefix(), /*recursive*/ true); - } else if (firstQualifierLookup) { - - // Try to make a proper qualifier out of the lookup result, and - // then just recurse on that. - NestedNameSpecifier *newQualifier; - if (TypeDecl *typeDecl = dyn_cast<TypeDecl>(firstQualifierLookup)) { - QualType type = getASTContext().getTypeDeclType(typeDecl); - - // Pretend we had a different nested name specifier. - newQualifier = NestedNameSpecifier::Create(getASTContext(), - /*prefix*/ nullptr, - /*template*/ false, - type.getTypePtr()); - } else if (NamespaceDecl *nspace = - dyn_cast<NamespaceDecl>(firstQualifierLookup)) { - newQualifier = NestedNameSpecifier::Create(getASTContext(), - /*prefix*/ nullptr, - nspace); - } else if (NamespaceAliasDecl *alias = - dyn_cast<NamespaceAliasDecl>(firstQualifierLookup)) { - newQualifier = NestedNameSpecifier::Create(getASTContext(), - /*prefix*/ nullptr, - alias); - } else { - // No sensible mangling to do here. - newQualifier = nullptr; - } - - if (newQualifier) - return mangleUnresolvedPrefix(newQualifier, /*lookup*/ nullptr, - recursive); - - } else { + else Out << "sr"; - } mangleSourceName(qualifier->getAsIdentifier()); break; @@ -1058,10 +889,9 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, /// Mangle an unresolved-name, which is generally used for names which /// weren't resolved to specific entities. void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier, - NamedDecl *firstQualifierLookup, DeclarationName name, unsigned knownArity) { - if (qualifier) mangleUnresolvedPrefix(qualifier, firstQualifierLookup); + if (qualifier) mangleUnresolvedPrefix(qualifier); switch (name.getNameKind()) { // <base-unresolved-name> ::= <simple-id> case DeclarationName::Identifier: @@ -1070,7 +900,7 @@ void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier, // <base-unresolved-name> ::= dn <destructor-name> case DeclarationName::CXXDestructorName: Out << "dn"; - mangleDestructorName(name.getCXXNameType()); + mangleUnresolvedTypeOrSimpleId(name.getCXXNameType()); break; // <base-unresolved-name> ::= on <operator-name> case DeclarationName::CXXConversionFunctionName: @@ -1648,29 +1478,149 @@ void CXXNameMangler::mangleType(TemplateName TN) { addSubstitution(TN); } -void CXXNameMangler::mangleDestructorName(QualType DestroyedType) { - // <destructor-name> ::= <unresolved-type> - // ::= <simple-id> - if (const auto *TST = DestroyedType->getAs<TemplateSpecializationType>()) { +bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, + StringRef Prefix) { + // Only certain other types are valid as prefixes; enumerate them. + switch (Ty->getTypeClass()) { + case Type::Builtin: + case Type::Complex: + case Type::Adjusted: + case Type::Decayed: + case Type::Pointer: + case Type::BlockPointer: + case Type::LValueReference: + case Type::RValueReference: + case Type::MemberPointer: + case Type::ConstantArray: + case Type::IncompleteArray: + case Type::VariableArray: + case Type::DependentSizedArray: + case Type::DependentSizedExtVector: + case Type::Vector: + case Type::ExtVector: + case Type::FunctionProto: + case Type::FunctionNoProto: + case Type::Paren: + case Type::Attributed: + case Type::Auto: + case Type::PackExpansion: + case Type::ObjCObject: + case Type::ObjCInterface: + case Type::ObjCObjectPointer: + case Type::Atomic: + llvm_unreachable("type is illegal as a nested name specifier"); + + case Type::SubstTemplateTypeParmPack: + // FIXME: not clear how to mangle this! + // template <class T...> class A { + // template <class U...> void foo(decltype(T::foo(U())) x...); + // }; + Out << "_SUBSTPACK_"; + break; + + // <unresolved-type> ::= <template-param> + // ::= <decltype> + // ::= <template-template-param> <template-args> + // (this last is not official yet) + case Type::TypeOfExpr: + case Type::TypeOf: + case Type::Decltype: + case Type::TemplateTypeParm: + case Type::UnaryTransform: + case Type::SubstTemplateTypeParm: + unresolvedType: + // Some callers want a prefix before the mangled type. + Out << Prefix; + + // This seems to do everything we want. It's not really + // sanctioned for a substituted template parameter, though. + mangleType(Ty); + + // We never want to print 'E' directly after an unresolved-type, + // so we return directly. + return true; + + case Type::Typedef: + mangleSourceName(cast<TypedefType>(Ty)->getDecl()->getIdentifier()); + break; + + case Type::UnresolvedUsing: + mangleSourceName( + cast<UnresolvedUsingType>(Ty)->getDecl()->getIdentifier()); + break; + + case Type::Enum: + case Type::Record: + mangleSourceName(cast<TagType>(Ty)->getDecl()->getIdentifier()); + break; + + case Type::TemplateSpecialization: { + const TemplateSpecializationType *TST = + cast<TemplateSpecializationType>(Ty); TemplateName TN = TST->getTemplateName(); - const auto *TD = TN.getAsTemplateDecl(); - if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TD)) { - // Proposed to cxx-abi-dev on 2015-02-17. - mangleTemplateParameter(TTP->getIndex()); - } else { - mangleUnscopedName(TD->getTemplatedDecl()); + switch (TN.getKind()) { + case TemplateName::Template: + case TemplateName::QualifiedTemplate: { + TemplateDecl *TD = TN.getAsTemplateDecl(); + + // If the base is a template template parameter, this is an + // unresolved type. + assert(TD && "no template for template specialization type"); + if (isa<TemplateTemplateParmDecl>(TD)) + goto unresolvedType; + + mangleSourceName(TD->getIdentifier()); + break; + } + + case TemplateName::OverloadedTemplate: + case TemplateName::DependentTemplate: + llvm_unreachable("invalid base for a template specialization type"); + + case TemplateName::SubstTemplateTemplateParm: { + SubstTemplateTemplateParmStorage *subst = + TN.getAsSubstTemplateTemplateParm(); + mangleExistingSubstitution(subst->getReplacement()); + break; + } + + case TemplateName::SubstTemplateTemplateParmPack: { + // FIXME: not clear how to mangle this! + // template <template <class U> class T...> class A { + // template <class U...> void foo(decltype(T<U>::foo) x...); + // }; + Out << "_SUBSTPACK_"; + break; } + } + mangleTemplateArgs(TST->getArgs(), TST->getNumArgs()); - } else if (const auto *DTST = - DestroyedType->getAs<DependentTemplateSpecializationType>()) { - const IdentifierInfo *II = DTST->getIdentifier(); - mangleSourceName(II); + break; + } + + case Type::InjectedClassName: + mangleSourceName( + cast<InjectedClassNameType>(Ty)->getDecl()->getIdentifier()); + break; + + case Type::DependentName: + mangleSourceName(cast<DependentNameType>(Ty)->getIdentifier()); + break; + + case Type::DependentTemplateSpecialization: { + const DependentTemplateSpecializationType *DTST = + cast<DependentTemplateSpecializationType>(Ty); + mangleSourceName(DTST->getIdentifier()); mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs()); - } else { - // We use the QualType mangle type variant here because it handles - // substitutions. - mangleType(DestroyedType); + break; } + + case Type::Elaborated: + return mangleUnresolvedTypeOrSimpleId( + cast<ElaboratedType>(Ty)->getNamedType(), Prefix); + } + + return false; } void CXXNameMangler::mangleOperatorName(DeclarationName Name, unsigned Arity) { @@ -2636,7 +2586,7 @@ void CXXNameMangler::mangleMemberExpr(const Expr *base, // ::= pt <expression> <unresolved-name> if (base) mangleMemberExprBase(base, isArrow); - mangleUnresolvedName(qualifier, firstQualifierLookup, member, arity); + mangleUnresolvedName(qualifier, member, arity); } /// Look at the callee of the given call expression and determine if @@ -2894,12 +2844,26 @@ recurse: const auto *PDE = cast<CXXPseudoDestructorExpr>(E); if (const Expr *Base = PDE->getBase()) mangleMemberExprBase(Base, PDE->isArrow()); - if (NestedNameSpecifier *Qualifier = PDE->getQualifier()) - mangleUnresolvedPrefix(Qualifier, /*FirstQualifierLookup=*/nullptr); + NestedNameSpecifier *Qualifier = PDE->getQualifier(); + QualType ScopeType; + if (TypeSourceInfo *ScopeInfo = PDE->getScopeTypeInfo()) { + if (Qualifier) { + mangleUnresolvedPrefix(Qualifier, + /*Recursive=*/true); + mangleUnresolvedTypeOrSimpleId(ScopeInfo->getType()); + Out << 'E'; + } else { + Out << "sr"; + if (!mangleUnresolvedTypeOrSimpleId(ScopeInfo->getType())) + Out << 'E'; + } + } else if (Qualifier) { + mangleUnresolvedPrefix(Qualifier); + } // <base-unresolved-name> ::= dn <destructor-name> Out << "dn"; QualType DestroyedType = PDE->getDestroyedType(); - mangleDestructorName(DestroyedType); + mangleUnresolvedTypeOrSimpleId(DestroyedType); break; } @@ -2934,7 +2898,7 @@ recurse: case Expr::UnresolvedLookupExprClass: { const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E); - mangleUnresolvedName(ULE->getQualifier(), nullptr, ULE->getName(), Arity); + mangleUnresolvedName(ULE->getQualifier(), ULE->getName(), Arity); // All the <unresolved-name> productions end in a // base-unresolved-name, where <template-args> are just tacked @@ -3248,8 +3212,7 @@ recurse: case Expr::DependentScopeDeclRefExprClass: { const DependentScopeDeclRefExpr *DRE = cast<DependentScopeDeclRefExpr>(E); - mangleUnresolvedName(DRE->getQualifier(), nullptr, DRE->getDeclName(), - Arity); + mangleUnresolvedName(DRE->getQualifier(), DRE->getDeclName(), Arity); // All the <unresolved-name> productions end in a // base-unresolved-name, where <template-args> are just tacked |