aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ItaniumMangle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/ItaniumMangle.cpp')
-rw-r--r--lib/AST/ItaniumMangle.cpp163
1 files changed, 131 insertions, 32 deletions
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 694fde317542..ab3e49d903cf 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -405,12 +405,14 @@ public:
CXXNameMangler(CXXNameMangler &Outer, raw_ostream &Out_)
: Context(Outer.Context), Out(Out_), NullOut(false),
Structor(Outer.Structor), StructorType(Outer.StructorType),
- SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {}
+ SeqID(Outer.SeqID), FunctionTypeDepth(Outer.FunctionTypeDepth),
+ AbiTagsRoot(AbiTags), Substitutions(Outer.Substitutions) {}
CXXNameMangler(CXXNameMangler &Outer, llvm::raw_null_ostream &Out_)
: Context(Outer.Context), Out(Out_), NullOut(true),
Structor(Outer.Structor), StructorType(Outer.StructorType),
- SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {}
+ SeqID(Outer.SeqID), FunctionTypeDepth(Outer.FunctionTypeDepth),
+ AbiTagsRoot(AbiTags), Substitutions(Outer.Substitutions) {}
#if MANGLE_CHECKER
~CXXNameMangler() {
@@ -458,11 +460,15 @@ private:
void addSubstitution(QualType T);
void addSubstitution(TemplateName Template);
void addSubstitution(uintptr_t Ptr);
+ // Destructive copy substitutions from other mangler.
+ void extendSubstitutions(CXXNameMangler* Other);
void mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
bool recursive = false);
void mangleUnresolvedName(NestedNameSpecifier *qualifier,
DeclarationName name,
+ const TemplateArgumentLoc *TemplateArgs,
+ unsigned NumTemplateArgs,
unsigned KnownArity = UnknownArity);
void mangleFunctionEncodingBareType(const FunctionDecl *FD);
@@ -487,6 +493,7 @@ private:
void mangleUnscopedTemplateName(TemplateName,
const AbiTagList *AdditionalAbiTags);
void mangleSourceName(const IdentifierInfo *II);
+ void mangleRegCallName(const IdentifierInfo *II);
void mangleSourceNameWithAbiTags(
const NamedDecl *ND, const AbiTagList *AdditionalAbiTags = nullptr);
void mangleLocalName(const Decl *D,
@@ -537,6 +544,8 @@ private:
NestedNameSpecifier *qualifier,
NamedDecl *firstQualifierLookup,
DeclarationName name,
+ const TemplateArgumentLoc *TemplateArgs,
+ unsigned NumTemplateArgs,
unsigned knownArity);
void mangleCastExpression(const Expr *E, StringRef CastEncoding);
void mangleInitListElements(const InitListExpr *InitList);
@@ -593,7 +602,7 @@ bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
return false;
const VarDecl *VD = dyn_cast<VarDecl>(D);
- if (VD) {
+ if (VD && !isa<DecompositionDecl>(D)) {
// C variables are not mangled.
if (VD->isExternC())
return false;
@@ -685,6 +694,10 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
// Output name with implicit tags and function encoding from temporary buffer.
mangleNameWithAbiTags(FD, &AdditionalAbiTags);
Out << FunctionEncodingStream.str().substr(EncodingPositionStart);
+
+ // Function encoding could create new substitutions so we have to add
+ // temp mangled substitutions to main mangler.
+ extendSubstitutions(&FunctionEncodingMangler);
}
void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
@@ -1151,9 +1164,10 @@ 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,
- DeclarationName name,
- unsigned knownArity) {
+void CXXNameMangler::mangleUnresolvedName(
+ NestedNameSpecifier *qualifier, DeclarationName name,
+ const TemplateArgumentLoc *TemplateArgs, unsigned NumTemplateArgs,
+ unsigned knownArity) {
if (qualifier) mangleUnresolvedPrefix(qualifier);
switch (name.getNameKind()) {
// <base-unresolved-name> ::= <simple-id>
@@ -1181,6 +1195,11 @@ void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier,
case DeclarationName::ObjCZeroArgSelector:
llvm_unreachable("Can't mangle Objective-C selector names here!");
}
+
+ // The <simple-id> and on <operator-name> productions end in an optional
+ // <template-args>.
+ if (TemplateArgs)
+ mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
}
void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
@@ -1193,7 +1212,26 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// ::= <source-name>
switch (Name.getNameKind()) {
case DeclarationName::Identifier: {
- if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
+ const IdentifierInfo *II = Name.getAsIdentifierInfo();
+
+ // We mangle decomposition declarations as the names of their bindings.
+ if (auto *DD = dyn_cast<DecompositionDecl>(ND)) {
+ // FIXME: Non-standard mangling for decomposition declarations:
+ //
+ // <unqualified-name> ::= DC <source-name>* E
+ //
+ // These can never be referenced across translation units, so we do
+ // not need a cross-vendor mangling for anything other than demanglers.
+ // Proposed on cxx-abi-dev on 2016-08-12
+ Out << "DC";
+ for (auto *BD : DD->bindings())
+ mangleSourceName(BD->getDeclName().getAsIdentifierInfo());
+ Out << 'E';
+ writeAbiTags(ND, AdditionalAbiTags);
+ break;
+ }
+
+ if (II) {
// We must avoid conflicts between internally- and externally-
// linked variable and function declaration names in the same TU:
// void test() { extern void foo(); }
@@ -1204,7 +1242,15 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
getEffectiveDeclContext(ND)->isFileContext())
Out << 'L';
- mangleSourceName(II);
+ auto *FD = dyn_cast<FunctionDecl>(ND);
+ bool IsRegCall = FD &&
+ FD->getType()->castAs<FunctionType>()->getCallConv() ==
+ clang::CC_X86RegCall;
+ if (IsRegCall)
+ mangleRegCallName(II);
+ else
+ mangleSourceName(II);
+
writeAbiTags(ND, AdditionalAbiTags);
break;
}
@@ -1378,6 +1424,14 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
}
}
+void CXXNameMangler::mangleRegCallName(const IdentifierInfo *II) {
+ // <source-name> ::= <positive length number> __regcall3__ <identifier>
+ // <number> ::= [n] <non-negative decimal integer>
+ // <identifier> ::= <unqualified source code identifier>
+ Out << II->getLength() + sizeof("__regcall3__") - 1 << "__regcall3__"
+ << II->getName();
+}
+
void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
// <source-name> ::= <positive length number> <identifier>
// <number> ::= [n] <non-negative decimal integer>
@@ -1471,7 +1525,7 @@ void CXXNameMangler::mangleLocalName(const Decl *D,
// numbering will be local to the particular argument in which it appears
// -- other default arguments do not affect its encoding.
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD);
- if (CXXRD->isLambda()) {
+ if (CXXRD && CXXRD->isLambda()) {
if (const ParmVarDecl *Parm
= dyn_cast_or_null<ParmVarDecl>(CXXRD->getLambdaContextDecl())) {
if (const FunctionDecl *Func
@@ -1820,6 +1874,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::ObjCObject:
case Type::ObjCInterface:
case Type::ObjCObjectPointer:
+ case Type::ObjCTypeParam:
case Type::Atomic:
case Type::Pipe:
llvm_unreachable("type is illegal as a nested name specifier");
@@ -2207,6 +2262,22 @@ void CXXNameMangler::mangleType(QualType T) {
// they aren't written.
// - Conversions on non-type template arguments need to be expressed, since
// they can affect the mangling of sizeof/alignof.
+ //
+ // FIXME: This is wrong when mapping to the canonical type for a dependent
+ // type discards instantiation-dependent portions of the type, such as for:
+ //
+ // template<typename T, int N> void f(T (&)[sizeof(N)]);
+ // template<typename T> void f(T() throw(typename T::type)); (pre-C++17)
+ //
+ // It's also wrong in the opposite direction when instantiation-dependent,
+ // canonically-equivalent types differ in some irrelevant portion of inner
+ // type sugar. In such cases, we fail to form correct substitutions, eg:
+ //
+ // template<int N> void f(A<sizeof(N)> *, A<sizeof(N)> (*));
+ //
+ // We should instead canonicalize the non-instantiation-dependent parts,
+ // regardless of whether the type as a whole is dependent or instantiation
+ // dependent.
if (!T->isInstantiationDependentType() || T->isDependentType())
T = T.getCanonicalType();
else {
@@ -2443,6 +2514,7 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) {
case CC_X86Pascal:
case CC_X86_64Win64:
case CC_X86_64SysV:
+ case CC_X86RegCall:
case CC_AAPCS:
case CC_AAPCS_VFP:
case CC_IntelOclBicc:
@@ -2509,6 +2581,24 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
// e.g. "const" in "int (A::*)() const".
mangleQualifiers(Qualifiers::fromCVRMask(T->getTypeQuals()));
+ // Mangle instantiation-dependent exception-specification, if present,
+ // per cxx-abi-dev proposal on 2016-10-11.
+ if (T->hasInstantiationDependentExceptionSpec()) {
+ if (T->getExceptionSpecType() == EST_ComputedNoexcept) {
+ Out << "DO";
+ mangleExpression(T->getNoexceptExpr());
+ Out << "E";
+ } else {
+ assert(T->getExceptionSpecType() == EST_Dynamic);
+ Out << "Dw";
+ for (auto ExceptTy : T->exceptions())
+ mangleType(ExceptTy);
+ Out << "E";
+ }
+ } else if (T->isNothrow(getASTContext())) {
+ Out << "Do";
+ }
+
Out << 'F';
// FIXME: We don't have enough information in the AST to produce the 'Y'
@@ -3115,12 +3205,14 @@ void CXXNameMangler::mangleMemberExpr(const Expr *base,
NestedNameSpecifier *qualifier,
NamedDecl *firstQualifierLookup,
DeclarationName member,
+ const TemplateArgumentLoc *TemplateArgs,
+ unsigned NumTemplateArgs,
unsigned arity) {
// <expression> ::= dt <expression> <unresolved-name>
// ::= pt <expression> <unresolved-name>
if (base)
mangleMemberExprBase(base, isArrow);
- mangleUnresolvedName(qualifier, member, arity);
+ mangleUnresolvedName(qualifier, member, TemplateArgs, NumTemplateArgs, arity);
}
/// Look at the callee of the given call expression and determine if
@@ -3209,6 +3301,8 @@ recurse:
case Expr::AddrLabelExprClass:
case Expr::DesignatedInitUpdateExprClass:
case Expr::ImplicitValueInitExprClass:
+ case Expr::ArrayInitLoopExprClass:
+ case Expr::ArrayInitIndexExprClass:
case Expr::NoInitExprClass:
case Expr::ParenListExprClass:
case Expr::LambdaExprClass:
@@ -3418,7 +3512,9 @@ recurse:
const MemberExpr *ME = cast<MemberExpr>(E);
mangleMemberExpr(ME->getBase(), ME->isArrow(),
ME->getQualifier(), nullptr,
- ME->getMemberDecl()->getDeclName(), Arity);
+ ME->getMemberDecl()->getDeclName(),
+ ME->getTemplateArgs(), ME->getNumTemplateArgs(),
+ Arity);
break;
}
@@ -3426,9 +3522,9 @@ recurse:
const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E);
mangleMemberExpr(ME->isImplicitAccess() ? nullptr : ME->getBase(),
ME->isArrow(), ME->getQualifier(), nullptr,
- ME->getMemberName(), Arity);
- if (ME->hasExplicitTemplateArgs())
- mangleTemplateArgs(ME->getTemplateArgs(), ME->getNumTemplateArgs());
+ ME->getMemberName(),
+ ME->getTemplateArgs(), ME->getNumTemplateArgs(),
+ Arity);
break;
}
@@ -3438,21 +3534,17 @@ recurse:
mangleMemberExpr(ME->isImplicitAccess() ? nullptr : ME->getBase(),
ME->isArrow(), ME->getQualifier(),
ME->getFirstQualifierFoundInScope(),
- ME->getMember(), Arity);
- if (ME->hasExplicitTemplateArgs())
- mangleTemplateArgs(ME->getTemplateArgs(), ME->getNumTemplateArgs());
+ ME->getMember(),
+ ME->getTemplateArgs(), ME->getNumTemplateArgs(),
+ Arity);
break;
}
case Expr::UnresolvedLookupExprClass: {
const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E);
- mangleUnresolvedName(ULE->getQualifier(), ULE->getName(), Arity);
-
- // All the <unresolved-name> productions end in a
- // base-unresolved-name, where <template-args> are just tacked
- // onto the end.
- if (ULE->hasExplicitTemplateArgs())
- mangleTemplateArgs(ULE->getTemplateArgs(), ULE->getNumTemplateArgs());
+ mangleUnresolvedName(ULE->getQualifier(), ULE->getName(),
+ ULE->getTemplateArgs(), ULE->getNumTemplateArgs(),
+ Arity);
break;
}
@@ -3707,7 +3799,10 @@ recurse:
case Expr::CXXOperatorCallExprClass: {
const CXXOperatorCallExpr *CE = cast<CXXOperatorCallExpr>(E);
unsigned NumArgs = CE->getNumArgs();
- mangleOperatorName(CE->getOperator(), /*Arity=*/NumArgs);
+ // A CXXOperatorCallExpr for OO_Arrow models only semantics, not syntax
+ // (the enclosing MemberExpr covers the syntactic portion).
+ if (CE->getOperator() != OO_Arrow)
+ mangleOperatorName(CE->getOperator(), /*Arity=*/NumArgs);
// Mangle the arguments.
for (unsigned i = 0; i != NumArgs; ++i)
mangleExpression(CE->getArg(i));
@@ -3768,13 +3863,9 @@ recurse:
case Expr::DependentScopeDeclRefExprClass: {
const DependentScopeDeclRefExpr *DRE = cast<DependentScopeDeclRefExpr>(E);
- mangleUnresolvedName(DRE->getQualifier(), DRE->getDeclName(), Arity);
-
- // All the <unresolved-name> productions end in a
- // base-unresolved-name, where <template-args> are just tacked
- // onto the end.
- if (DRE->hasExplicitTemplateArgs())
- mangleTemplateArgs(DRE->getTemplateArgs(), DRE->getNumTemplateArgs());
+ mangleUnresolvedName(DRE->getQualifier(), DRE->getDeclName(),
+ DRE->getTemplateArgs(), DRE->getNumTemplateArgs(),
+ Arity);
break;
}
@@ -4406,6 +4497,14 @@ void CXXNameMangler::addSubstitution(uintptr_t Ptr) {
Substitutions[Ptr] = SeqID++;
}
+void CXXNameMangler::extendSubstitutions(CXXNameMangler* Other) {
+ assert(Other->SeqID >= SeqID && "Must be superset of substitutions!");
+ if (Other->SeqID > SeqID) {
+ Substitutions.swap(Other->Substitutions);
+ SeqID = Other->SeqID;
+ }
+}
+
CXXNameMangler::AbiTagList
CXXNameMangler::makeFunctionReturnTypeTags(const FunctionDecl *FD) {
// When derived abi tags are disabled there is no need to make any list.