r229809 - Itanium ABI: Properly qualify the destructor-name
Craig Topper
craig.topper at gmail.com
Wed Feb 18 21:34:07 PST 2015
I think this left behind a nullptr argument being passed to
mangleUnresolvedPrefix here
case TemplateName::DependentTemplate: {
const DependentTemplateName *Dependent =
TN.getAsDependentTemplateName();
assert(Dependent->isIdentifier());
// <class-enum-type> ::= <name>
// <name> ::= <nested-name>
mangleUnresolvedPrefix(Dependent->getQualifier(), nullptr);
mangleSourceName(Dependent->getIdentifier());
break;
}
On Wed, Feb 18, 2015 at 6:16 PM, David Majnemer <david.majnemer at gmail.com>
wrote:
> Author: majnemer
> Date: Wed Feb 18 20:16:16 2015
> New Revision: 229809
>
> URL: http://llvm.org/viewvc/llvm-project?rev=229809&view=rev
> Log:
> 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.
>
> Modified:
> cfe/trunk/lib/AST/ItaniumMangle.cpp
> cfe/trunk/test/CodeGenCXX/mangle.cpp
>
> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=229809&r1=229808&r2=229809&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Feb 18 20:16:16 2015
> @@ -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(QualTy
> /// \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::mangleUnresolvedPre
>
> case NestedNameSpecifier::Namespace:
> if (qualifier->getPrefix())
> - mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup,
> + mangleUnresolvedPrefix(qualifier->getPrefix(),
> /*recursive*/ true);
> else
> Out << "sr";
> @@ -840,7 +838,7 @@ void CXXNameMangler::mangleUnresolvedPre
> 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::mangleUnresolvedPre
> // - 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::mangleUnresolvedPre
> /// 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::mangleUnresolvedNam
> // <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(Template
> 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(co
> // ::= 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
>
> Modified: cfe/trunk/test/CodeGenCXX/mangle.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=229809&r1=229808&r2=229809&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/mangle.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/mangle.cpp Wed Feb 18 20:16:16 2015
> @@ -1024,6 +1024,12 @@ namespace test51 {
> template void fun<S1<int> >();
> // CHECK-LABEL: @_ZN6test513funI2S1IiEEEDTcldtcvT__EdnS3_EEv
>
> + enum E {};
> + template <typename T>
> + struct X {
> + struct Y {};
> + };
> +
> template <typename T>
> decltype(S1<T>().~S1<T>()) fun1() {};
> template <typename U, typename T>
> @@ -1036,6 +1042,10 @@ namespace test51 {
> decltype(S1<int>().~S1<T>()) fun5(){};
> template <template <typename T> class U>
> decltype(S1<int>().~U<int>()) fun6(){};
> + template <typename T>
> + decltype(E().E::~T()) fun7() {}
> + template <template <typename> class U>
> + decltype(X<int>::Y().U<int>::Y::~Y()) fun8() {}
> template void fun1<int>();
> // CHECK-LABEL: @_ZN6test514fun1IiEEDTcldtcv2S1IT_E_Edn2S1IS2_EEEv
> template void fun2<S1<int>, int>();
> @@ -1045,6 +1055,10 @@ namespace test51 {
> template void fun4<int>();
> // CHECK-LABEL:
> @_ZN6test514fun4IiEEDTcmcldtcv2S1IT_E_Edn2S1IS2_EEcldtcvS3__Edn2S1IS2_EEEv
> template void fun5<int>();
> - // CHECK-LABEL: @_ZN6test514fun6I2S1EEDTcldtcvS1_IiE_EdnT_IiEEEv
> + // CHECK-LABEL: @_ZN6test514fun5IiEEDTcldtcv2S1IiE_Edn2S1IT_EEEv
> template void fun6<S1>();
> + // CHECK-LABEL: @_ZN6test514fun6I2S1EEDTcldtcvS1_IiE_EdnT_IiEEEv
> + template void fun7<E>();
> + // CHECK-LABEL: @_ZN6test514fun7INS_1EEEEDTcldtcvS1__Esr1EEdnT_EEv
> + template void fun8<X>();
> }
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
--
~Craig
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150218/982d5359/attachment.html>
More information about the cfe-commits
mailing list