r229615 - Itanium ABI: Improve our mangling of <destructor-name>
David Majnemer
david.majnemer at gmail.com
Tue Feb 17 18:28:02 PST 2015
Author: majnemer
Date: Tue Feb 17 20:28:01 2015
New Revision: 229615
URL: http://llvm.org/viewvc/llvm-project?rev=229615&view=rev
Log:
Itanium ABI: Improve our mangling of <destructor-name>
Our mangling of <destructor-name> wasn't quite right: we'd introduce
mangling substitutions where one shouldn't be possible. We also didn't
correctly handle the case where the destroyed type was not dependent but
still a TemplateSpecializationType.
N.B. There isn't a mangling for a template-template parameter showing up
as the destroyed type. We do the 'obvious' thing and mangle the index
of the parameter.
Modified:
cfe/trunk/lib/AST/ItaniumMangle.cpp
cfe/trunk/test/CodeGenCXX/mangle-subst.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=229615&r1=229614&r2=229615&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Tue Feb 17 20:28:01 2015
@@ -352,6 +352,8 @@ private:
void manglePrefix(QualType type);
void mangleTemplatePrefix(const TemplateDecl *ND, bool NoFunction=false);
void mangleTemplatePrefix(TemplateName Template);
+ void mangleDestructorName(QualType DestroyedType);
+ void mangleOperatorName(DeclarationName Name, unsigned Arity);
void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
void mangleQualifiers(Qualifiers Quals);
void mangleRefQualifier(RefQualifierKind RefQualifier);
@@ -752,8 +754,7 @@ void CXXNameMangler::mangleCallOffset(in
}
void CXXNameMangler::manglePrefix(QualType type) {
- if (const TemplateSpecializationType *TST =
- type->getAs<TemplateSpecializationType>()) {
+ if (const auto *TST = type->getAs<TemplateSpecializationType>()) {
if (!mangleSubstitution(QualType(TST, 0))) {
mangleTemplatePrefix(TST->getTemplateName());
@@ -763,17 +764,19 @@ void CXXNameMangler::manglePrefix(QualTy
mangleTemplateArgs(TST->getArgs(), TST->getNumArgs());
addSubstitution(QualType(TST, 0));
}
- } else if (const DependentTemplateSpecializationType *DTST
- = type->getAs<DependentTemplateSpecializationType>()) {
- TemplateName Template
- = getASTContext().getDependentTemplateName(DTST->getQualifier(),
- DTST->getIdentifier());
- mangleTemplatePrefix(Template);
+ } else if (const auto *DTST =
+ type->getAs<DependentTemplateSpecializationType>()) {
+ if (!mangleSubstitution(QualType(DTST, 0))) {
+ TemplateName Template = getASTContext().getDependentTemplateName(
+ DTST->getQualifier(), DTST->getIdentifier());
+ mangleTemplatePrefix(Template);
- // FIXME: GCC does not appear to mangle the template arguments when
- // the template in question is a dependent template name. Should we
- // emulate that badness?
- mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs());
+ // FIXME: GCC does not appear to mangle the template arguments when
+ // the template in question is a dependent template name. Should we
+ // emulate that badness?
+ mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs());
+ addSubstitution(QualType(DTST, 0));
+ }
} else {
// We use the QualType mangle type variant here because it handles
// substitutions.
@@ -1054,15 +1057,20 @@ void CXXNameMangler::mangleUnresolvedNam
switch (name.getNameKind()) {
// <base-unresolved-name> ::= <simple-id>
case DeclarationName::Identifier:
+ mangleSourceName(name.getAsIdentifierInfo());
+ break;
+ // <base-unresolved-name> ::= dn <destructor-name>
+ case DeclarationName::CXXDestructorName:
+ Out << "dn";
+ mangleDestructorName(name.getCXXNameType());
break;
// <base-unresolved-name> ::= on <operator-name>
case DeclarationName::CXXConversionFunctionName:
case DeclarationName::CXXLiteralOperatorName:
case DeclarationName::CXXOperatorName:
Out << "on";
+ mangleOperatorName(name, knownArity);
break;
- case DeclarationName::CXXDestructorName:
- llvm_unreachable("Can't mangle a constructor name!");
case DeclarationName::CXXConstructorName:
llvm_unreachable("Can't mangle a constructor name!");
case DeclarationName::CXXUsingDirective:
@@ -1072,12 +1080,12 @@ void CXXNameMangler::mangleUnresolvedNam
case DeclarationName::ObjCZeroArgSelector:
llvm_unreachable("Can't mangle Objective-C selector names here!");
}
- mangleUnqualifiedName(nullptr, name, knownArity);
}
void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
DeclarationName Name,
unsigned KnownArity) {
+ unsigned Arity = KnownArity;
// <unqualified-name> ::= <operator-name>
// ::= <ctor-dtor-name>
// ::= <source-name>
@@ -1219,33 +1227,19 @@ void CXXNameMangler::mangleUnqualifiedNa
mangleCXXDtorType(Dtor_Complete);
break;
- case DeclarationName::CXXConversionFunctionName:
- // <operator-name> ::= cv <type> # (cast)
- Out << "cv";
- mangleType(Name.getCXXNameType());
- break;
-
- case DeclarationName::CXXOperatorName: {
- unsigned Arity;
- if (ND) {
+ case DeclarationName::CXXOperatorName:
+ if (ND && Arity == UnknownArity) {
Arity = cast<FunctionDecl>(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<CXXMethodDecl>(ND))
- Arity++;
- } else
- Arity = KnownArity;
-
- mangleOperatorName(Name.getCXXOverloadedOperator(), Arity);
- break;
- }
-
+ // If we have a member function, we need to include the 'this' pointer.
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(ND))
+ if (!MD->isStatic())
+ Arity++;
+ }
+ // FALLTHROUGH
+ case DeclarationName::CXXConversionFunctionName:
case DeclarationName::CXXLiteralOperatorName:
- // FIXME: This mangling is not yet official.
- Out << "li";
- mangleSourceName(Name.getCXXLiteralIdentifier());
+ mangleOperatorName(Name, Arity);
break;
case DeclarationName::CXXUsingDirective:
@@ -1646,6 +1640,61 @@ void CXXNameMangler::mangleType(Template
addSubstitution(TN);
}
+void CXXNameMangler::mangleDestructorName(QualType DestroyedType) {
+ // <destructor-name> ::= <unresolved-type>
+ // ::= <simple-id>
+ if (const auto *TST = DestroyedType->getAs<TemplateSpecializationType>()) {
+ 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());
+ }
+ mangleTemplateArgs(TST->getArgs(), TST->getNumArgs());
+ } else if (const auto *DTST =
+ DestroyedType->getAs<DependentTemplateSpecializationType>()) {
+ const IdentifierInfo *II = DTST->getIdentifier();
+ mangleSourceName(II);
+ mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs());
+ } else {
+ // We use the QualType mangle type variant here because it handles
+ // substitutions.
+ mangleType(DestroyedType);
+ }
+}
+
+void CXXNameMangler::mangleOperatorName(DeclarationName Name, unsigned Arity) {
+ switch (Name.getNameKind()) {
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXUsingDirective:
+ case DeclarationName::Identifier:
+ case DeclarationName::ObjCMultiArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCZeroArgSelector:
+ llvm_unreachable("Not an operator name");
+
+ case DeclarationName::CXXConversionFunctionName:
+ // <operator-name> ::= cv <type> # (cast)
+ Out << "cv";
+ mangleType(Name.getCXXNameType());
+ break;
+
+ case DeclarationName::CXXLiteralOperatorName:
+ Out << "li";
+ mangleSourceName(Name.getCXXLiteralIdentifier());
+ return;
+
+ case DeclarationName::CXXOperatorName:
+ mangleOperatorName(Name.getCXXOverloadedOperator(), Arity);
+ break;
+ }
+}
+
+
+
void
CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
switch (OO) {
@@ -2841,9 +2890,8 @@ recurse:
mangleUnresolvedPrefix(Qualifier, /*FirstQualifierLookup=*/nullptr);
// <base-unresolved-name> ::= dn <destructor-name>
Out << "dn";
- // <destructor-name> ::= <unresolved-type>
- // ::= <simple-id>
- manglePrefix(PDE->getDestroyedType());
+ QualType DestroyedType = PDE->getDestroyedType();
+ mangleDestructorName(DestroyedType);
break;
}
Modified: cfe/trunk/test/CodeGenCXX/mangle-subst.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-subst.cpp?rev=229615&r1=229614&r2=229615&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-subst.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-subst.cpp Tue Feb 17 20:28:01 2015
@@ -80,3 +80,19 @@ void f(void (B::*)(), A, A) { }
void f(void (B::*)(), A, A, void (B::*)(A), void (A::*)()) { }
}
+
+namespace ManglePrefix {
+template <typename>
+struct X {
+ template <typename>
+ struct Y {
+ typedef int type;
+ typedef int type2;
+ };
+};
+template <typename T>
+typename X<T>::template Y<T>::type f(typename X<T>::template Y<T>::type2) { return 0; }
+
+// CHECK: @_ZN12ManglePrefix1fIiEENS_1XIT_E1YIS2_E4typeENS5_5type2E
+template int f<int>(int);
+}
Modified: cfe/trunk/test/CodeGenCXX/mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=229615&r1=229614&r2=229615&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle.cpp Tue Feb 17 20:28:01 2015
@@ -1030,10 +1030,21 @@ namespace test51 {
decltype(U().~S1<T>()) fun2() {}
template <typename U, typename T>
decltype(S1<T>().~U()) fun3() {}
+ template <typename T>
+ decltype(S1<T>().~S1<T>(), S1<T>().~S1<T>()) fun4() {};
+ template <typename T>
+ decltype(S1<int>().~S1<T>()) fun5(){};
+ template <template <typename T> class U>
+ decltype(S1<int>().~U<int>()) fun6(){};
template void fun1<int>();
// CHECK-LABEL: @_ZN6test514fun1IiEEDTcldtcv2S1IT_E_Edn2S1IS2_EEEv
template void fun2<S1<int>, int>();
// CHECK-LABEL: @_ZN6test514fun2I2S1IiEiEEDTcldtcvT__Edn2S1IT0_EEEv
template void fun3<S1<int>, int>();
// CHECK-LABEL: @_ZN6test514fun3I2S1IiEiEEDTcldtcvS1_IT0_E_EdnT_EEv
+ template void fun4<int>();
+ // CHECK-LABEL: @_ZN6test514fun4IiEEDTcmcldtcv2S1IT_E_Edn2S1IS2_EEcldtcvS3__Edn2S1IS2_EEEv
+ template void fun5<int>();
+ // CHECK-LABEL: @_ZN6test514fun6I2S1EEDTcldtcvS1_IiE_EdnT_IiEEEv
+ template void fun6<S1>();
}
More information about the cfe-commits
mailing list