summaryrefslogtreecommitdiff
path: root/lib/AST/ItaniumMangle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/ItaniumMangle.cpp')
-rw-r--r--lib/AST/ItaniumMangle.cpp154
1 files changed, 119 insertions, 35 deletions
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 6c813f09a4b3..c55a90137578 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -170,6 +170,8 @@ public:
void mangleStringLiteral(const StringLiteral *, raw_ostream &) override;
+ void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) override;
+
bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
// Lambda closure types are already numbered.
if (isLambda(ND))
@@ -424,6 +426,7 @@ public:
void mangleName(const NamedDecl *ND);
void mangleType(QualType T);
void mangleNameOrStandardSubstitution(const NamedDecl *ND);
+ void mangleLambdaSig(const CXXRecordDecl *Lambda);
private:
@@ -513,7 +516,7 @@ private:
#define ABSTRACT_TYPE(CLASS, PARENT)
#define NON_CANONICAL_TYPE(CLASS, PARENT)
#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T);
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
void mangleType(const TagType*);
void mangleType(TemplateName);
@@ -550,7 +553,7 @@ private:
void mangleTemplateArgs(const TemplateArgumentList &AL);
void mangleTemplateArg(TemplateArgument A);
- void mangleTemplateParameter(unsigned Index);
+ void mangleTemplateParameter(unsigned Depth, unsigned Index);
void mangleFunctionParam(const ParmVarDecl *parm);
@@ -965,8 +968,8 @@ void CXXNameMangler::mangleUnscopedTemplateName(
if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) {
assert(!AdditionalAbiTags &&
"template template param cannot have abi tags");
- mangleTemplateParameter(TTP->getIndex());
- } else if (isa<BuiltinTemplateDecl>(ND)) {
+ mangleTemplateParameter(TTP->getDepth(), TTP->getIndex());
+ } else if (isa<BuiltinTemplateDecl>(ND) || isa<ConceptDecl>(ND)) {
mangleUnscopedName(ND, AdditionalAbiTags);
} else {
mangleUnscopedName(ND->getTemplatedDecl(), AdditionalAbiTags);
@@ -1321,7 +1324,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
// We must have an anonymous union or struct declaration.
- const RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl();
+ const RecordDecl *RD = VD->getType()->castAs<RecordType>()->getDecl();
// Itanium C++ ABI 5.1.2:
//
@@ -1685,17 +1688,45 @@ void CXXNameMangler::mangleUnqualifiedBlock(const BlockDecl *Block) {
// ::= Ty # template type parameter
// ::= Tn <type> # template non-type parameter
// ::= Tt <template-param-decl>* E # template template parameter
+// ::= Tp <template-param-decl> # template parameter pack
void CXXNameMangler::mangleTemplateParamDecl(const NamedDecl *Decl) {
- if (isa<TemplateTypeParmDecl>(Decl)) {
+ if (auto *Ty = dyn_cast<TemplateTypeParmDecl>(Decl)) {
+ if (Ty->isParameterPack())
+ Out << "Tp";
Out << "Ty";
} else if (auto *Tn = dyn_cast<NonTypeTemplateParmDecl>(Decl)) {
- Out << "Tn";
- mangleType(Tn->getType());
+ if (Tn->isExpandedParameterPack()) {
+ for (unsigned I = 0, N = Tn->getNumExpansionTypes(); I != N; ++I) {
+ Out << "Tn";
+ mangleType(Tn->getExpansionType(I));
+ }
+ } else {
+ QualType T = Tn->getType();
+ if (Tn->isParameterPack()) {
+ Out << "Tp";
+ if (auto *PackExpansion = T->getAs<PackExpansionType>())
+ T = PackExpansion->getPattern();
+ }
+ Out << "Tn";
+ mangleType(T);
+ }
} else if (auto *Tt = dyn_cast<TemplateTemplateParmDecl>(Decl)) {
- Out << "Tt";
- for (auto *Param : *Tt->getTemplateParameters())
- mangleTemplateParamDecl(Param);
- Out << "E";
+ if (Tt->isExpandedParameterPack()) {
+ for (unsigned I = 0, N = Tt->getNumExpansionTemplateParameters(); I != N;
+ ++I) {
+ Out << "Tt";
+ for (auto *Param : *Tt->getExpansionTemplateParameters(I))
+ mangleTemplateParamDecl(Param);
+ Out << "E";
+ }
+ } else {
+ if (Tt->isParameterPack())
+ Out << "Tp";
+ Out << "Tt";
+ for (auto *Param : *Tt->getTemplateParameters())
+ mangleTemplateParamDecl(Param);
+ Out << "E";
+ }
}
}
@@ -1726,12 +1757,7 @@ void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
}
Out << "Ul";
- for (auto *D : Lambda->getLambdaExplicitTemplateParameters())
- mangleTemplateParamDecl(D);
- const FunctionProtoType *Proto = Lambda->getLambdaTypeInfo()->getType()->
- getAs<FunctionProtoType>();
- mangleBareFunctionType(Proto, /*MangleReturnType=*/false,
- Lambda->getLambdaStaticInvoker());
+ mangleLambdaSig(Lambda);
Out << "E";
// The number is omitted for the first closure type with a given
@@ -1746,6 +1772,15 @@ void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
Out << '_';
}
+void CXXNameMangler::mangleLambdaSig(const CXXRecordDecl *Lambda) {
+ for (auto *D : Lambda->getLambdaExplicitTemplateParameters())
+ mangleTemplateParamDecl(D);
+ const FunctionProtoType *Proto = Lambda->getLambdaTypeInfo()->getType()->
+ getAs<FunctionProtoType>();
+ mangleBareFunctionType(Proto, /*MangleReturnType=*/false,
+ Lambda->getLambdaStaticInvoker());
+}
+
void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) {
switch (qualifier->getKind()) {
case NestedNameSpecifier::Global:
@@ -1852,10 +1887,10 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND,
// <template-template-param> ::= <template-param>
if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) {
- mangleTemplateParameter(TTP->getIndex());
+ mangleTemplateParameter(TTP->getDepth(), TTP->getIndex());
} else {
manglePrefix(getEffectiveDeclContext(ND), NoFunction);
- if (isa<BuiltinTemplateDecl>(ND))
+ if (isa<BuiltinTemplateDecl>(ND) || isa<ConceptDecl>(ND))
mangleUnqualifiedName(ND, nullptr);
else
mangleUnqualifiedName(ND->getTemplatedDecl(), nullptr);
@@ -1885,8 +1920,8 @@ void CXXNameMangler::mangleType(TemplateName TN) {
goto HaveDecl;
HaveDecl:
- if (isa<TemplateTemplateParmDecl>(TD))
- mangleTemplateParameter(cast<TemplateTemplateParmDecl>(TD)->getIndex());
+ if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TD))
+ mangleTemplateParameter(TTP->getDepth(), TTP->getIndex());
else
mangleName(TD);
break;
@@ -2464,7 +2499,7 @@ void CXXNameMangler::mangleType(QualType T) {
case Type::CLASS: \
mangleType(static_cast<const CLASS##Type*>(ty)); \
break;
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
}
}
@@ -2671,6 +2706,15 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
Out << type_name.size() << type_name; \
break;
#include "clang/Basic/OpenCLExtensionTypes.def"
+ // The SVE types are effectively target-specific. The mangling scheme
+ // is defined in the appendices to the Procedure Call Standard for the
+ // Arm Architecture.
+#define SVE_TYPE(Name, Id, SingletonId) \
+ case BuiltinType::Id: \
+ type_name = Name; \
+ Out << 'u' << type_name.size() << type_name; \
+ break;
+#include "clang/Basic/AArch64SVEACLETypes.def"
}
}
@@ -2955,7 +2999,7 @@ void CXXNameMangler::mangleType(const MemberPointerType *T) {
// <type> ::= <template-param>
void CXXNameMangler::mangleType(const TemplateTypeParmType *T) {
- mangleTemplateParameter(T->getIndex());
+ mangleTemplateParameter(T->getDepth(), T->getIndex());
}
// <type> ::= <template-param>
@@ -3526,7 +3570,7 @@ void CXXNameMangler::mangleDeclRefExpr(const NamedDecl *D) {
case Decl::NonTypeTemplateParm:
const NonTypeTemplateParmDecl *PD = cast<NonTypeTemplateParmDecl>(D);
- mangleTemplateParameter(PD->getIndex());
+ mangleTemplateParameter(PD->getDepth(), PD->getIndex());
break;
}
}
@@ -4046,6 +4090,17 @@ recurse:
break;
}
+ case Expr::CXXRewrittenBinaryOperatorClass: {
+ // The mangled form represents the original syntax.
+ CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
+ cast<CXXRewrittenBinaryOperator>(E)->getDecomposedForm();
+ mangleOperatorName(BinaryOperator::getOverloadedOperator(Decomposed.Opcode),
+ /*Arity=*/2);
+ mangleExpression(Decomposed.LHS);
+ mangleExpression(Decomposed.RHS);
+ break;
+ }
+
case Expr::ConditionalOperatorClass: {
const ConditionalOperator *CO = cast<ConditionalOperator>(E);
mangleOperatorName(OO_Conditional, /*Arity=*/3);
@@ -4123,6 +4178,18 @@ recurse:
mangleExpression(cast<ParenExpr>(E)->getSubExpr(), Arity);
break;
+
+ case Expr::ConceptSpecializationExprClass: {
+ // <expr-primary> ::= L <mangled-name> E # external name
+ Out << "L_Z";
+ auto *CSE = cast<ConceptSpecializationExpr>(E);
+ mangleTemplateName(CSE->getNamedConcept(),
+ CSE->getTemplateArguments().data(),
+ CSE->getTemplateArguments().size());
+ Out << 'E';
+ break;
+ }
+
case Expr::DeclRefExprClass:
mangleDeclRefExpr(cast<DeclRefExpr>(E)->getDecl());
break;
@@ -4229,8 +4296,11 @@ recurse:
}
case Expr::GNUNullExprClass:
- // FIXME: should this really be mangled the same as nullptr?
- // fallthrough
+ // Mangle as if an integer literal 0.
+ Out << 'L';
+ mangleType(E->getType());
+ Out << "0E";
+ break;
case Expr::CXXNullPtrLiteralExprClass: {
Out << "LDnE";
@@ -4255,13 +4325,13 @@ recurse:
Out << "sZ";
const NamedDecl *Pack = SPE->getPack();
if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Pack))
- mangleTemplateParameter(TTP->getIndex());
+ mangleTemplateParameter(TTP->getDepth(), TTP->getIndex());
else if (const NonTypeTemplateParmDecl *NTTP
= dyn_cast<NonTypeTemplateParmDecl>(Pack))
- mangleTemplateParameter(NTTP->getIndex());
+ mangleTemplateParameter(NTTP->getDepth(), NTTP->getIndex());
else if (const TemplateTemplateParmDecl *TempTP
= dyn_cast<TemplateTemplateParmDecl>(Pack))
- mangleTemplateParameter(TempTP->getIndex());
+ mangleTemplateParameter(TempTP->getDepth(), TempTP->getIndex());
else
mangleFunctionParam(cast<ParmVarDecl>(Pack));
break;
@@ -4548,13 +4618,21 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A) {
}
}
-void CXXNameMangler::mangleTemplateParameter(unsigned Index) {
+void CXXNameMangler::mangleTemplateParameter(unsigned Depth, unsigned Index) {
// <template-param> ::= T_ # first template parameter
// ::= T <parameter-2 non-negative number> _
- if (Index == 0)
- Out << "T_";
- else
- Out << 'T' << (Index - 1) << '_';
+ // ::= TL <L-1 non-negative number> __
+ // ::= TL <L-1 non-negative number> _
+ // <parameter-2 non-negative number> _
+ //
+ // The latter two manglings are from a proposal here:
+ // https://github.com/itanium-cxx-abi/cxx-abi/issues/31#issuecomment-528122117
+ Out << 'T';
+ if (Depth != 0)
+ Out << 'L' << (Depth - 1) << '_';
+ if (Index != 0)
+ Out << (Index - 1);
+ Out << '_';
}
void CXXNameMangler::mangleSeqID(unsigned SeqID) {
@@ -5071,6 +5149,12 @@ void ItaniumMangleContextImpl::mangleStringLiteral(const StringLiteral *, raw_os
llvm_unreachable("Can't mangle string literals");
}
+void ItaniumMangleContextImpl::mangleLambdaSig(const CXXRecordDecl *Lambda,
+ raw_ostream &Out) {
+ CXXNameMangler Mangler(*this, Out);
+ Mangler.mangleLambdaSig(Lambda);
+}
+
ItaniumMangleContext *
ItaniumMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
return new ItaniumMangleContextImpl(Context, Diags);