summaryrefslogtreecommitdiff
path: root/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp754
1 files changed, 592 insertions, 162 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp
index 3f6b682f238f..694fde317542 100644
--- a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp
@@ -20,6 +20,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
@@ -66,8 +67,9 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) {
}
const DeclContext *DC = D->getDeclContext();
- if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(DC))
- return getEffectiveDeclContext(CD);
+ if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC)) {
+ return getEffectiveDeclContext(cast<Decl>(DC));
+ }
if (const auto *VD = dyn_cast<VarDecl>(D))
if (VD->isExternC())
@@ -77,7 +79,7 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) {
if (FD->isExternC())
return FD->getASTContext().getTranslationUnitDecl();
- return DC;
+ return DC->getRedeclContext();
}
static const DeclContext *getEffectiveParentContext(const DeclContext *DC) {
@@ -212,6 +214,12 @@ public:
class CXXNameMangler {
ItaniumMangleContextImpl &Context;
raw_ostream &Out;
+ bool NullOut = false;
+ /// In the "DisableDerivedAbiTags" mode derived ABI tags are not calculated.
+ /// This mode is used when mangler creates another mangler recursively to
+ /// calculate ABI tags for the function return value or the variable type.
+ /// Also it is required to avoid infinite recursion in some cases.
+ bool DisableDerivedAbiTags = false;
/// The "structor" is the top-level declaration being mangled, if
/// that's not a template specialization; otherwise it's the pattern
@@ -261,15 +269,126 @@ class CXXNameMangler {
} FunctionTypeDepth;
+ // abi_tag is a gcc attribute, taking one or more strings called "tags".
+ // The goal is to annotate against which version of a library an object was
+ // built and to be able to provide backwards compatibility ("dual abi").
+ // For more information see docs/ItaniumMangleAbiTags.rst.
+ typedef SmallVector<StringRef, 4> AbiTagList;
+
+ // State to gather all implicit and explicit tags used in a mangled name.
+ // Must always have an instance of this while emitting any name to keep
+ // track.
+ class AbiTagState final {
+ public:
+ explicit AbiTagState(AbiTagState *&Head) : LinkHead(Head) {
+ Parent = LinkHead;
+ LinkHead = this;
+ }
+
+ // No copy, no move.
+ AbiTagState(const AbiTagState &) = delete;
+ AbiTagState &operator=(const AbiTagState &) = delete;
+
+ ~AbiTagState() { pop(); }
+
+ void write(raw_ostream &Out, const NamedDecl *ND,
+ const AbiTagList *AdditionalAbiTags) {
+ ND = cast<NamedDecl>(ND->getCanonicalDecl());
+ if (!isa<FunctionDecl>(ND) && !isa<VarDecl>(ND)) {
+ assert(
+ !AdditionalAbiTags &&
+ "only function and variables need a list of additional abi tags");
+ if (const auto *NS = dyn_cast<NamespaceDecl>(ND)) {
+ if (const auto *AbiTag = NS->getAttr<AbiTagAttr>()) {
+ UsedAbiTags.insert(UsedAbiTags.end(), AbiTag->tags().begin(),
+ AbiTag->tags().end());
+ }
+ // Don't emit abi tags for namespaces.
+ return;
+ }
+ }
+
+ AbiTagList TagList;
+ if (const auto *AbiTag = ND->getAttr<AbiTagAttr>()) {
+ UsedAbiTags.insert(UsedAbiTags.end(), AbiTag->tags().begin(),
+ AbiTag->tags().end());
+ TagList.insert(TagList.end(), AbiTag->tags().begin(),
+ AbiTag->tags().end());
+ }
+
+ if (AdditionalAbiTags) {
+ UsedAbiTags.insert(UsedAbiTags.end(), AdditionalAbiTags->begin(),
+ AdditionalAbiTags->end());
+ TagList.insert(TagList.end(), AdditionalAbiTags->begin(),
+ AdditionalAbiTags->end());
+ }
+
+ std::sort(TagList.begin(), TagList.end());
+ TagList.erase(std::unique(TagList.begin(), TagList.end()), TagList.end());
+
+ writeSortedUniqueAbiTags(Out, TagList);
+ }
+
+ const AbiTagList &getUsedAbiTags() const { return UsedAbiTags; }
+ void setUsedAbiTags(const AbiTagList &AbiTags) {
+ UsedAbiTags = AbiTags;
+ }
+
+ const AbiTagList &getEmittedAbiTags() const {
+ return EmittedAbiTags;
+ }
+
+ const AbiTagList &getSortedUniqueUsedAbiTags() {
+ std::sort(UsedAbiTags.begin(), UsedAbiTags.end());
+ UsedAbiTags.erase(std::unique(UsedAbiTags.begin(), UsedAbiTags.end()),
+ UsedAbiTags.end());
+ return UsedAbiTags;
+ }
+
+ private:
+ //! All abi tags used implicitly or explicitly.
+ AbiTagList UsedAbiTags;
+ //! All explicit abi tags (i.e. not from namespace).
+ AbiTagList EmittedAbiTags;
+
+ AbiTagState *&LinkHead;
+ AbiTagState *Parent = nullptr;
+
+ void pop() {
+ assert(LinkHead == this &&
+ "abi tag link head must point to us on destruction");
+ if (Parent) {
+ Parent->UsedAbiTags.insert(Parent->UsedAbiTags.end(),
+ UsedAbiTags.begin(), UsedAbiTags.end());
+ Parent->EmittedAbiTags.insert(Parent->EmittedAbiTags.end(),
+ EmittedAbiTags.begin(),
+ EmittedAbiTags.end());
+ }
+ LinkHead = Parent;
+ }
+
+ void writeSortedUniqueAbiTags(raw_ostream &Out, const AbiTagList &AbiTags) {
+ for (const auto &Tag : AbiTags) {
+ EmittedAbiTags.push_back(Tag);
+ Out << "B";
+ Out << Tag.size();
+ Out << Tag;
+ }
+ }
+ };
+
+ AbiTagState *AbiTags = nullptr;
+ AbiTagState AbiTagsRoot;
+
llvm::DenseMap<uintptr_t, unsigned> Substitutions;
ASTContext &getASTContext() const { return Context.getASTContext(); }
public:
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
- const NamedDecl *D = nullptr)
- : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(0),
- SeqID(0) {
+ const NamedDecl *D = nullptr, bool NullOut_ = false)
+ : Context(C), Out(Out_), NullOut(NullOut_), Structor(getStructor(D)),
+ StructorType(0), SeqID(0), AbiTagsRoot(AbiTags) {
// These can't be mangled without a ctor type or dtor type.
assert(!D || (!isa<CXXDestructorDecl>(D) &&
!isa<CXXConstructorDecl>(D)));
@@ -277,11 +396,21 @@ public:
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
const CXXConstructorDecl *D, CXXCtorType Type)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
- SeqID(0) { }
+ SeqID(0), AbiTagsRoot(AbiTags) { }
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
const CXXDestructorDecl *D, CXXDtorType Type)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
- SeqID(0) { }
+ SeqID(0), AbiTagsRoot(AbiTags) { }
+
+ CXXNameMangler(CXXNameMangler &Outer, raw_ostream &Out_)
+ : Context(Outer.Context), Out(Out_), NullOut(false),
+ Structor(Outer.Structor), StructorType(Outer.StructorType),
+ SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {}
+
+ 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) {}
#if MANGLE_CHECKER
~CXXNameMangler() {
@@ -296,6 +425,9 @@ public:
#endif
raw_ostream &getStream() { return Out; }
+ void disableDerivedAbiTags() { DisableDerivedAbiTags = true; }
+ static bool shouldHaveAbiTags(ItaniumMangleContextImpl &C, const VarDecl *VD);
+
void mangle(const NamedDecl *D);
void mangleCallOffset(int64_t NonVirtual, int64_t Virtual);
void mangleNumber(const llvm::APSInt &I);
@@ -314,7 +446,6 @@ private:
bool mangleSubstitution(TemplateName Template);
bool mangleSubstitution(uintptr_t Ptr);
- void mangleExistingSubstitution(QualType type);
void mangleExistingSubstitution(TemplateName name);
bool mangleStandardSubstitution(const NamedDecl *ND);
@@ -334,23 +465,37 @@ private:
DeclarationName name,
unsigned KnownArity = UnknownArity);
- void mangleName(const TemplateDecl *TD,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs);
- void mangleUnqualifiedName(const NamedDecl *ND) {
- mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity);
+ void mangleFunctionEncodingBareType(const FunctionDecl *FD);
+
+ void mangleNameWithAbiTags(const NamedDecl *ND,
+ const AbiTagList *AdditionalAbiTags);
+ void mangleTemplateName(const TemplateDecl *TD,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs);
+ void mangleUnqualifiedName(const NamedDecl *ND,
+ const AbiTagList *AdditionalAbiTags) {
+ mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity,
+ AdditionalAbiTags);
}
void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name,
- unsigned KnownArity);
- void mangleUnscopedName(const NamedDecl *ND);
- void mangleUnscopedTemplateName(const TemplateDecl *ND);
- void mangleUnscopedTemplateName(TemplateName);
+ unsigned KnownArity,
+ const AbiTagList *AdditionalAbiTags);
+ void mangleUnscopedName(const NamedDecl *ND,
+ const AbiTagList *AdditionalAbiTags);
+ void mangleUnscopedTemplateName(const TemplateDecl *ND,
+ const AbiTagList *AdditionalAbiTags);
+ void mangleUnscopedTemplateName(TemplateName,
+ const AbiTagList *AdditionalAbiTags);
void mangleSourceName(const IdentifierInfo *II);
- void mangleLocalName(const Decl *D);
+ void mangleSourceNameWithAbiTags(
+ const NamedDecl *ND, const AbiTagList *AdditionalAbiTags = nullptr);
+ void mangleLocalName(const Decl *D,
+ const AbiTagList *AdditionalAbiTags);
void mangleBlockForPrefix(const BlockDecl *Block);
void mangleUnqualifiedBlock(const BlockDecl *Block);
void mangleLambda(const CXXRecordDecl *Lambda);
void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,
+ const AbiTagList *AdditionalAbiTags,
bool NoFunction=false);
void mangleNestedName(const TemplateDecl *TD,
const TemplateArgument *TemplateArgs,
@@ -364,6 +509,7 @@ private:
StringRef Prefix = "");
void mangleOperatorName(DeclarationName Name, unsigned Arity);
void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
+ void mangleVendorQualifier(StringRef qualifier);
void mangleQualifiers(Qualifiers Quals);
void mangleRefQualifier(RefQualifierKind RefQualifier);
@@ -377,7 +523,10 @@ private:
void mangleType(const TagType*);
void mangleType(TemplateName);
- void mangleBareFunctionType(const FunctionType *T, bool MangleReturnType,
+ static StringRef getCallingConvQualifierName(CallingConv CC);
+ void mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo info);
+ void mangleExtFunctionInfo(const FunctionType *T);
+ void mangleBareFunctionType(const FunctionProtoType *T, bool MangleReturnType,
const FunctionDecl *FD = nullptr);
void mangleNeonVectorType(const VectorType *T);
void mangleAArch64NeonVectorType(const VectorType *T);
@@ -392,7 +541,7 @@ private:
void mangleCastExpression(const Expr *E, StringRef CastEncoding);
void mangleInitListElements(const InitListExpr *InitList);
void mangleExpression(const Expr *E, unsigned Arity = UnknownArity);
- void mangleCXXCtorType(CXXCtorType T);
+ void mangleCXXCtorType(CXXCtorType T, const CXXRecordDecl *InheritedFrom);
void mangleCXXDtorType(CXXDtorType T);
void mangleTemplateArgs(const TemplateArgumentLoc *TemplateArgs,
@@ -405,6 +554,14 @@ private:
void mangleTemplateParameter(unsigned Index);
void mangleFunctionParam(const ParmVarDecl *parm);
+
+ void writeAbiTags(const NamedDecl *ND,
+ const AbiTagList *AdditionalAbiTags);
+
+ // Returns sorted unique list of ABI tags.
+ AbiTagList makeFunctionReturnTypeTags(const FunctionDecl *FD);
+ // Returns sorted unique list of ABI tags.
+ AbiTagList makeVariableTypeTags(const VarDecl *VD);
};
}
@@ -448,6 +605,7 @@ bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
while (!DC->isNamespace() && !DC->isTranslationUnit())
DC = getEffectiveParentContext(DC);
if (DC->isTranslationUnit() && D->getFormalLinkage() != InternalLinkage &&
+ !CXXNameMangler::shouldHaveAbiTags(*this, VD) &&
!isa<VarTemplateSpecializationDecl>(D))
return false;
}
@@ -455,6 +613,18 @@ bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
return true;
}
+void CXXNameMangler::writeAbiTags(const NamedDecl *ND,
+ const AbiTagList *AdditionalAbiTags) {
+ assert(AbiTags && "require AbiTagState");
+ AbiTags->write(Out, ND, DisableDerivedAbiTags ? nullptr : AdditionalAbiTags);
+}
+
+void CXXNameMangler::mangleSourceNameWithAbiTags(
+ const NamedDecl *ND, const AbiTagList *AdditionalAbiTags) {
+ mangleSourceName(ND->getIdentifier());
+ writeAbiTags(ND, AdditionalAbiTags);
+}
+
void CXXNameMangler::mangle(const NamedDecl *D) {
// <mangled-name> ::= _Z <encoding>
// ::= <data name>
@@ -472,12 +642,52 @@ void CXXNameMangler::mangle(const NamedDecl *D) {
void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
// <encoding> ::= <function name> <bare-function-type>
- mangleName(FD);
// Don't mangle in the type if this isn't a decl we should typically mangle.
- if (!Context.shouldMangleDeclName(FD))
+ if (!Context.shouldMangleDeclName(FD)) {
+ mangleName(FD);
+ return;
+ }
+
+ AbiTagList ReturnTypeAbiTags = makeFunctionReturnTypeTags(FD);
+ if (ReturnTypeAbiTags.empty()) {
+ // There are no tags for return type, the simplest case.
+ mangleName(FD);
+ mangleFunctionEncodingBareType(FD);
return;
+ }
+ // Mangle function name and encoding to temporary buffer.
+ // We have to output name and encoding to the same mangler to get the same
+ // substitution as it will be in final mangling.
+ SmallString<256> FunctionEncodingBuf;
+ llvm::raw_svector_ostream FunctionEncodingStream(FunctionEncodingBuf);
+ CXXNameMangler FunctionEncodingMangler(*this, FunctionEncodingStream);
+ // Output name of the function.
+ FunctionEncodingMangler.disableDerivedAbiTags();
+ FunctionEncodingMangler.mangleNameWithAbiTags(FD, nullptr);
+
+ // Remember length of the function name in the buffer.
+ size_t EncodingPositionStart = FunctionEncodingStream.str().size();
+ FunctionEncodingMangler.mangleFunctionEncodingBareType(FD);
+
+ // Get tags from return type that are not present in function name or
+ // encoding.
+ const AbiTagList &UsedAbiTags =
+ FunctionEncodingMangler.AbiTagsRoot.getSortedUniqueUsedAbiTags();
+ AbiTagList AdditionalAbiTags(ReturnTypeAbiTags.size());
+ AdditionalAbiTags.erase(
+ std::set_difference(ReturnTypeAbiTags.begin(), ReturnTypeAbiTags.end(),
+ UsedAbiTags.begin(), UsedAbiTags.end(),
+ AdditionalAbiTags.begin()),
+ AdditionalAbiTags.end());
+
+ // Output name with implicit tags and function encoding from temporary buffer.
+ mangleNameWithAbiTags(FD, &AdditionalAbiTags);
+ Out << FunctionEncodingStream.str().substr(EncodingPositionStart);
+}
+
+void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
if (FD->hasAttr<EnableIfAttr>()) {
FunctionTypeDepthState Saved = FunctionTypeDepth.push();
Out << "Ua9enable_ifI";
@@ -497,6 +707,12 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
FunctionTypeDepth.pop(Saved);
}
+ // When mangling an inheriting constructor, the bare function type used is
+ // that of the inherited constructor.
+ if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
+ if (auto Inherited = CD->getInheritedConstructor())
+ FD = Inherited.getConstructor();
+
// Whether the mangling of a function type includes the return type depends on
// the context and the nature of the function. The rules for deciding whether
// the return type is included are:
@@ -523,7 +739,7 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
FD = PrimaryTemplate->getTemplatedDecl();
}
- mangleBareFunctionType(FD->getType()->getAs<FunctionType>(),
+ mangleBareFunctionType(FD->getType()->castAs<FunctionProtoType>(),
MangleReturnType, FD);
}
@@ -557,7 +773,7 @@ static bool isStdNamespace(const DeclContext *DC) {
static const TemplateDecl *
isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
// Check if we have a function template.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {
TemplateArgs = FD->getTemplateSpecializationArgs();
return TD;
@@ -582,6 +798,40 @@ isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
}
void CXXNameMangler::mangleName(const NamedDecl *ND) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+ // Variables should have implicit tags from its type.
+ AbiTagList VariableTypeAbiTags = makeVariableTypeTags(VD);
+ if (VariableTypeAbiTags.empty()) {
+ // Simple case no variable type tags.
+ mangleNameWithAbiTags(VD, nullptr);
+ return;
+ }
+
+ // Mangle variable name to null stream to collect tags.
+ llvm::raw_null_ostream NullOutStream;
+ CXXNameMangler VariableNameMangler(*this, NullOutStream);
+ VariableNameMangler.disableDerivedAbiTags();
+ VariableNameMangler.mangleNameWithAbiTags(VD, nullptr);
+
+ // Get tags from variable type that are not present in its name.
+ const AbiTagList &UsedAbiTags =
+ VariableNameMangler.AbiTagsRoot.getSortedUniqueUsedAbiTags();
+ AbiTagList AdditionalAbiTags(VariableTypeAbiTags.size());
+ AdditionalAbiTags.erase(
+ std::set_difference(VariableTypeAbiTags.begin(),
+ VariableTypeAbiTags.end(), UsedAbiTags.begin(),
+ UsedAbiTags.end(), AdditionalAbiTags.begin()),
+ AdditionalAbiTags.end());
+
+ // Output name with implicit tags.
+ mangleNameWithAbiTags(VD, &AdditionalAbiTags);
+ } else {
+ mangleNameWithAbiTags(ND, nullptr);
+ }
+}
+
+void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND,
+ const AbiTagList *AdditionalAbiTags) {
// <name> ::= <nested-name>
// ::= <unscoped-name>
// ::= <unscoped-template-name> <template-args>
@@ -597,7 +847,7 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) {
while (!DC->isNamespace() && !DC->isTranslationUnit())
DC = getEffectiveParentContext(DC);
else if (GetLocalClassDecl(ND)) {
- mangleLocalName(ND);
+ mangleLocalName(ND, AdditionalAbiTags);
return;
}
@@ -607,76 +857,88 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) {
// Check if we have a template.
const TemplateArgumentList *TemplateArgs = nullptr;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
- mangleUnscopedTemplateName(TD);
+ mangleUnscopedTemplateName(TD, AdditionalAbiTags);
mangleTemplateArgs(*TemplateArgs);
return;
}
- mangleUnscopedName(ND);
+ mangleUnscopedName(ND, AdditionalAbiTags);
return;
}
if (isLocalContainerContext(DC)) {
- mangleLocalName(ND);
+ mangleLocalName(ND, AdditionalAbiTags);
return;
}
- mangleNestedName(ND, DC);
+ mangleNestedName(ND, DC, AdditionalAbiTags);
}
-void CXXNameMangler::mangleName(const TemplateDecl *TD,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs) {
+
+void CXXNameMangler::mangleTemplateName(const TemplateDecl *TD,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs) {
const DeclContext *DC = IgnoreLinkageSpecDecls(getEffectiveDeclContext(TD));
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
- mangleUnscopedTemplateName(TD);
+ mangleUnscopedTemplateName(TD, nullptr);
mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
} else {
mangleNestedName(TD, TemplateArgs, NumTemplateArgs);
}
}
-void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND) {
+void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND,
+ const AbiTagList *AdditionalAbiTags) {
// <unscoped-name> ::= <unqualified-name>
// ::= St <unqualified-name> # ::std::
if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND))))
Out << "St";
- mangleUnqualifiedName(ND);
+ mangleUnqualifiedName(ND, AdditionalAbiTags);
}
-void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) {
+void CXXNameMangler::mangleUnscopedTemplateName(
+ const TemplateDecl *ND, const AbiTagList *AdditionalAbiTags) {
// <unscoped-template-name> ::= <unscoped-name>
// ::= <substitution>
if (mangleSubstitution(ND))
return;
// <template-template-param> ::= <template-param>
- if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND))
+ if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) {
+ assert(!AdditionalAbiTags &&
+ "template template param cannot have abi tags");
mangleTemplateParameter(TTP->getIndex());
- else
- mangleUnscopedName(ND->getTemplatedDecl());
+ } else if (isa<BuiltinTemplateDecl>(ND)) {
+ mangleUnscopedName(ND, AdditionalAbiTags);
+ } else {
+ mangleUnscopedName(ND->getTemplatedDecl(), AdditionalAbiTags);
+ }
addSubstitution(ND);
}
-void CXXNameMangler::mangleUnscopedTemplateName(TemplateName Template) {
+void CXXNameMangler::mangleUnscopedTemplateName(
+ TemplateName Template, const AbiTagList *AdditionalAbiTags) {
// <unscoped-template-name> ::= <unscoped-name>
// ::= <substitution>
if (TemplateDecl *TD = Template.getAsTemplateDecl())
- return mangleUnscopedTemplateName(TD);
+ return mangleUnscopedTemplateName(TD, AdditionalAbiTags);
if (mangleSubstitution(Template))
return;
+ assert(!AdditionalAbiTags &&
+ "dependent template name cannot have abi tags");
+
DependentTemplateName *Dependent = Template.getAsDependentTemplateName();
assert(Dependent && "Not a dependent template name?");
if (const IdentifierInfo *Id = Dependent->getIdentifier())
mangleSourceName(Id);
else
mangleOperatorName(Dependent->getOperator(), UnknownArity);
-
+
addSubstitution(Template);
}
@@ -834,7 +1096,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
/*recursive*/ true);
else
Out << "sr";
- mangleSourceName(qualifier->getAsNamespace()->getIdentifier());
+ mangleSourceNameWithAbiTags(qualifier->getAsNamespace());
break;
case NestedNameSpecifier::NamespaceAlias:
if (qualifier->getPrefix())
@@ -842,7 +1104,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
/*recursive*/ true);
else
Out << "sr";
- mangleSourceName(qualifier->getAsNamespaceAlias()->getIdentifier());
+ mangleSourceNameWithAbiTags(qualifier->getAsNamespaceAlias());
break;
case NestedNameSpecifier::TypeSpec:
@@ -877,6 +1139,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
Out << "sr";
mangleSourceName(qualifier->getAsIdentifier());
+ // An Identifier has no type information, so we can't emit abi tags for it.
break;
}
@@ -922,7 +1185,8 @@ void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier,
void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
DeclarationName Name,
- unsigned KnownArity) {
+ unsigned KnownArity,
+ const AbiTagList *AdditionalAbiTags) {
unsigned Arity = KnownArity;
// <unqualified-name> ::= <operator-name>
// ::= <ctor-dtor-name>
@@ -941,6 +1205,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
Out << 'L';
mangleSourceName(II);
+ writeAbiTags(ND, AdditionalAbiTags);
break;
}
@@ -980,6 +1245,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
assert(FD->getIdentifier() && "Data member name isn't an identifier!");
mangleSourceName(FD->getIdentifier());
+ // Not emitting abi tags: internal name anyway.
break;
}
@@ -1000,6 +1266,10 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
assert(D->getDeclName().getAsIdentifierInfo() &&
"Typedef was not named!");
mangleSourceName(D->getDeclName().getAsIdentifierInfo());
+ assert(!AdditionalAbiTags && "Type cannot have additional abi tags");
+ // Explicit abi tags are still possible; take from underlying type, not
+ // from typedef.
+ writeAbiTags(TD, nullptr);
break;
}
@@ -1009,6 +1279,8 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// <lambda-sig> ::= <parameter-type>+ # Parameter types or 'v' for 'void'.
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
if (Record->isLambda() && Record->getLambdaManglingNumber()) {
+ assert(!AdditionalAbiTags &&
+ "Lambda type cannot have additional abi tags");
mangleLambda(Record);
break;
}
@@ -1020,11 +1292,13 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
if (UnnamedMangle > 1)
Out << UnnamedMangle - 2;
Out << '_';
+ writeAbiTags(TD, AdditionalAbiTags);
break;
}
- // Get a unique id for the anonymous struct.
- unsigned AnonStructId = Context.getAnonymousStructId(TD);
+ // Get a unique id for the anonymous struct. If it is not a real output
+ // ID doesn't matter so use fake one.
+ unsigned AnonStructId = NullOut ? 0 : Context.getAnonymousStructId(TD);
// Mangle it as a source name in the form
// [n] $_<id>
@@ -1043,16 +1317,33 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
case DeclarationName::ObjCMultiArgSelector:
llvm_unreachable("Can't mangle Objective-C selector names here!");
- case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXConstructorName: {
+ const CXXRecordDecl *InheritedFrom = nullptr;
+ const TemplateArgumentList *InheritedTemplateArgs = nullptr;
+ if (auto Inherited =
+ cast<CXXConstructorDecl>(ND)->getInheritedConstructor()) {
+ InheritedFrom = Inherited.getConstructor()->getParent();
+ InheritedTemplateArgs =
+ Inherited.getConstructor()->getTemplateSpecializationArgs();
+ }
+
if (ND == Structor)
// If the named decl is the C++ constructor we're mangling, use the type
// we were given.
- mangleCXXCtorType(static_cast<CXXCtorType>(StructorType));
+ mangleCXXCtorType(static_cast<CXXCtorType>(StructorType), InheritedFrom);
else
// Otherwise, use the complete constructor name. This is relevant if a
// class with a constructor is declared within a constructor.
- mangleCXXCtorType(Ctor_Complete);
+ mangleCXXCtorType(Ctor_Complete, InheritedFrom);
+
+ // FIXME: The template arguments are part of the enclosing prefix or
+ // nested-name, but it's more convenient to mangle them here.
+ if (InheritedTemplateArgs)
+ mangleTemplateArgs(*InheritedTemplateArgs);
+
+ writeAbiTags(ND, AdditionalAbiTags);
break;
+ }
case DeclarationName::CXXDestructorName:
if (ND == Structor)
@@ -1063,6 +1354,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// Otherwise, use the complete destructor name. This is relevant if a
// class with a destructor is declared within a destructor.
mangleCXXDtorType(Dtor_Complete);
+ writeAbiTags(ND, AdditionalAbiTags);
break;
case DeclarationName::CXXOperatorName:
@@ -1078,6 +1370,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
case DeclarationName::CXXConversionFunctionName:
case DeclarationName::CXXLiteralOperatorName:
mangleOperatorName(Name, Arity);
+ writeAbiTags(ND, AdditionalAbiTags);
break;
case DeclarationName::CXXUsingDirective:
@@ -1094,6 +1387,7 @@ void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
const DeclContext *DC,
+ const AbiTagList *AdditionalAbiTags,
bool NoFunction) {
// <nested-name>
// ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
@@ -1119,7 +1413,7 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
}
else {
manglePrefix(DC, NoFunction);
- mangleUnqualifiedName(ND);
+ mangleUnqualifiedName(ND, AdditionalAbiTags);
}
Out << 'E';
@@ -1137,7 +1431,8 @@ void CXXNameMangler::mangleNestedName(const TemplateDecl *TD,
Out << 'E';
}
-void CXXNameMangler::mangleLocalName(const Decl *D) {
+void CXXNameMangler::mangleLocalName(const Decl *D,
+ const AbiTagList *AdditionalAbiTags) {
// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
// := Z <function encoding> E s [<discriminator>]
// <local-name> := Z <function encoding> E d [ <parameter number> ]
@@ -1149,15 +1444,26 @@ void CXXNameMangler::mangleLocalName(const Decl *D) {
Out << 'Z';
- if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))
- mangleObjCMethodName(MD);
- else if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC))
- mangleBlockForPrefix(BD);
- else
- mangleFunctionEncoding(cast<FunctionDecl>(DC));
+ {
+ AbiTagState LocalAbiTags(AbiTags);
+
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))
+ mangleObjCMethodName(MD);
+ else if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC))
+ mangleBlockForPrefix(BD);
+ else
+ mangleFunctionEncoding(cast<FunctionDecl>(DC));
+
+ // Implicit ABI tags (from namespace) are not available in the following
+ // entity; reset to actually emitted tags, which are available.
+ LocalAbiTags.setUsedAbiTags(LocalAbiTags.getEmittedAbiTags());
+ }
Out << 'E';
+ // GCC 5.3.0 doesn't emit derived ABI tags for local names but that seems to
+ // be a bug that is fixed in trunk.
+
if (RD) {
// The parameter number is omitted for the last parameter, 0 for the
// second-to-last parameter, 1 for the third-to-last parameter, etc. The
@@ -1182,13 +1488,15 @@ void CXXNameMangler::mangleLocalName(const Decl *D) {
// Mangle the name relative to the closest enclosing function.
// equality ok because RD derived from ND above
if (D == RD) {
- mangleUnqualifiedName(RD);
+ mangleUnqualifiedName(RD, AdditionalAbiTags);
} else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
manglePrefix(getEffectiveDeclContext(BD), true /*NoFunction*/);
+ assert(!AdditionalAbiTags && "Block cannot have additional abi tags");
mangleUnqualifiedBlock(BD);
} else {
const NamedDecl *ND = cast<NamedDecl>(D);
- mangleNestedName(ND, getEffectiveDeclContext(ND), true /*NoFunction*/);
+ mangleNestedName(ND, getEffectiveDeclContext(ND), AdditionalAbiTags,
+ true /*NoFunction*/);
}
} else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
// Mangle a block in a default parameter; see above explanation for
@@ -1205,9 +1513,10 @@ void CXXNameMangler::mangleLocalName(const Decl *D) {
}
}
+ assert(!AdditionalAbiTags && "Block cannot have additional abi tags");
mangleUnqualifiedBlock(BD);
} else {
- mangleUnqualifiedName(cast<NamedDecl>(D));
+ mangleUnqualifiedName(cast<NamedDecl>(D), AdditionalAbiTags);
}
if (const NamedDecl *ND = dyn_cast<NamedDecl>(RD ? RD : D)) {
@@ -1223,12 +1532,12 @@ void CXXNameMangler::mangleLocalName(const Decl *D) {
void CXXNameMangler::mangleBlockForPrefix(const BlockDecl *Block) {
if (GetLocalClassDecl(Block)) {
- mangleLocalName(Block);
+ mangleLocalName(Block, /* AdditionalAbiTags */ nullptr);
return;
}
const DeclContext *DC = getEffectiveDeclContext(Block);
if (isLocalContainerContext(DC)) {
- mangleLocalName(Block);
+ mangleLocalName(Block, /* AdditionalAbiTags */ nullptr);
return;
}
manglePrefix(getEffectiveDeclContext(Block));
@@ -1239,10 +1548,10 @@ void CXXNameMangler::mangleUnqualifiedBlock(const BlockDecl *Block) {
if (Decl *Context = Block->getBlockManglingContextDecl()) {
if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) &&
Context->getDeclContext()->isRecord()) {
- if (const IdentifierInfo *Name
- = cast<NamedDecl>(Context)->getIdentifier()) {
- mangleSourceName(Name);
- Out << 'M';
+ const auto *ND = cast<NamedDecl>(Context);
+ if (ND->getIdentifier()) {
+ mangleSourceNameWithAbiTags(ND);
+ Out << 'M';
}
}
}
@@ -1275,7 +1584,7 @@ void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
if (const IdentifierInfo *Name
= cast<NamedDecl>(Context)->getIdentifier()) {
mangleSourceName(Name);
- Out << 'M';
+ Out << 'M';
}
}
}
@@ -1362,7 +1671,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
mangleTemplateArgs(*TemplateArgs);
} else {
manglePrefix(getEffectiveDeclContext(ND), NoFunction);
- mangleUnqualifiedName(ND);
+ mangleUnqualifiedName(ND, nullptr);
}
addSubstitution(ND);
@@ -1377,19 +1686,19 @@ void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) {
if (QualifiedTemplateName *Qualified = Template.getAsQualifiedTemplateName())
manglePrefix(Qualified->getQualifier());
-
+
if (OverloadedTemplateStorage *Overloaded
= Template.getAsOverloadedTemplate()) {
mangleUnqualifiedName(nullptr, (*Overloaded->begin())->getDeclName(),
- UnknownArity);
+ UnknownArity, nullptr);
return;
}
-
+
DependentTemplateName *Dependent = Template.getAsDependentTemplateName();
assert(Dependent && "Unknown template name kind?");
if (NestedNameSpecifier *Qualifier = Dependent->getQualifier())
manglePrefix(Qualifier);
- mangleUnscopedTemplateName(Template);
+ mangleUnscopedTemplateName(Template, /* AdditionalAbiTags */ nullptr);
}
void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND,
@@ -1408,7 +1717,10 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND,
mangleTemplateParameter(TTP->getIndex());
} else {
manglePrefix(getEffectiveDeclContext(ND), NoFunction);
- mangleUnqualifiedName(ND->getTemplatedDecl());
+ if (isa<BuiltinTemplateDecl>(ND))
+ mangleUnqualifiedName(ND, nullptr);
+ else
+ mangleUnqualifiedName(ND->getTemplatedDecl(), nullptr);
}
addSubstitution(ND);
@@ -1543,17 +1855,17 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
return true;
case Type::Typedef:
- mangleSourceName(cast<TypedefType>(Ty)->getDecl()->getIdentifier());
+ mangleSourceNameWithAbiTags(cast<TypedefType>(Ty)->getDecl());
break;
case Type::UnresolvedUsing:
- mangleSourceName(
- cast<UnresolvedUsingType>(Ty)->getDecl()->getIdentifier());
+ mangleSourceNameWithAbiTags(
+ cast<UnresolvedUsingType>(Ty)->getDecl());
break;
case Type::Enum:
case Type::Record:
- mangleSourceName(cast<TagType>(Ty)->getDecl()->getIdentifier());
+ mangleSourceNameWithAbiTags(cast<TagType>(Ty)->getDecl());
break;
case Type::TemplateSpecialization: {
@@ -1571,7 +1883,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
if (isa<TemplateTemplateParmDecl>(TD))
goto unresolvedType;
- mangleSourceName(TD->getIdentifier());
+ mangleSourceNameWithAbiTags(TD);
break;
}
@@ -1601,8 +1913,8 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
}
case Type::InjectedClassName:
- mangleSourceName(
- cast<InjectedClassNameType>(Ty)->getDecl()->getIdentifier());
+ mangleSourceNameWithAbiTags(
+ cast<InjectedClassNameType>(Ty)->getDecl());
break;
case Type::DependentName:
@@ -1653,8 +1965,6 @@ void CXXNameMangler::mangleOperatorName(DeclarationName Name, unsigned Arity) {
}
}
-
-
void
CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
switch (OO) {
@@ -1767,14 +2077,9 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
}
void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
- // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const
- if (Quals.hasRestrict())
- Out << 'r';
- if (Quals.hasVolatile())
- Out << 'V';
- if (Quals.hasConst())
- Out << 'K';
+ // Vendor qualifiers come first.
+ // Address space qualifiers start with an ordinary letter.
if (Quals.hasAddressSpace()) {
// Address space extension:
//
@@ -1788,7 +2093,7 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
// <target-addrspace> ::= "AS" <address-space-number>
unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
- ASString = "AS" + llvm::utostr_32(TargetAS);
+ ASString = "AS" + llvm::utostr(TargetAS);
} else {
switch (AS) {
default: llvm_unreachable("Not a language specific address space");
@@ -1802,10 +2107,10 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
case LangAS::cuda_shared: ASString = "CUshared"; break;
}
}
- Out << 'U' << ASString.size() << ASString;
+ mangleVendorQualifier(ASString);
}
-
- StringRef LifetimeName;
+
+ // The ARC ownership qualifiers start with underscores.
switch (Quals.getObjCLifetime()) {
// Objective-C ARC Extension:
//
@@ -1816,15 +2121,15 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
break;
case Qualifiers::OCL_Weak:
- LifetimeName = "__weak";
+ mangleVendorQualifier("__weak");
break;
case Qualifiers::OCL_Strong:
- LifetimeName = "__strong";
+ mangleVendorQualifier("__strong");
break;
case Qualifiers::OCL_Autoreleasing:
- LifetimeName = "__autoreleasing";
+ mangleVendorQualifier("__autoreleasing");
break;
case Qualifiers::OCL_ExplicitNone:
@@ -1837,8 +2142,18 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
// in any type signatures that need to be mangled.
break;
}
- if (!LifetimeName.empty())
- Out << 'U' << LifetimeName.size() << LifetimeName;
+
+ // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const
+ if (Quals.hasRestrict())
+ Out << 'r';
+ if (Quals.hasVolatile())
+ Out << 'V';
+ if (Quals.hasConst())
+ Out << 'K';
+}
+
+void CXXNameMangler::mangleVendorQualifier(StringRef name) {
+ Out << 'U' << name.size() << name;
}
void CXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {
@@ -1981,7 +2296,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
// ::= f # float
// ::= d # double
// ::= e # long double, __float80
- // UNSUPPORTED: ::= g # __float128
+ // ::= g # __float128
// UNSUPPORTED: ::= Dd # IEEE 754r decimal floating point (64 bits)
// UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits)
// UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits)
@@ -1990,6 +2305,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
// ::= Ds # char16_t
// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
// ::= u <source-name> # vendor extended type
+ std::string type_name;
switch (T->getKind()) {
case BuiltinType::Void:
Out << 'v';
@@ -2061,6 +2377,12 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
? 'g'
: 'e');
break;
+ case BuiltinType::Float128:
+ if (getASTContext().getTargetInfo().useFloat128ManglingForLongDouble())
+ Out << "U10__float128"; // Match the GCC mangling
+ else
+ Out << 'g';
+ break;
case BuiltinType::NullPtr:
Out << "Dn";
break;
@@ -2070,7 +2392,9 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
case BuiltinType::Id:
#include "clang/AST/BuiltinTypes.def"
case BuiltinType::Dependent:
- llvm_unreachable("mangling a placeholder type");
+ if (!NullOut)
+ llvm_unreachable("mangling a placeholder type");
+ break;
case BuiltinType::ObjCId:
Out << "11objc_object";
break;
@@ -2080,42 +2404,12 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
case BuiltinType::ObjCSel:
Out << "13objc_selector";
break;
- case BuiltinType::OCLImage1d:
- Out << "11ocl_image1d";
- break;
- case BuiltinType::OCLImage1dArray:
- Out << "16ocl_image1darray";
- break;
- case BuiltinType::OCLImage1dBuffer:
- Out << "17ocl_image1dbuffer";
- break;
- case BuiltinType::OCLImage2d:
- Out << "11ocl_image2d";
- break;
- case BuiltinType::OCLImage2dArray:
- Out << "16ocl_image2darray";
- break;
- case BuiltinType::OCLImage2dDepth:
- Out << "16ocl_image2ddepth";
- break;
- case BuiltinType::OCLImage2dArrayDepth:
- Out << "21ocl_image2darraydepth";
- break;
- case BuiltinType::OCLImage2dMSAA:
- Out << "15ocl_image2dmsaa";
- break;
- case BuiltinType::OCLImage2dArrayMSAA:
- Out << "20ocl_image2darraymsaa";
- break;
- case BuiltinType::OCLImage2dMSAADepth:
- Out << "20ocl_image2dmsaadepth";
- break;
- case BuiltinType::OCLImage2dArrayMSAADepth:
- Out << "35ocl_image2darraymsaadepth";
- break;
- case BuiltinType::OCLImage3d:
- Out << "11ocl_image3d";
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
+ case BuiltinType::Id: \
+ type_name = "ocl_" #ImgType "_" #Suffix; \
+ Out << type_name.size() << type_name; \
break;
+#include "clang/Basic/OpenCLImageTypes.def"
case BuiltinType::OCLSampler:
Out << "11ocl_sampler";
break;
@@ -2137,10 +2431,80 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
}
}
+StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) {
+ switch (CC) {
+ case CC_C:
+ return "";
+
+ case CC_X86StdCall:
+ case CC_X86FastCall:
+ case CC_X86ThisCall:
+ case CC_X86VectorCall:
+ case CC_X86Pascal:
+ case CC_X86_64Win64:
+ case CC_X86_64SysV:
+ case CC_AAPCS:
+ case CC_AAPCS_VFP:
+ case CC_IntelOclBicc:
+ case CC_SpirFunction:
+ case CC_OpenCLKernel:
+ case CC_PreserveMost:
+ case CC_PreserveAll:
+ // FIXME: we should be mangling all of the above.
+ return "";
+
+ case CC_Swift:
+ return "swiftcall";
+ }
+ llvm_unreachable("bad calling convention");
+}
+
+void CXXNameMangler::mangleExtFunctionInfo(const FunctionType *T) {
+ // Fast path.
+ if (T->getExtInfo() == FunctionType::ExtInfo())
+ return;
+
+ // Vendor-specific qualifiers are emitted in reverse alphabetical order.
+ // This will get more complicated in the future if we mangle other
+ // things here; but for now, since we mangle ns_returns_retained as
+ // a qualifier on the result type, we can get away with this:
+ StringRef CCQualifier = getCallingConvQualifierName(T->getExtInfo().getCC());
+ if (!CCQualifier.empty())
+ mangleVendorQualifier(CCQualifier);
+
+ // FIXME: regparm
+ // FIXME: noreturn
+}
+
+void
+CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
+ // Vendor-specific qualifiers are emitted in reverse alphabetical order.
+
+ // Note that these are *not* substitution candidates. Demanglers might
+ // have trouble with this if the parameter type is fully substituted.
+
+ switch (PI.getABI()) {
+ case ParameterABI::Ordinary:
+ break;
+
+ // All of these start with "swift", so they come before "ns_consumed".
+ case ParameterABI::SwiftContext:
+ case ParameterABI::SwiftErrorResult:
+ case ParameterABI::SwiftIndirectResult:
+ mangleVendorQualifier(getParameterABISpelling(PI.getABI()));
+ break;
+ }
+
+ if (PI.isConsumed())
+ mangleVendorQualifier("ns_consumed");
+}
+
// <type> ::= <function-type>
// <function-type> ::= [<CV-qualifiers>] F [Y]
// <bare-function-type> [<ref-qualifier>] E
void CXXNameMangler::mangleType(const FunctionProtoType *T) {
+ mangleExtFunctionInfo(T);
+
// Mangle CV-qualifiers, if present. These are 'this' qualifiers,
// e.g. "const" in "int (A::*)() const".
mangleQualifiers(Qualifiers::fromCVRMask(T->getTypeQuals()));
@@ -2173,12 +2537,9 @@ void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {
Out << 'E';
}
-void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
+void CXXNameMangler::mangleBareFunctionType(const FunctionProtoType *Proto,
bool MangleReturnType,
const FunctionDecl *FD) {
- // We should never be mangling something without a prototype.
- const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
-
// Record that we're in a function type. See mangleFunctionParam
// for details on what we're trying to achieve here.
FunctionTypeDepthState saved = FunctionTypeDepth.push();
@@ -2186,7 +2547,20 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
// <bare-function-type> ::= <signature type>+
if (MangleReturnType) {
FunctionTypeDepth.enterResultType();
- mangleType(Proto->getReturnType());
+
+ // Mangle ns_returns_retained as an order-sensitive qualifier here.
+ if (Proto->getExtInfo().getProducesResult() && FD == nullptr)
+ mangleVendorQualifier("ns_returns_retained");
+
+ // Mangle the return type without any direct ARC ownership qualifiers.
+ QualType ReturnTy = Proto->getReturnType();
+ if (ReturnTy.getObjCLifetime()) {
+ auto SplitReturnTy = ReturnTy.split();
+ SplitReturnTy.Quals.removeObjCLifetime();
+ ReturnTy = getASTContext().getQualifiedType(SplitReturnTy);
+ }
+ mangleType(ReturnTy);
+
FunctionTypeDepth.leaveResultType();
}
@@ -2200,7 +2574,13 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
assert(!FD || FD->getNumParams() == Proto->getNumParams());
for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) {
- const auto &ParamTy = Proto->getParamType(I);
+ // Mangle extended parameter info as order-sensitive qualifiers here.
+ if (Proto->hasExtParameterInfos() && FD == nullptr) {
+ mangleExtParameterInfo(Proto->getExtParameterInfo(I));
+ }
+
+ // Mangle the type.
+ QualType ParamTy = Proto->getParamType(I);
mangleType(Context.getASTContext().getSignatureParameterType(ParamTy));
if (FD) {
@@ -2546,7 +2926,7 @@ void CXXNameMangler::mangleType(const InjectedClassNameType *T) {
void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
if (TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl()) {
- mangleName(TD, T->getArgs(), T->getNumArgs());
+ mangleTemplateName(TD, T->getArgs(), T->getNumArgs());
} else {
if (mangleSubstitution(QualType(T, 0)))
return;
@@ -2662,7 +3042,7 @@ void CXXNameMangler::mangleType(const UnaryTransformType *T) {
}
}
- mangleType(T->getUnderlyingType());
+ mangleType(T->getBaseType());
}
void CXXNameMangler::mangleType(const AutoType *T) {
@@ -2836,6 +3216,7 @@ recurse:
case Expr::MSPropertySubscriptExprClass:
case Expr::TypoExprClass: // This should no longer exist in the AST by now.
case Expr::OMPArraySectionExprClass:
+ case Expr::CXXInheritedCtorInitExprClass:
llvm_unreachable("unexpected statement kind");
// FIXME: invent manglings for all these.
@@ -2858,6 +3239,7 @@ recurse:
case Expr::ObjCDictionaryLiteralClass:
case Expr::ObjCSubscriptRefExprClass:
case Expr::ObjCIndirectCopyRestoreExprClass:
+ case Expr::ObjCAvailabilityCheckExprClass:
case Expr::OffsetOfExprClass:
case Expr::PredefinedExprClass:
case Expr::ShuffleVectorExprClass:
@@ -2872,12 +3254,14 @@ recurse:
case Expr::PseudoObjectExprClass:
case Expr::AtomicExprClass:
{
- // As bad as this diagnostic is, it's better than crashing.
- DiagnosticsEngine &Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot yet mangle expression type %0");
- Diags.Report(E->getExprLoc(), DiagID)
- << E->getStmtClassName() << E->getSourceRange();
+ if (!NullOut) {
+ // As bad as this diagnostic is, it's better than crashing.
+ DiagnosticsEngine &Diags = Context.getDiags();
+ unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "cannot yet mangle expression type %0");
+ Diags.Report(E->getExprLoc(), DiagID)
+ << E->getStmtClassName() << E->getSourceRange();
+ }
break;
}
@@ -3615,25 +3999,33 @@ void CXXNameMangler::mangleFunctionParam(const ParmVarDecl *parm) {
Out << '_';
}
-void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) {
+void CXXNameMangler::mangleCXXCtorType(CXXCtorType T,
+ const CXXRecordDecl *InheritedFrom) {
// <ctor-dtor-name> ::= C1 # complete object constructor
// ::= C2 # base object constructor
+ // ::= CI1 <type> # complete inheriting constructor
+ // ::= CI2 <type> # base inheriting constructor
//
// In addition, C5 is a comdat name with C1 and C2 in it.
+ Out << 'C';
+ if (InheritedFrom)
+ Out << 'I';
switch (T) {
case Ctor_Complete:
- Out << "C1";
+ Out << '1';
break;
case Ctor_Base:
- Out << "C2";
+ Out << '2';
break;
case Ctor_Comdat:
- Out << "C5";
+ Out << '5';
break;
case Ctor_DefaultClosure:
case Ctor_CopyingClosure:
llvm_unreachable("closure constructors don't exist for the Itanium ABI!");
}
+ if (InheritedFrom)
+ mangleName(InheritedFrom);
}
void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
@@ -3745,7 +4137,7 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A) {
Out << 'L';
// References to external entities use the mangled name; if the name would
- // not normally be manged then mangle it as unqualified.
+ // not normally be mangled then mangle it as unqualified.
mangle(D);
Out << 'E';
@@ -3801,12 +4193,6 @@ void CXXNameMangler::mangleSeqID(unsigned SeqID) {
Out << '_';
}
-void CXXNameMangler::mangleExistingSubstitution(QualType type) {
- bool result = mangleSubstitution(type);
- assert(result && "no existing substitution for type");
- (void) result;
-}
-
void CXXNameMangler::mangleExistingSubstitution(TemplateName tname) {
bool result = mangleSubstitution(tname);
assert(result && "no existing substitution for template name");
@@ -4020,6 +4406,48 @@ void CXXNameMangler::addSubstitution(uintptr_t Ptr) {
Substitutions[Ptr] = SeqID++;
}
+CXXNameMangler::AbiTagList
+CXXNameMangler::makeFunctionReturnTypeTags(const FunctionDecl *FD) {
+ // When derived abi tags are disabled there is no need to make any list.
+ if (DisableDerivedAbiTags)
+ return AbiTagList();
+
+ llvm::raw_null_ostream NullOutStream;
+ CXXNameMangler TrackReturnTypeTags(*this, NullOutStream);
+ TrackReturnTypeTags.disableDerivedAbiTags();
+
+ const FunctionProtoType *Proto =
+ cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>());
+ TrackReturnTypeTags.FunctionTypeDepth.enterResultType();
+ TrackReturnTypeTags.mangleType(Proto->getReturnType());
+ TrackReturnTypeTags.FunctionTypeDepth.leaveResultType();
+
+ return TrackReturnTypeTags.AbiTagsRoot.getSortedUniqueUsedAbiTags();
+}
+
+CXXNameMangler::AbiTagList
+CXXNameMangler::makeVariableTypeTags(const VarDecl *VD) {
+ // When derived abi tags are disabled there is no need to make any list.
+ if (DisableDerivedAbiTags)
+ return AbiTagList();
+
+ llvm::raw_null_ostream NullOutStream;
+ CXXNameMangler TrackVariableType(*this, NullOutStream);
+ TrackVariableType.disableDerivedAbiTags();
+
+ TrackVariableType.mangleType(VD->getType());
+
+ return TrackVariableType.AbiTagsRoot.getSortedUniqueUsedAbiTags();
+}
+
+bool CXXNameMangler::shouldHaveAbiTags(ItaniumMangleContextImpl &C,
+ const VarDecl *VD) {
+ llvm::raw_null_ostream NullOutStream;
+ CXXNameMangler TrackAbiTags(C, NullOutStream, nullptr, true);
+ TrackAbiTags.mangle(VD);
+ return TrackAbiTags.AbiTagsRoot.getUsedAbiTags().size();
+}
+
//
/// Mangles the name of the declaration D and emits that name to the given
@@ -4121,6 +4549,8 @@ void ItaniumMangleContextImpl::mangleStaticGuardVariable(const VarDecl *D,
// <special-name> ::= GV <object name> # Guard variable for one-time
// # initialization
CXXNameMangler Mangler(*this, Out);
+ // GCC 5.3.0 doesn't emit derived ABI tags for local names but that seems to
+ // be a bug that is fixed in trunk.
Mangler.getStream() << "_ZGV";
Mangler.mangleName(D);
}