r229809 - Itanium ABI: Properly qualify the destructor-name
David Majnemer
david.majnemer at gmail.com
Wed Feb 18 18:16:17 PST 2015
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>();
}
More information about the cfe-commits
mailing list