aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/MicrosoftMangle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/MicrosoftMangle.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/AST/MicrosoftMangle.cpp579
1 files changed, 383 insertions, 196 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/MicrosoftMangle.cpp b/contrib/llvm-project/clang/lib/AST/MicrosoftMangle.cpp
index d89cddd2adda..36b5bf64f675 100644
--- a/contrib/llvm-project/clang/lib/AST/MicrosoftMangle.cpp
+++ b/contrib/llvm-project/clang/lib/AST/MicrosoftMangle.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/GlobalDecl.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/VTableBuilder.h"
#include "clang/Basic/ABI.h"
@@ -28,17 +29,32 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CRC.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/xxhash.h"
+#include <functional>
+#include <optional>
using namespace clang;
namespace {
+// Get GlobalDecl of DeclContext of local entities.
+static GlobalDecl getGlobalDeclAsDeclContext(const DeclContext *DC) {
+ GlobalDecl GD;
+ if (auto *CD = dyn_cast<CXXConstructorDecl>(DC))
+ GD = GlobalDecl(CD, Ctor_Complete);
+ else if (auto *DD = dyn_cast<CXXDestructorDecl>(DC))
+ GD = GlobalDecl(DD, Dtor_Complete);
+ else
+ GD = GlobalDecl(cast<FunctionDecl>(DC));
+ return GD;
+}
+
struct msvc_hashing_ostream : public llvm::raw_svector_ostream {
raw_ostream &OS;
llvm::SmallString<64> Buffer;
@@ -47,7 +63,7 @@ struct msvc_hashing_ostream : public llvm::raw_svector_ostream {
: llvm::raw_svector_ostream(Buffer), OS(OS) {}
~msvc_hashing_ostream() override {
StringRef MangledName = str();
- bool StartsWithEscape = MangledName.startswith("\01");
+ bool StartsWithEscape = MangledName.starts_with("\01");
if (StartsWithEscape)
MangledName = MangledName.drop_front(1);
if (MangledName.size() < 4096) {
@@ -129,12 +145,13 @@ class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
- llvm::DenseMap<const NamedDecl *, unsigned> SEHFilterIds;
- llvm::DenseMap<const NamedDecl *, unsigned> SEHFinallyIds;
+ llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
+ llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
SmallString<16> AnonymousNamespaceHash;
public:
- MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags);
+ MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags,
+ bool IsAux = false);
bool shouldMangleCXXName(const NamedDecl *D) override;
bool shouldMangleStringLiteral(const StringLiteral *SL) override;
void mangleCXXName(GlobalDecl GD, raw_ostream &Out) override;
@@ -165,7 +182,8 @@ public:
int32_t VBPtrOffset, uint32_t VBIndex,
raw_ostream &Out) override;
void mangleCXXRTTI(QualType T, raw_ostream &Out) override;
- void mangleCXXRTTIName(QualType T, raw_ostream &Out) override;
+ void mangleCXXRTTIName(QualType T, raw_ostream &Out,
+ bool NormalizeIntegers) override;
void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived,
uint32_t NVOffset, int32_t VBPtrOffset,
uint32_t VBTableOffset, uint32_t Flags,
@@ -178,7 +196,8 @@ public:
mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) override;
- void mangleTypeName(QualType T, raw_ostream &) override;
+ void mangleCanonicalTypeName(QualType T, raw_ostream &,
+ bool NormalizeIntegers) override;
void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber,
raw_ostream &) override;
void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override;
@@ -187,9 +206,9 @@ public:
void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
void mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &Out) override;
- void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
+ void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
raw_ostream &Out) override;
- void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
+ void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
raw_ostream &Out) override;
void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override;
bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
@@ -208,7 +227,7 @@ public:
// Use the canonical number for externally visible decls.
if (ND->isExternallyVisible()) {
- disc = getASTContext().getManglingNumber(ND);
+ disc = getASTContext().getManglingNumber(ND, isAux());
return true;
}
@@ -271,12 +290,8 @@ public:
assert(!RD->isExternallyVisible() && "RD must not be visible!");
assert(RD->getLambdaManglingNumber() == 0 &&
"RD must not have a mangling number!");
- llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator Result =
- LambdaIds.find(RD);
// The lambda should exist, but return 0 in case it doesn't.
- if (Result == LambdaIds.end())
- return 0;
- return Result->second;
+ return LambdaIds.lookup(RD);
}
/// Return a character sequence that is (somewhat) unique to the TU suitable
@@ -310,8 +325,8 @@ class MicrosoftCXXNameMangler {
typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
TemplateArgStringMap TemplateArgStrings;
- llvm::StringSaver TemplateArgStringStorage;
llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
+ llvm::StringSaver TemplateArgStringStorage;
typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
PassObjectSizeArgsSet PassObjectSizeArgs;
@@ -322,38 +337,43 @@ class MicrosoftCXXNameMangler {
public:
enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
+ enum class TplArgKind { ClassNTTP, StructuralValue };
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
: Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
TemplateArgStringStorage(TemplateArgStringStorageAlloc),
- PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
- 64) {}
+ PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
+ LangAS::Default) == 64) {}
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
const CXXConstructorDecl *D, CXXCtorType Type)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
TemplateArgStringStorage(TemplateArgStringStorageAlloc),
- PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
- 64) {}
+ PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
+ LangAS::Default) == 64) {}
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
const CXXDestructorDecl *D, CXXDtorType Type)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
TemplateArgStringStorage(TemplateArgStringStorageAlloc),
- PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
- 64) {}
+ PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
+ LangAS::Default) == 64) {}
raw_ostream &getStream() const { return Out; }
- void mangle(const NamedDecl *D, StringRef Prefix = "?");
- void mangleName(const NamedDecl *ND);
- void mangleFunctionEncoding(const FunctionDecl *FD, bool ShouldMangle);
+ void mangle(GlobalDecl GD, StringRef Prefix = "?");
+ void mangleName(GlobalDecl GD);
+ void mangleFunctionEncoding(GlobalDecl GD, bool ShouldMangle);
void mangleVariableEncoding(const VarDecl *VD);
void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD,
StringRef Prefix = "$");
+ void mangleMemberDataPointerInClassNTTP(const CXXRecordDecl *,
+ const ValueDecl *);
void mangleMemberFunctionPointer(const CXXRecordDecl *RD,
const CXXMethodDecl *MD,
StringRef Prefix = "$");
+ void mangleMemberFunctionPointerInClassNTTP(const CXXRecordDecl *RD,
+ const CXXMethodDecl *MD);
void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
const MethodVFTableLocation &ML);
void mangleNumber(int64_t Number);
@@ -362,7 +382,7 @@ public:
void mangleBits(llvm::APInt Number);
void mangleTagTypeKind(TagTypeKind TK);
void mangleArtificialTagType(TagTypeKind TK, StringRef UnqualifiedName,
- ArrayRef<StringRef> NestedNames = None);
+ ArrayRef<StringRef> NestedNames = std::nullopt);
void mangleAddressSpaceType(QualType T, Qualifiers Quals, SourceRange Range);
void mangleType(QualType T, SourceRange Range,
QualifierMangleMode QMM = QMM_Mangle);
@@ -370,7 +390,7 @@ public:
const FunctionDecl *D = nullptr,
bool ForceThisQuals = false,
bool MangleExceptionSpec = true);
- void mangleNestedName(const NamedDecl *ND);
+ void mangleNestedName(GlobalDecl GD);
private:
bool isStructorDecl(const NamedDecl *ND) const {
@@ -384,10 +404,10 @@ private:
AddrSpace == LangAS::ptr32_uptr));
}
- void mangleUnqualifiedName(const NamedDecl *ND) {
- mangleUnqualifiedName(ND, ND->getDeclName());
+ void mangleUnqualifiedName(GlobalDecl GD) {
+ mangleUnqualifiedName(GD, cast<NamedDecl>(GD.getDecl())->getDeclName());
}
- void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name);
+ void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name);
void mangleSourceName(StringRef Name);
void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc);
void mangleCXXDtorType(CXXDtorType T);
@@ -396,9 +416,9 @@ private:
void manglePointerCVQualifiers(Qualifiers Quals);
void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType);
- void mangleUnscopedTemplateName(const TemplateDecl *ND);
+ void mangleUnscopedTemplateName(GlobalDecl GD);
void
- mangleTemplateInstantiationName(const TemplateDecl *TD,
+ mangleTemplateInstantiationName(GlobalDecl GD,
const TemplateArgumentList &TemplateArgs);
void mangleObjCMethodName(const ObjCMethodDecl *MD);
@@ -434,7 +454,7 @@ private:
const TemplateArgumentList &TemplateArgs);
void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA,
const NamedDecl *Parm);
- void mangleTemplateArgValue(QualType T, const APValue &V,
+ void mangleTemplateArgValue(QualType T, const APValue &V, TplArgKind,
bool WithScalarType = false);
void mangleObjCProtocol(const ObjCProtocolDecl *PD);
@@ -446,8 +466,9 @@ private:
}
MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(ASTContext &Context,
- DiagnosticsEngine &Diags)
- : MicrosoftMangleContext(Context, Diags) {
+ DiagnosticsEngine &Diags,
+ bool IsAux)
+ : MicrosoftMangleContext(Context, Diags, IsAux) {
// To mangle anonymous namespaces, hash the path to the main source file. The
// path should be whatever (probably relative) path was passed on the command
// line. The goal is for the compiler to produce the same output regardless of
@@ -463,9 +484,9 @@ MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(ASTContext &Context,
// The generated names are intended to look similar to what MSVC generates,
// which are something like "?A0x01234567@".
SourceManager &SM = Context.getSourceManager();
- if (const FileEntry *FE = SM.getFileEntryForID(SM.getMainFileID())) {
+ if (OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getMainFileID())) {
// Truncate the hash so we get 8 characters of hexadecimal.
- uint32_t TruncatedHash = uint32_t(xxHash64(FE->getName()));
+ uint32_t TruncatedHash = uint32_t(xxh3_64bits(FE->getName()));
AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
} else {
// If we don't have a path to the main file, we'll just use 0.
@@ -519,9 +540,8 @@ bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
while (!DC->isNamespace() && !DC->isTranslationUnit())
DC = getEffectiveParentContext(DC);
- if (DC->isTranslationUnit() && D->getFormalLinkage() == InternalLinkage &&
- !isa<VarTemplateSpecializationDecl>(D) &&
- D->getIdentifier() != nullptr)
+ if (DC->isTranslationUnit() && D->getFormalLinkage() == Linkage::Internal &&
+ !isa<VarTemplateSpecializationDecl>(D) && D->getIdentifier() != nullptr)
return false;
}
@@ -533,7 +553,8 @@ MicrosoftMangleContextImpl::shouldMangleStringLiteral(const StringLiteral *SL) {
return true;
}
-void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) {
+void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) {
+ const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
// MSVC doesn't mangle C++ names the same way it mangles extern "C" names.
// Therefore it's really important that we don't decorate the
// name with leading underscores or leading/trailing at signs. So, by
@@ -542,9 +563,9 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) {
// <mangled-name> ::= ? <name> <type-encoding>
Out << Prefix;
- mangleName(D);
+ mangleName(GD);
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- mangleFunctionEncoding(FD, Context.shouldMangleDeclName(FD));
+ mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
mangleVariableEncoding(VD);
else if (isa<MSGuidDecl>(D))
@@ -558,8 +579,9 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) {
llvm_unreachable("Tried to mangle unexpected NamedDecl!");
}
-void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD,
+void MicrosoftCXXNameMangler::mangleFunctionEncoding(GlobalDecl GD,
bool ShouldMangle) {
+ const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
// <type-encoding> ::= <function-class> <function-type>
// Since MSVC operates on the type as written and not the canonical type, it
@@ -691,6 +713,28 @@ void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD,
mangleNumber(VBTableOffset);
}
+void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
+ const CXXRecordDecl *RD, const ValueDecl *VD) {
+ MSInheritanceModel IM = RD->getMSInheritanceModel();
+ // <nttp-class-member-data-pointer> ::= <member-data-pointer>
+ // ::= N
+ // ::= 8 <postfix> @ <unqualified-name> @
+
+ if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
+ return mangleMemberDataPointer(RD, VD, "");
+
+ if (!VD) {
+ Out << 'N';
+ return;
+ }
+
+ Out << '8';
+ mangleNestedName(VD);
+ Out << '@';
+ mangleUnqualifiedName(VD);
+ Out << '@';
+}
+
void
MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
const CXXMethodDecl *MD,
@@ -755,11 +799,39 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
mangleNumber(VBTableOffset);
}
+void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
+ const CXXRecordDecl *RD, const CXXMethodDecl *MD) {
+ // <nttp-class-member-function-pointer> ::= <member-function-pointer>
+ // ::= N
+ // ::= E? <virtual-mem-ptr-thunk>
+ // ::= E? <mangled-name> <type-encoding>
+
+ if (!MD) {
+ if (RD->getMSInheritanceModel() != MSInheritanceModel::Single)
+ return mangleMemberFunctionPointer(RD, MD, "");
+
+ Out << 'N';
+ return;
+ }
+
+ Out << "E?";
+ if (MD->isVirtual()) {
+ MicrosoftVTableContext *VTContext =
+ cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
+ MethodVFTableLocation ML =
+ VTContext->getMethodVFTableLocation(GlobalDecl(MD));
+ mangleVirtualMemPtrThunk(MD, ML);
+ } else {
+ mangleName(MD);
+ mangleFunctionEncoding(MD, /*ShouldMangle=*/true);
+ }
+}
+
void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD, const MethodVFTableLocation &ML) {
// Get the vftable offset.
CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
- getASTContext().getTargetInfo().getPointerWidth(0));
+ getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
uint64_t OffsetInVFTable = ML.Index * PointerWidth.getQuantity();
Out << "?_9";
@@ -770,13 +842,13 @@ void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
mangleCallingConvention(MD->getType()->castAs<FunctionProtoType>());
}
-void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {
+void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {
// <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
// Always start with the unqualified name.
- mangleUnqualifiedName(ND);
+ mangleUnqualifiedName(GD);
- mangleNestedName(ND);
+ mangleNestedName(GD);
// Terminate the whole name with an '@'.
Out << '@';
@@ -791,8 +863,8 @@ void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
// to convert every integer to signed 64 bit before mangling (including
// unsigned 64 bit values). Do the same, but preserve bits beyond the bottom
// 64.
- llvm::APInt Value =
- Number.isSigned() ? Number.sextOrSelf(64) : Number.zextOrSelf(64);
+ unsigned Width = std::max(Number.getBitWidth(), 64U);
+ llvm::APInt Value = Number.extend(Width);
// <non-negative integer> ::= A@ # when Number == 0
// ::= <decimal digit> # when 1 <= Number <= 10
@@ -821,6 +893,13 @@ void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
case APFloat::S_x87DoubleExtended: Out << 'X'; break;
case APFloat::S_IEEEquad: Out << 'Y'; break;
case APFloat::S_PPCDoubleDouble: Out << 'Z'; break;
+ case APFloat::S_Float8E5M2:
+ case APFloat::S_Float8E4M3FN:
+ case APFloat::S_Float8E5M2FNUZ:
+ case APFloat::S_Float8E4M3FNUZ:
+ case APFloat::S_Float8E4M3B11FNUZ:
+ case APFloat::S_FloatTF32:
+ llvm_unreachable("Tried to mangle unexpected APFloat semantics");
}
mangleBits(Number.bitcastToAPInt());
@@ -844,13 +923,14 @@ void MicrosoftCXXNameMangler::mangleBits(llvm::APInt Value) {
}
}
-static const TemplateDecl *
-isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
+static GlobalDecl isTemplate(GlobalDecl GD,
+ const TemplateArgumentList *&TemplateArgs) {
+ const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
// Check if we have a function template.
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {
TemplateArgs = FD->getTemplateSpecializationArgs();
- return TD;
+ return GD.getWithDecl(TD);
}
}
@@ -858,21 +938,22 @@ isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
if (const ClassTemplateSpecializationDecl *Spec =
dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
TemplateArgs = &Spec->getTemplateArgs();
- return Spec->getSpecializedTemplate();
+ return GD.getWithDecl(Spec->getSpecializedTemplate());
}
// Check if we have a variable template.
if (const VarTemplateSpecializationDecl *Spec =
dyn_cast<VarTemplateSpecializationDecl>(ND)) {
TemplateArgs = &Spec->getTemplateArgs();
- return Spec->getSpecializedTemplate();
+ return GD.getWithDecl(Spec->getSpecializedTemplate());
}
- return nullptr;
+ return GlobalDecl();
}
-void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
+void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
DeclarationName Name) {
+ const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
// <unqualified-name> ::= <operator-name>
// ::= <ctor-dtor-name>
// ::= <source-name>
@@ -880,11 +961,11 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// Check if we have a template.
const TemplateArgumentList *TemplateArgs = nullptr;
- if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
+ if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) {
// Function templates aren't considered for name back referencing. This
// makes sense since function templates aren't likely to occur multiple
// times in a symbol.
- if (isa<FunctionTemplateDecl>(TD)) {
+ if (isa<FunctionTemplateDecl>(TD.getDecl())) {
mangleTemplateInstantiationName(TD, *TemplateArgs);
Out << '@';
return;
@@ -945,7 +1026,19 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
switch (Name.getNameKind()) {
case DeclarationName::Identifier: {
if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
- mangleSourceName(II->getName());
+ bool IsDeviceStub =
+ ND &&
+ ((isa<FunctionDecl>(ND) && ND->hasAttr<CUDAGlobalAttr>()) ||
+ (isa<FunctionTemplateDecl>(ND) &&
+ cast<FunctionTemplateDecl>(ND)
+ ->getTemplatedDecl()
+ ->hasAttr<CUDAGlobalAttr>())) &&
+ GD.getKernelReferenceKind() == KernelReferenceKind::Stub;
+ if (IsDeviceStub)
+ mangleSourceName(
+ (llvm::Twine("__device_stub__") + II->getName()).str());
+ else
+ mangleSourceName(II->getName());
break;
}
@@ -996,7 +1089,7 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
if (const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
Out << "?__N";
mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
- TPO->getValue());
+ TPO->getValue(), TplArgKind::ClassNTTP);
break;
}
@@ -1146,7 +1239,13 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// <postfix> ::= <unqualified-name> [<postfix>]
// ::= <substitution> [<postfix>]
-void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) {
+void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {
+ const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
+
+ if (const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
+ for (unsigned I = 1, IE = ID->getChainingSize(); I < IE; ++I)
+ mangleSourceName("<unnamed-tag>");
+
const DeclContext *DC = getEffectiveDeclContext(ND);
while (!DC->isTranslationUnit()) {
if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
@@ -1214,9 +1313,9 @@ void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) {
if (PointersAre64Bit)
Out << 'E';
Out << 'A';
- mangleArtificialTagType(TTK_Struct,
- Discriminate("__block_literal", Discriminator,
- ParameterDiscriminator));
+ mangleArtificialTagType(TagTypeKind::Struct,
+ Discriminate("__block_literal", Discriminator,
+ ParameterDiscriminator));
Out << "@Z";
// If the effective context was a Record, we have fully mangled the
@@ -1229,7 +1328,7 @@ void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) {
} else if (isa<NamedDecl>(DC)) {
ND = cast<NamedDecl>(DC);
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
- mangle(FD, "?");
+ mangle(getGlobalDeclAsDeclContext(FD), "?");
break;
} else {
mangleUnqualifiedName(ND);
@@ -1418,7 +1517,7 @@ void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
}
void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
- const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
+ GlobalDecl GD, const TemplateArgumentList &TemplateArgs) {
// <template-name> ::= <unscoped-template-name> <template-args>
// ::= <substitution>
// Always start with the unqualified name.
@@ -1433,8 +1532,8 @@ void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
TemplateArgBackReferences.swap(OuterTemplateArgsContext);
PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
- mangleUnscopedTemplateName(TD);
- mangleTemplateArgs(TD, TemplateArgs);
+ mangleUnscopedTemplateName(GD);
+ mangleTemplateArgs(cast<TemplateDecl>(GD.getDecl()), TemplateArgs);
// Restore the previous back reference contexts.
NameBackReferences.swap(OuterTemplateContext);
@@ -1443,11 +1542,10 @@ void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
}
-void
-MicrosoftCXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *TD) {
+void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {
// <unscoped-template-name> ::= ?$ <unqualified-name>
Out << "?$";
- mangleUnqualifiedName(TD);
+ mangleUnqualifiedName(GD);
}
void MicrosoftCXXNameMangler::mangleIntegerLiteral(
@@ -1474,7 +1572,7 @@ void MicrosoftCXXNameMangler::mangleIntegerLiteral(
void MicrosoftCXXNameMangler::mangleExpression(
const Expr *E, const NonTypeTemplateParmDecl *PD) {
// See if this is a constant expression.
- if (Optional<llvm::APSInt> Value =
+ if (std::optional<llvm::APSInt> Value =
E->getIntegerConstantExpr(Context.getASTContext())) {
mangleIntegerLiteral(*Value, PD, E->getType());
return;
@@ -1507,6 +1605,22 @@ void MicrosoftCXXNameMangler::mangleTemplateArgs(
}
}
+/// If value V (with type T) represents a decayed pointer to the first element
+/// of an array, return that array.
+static ValueDecl *getAsArrayToPointerDecayedDecl(QualType T, const APValue &V) {
+ // Must be a pointer...
+ if (!T->isPointerType() || !V.isLValue() || !V.hasLValuePath() ||
+ !V.getLValueBase())
+ return nullptr;
+ // ... to element 0 of an array.
+ QualType BaseT = V.getLValueBase().getType();
+ if (!BaseT->isArrayType() || V.getLValuePath().size() != 1 ||
+ V.getLValuePath()[0].getAsArrayIndex() != 0)
+ return nullptr;
+ return const_cast<ValueDecl *>(
+ V.getLValueBase().dyn_cast<const ValueDecl *>());
+}
+
void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
const TemplateArgument &TA,
const NamedDecl *Parm) {
@@ -1530,7 +1644,6 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
// ::= 8 <class> <unqualified-name> @
// ::= A <type> <non-negative integer> # float
// ::= B <type> <non-negative integer> # double
- // ::= E <mangled-name> # reference to D
// # pointer to member, by component value
// ::= F <number> <number>
// ::= G <number> <number> <number>
@@ -1573,9 +1686,9 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
Out << "$";
auto *TPO = cast<TemplateParamObjectDecl>(ND);
mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
- TPO->getValue());
+ TPO->getValue(), TplArgKind::ClassNTTP);
} else {
- mangle(ND, TA.getParamTypeForDecl()->isReferenceType() ? "$E?" : "$1?");
+ mangle(ND, "$1?");
}
break;
}
@@ -1616,6 +1729,27 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
cast<NonTypeTemplateParmDecl>(Parm), T);
break;
}
+ case TemplateArgument::StructuralValue:
+ if (ValueDecl *D = getAsArrayToPointerDecayedDecl(
+ TA.getStructuralValueType(), TA.getAsStructuralValue())) {
+ // Mangle the result of array-to-pointer decay as if it were a reference
+ // to the original declaration, to match MSVC's behavior. This can result
+ // in mangling collisions in some cases!
+ return mangleTemplateArg(
+ TD, TemplateArgument(D, TA.getStructuralValueType()), Parm);
+ }
+ Out << "$";
+ if (cast<NonTypeTemplateParmDecl>(Parm)
+ ->getType()
+ ->getContainedDeducedType()) {
+ Out << "M";
+ mangleType(TA.getNonTypeTemplateArgumentType(), SourceRange(), QMM_Drop);
+ }
+ mangleTemplateArgValue(TA.getStructuralValueType(),
+ TA.getAsStructuralValue(),
+ TplArgKind::StructuralValue,
+ /*WithScalarType=*/false);
+ break;
case TemplateArgument::Expression:
mangleExpression(TA.getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
break;
@@ -1658,6 +1792,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
const APValue &V,
+ TplArgKind TAK,
bool WithScalarType) {
switch (V.getKind()) {
case APValue::None:
@@ -1704,46 +1839,62 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
// FIXME: This can only happen as an extension. Invent a mangling.
break;
} else if (auto *VD = Base.dyn_cast<const ValueDecl*>()) {
- Out << (T->isReferenceType() ? "E" : "1");
+ Out << "E";
mangle(VD);
} else {
break;
}
} else {
- unsigned NumAts = 0;
- if (T->isPointerType()) {
+ if (TAK == TplArgKind::ClassNTTP && T->isPointerType())
Out << "5";
- ++NumAts;
- }
- QualType T = Base.getType();
+ SmallVector<char, 2> EntryTypes;
+ SmallVector<std::function<void()>, 2> EntryManglers;
+ QualType ET = Base.getType();
for (APValue::LValuePathEntry E : V.getLValuePath()) {
- // We don't know how to mangle array subscripting yet.
- if (T->isArrayType())
- goto mangling_unknown;
+ if (auto *AT = ET->getAsArrayTypeUnsafe()) {
+ EntryTypes.push_back('C');
+ EntryManglers.push_back([this, I = E.getAsArrayIndex()] {
+ Out << '0';
+ mangleNumber(I);
+ Out << '@';
+ });
+ ET = AT->getElementType();
+ continue;
+ }
const Decl *D = E.getAsBaseOrMember().getPointer();
- auto *FD = dyn_cast<FieldDecl>(D);
- // We don't know how to mangle derived-to-base conversions yet.
- if (!FD)
- goto mangling_unknown;
-
- Out << "6";
- ++NumAts;
- T = FD->getType();
+ if (auto *FD = dyn_cast<FieldDecl>(D)) {
+ ET = FD->getType();
+ if (const auto *RD = ET->getAsRecordDecl())
+ if (RD->isAnonymousStructOrUnion())
+ continue;
+ } else {
+ ET = getASTContext().getRecordType(cast<CXXRecordDecl>(D));
+ // Bug in MSVC: fully qualified name of base class should be used for
+ // mangling to prevent collisions e.g. on base classes with same names
+ // in different namespaces.
+ }
+
+ EntryTypes.push_back('6');
+ EntryManglers.push_back([this, D] {
+ mangleUnqualifiedName(cast<NamedDecl>(D));
+ Out << '@';
+ });
}
+ for (auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
+ Out << *I;
+
auto *VD = Base.dyn_cast<const ValueDecl*>();
if (!VD)
break;
- Out << "E";
+ Out << (TAK == TplArgKind::ClassNTTP ? 'E' : '1');
mangle(VD);
- for (APValue::LValuePathEntry E : V.getLValuePath()) {
- const Decl *D = E.getAsBaseOrMember().getPointer();
- mangleUnqualifiedName(cast<FieldDecl>(D));
- }
- for (unsigned I = 0; I != NumAts; ++I)
+ for (const std::function<void()> &Mangler : EntryManglers)
+ Mangler();
+ if (TAK == TplArgKind::ClassNTTP && T->isPointerType())
Out << '@';
}
@@ -1754,20 +1905,21 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
if (WithScalarType)
mangleType(T, SourceRange(), QMM_Escape);
- // FIXME: The below manglings don't include a conversion, so bail if there
- // would be one. MSVC mangles the (possibly converted) value of the
- // pointer-to-member object as if it were a struct, leading to collisions
- // in some cases.
- if (!V.getMemberPointerPath().empty())
- break;
-
const CXXRecordDecl *RD =
T->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
const ValueDecl *D = V.getMemberPointerDecl();
- if (T->isMemberDataPointerType())
- mangleMemberDataPointer(RD, D, "");
- else
- mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D), "");
+ if (TAK == TplArgKind::ClassNTTP) {
+ if (T->isMemberDataPointerType())
+ mangleMemberDataPointerInClassNTTP(RD, D);
+ else
+ mangleMemberFunctionPointerInClassNTTP(RD,
+ cast_or_null<CXXMethodDecl>(D));
+ } else {
+ if (T->isMemberDataPointerType())
+ mangleMemberDataPointer(RD, D, "");
+ else
+ mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D), "");
+ }
return;
}
@@ -1779,11 +1931,11 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
unsigned BaseIndex = 0;
for (const CXXBaseSpecifier &B : RD->bases())
- mangleTemplateArgValue(B.getType(), V.getStructBase(BaseIndex++));
+ mangleTemplateArgValue(B.getType(), V.getStructBase(BaseIndex++), TAK);
for (const FieldDecl *FD : RD->fields())
if (!FD->isUnnamedBitfield())
mangleTemplateArgValue(FD->getType(),
- V.getStructField(FD->getFieldIndex()),
+ V.getStructField(FD->getFieldIndex()), TAK,
/*WithScalarType*/ true);
Out << '@';
return;
@@ -1794,7 +1946,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
mangleType(T, SourceRange(), QMM_Escape);
if (const FieldDecl *FD = V.getUnionField()) {
mangleUnqualifiedName(FD);
- mangleTemplateArgValue(FD->getType(), V.getUnionValue());
+ mangleTemplateArgValue(FD->getType(), V.getUnionValue(), TAK);
}
Out << '@';
return;
@@ -1826,7 +1978,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
const APValue &ElemV = I < V.getArrayInitializedElts()
? V.getArrayInitializedElt(I)
: V.getArrayFiller();
- mangleTemplateArgValue(ElemT, ElemV);
+ mangleTemplateArgValue(ElemT, ElemV, TAK);
Out << '@';
}
Out << '@';
@@ -1843,7 +1995,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
mangleType(ElemT, SourceRange(), QMM_Escape);
for (unsigned I = 0, N = V.getVectorLength(); I != N; ++I) {
const APValue &ElemV = V.getVectorElt(I);
- mangleTemplateArgValue(ElemT, ElemV);
+ mangleTemplateArgValue(ElemT, ElemV, TAK);
Out << '@';
}
Out << "@@";
@@ -1855,7 +2007,6 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
break;
}
-mangling_unknown:
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(
DiagnosticsEngine::Error, "cannot mangle this template argument yet");
@@ -1869,9 +2020,9 @@ void MicrosoftCXXNameMangler::mangleObjCProtocol(const ObjCProtocolDecl *PD) {
Stream << "?$";
Extra.mangleSourceName("Protocol");
- Extra.mangleArtificialTagType(TTK_Struct, PD->getName());
+ Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->getName());
- mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__ObjC"});
+ mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
}
void MicrosoftCXXNameMangler::mangleObjCLifetime(const QualType Type,
@@ -1900,7 +2051,7 @@ void MicrosoftCXXNameMangler::mangleObjCLifetime(const QualType Type,
Extra.manglePointerExtQualifiers(Quals, Type);
Extra.mangleType(Type, Range);
- mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__ObjC"});
+ mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
}
void MicrosoftCXXNameMangler::mangleObjCKindOfType(const ObjCObjectType *T,
@@ -1914,10 +2065,10 @@ void MicrosoftCXXNameMangler::mangleObjCKindOfType(const ObjCObjectType *T,
Extra.mangleSourceName("KindOf");
Extra.mangleType(QualType(T, 0)
.stripObjCKindOfType(getASTContext())
- ->getAs<ObjCObjectType>(),
+ ->castAs<ObjCObjectType>(),
Quals, Range);
- mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__ObjC"});
+ mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
}
void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
@@ -2118,7 +2269,8 @@ void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
if (Found == FunArgBackReferences.end()) {
std::string Name =
Dynamic ? "__pass_dynamic_object_size" : "__pass_object_size";
- mangleArtificialTagType(TTK_Enum, Name + llvm::utostr(Type), {"__clang"});
+ mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(Type),
+ {"__clang"});
if (FunArgBackReferences.size() < 10) {
size_t Size = FunArgBackReferences.size();
@@ -2199,7 +2351,7 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
Extra.mangleType(T, Range, QMM_Escape);
mangleQualifiers(Qualifiers(), false);
- mangleArtificialTagType(TTK_Struct, ASMangling, {"__clang"});
+ mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {"__clang"});
}
void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
@@ -2381,13 +2533,13 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
llvm_unreachable("placeholder types shouldn't get to name mangling");
case BuiltinType::ObjCId:
- mangleArtificialTagType(TTK_Struct, "objc_object");
+ mangleArtificialTagType(TagTypeKind::Struct, "objc_object");
break;
case BuiltinType::ObjCClass:
- mangleArtificialTagType(TTK_Struct, "objc_class");
+ mangleArtificialTagType(TagTypeKind::Struct, "objc_class");
break;
case BuiltinType::ObjCSel:
- mangleArtificialTagType(TTK_Struct, "objc_selector");
+ mangleArtificialTagType(TagTypeKind::Struct, "objc_selector");
break;
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
@@ -2397,27 +2549,27 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
#include "clang/Basic/OpenCLImageTypes.def"
case BuiltinType::OCLSampler:
Out << "PA";
- mangleArtificialTagType(TTK_Struct, "ocl_sampler");
+ mangleArtificialTagType(TagTypeKind::Struct, "ocl_sampler");
break;
case BuiltinType::OCLEvent:
Out << "PA";
- mangleArtificialTagType(TTK_Struct, "ocl_event");
+ mangleArtificialTagType(TagTypeKind::Struct, "ocl_event");
break;
case BuiltinType::OCLClkEvent:
Out << "PA";
- mangleArtificialTagType(TTK_Struct, "ocl_clkevent");
+ mangleArtificialTagType(TagTypeKind::Struct, "ocl_clkevent");
break;
case BuiltinType::OCLQueue:
Out << "PA";
- mangleArtificialTagType(TTK_Struct, "ocl_queue");
+ mangleArtificialTagType(TagTypeKind::Struct, "ocl_queue");
break;
case BuiltinType::OCLReserveID:
Out << "PA";
- mangleArtificialTagType(TTK_Struct, "ocl_reserveid");
+ mangleArtificialTagType(TagTypeKind::Struct, "ocl_reserveid");
break;
-#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
- case BuiltinType::Id: \
- mangleArtificialTagType(TTK_Struct, "ocl_" #ExtType); \
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+ case BuiltinType::Id: \
+ mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
break;
#include "clang/Basic/OpenCLExtensionTypes.def"
@@ -2426,13 +2578,29 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
break;
case BuiltinType::Float16:
- mangleArtificialTagType(TTK_Struct, "_Float16", {"__clang"});
+ mangleArtificialTagType(TagTypeKind::Struct, "_Float16", {"__clang"});
break;
case BuiltinType::Half:
- mangleArtificialTagType(TTK_Struct, "_Half", {"__clang"});
+ if (!getASTContext().getLangOpts().HLSL)
+ mangleArtificialTagType(TagTypeKind::Struct, "_Half", {"__clang"});
+ else if (getASTContext().getLangOpts().NativeHalfType)
+ Out << "$f16@";
+ else
+ Out << "$halff@";
break;
+ case BuiltinType::BFloat16:
+ mangleArtificialTagType(TagTypeKind::Struct, "__bf16", {"__clang"});
+ break;
+
+#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
+ case BuiltinType::Id: \
+ mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
+ mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
+ break;
+
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
#define SVE_TYPE(Name, Id, SingletonId) \
case BuiltinType::Id:
#include "clang/Basic/AArch64SVEACLETypes.def"
@@ -2465,7 +2633,7 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
case BuiltinType::SatUShortFract:
case BuiltinType::SatUFract:
case BuiltinType::SatULongFract:
- case BuiltinType::BFloat16:
+ case BuiltinType::Ibm128:
case BuiltinType::Float128: {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(
@@ -2514,7 +2682,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
if (MD->getParent()->isLambda())
IsInLambda = true;
- if (MD->isInstance())
+ if (MD->isImplicitObjectMemberFunction())
HasThisQuals = true;
if (isa<CXXDestructorDecl>(MD)) {
IsStructor = true;
@@ -2568,7 +2736,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
// Copy constructor closure always takes an unqualified reference.
mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
Proto->getParamType(0)
- ->getAs<LValueReferenceType>()
+ ->castAs<LValueReferenceType>()
->getPointeeType(),
/*SpelledAsLValue=*/true),
Range);
@@ -2623,6 +2791,10 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
} else {
// Happens for function pointer type arguments for example.
for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) {
+ // Explicit object parameters are prefixed by "_V".
+ if (I == 0 && D && D->getParamDecl(I)->isExplicitObjectParameter())
+ Out << "_V";
+
mangleFunctionArgumentType(Proto->getParamType(I), Range);
// Mangle each pass_object_size parameter as if it's a parameter of enum
// type passed directly after the parameter with the pass_object_size
@@ -2688,7 +2860,7 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
case AS_none:
llvm_unreachable("Unsupported access specifier");
case AS_private:
- if (MD->isStatic())
+ if (!MD->isImplicitObjectMemberFunction())
Out << 'C';
else if (IsVirtual)
Out << 'E';
@@ -2696,7 +2868,7 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
Out << 'A';
break;
case AS_protected:
- if (MD->isStatic())
+ if (!MD->isImplicitObjectMemberFunction())
Out << 'K';
else if (IsVirtual)
Out << 'M';
@@ -2704,7 +2876,7 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
Out << 'I';
break;
case AS_public:
- if (MD->isStatic())
+ if (!MD->isImplicitObjectMemberFunction())
Out << 'S';
else if (IsVirtual)
Out << 'U';
@@ -2731,6 +2903,7 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
// ::= T # __attribute__((__swiftasynccall__))
// // Clang-only
// ::= w # __regcall
+ // ::= x # __regcall4
// The 'export' calling conventions are from a bygone era
// (*cough*Win16*cough*) when functions were declared for export with
// that keyword. (It didn't actually export them, it just made them so
@@ -2751,7 +2924,12 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
case CC_Swift: Out << 'S'; break;
case CC_SwiftAsync: Out << 'W'; break;
case CC_PreserveMost: Out << 'U'; break;
- case CC_X86RegCall: Out << 'w'; break;
+ case CC_X86RegCall:
+ if (getASTContext().getLangOpts().RegCall4)
+ Out << "x";
+ else
+ Out << "w";
+ break;
}
}
void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T) {
@@ -2786,19 +2964,19 @@ void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,
// <enum-type> ::= W4 <name>
void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) {
switch (TTK) {
- case TTK_Union:
- Out << 'T';
- break;
- case TTK_Struct:
- case TTK_Interface:
- Out << 'U';
- break;
- case TTK_Class:
- Out << 'V';
- break;
- case TTK_Enum:
- Out << "W4";
- break;
+ case TagTypeKind::Union:
+ Out << 'T';
+ break;
+ case TagTypeKind::Struct:
+ case TagTypeKind::Interface:
+ Out << 'U';
+ break;
+ case TagTypeKind::Class:
+ Out << 'V';
+ break;
+ case TagTypeKind::Enum:
+ Out << "W4";
+ break;
}
}
void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers,
@@ -2824,8 +3002,8 @@ void MicrosoftCXXNameMangler::mangleArtificialTagType(
// Always start with the unqualified name.
mangleSourceName(UnqualifiedName);
- for (auto I = NestedNames.rbegin(), E = NestedNames.rend(); I != E; ++I)
- mangleSourceName(*I);
+ for (StringRef N : llvm::reverse(NestedNames))
+ mangleSourceName(N);
// Terminate the whole name with an '@'.
Out << '@';
@@ -3008,11 +3186,11 @@ void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, Qualifiers,
Extra.mangleSourceName("_Complex");
Extra.mangleType(ElementType, Range, QMM_Escape);
- mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"});
+ mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
}
// Returns true for types that mangleArtificialTagType() gets called for with
-// TTK_Union, TTK_Struct, TTK_Class and where compatibility with MSVC's
+// TagTypeKind Union, Struct, Class and where compatibility with MSVC's
// mangling matters.
// (It doesn't matter for Objective-C types and the like that cl.exe doesn't
// support.)
@@ -3033,23 +3211,29 @@ bool MicrosoftCXXNameMangler::isArtificialTagType(QualType T) const {
void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,
SourceRange Range) {
- const BuiltinType *ET = T->getElementType()->getAs<BuiltinType>();
- assert(ET && "vectors with non-builtin elements are unsupported");
+ QualType EltTy = T->getElementType();
+ const BuiltinType *ET = EltTy->getAs<BuiltinType>();
+ const BitIntType *BitIntTy = EltTy->getAs<BitIntType>();
+ assert((ET || BitIntTy) &&
+ "vectors with non-builtin/_BitInt elements are unsupported");
uint64_t Width = getASTContext().getTypeSize(T);
// Pattern match exactly the typedefs in our intrinsic headers. Anything that
// doesn't match the Intel types uses a custom mangling below.
size_t OutSizeBefore = Out.tell();
if (!isa<ExtVectorType>(T)) {
- if (getASTContext().getTargetInfo().getTriple().isX86()) {
+ if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {
- mangleArtificialTagType(TTK_Union, "__m64");
+ mangleArtificialTagType(TagTypeKind::Union, "__m64");
} else if (Width >= 128) {
if (ET->getKind() == BuiltinType::Float)
- mangleArtificialTagType(TTK_Union, "__m" + llvm::utostr(Width));
+ mangleArtificialTagType(TagTypeKind::Union,
+ "__m" + llvm::utostr(Width));
else if (ET->getKind() == BuiltinType::LongLong)
- mangleArtificialTagType(TTK_Union, "__m" + llvm::utostr(Width) + 'i');
+ mangleArtificialTagType(TagTypeKind::Union,
+ "__m" + llvm::utostr(Width) + 'i');
else if (ET->getKind() == BuiltinType::Double)
- mangleArtificialTagType(TTK_Struct, "__m" + llvm::utostr(Width) + 'd');
+ mangleArtificialTagType(TagTypeKind::Struct,
+ "__m" + llvm::utostr(Width) + 'd');
}
}
}
@@ -3065,10 +3249,11 @@ void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,
MicrosoftCXXNameMangler Extra(Context, Stream);
Stream << "?$";
Extra.mangleSourceName("__vector");
- Extra.mangleType(QualType(ET, 0), Range, QMM_Escape);
+ Extra.mangleType(QualType(ET ? static_cast<const Type *>(ET) : BitIntTy, 0),
+ Range, QMM_Escape);
Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()));
- mangleArtificialTagType(TTK_Union, TemplateMangling, {"__clang"});
+ mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {"__clang"});
}
}
@@ -3124,7 +3309,7 @@ void MicrosoftCXXNameMangler::mangleType(const DependentAddressSpaceType *T,
void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,
SourceRange) {
// ObjC interfaces have structs underlying them.
- mangleTagTypeKind(TTK_Struct);
+ mangleTagTypeKind(TagTypeKind::Struct);
mangleName(T->getDecl());
}
@@ -3144,7 +3329,7 @@ void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,
TemplateArgBackReferences.swap(OuterTemplateArgsContext);
NameBackReferences.swap(OuterTemplateContext);
- mangleTagTypeKind(TTK_Struct);
+ mangleTagTypeKind(TagTypeKind::Struct);
Out << "?$";
if (T->isObjCId())
@@ -3292,7 +3477,7 @@ void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers,
Extra.mangleSourceName("_Atomic");
Extra.mangleType(ValueType, Range, QMM_Escape);
- mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"});
+ mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
}
void MicrosoftCXXNameMangler::mangleType(const PipeType *T, Qualifiers,
@@ -3307,7 +3492,7 @@ void MicrosoftCXXNameMangler::mangleType(const PipeType *T, Qualifiers,
Extra.mangleType(ElementType, Range, QMM_Escape);
Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()));
- mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"});
+ mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
}
void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
@@ -3322,39 +3507,39 @@ void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
if (auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
auto Type = GD.getCtorType();
MicrosoftCXXNameMangler mangler(*this, MHO, CD, Type);
- return mangler.mangle(D);
+ return mangler.mangle(GD);
}
if (auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
auto Type = GD.getDtorType();
MicrosoftCXXNameMangler mangler(*this, MHO, DD, Type);
- return mangler.mangle(D);
+ return mangler.mangle(GD);
}
MicrosoftCXXNameMangler Mangler(*this, MHO);
- return Mangler.mangle(D);
+ return Mangler.mangle(GD);
}
-void MicrosoftCXXNameMangler::mangleType(const ExtIntType *T, Qualifiers,
+void MicrosoftCXXNameMangler::mangleType(const BitIntType *T, Qualifiers,
SourceRange Range) {
llvm::SmallString<64> TemplateMangling;
llvm::raw_svector_ostream Stream(TemplateMangling);
MicrosoftCXXNameMangler Extra(Context, Stream);
Stream << "?$";
if (T->isUnsigned())
- Extra.mangleSourceName("_UExtInt");
+ Extra.mangleSourceName("_UBitInt");
else
- Extra.mangleSourceName("_ExtInt");
+ Extra.mangleSourceName("_BitInt");
Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()));
- mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"});
+ mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
}
-void MicrosoftCXXNameMangler::mangleType(const DependentExtIntType *T,
+void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,
Qualifiers, SourceRange Range) {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(
- DiagnosticsEngine::Error, "cannot mangle this DependentExtInt type yet");
+ DiagnosticsEngine::Error, "cannot mangle this DependentBitInt type yet");
Diags.Report(Range.getBegin(), DiagID) << Range;
}
@@ -3538,8 +3723,8 @@ void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
Mangler.getStream() << "@8";
}
-void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T,
- raw_ostream &Out) {
+void MicrosoftMangleContextImpl::mangleCXXRTTIName(
+ QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {
MicrosoftCXXNameMangler Mangler(*this, Out);
Mangler.getStream() << '.';
Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
@@ -3602,7 +3787,7 @@ void MicrosoftMangleContextImpl::mangleCXXCatchableType(
// FIXME: It is known that the Ctor is present in 2013, and in 2017.7
// (_MSC_VER 1914) and newer, and that it's omitted in 2015 and 2017.4
// (_MSC_VER 1911), but it's unknown when exactly it reappeared (1914?
- // Or 1912, 1913 aleady?).
+ // Or 1912, 1913 already?).
bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
LangOptions::MSVC2015) &&
!getASTContext().getLangOpts().isCompatibleWithMSVC(
@@ -3670,20 +3855,20 @@ void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
llvm::raw_svector_ostream Stream(VFTableMangling);
mangleCXXVFTable(Derived, BasePath, Stream);
- if (VFTableMangling.startswith("??@")) {
- assert(VFTableMangling.endswith("@"));
+ if (VFTableMangling.starts_with("??@")) {
+ assert(VFTableMangling.ends_with("@"));
Out << VFTableMangling << "??_R4@";
return;
}
- assert(VFTableMangling.startswith("??_7") ||
- VFTableMangling.startswith("??_S"));
+ assert(VFTableMangling.starts_with("??_7") ||
+ VFTableMangling.starts_with("??_S"));
Out << "??_R4" << VFTableMangling.str().drop_front(4);
}
void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
- const NamedDecl *EnclosingDecl, raw_ostream &Out) {
+ GlobalDecl EnclosingDecl, raw_ostream &Out) {
msvc_hashing_ostream MHO(Out);
MicrosoftCXXNameMangler Mangler(*this, MHO);
// The function body is in the same comdat as the function with the handler,
@@ -3695,7 +3880,7 @@ void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
}
void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
- const NamedDecl *EnclosingDecl, raw_ostream &Out) {
+ GlobalDecl EnclosingDecl, raw_ostream &Out) {
msvc_hashing_ostream MHO(Out);
MicrosoftCXXNameMangler Mangler(*this, MHO);
// The function body is in the same comdat as the function with the handler,
@@ -3706,12 +3891,13 @@ void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
Mangler.mangleName(EnclosingDecl);
}
-void MicrosoftMangleContextImpl::mangleTypeName(QualType T, raw_ostream &Out) {
+void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
+ QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {
// This is just a made up unique string for the purposes of tbaa. undname
// does *not* know how to demangle it.
MicrosoftCXXNameMangler Mangler(*this, Out);
Mangler.getStream() << '?';
- Mangler.mangleType(T, SourceRange());
+ Mangler.mangleType(T.getCanonicalType(), SourceRange());
}
void MicrosoftMangleContextImpl::mangleReferenceTemporary(
@@ -3883,7 +4069,7 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
// - ?[A-Z]: The range from \xc1 to \xda.
// - ?[0-9]: The set of [,/\:. \n\t'-].
// - ?$XX: A fallback which maps nibbles.
- if (isIdentifierBody(Byte, /*AllowDollar=*/true)) {
+ if (isAsciiIdentifierContinue(Byte, /*AllowDollar=*/true)) {
Mangler.getStream() << Byte;
} else if (isLetter(Byte & 0x7f)) {
Mangler.getStream() << '?' << static_cast<char>(Byte & 0x7f);
@@ -3914,7 +4100,8 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
Mangler.getStream() << '@';
}
-MicrosoftMangleContext *
-MicrosoftMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
- return new MicrosoftMangleContextImpl(Context, Diags);
+MicrosoftMangleContext *MicrosoftMangleContext::create(ASTContext &Context,
+ DiagnosticsEngine &Diags,
+ bool IsAux) {
+ return new MicrosoftMangleContextImpl(Context, Diags, IsAux);
}