31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/StringExtras.h"
33#include "llvm/Support/CRC.h"
34#include "llvm/Support/MD5.h"
35#include "llvm/Support/StringSaver.h"
36#include "llvm/Support/xxhash.h"
47 if (
auto *CD = dyn_cast<CXXConstructorDecl>(DC))
49 else if (
auto *DD = dyn_cast<CXXDestructorDecl>(DC))
56struct msvc_hashing_ostream :
public llvm::raw_svector_ostream {
58 llvm::SmallString<64> Buffer;
60 msvc_hashing_ostream(raw_ostream &OS)
61 : llvm::raw_svector_ostream(Buffer), OS(OS) {}
62 ~msvc_hashing_ostream()
override {
63 StringRef MangledName = str();
64 bool StartsWithEscape = MangledName.starts_with(
"\01");
66 MangledName = MangledName.drop_front(1);
67 if (MangledName.size() < 4096) {
73 llvm::MD5::MD5Result Hash;
74 Hasher.update(MangledName);
77 SmallString<32> HexString;
78 llvm::MD5::stringifyResult(Hash, HexString);
82 OS <<
"??@" << HexString <<
'@';
87getLambdaDefaultArgumentDeclContext(
const Decl *D) {
88 if (
const auto *RD = dyn_cast<CXXRecordDecl>(D))
90 if (
const auto *Parm =
91 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
92 return Parm->getDeclContext();
105 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))
109 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
111 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
112 return ContextParam->getDeclContext();
118 return getEffectiveDeclContext(
cast<Decl>(DC));
125 return getEffectiveDeclContext(
cast<Decl>(DC));
129 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
133 if (
const auto *FTD = FD->getPrimaryTemplate())
134 return FTD->getTemplatedDecl()->getCanonicalDecl();
136 return FD->getCanonicalDecl();
142 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
143 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
144 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
145 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
146 llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
147 llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
148 SmallString<16> AnonymousNamespaceHash;
151 MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags,
153 bool shouldMangleCXXName(
const NamedDecl *D)
override;
154 bool shouldMangleStringLiteral(
const StringLiteral *SL)
override;
155 void mangleCXXName(GlobalDecl GD, raw_ostream &Out)
override;
156 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
157 const MethodVFTableLocation &ML,
158 raw_ostream &Out)
override;
159 void mangleThunk(
const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
160 bool ElideOverrideInfo, raw_ostream &)
override;
162 const ThunkInfo &Thunk,
bool ElideOverrideInfo,
163 raw_ostream &)
override;
164 void mangleCXXVFTable(
const CXXRecordDecl *Derived,
165 ArrayRef<const CXXRecordDecl *> BasePath,
166 raw_ostream &Out)
override;
167 void mangleCXXVBTable(
const CXXRecordDecl *Derived,
168 ArrayRef<const CXXRecordDecl *> BasePath,
169 raw_ostream &Out)
override;
171 void mangleCXXVTable(
const CXXRecordDecl *, raw_ostream &)
override;
172 void mangleCXXVirtualDisplacementMap(
const CXXRecordDecl *SrcRD,
173 const CXXRecordDecl *DstRD,
174 raw_ostream &Out)
override;
175 void mangleCXXThrowInfo(QualType
T,
bool IsConst,
bool IsVolatile,
176 bool IsUnaligned, uint32_t NumEntries,
177 raw_ostream &Out)
override;
178 void mangleCXXCatchableTypeArray(QualType
T, uint32_t NumEntries,
179 raw_ostream &Out)
override;
180 void mangleCXXCatchableType(QualType
T,
const CXXConstructorDecl *CD,
182 int32_t VBPtrOffset, uint32_t VBIndex,
183 raw_ostream &Out)
override;
184 void mangleCXXRTTI(QualType
T, raw_ostream &Out)
override;
185 void mangleCXXRTTIName(QualType
T, raw_ostream &Out,
186 bool NormalizeIntegers)
override;
187 void mangleCXXRTTIBaseClassDescriptor(
const CXXRecordDecl *Derived,
188 uint32_t NVOffset, int32_t VBPtrOffset,
189 uint32_t VBTableOffset, uint32_t Flags,
190 raw_ostream &Out)
override;
191 void mangleCXXRTTIBaseClassArray(
const CXXRecordDecl *Derived,
192 raw_ostream &Out)
override;
193 void mangleCXXRTTIClassHierarchyDescriptor(
const CXXRecordDecl *Derived,
194 raw_ostream &Out)
override;
196 mangleCXXRTTICompleteObjectLocator(
const CXXRecordDecl *Derived,
197 ArrayRef<const CXXRecordDecl *> BasePath,
198 raw_ostream &Out)
override;
199 void mangleCanonicalTypeName(QualType
T, raw_ostream &,
200 bool NormalizeIntegers)
override;
201 void mangleReferenceTemporary(
const VarDecl *,
unsigned ManglingNumber,
202 raw_ostream &)
override;
203 void mangleStaticGuardVariable(
const VarDecl *D, raw_ostream &Out)
override;
204 void mangleThreadSafeStaticGuardVariable(
const VarDecl *D,
unsigned GuardNum,
205 raw_ostream &Out)
override;
206 void mangleDynamicInitializer(
const VarDecl *D, raw_ostream &Out)
override;
207 void mangleDynamicAtExitDestructor(
const VarDecl *D,
208 raw_ostream &Out)
override;
209 void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
210 raw_ostream &Out)
override;
211 void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
212 raw_ostream &Out)
override;
213 void mangleStringLiteral(
const StringLiteral *SL, raw_ostream &Out)
override;
214 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
215 const DeclContext *DC = getEffectiveDeclContext(ND);
221 if (
const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
222 if (RD->isLambda()) {
230 disc = getASTContext().getManglingNumber(ND, isAux());
235 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
236 if (!
Tag->hasNameForLinkage() &&
237 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
238 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))
243 unsigned &discriminator = Uniquifier[ND];
245 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
246 disc = discriminator + 1;
250 std::string getLambdaString(
const CXXRecordDecl *Lambda)
override {
251 assert(Lambda->
isLambda() &&
"RD must be a lambda!");
252 std::string Name(
"<lambda_");
257 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
258 const FunctionDecl *
Func =
262 unsigned DefaultArgNo =
264 Name += llvm::utostr(DefaultArgNo);
268 if (LambdaManglingNumber)
269 LambdaId = LambdaManglingNumber;
271 LambdaId = getLambdaIdForDebugInfo(Lambda);
273 Name += llvm::utostr(LambdaId);
278 unsigned getLambdaId(
const CXXRecordDecl *RD) {
279 assert(RD->
isLambda() &&
"RD must be a lambda!");
282 "RD must not have a mangling number!");
283 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator,
bool>
284 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
285 return Result.first->second;
288 unsigned getLambdaIdForDebugInfo(
const CXXRecordDecl *RD) {
289 assert(RD->
isLambda() &&
"RD must be a lambda!");
292 "RD must not have a mangling number!");
294 return LambdaIds.lookup(RD);
299 StringRef getAnonymousNamespaceHash()
const {
300 return AnonymousNamespaceHash;
304 void mangleInitFiniStub(
const VarDecl *D,
char CharCode, raw_ostream &Out);
309class MicrosoftCXXNameMangler {
310 MicrosoftMangleContextImpl &Context;
316 const NamedDecl *Structor;
317 unsigned StructorType;
319 typedef llvm::SmallVector<std::string, 10> BackRefVec;
320 BackRefVec NameBackReferences;
322 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
323 ArgBackRefMap FunArgBackReferences;
324 ArgBackRefMap TemplateArgBackReferences;
326 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
327 TemplateArgStringMap TemplateArgStrings;
328 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
329 llvm::StringSaver TemplateArgStringStorage;
331 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
332 PassObjectSizeArgsSet PassObjectSizeArgs;
334 ASTContext &getASTContext()
const {
return Context.getASTContext(); }
336 const bool PointersAre64Bit;
338 DiagnosticBuilder
Error(SourceLocation, StringRef, StringRef);
339 DiagnosticBuilder
Error(SourceLocation, StringRef);
340 DiagnosticBuilder
Error(StringRef);
343 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
344 enum class TplArgKind { ClassNTTP, StructuralValue };
346 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_)
347 : Context(
C), Out(Out_), Structor(
nullptr), StructorType(-1),
348 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
349 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
352 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
354 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
355 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
356 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
359 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
361 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
362 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
363 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
366 raw_ostream &getStream()
const {
return Out; }
368 void mangle(GlobalDecl GD, StringRef Prefix =
"?");
369 void mangleName(GlobalDecl GD);
370 void mangleFunctionEncoding(GlobalDecl GD,
bool ShouldMangle);
371 void mangleVariableEncoding(
const VarDecl *VD);
372 void mangleMemberDataPointer(
const CXXRecordDecl *RD,
const ValueDecl *VD,
373 const NonTypeTemplateParmDecl *PD,
374 QualType TemplateArgType,
375 StringRef Prefix =
"$");
376 void mangleMemberDataPointerInClassNTTP(
const CXXRecordDecl *,
378 void mangleMemberFunctionPointer(
const CXXRecordDecl *RD,
379 const CXXMethodDecl *MD,
380 const NonTypeTemplateParmDecl *PD,
381 QualType TemplateArgType,
382 StringRef Prefix =
"$");
383 void mangleFunctionPointer(
const FunctionDecl *FD,
384 const NonTypeTemplateParmDecl *PD,
385 QualType TemplateArgType);
386 void mangleVarDecl(
const VarDecl *VD,
const NonTypeTemplateParmDecl *PD,
387 QualType TemplateArgType);
388 void mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD,
389 const CXXMethodDecl *MD);
390 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
391 const MethodVFTableLocation &ML);
392 void mangleNumber(int64_t Number);
393 void mangleNumber(llvm::APSInt Number);
394 void mangleFloat(llvm::APFloat Number);
395 void mangleBits(llvm::APInt Number);
397 void mangleArtificialTagType(
TagTypeKind TK, StringRef UnqualifiedName,
398 ArrayRef<StringRef> NestedNames = {});
399 void mangleAddressSpaceType(QualType
T, Qualifiers Quals, SourceRange Range);
400 void mangleType(QualType
T, SourceRange Range,
401 QualifierMangleMode QMM = QMM_Mangle);
402 void mangleFunctionType(
const FunctionType *
T,
403 const FunctionDecl *D =
nullptr,
404 bool ForceThisQuals =
false,
405 bool MangleExceptionSpec =
true);
406 void mangleSourceName(StringRef Name);
407 void mangleNestedName(GlobalDecl GD);
409 void mangleAutoReturnType(QualType
T, QualifierMangleMode QMM);
412 bool isStructorDecl(
const NamedDecl *ND)
const {
413 return ND == Structor || getStructor(ND) == Structor;
416 bool is64BitPointer(Qualifiers Quals)
const {
418 return AddrSpace == LangAS::ptr64 ||
419 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||
420 AddrSpace == LangAS::ptr32_uptr));
423 void mangleUnqualifiedName(GlobalDecl GD) {
426 void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name);
429 void mangleQualifiers(Qualifiers Quals,
bool IsMember);
431 void manglePointerCVQualifiers(Qualifiers Quals);
432 void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType);
433 void manglePointerAuthQualifier(Qualifiers Quals);
435 void mangleUnscopedTemplateName(GlobalDecl GD);
437 mangleTemplateInstantiationName(GlobalDecl GD,
438 const TemplateArgumentList &TemplateArgs);
441 void mangleFunctionArgumentType(QualType
T, SourceRange Range);
442 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
444 bool isArtificialTagType(QualType
T)
const;
447#define ABSTRACT_TYPE(CLASS, PARENT)
448#define NON_CANONICAL_TYPE(CLASS, PARENT)
449#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
452#include "clang/AST/TypeNodes.inc"
454#undef NON_CANONICAL_TYPE
457 void mangleType(
const TagDecl *TD);
458 void mangleDecayedArrayType(
const ArrayType *
T);
463 void mangleIntegerLiteral(
const llvm::APSInt &Number,
474 bool WithScalarType =
false);
489MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(
ASTContext &Context,
510 uint32_t TruncatedHash = uint32_t(xxh3_64bits(FE->getName()));
511 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
514 AnonymousNamespaceHash =
"0";
518bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *D) {
519 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
522 if (FD->hasAttr<OverloadableAttr>())
534 if (FD->isMSVCRTEntryPoint())
548 if (!getASTContext().getLangOpts().
CPlusPlus)
551 const VarDecl *VD = dyn_cast<VarDecl>(D);
558 const DeclContext *DC = getEffectiveDeclContext(D);
562 DC = getEffectiveParentContext(DC);
573MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
577DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
580 DiagnosticsEngine &Diags = Context.getDiags();
582 "cannot mangle this %0 %1 yet");
583 return Diags.
Report(loc, DiagID) << thing1 << thing2;
586DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
588 DiagnosticsEngine &Diags = Context.getDiags();
590 "cannot mangle this %0 yet");
591 return Diags.
Report(loc, DiagID) << thingy;
594DiagnosticBuilder MicrosoftCXXNameMangler::Error(StringRef thingy) {
595 DiagnosticsEngine &Diags = Context.getDiags();
598 "cannot mangle this %0 yet");
599 return Diags.
Report(DiagID) << thingy;
602void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) {
613 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
614 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
615 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
616 mangleVariableEncoding(VD);
620 Out <<
"3U__s_GUID@@B";
625 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
628void MicrosoftCXXNameMangler::mangleFunctionEncoding(GlobalDecl GD,
640 const FunctionProtoType *FT = FD->
getType()->
castAs<FunctionProtoType>();
653 mangleFunctionClass(FD);
655 mangleFunctionType(FT, FD,
false,
false);
661void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
692 mangleType(Ty, SR, QMM_Drop);
693 manglePointerExtQualifiers(
695 if (
const MemberPointerType *MPT = Ty->
getAs<MemberPointerType>()) {
696 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
699 mangleName(MPT->getMostRecentCXXRecordDecl());
702 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
704 mangleDecayedArrayType(AT);
705 if (AT->getElementType()->isArrayType())
710 mangleType(Ty, SR, QMM_Drop);
715void MicrosoftCXXNameMangler::mangleMemberDataPointer(
716 const CXXRecordDecl *RD,
const ValueDecl *VD,
717 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
731 FieldOffset = getASTContext().getFieldOffset(VD);
732 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
733 "cannot take address of bitfield");
734 FieldOffset /= getASTContext().getCharWidth();
738 if (IM == MSInheritanceModel::Virtual)
739 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
748 case MSInheritanceModel::Single: Code =
'0';
break;
749 case MSInheritanceModel::Multiple: Code =
'0';
break;
750 case MSInheritanceModel::Virtual: Code =
'F';
break;
751 case MSInheritanceModel::Unspecified: Code =
'G';
break;
757 getASTContext().getLangOpts().isCompatibleWithMSVC(
758 LangOptions::MSVC2019) &&
760 !TemplateArgType.
isNull()) {
762 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
767 mangleNumber(FieldOffset);
775 mangleNumber(VBTableOffset);
778void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
779 const CXXRecordDecl *RD,
const ValueDecl *VD) {
785 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
786 return mangleMemberDataPointer(RD, VD,
nullptr, QualType(),
"");
794 mangleNestedName(VD);
796 mangleUnqualifiedName(VD);
800void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
801 const CXXRecordDecl *RD,
const CXXMethodDecl *MD,
802 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
818 case MSInheritanceModel::Single: Code =
'1';
break;
819 case MSInheritanceModel::Multiple: Code =
'H';
break;
820 case MSInheritanceModel::Virtual: Code =
'I';
break;
821 case MSInheritanceModel::Unspecified: Code =
'J';
break;
832 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
833 LangOptions::MSVC2019) &&
835 !TemplateArgType.
isNull()) {
837 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
842 MicrosoftVTableContext *VTContext =
844 MethodVFTableLocation ML =
846 mangleVirtualMemPtrThunk(MD, ML);
850 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
855 mangleFunctionEncoding(MD,
true);
858 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
859 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
862 if (IM == MSInheritanceModel::Single) {
863 Out << Prefix <<
"0A@";
866 if (IM == MSInheritanceModel::Unspecified)
868 Out << Prefix << Code;
872 mangleNumber(
static_cast<uint32_t>(NVOffset));
874 mangleNumber(VBPtrOffset);
876 mangleNumber(VBTableOffset);
879void MicrosoftCXXNameMangler::mangleFunctionPointer(
880 const FunctionDecl *FD,
const NonTypeTemplateParmDecl *PD,
881 QualType TemplateArgType) {
888 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
889 LangOptions::MSVC2019) &&
891 !TemplateArgType.
isNull()) {
893 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
898 mangleFunctionEncoding(FD,
true);
901void MicrosoftCXXNameMangler::mangleVarDecl(
const VarDecl *VD,
902 const NonTypeTemplateParmDecl *PD,
903 QualType TemplateArgType) {
910 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
911 LangOptions::MSVC2019) &&
913 !TemplateArgType.
isNull()) {
915 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
920 mangleVariableEncoding(VD);
923void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
924 const CXXRecordDecl *RD,
const CXXMethodDecl *MD) {
932 return mangleMemberFunctionPointer(RD, MD,
nullptr, QualType(),
"");
940 MicrosoftVTableContext *VTContext =
942 MethodVFTableLocation ML =
944 mangleVirtualMemPtrThunk(MD, ML);
947 mangleFunctionEncoding(MD,
true);
951void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
952 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML) {
954 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
955 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
961 mangleNumber(OffsetInVFTable);
963 mangleCallingConvention(MD->
getType()->
castAs<FunctionProtoType>(),
967void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {
971 mangleUnqualifiedName(GD);
973 mangleNestedName(GD);
979void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
980 mangleNumber(llvm::APSInt(llvm::APInt(64, Number),
false));
983void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
988 unsigned Width = std::max(Number.getBitWidth(), 64U);
989 llvm::APInt
Value = Number.extend(Width);
997 if (
Value.isNegative()) {
1004void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
1005 using llvm::APFloat;
1007 switch (APFloat::SemanticsToEnum(Number.getSemantics())) {
1008 case APFloat::S_IEEEsingle:
Out <<
'A';
break;
1009 case APFloat::S_IEEEdouble:
Out <<
'B';
break;
1013 case APFloat::S_IEEEhalf:
Out <<
'V';
break;
1014 case APFloat::S_BFloat:
Out <<
'W';
break;
1015 case APFloat::S_x87DoubleExtended:
Out <<
'X';
break;
1016 case APFloat::S_IEEEquad:
Out <<
'Y';
break;
1017 case APFloat::S_PPCDoubleDouble:
Out <<
'Z';
break;
1018 case APFloat::S_PPCDoubleDoubleLegacy:
1019 case APFloat::S_Float8E5M2:
1020 case APFloat::S_Float8E4M3:
1021 case APFloat::S_Float8E4M3FN:
1022 case APFloat::S_Float8E5M2FNUZ:
1023 case APFloat::S_Float8E4M3FNUZ:
1024 case APFloat::S_Float8E4M3B11FNUZ:
1025 case APFloat::S_Float8E3M4:
1026 case APFloat::S_FloatTF32:
1027 case APFloat::S_Float8E8M0FNU:
1028 case APFloat::S_Float6E3M2FN:
1029 case APFloat::S_Float6E2M3FN:
1030 case APFloat::S_Float4E2M1FN:
1031 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
1034 mangleBits(Number.bitcastToAPInt());
1037void MicrosoftCXXNameMangler::mangleBits(llvm::APInt
Value) {
1046 llvm::SmallString<32> EncodedNumberBuffer;
1048 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
1049 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1050 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1059 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1068 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1069 TemplateArgs = &Spec->getTemplateArgs();
1070 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1075 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1076 TemplateArgs = &Spec->getTemplateArgs();
1077 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1083void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
1084 DeclarationName Name) {
1092 const TemplateArgumentList *TemplateArgs =
nullptr;
1093 if (GlobalDecl TD =
isTemplate(GD, TemplateArgs)) {
1098 mangleTemplateInstantiationName(TD, *TemplateArgs);
1121 ArgBackRefMap::iterator
Found = TemplateArgBackReferences.find(ND);
1122 if (
Found == TemplateArgBackReferences.end()) {
1124 TemplateArgStringMap::iterator
Found = TemplateArgStrings.find(ND);
1125 if (
Found == TemplateArgStrings.end()) {
1127 llvm::SmallString<64> TemplateMangling;
1128 llvm::raw_svector_ostream Stream(TemplateMangling);
1129 MicrosoftCXXNameMangler
Extra(Context, Stream);
1130 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1133 mangleSourceName(TemplateMangling);
1137 BackRefVec::iterator StringFound =
1138 llvm::find(NameBackReferences, TemplateMangling);
1139 if (StringFound != NameBackReferences.end()) {
1140 TemplateArgBackReferences[ND] =
1141 StringFound - NameBackReferences.begin();
1143 TemplateArgStrings[ND] =
1144 TemplateArgStringStorage.save(TemplateMangling.str());
1163 ->getTemplatedDecl()
1166 bool IsOCLDeviceStub =
1168 DeviceKernelAttr::isOpenCLSpelling(
1169 ND->
getAttr<DeviceKernelAttr>()) &&
1173 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1174 else if (IsOCLDeviceStub)
1176 (llvm::Twine(
"__clang_ocl_kern_imp_") + II->getName()).str());
1178 mangleSourceName(II->getName());
1183 assert(ND &&
"mangling empty name without declaration");
1185 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1186 if (NS->isAnonymousNamespace()) {
1187 Out <<
"?A0x" << Context.getAnonymousNamespaceHash() <<
'@';
1192 if (
const DecompositionDecl *DD = dyn_cast<DecompositionDecl>(ND)) {
1195 llvm::SmallString<64> Name(
"$S");
1197 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1198 mangleSourceName(Name);
1202 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1205 assert(RD &&
"expected variable decl to have a record type");
1209 llvm::SmallString<64> Name(
"$S");
1211 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1212 mangleSourceName(Name.str());
1216 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1219 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1220 llvm::raw_svector_ostream GUIDOS(GUID);
1221 Context.mangleMSGuidDecl(GD, GUIDOS);
1222 mangleSourceName(GUID);
1226 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1228 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1229 TPO->getValue(), TplArgKind::ClassNTTP);
1237 "Typedef should not be in another decl context!");
1239 "Typedef was not named!");
1244 if (
const CXXRecordDecl *
Record = dyn_cast<CXXRecordDecl>(TD)) {
1245 if (
Record->isLambda()) {
1246 llvm::SmallString<10> Name(
"<lambda_");
1248 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1249 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1251 const ParmVarDecl *Parm =
1252 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1253 const FunctionDecl *
Func =
1257 unsigned DefaultArgNo =
1259 Name += llvm::utostr(DefaultArgNo);
1263 if (LambdaManglingNumber)
1264 LambdaId = LambdaManglingNumber;
1266 LambdaId = Context.getLambdaId(
Record);
1268 Name += llvm::utostr(LambdaId);
1271 mangleSourceName(Name);
1275 if (LambdaManglingNumber && LambdaContextDecl) {
1286 llvm::SmallString<64> Name;
1287 if (DeclaratorDecl *DD =
1291 Name +=
"<unnamed-type-";
1292 Name += DD->getName();
1293 }
else if (TypedefNameDecl *TND =
1298 Name +=
"<unnamed-type-";
1299 Name += TND->getName();
1304 Name +=
"<unnamed-enum-";
1305 Name += ED->enumerator_begin()->getName();
1308 Name +=
"<unnamed-type-$S";
1309 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1312 mangleSourceName(Name.str());
1322 llvm::SmallString<64> Name;
1323 mangleSourceName(Name.str());
1328 if (isStructorDecl(ND)) {
1342 if (isStructorDecl(ND))
1345 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1359 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1364 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1369 llvm_unreachable(
"Can't mangle a deduction guide name!");
1372 llvm_unreachable(
"Can't mangle a using directive name!");
1378void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {
1381 if (
const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1382 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1383 mangleSourceName(
"<unnamed-tag>");
1385 const DeclContext *DC = getEffectiveDeclContext(ND);
1389 if (Context.getNextDiscriminator(ND, Disc)) {
1396 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1398 [](StringRef Name,
const unsigned Discriminator,
1399 const unsigned ParameterDiscriminator) -> std::string {
1401 llvm::raw_string_ostream Stream(Buffer);
1404 Stream <<
'_' << Discriminator;
1405 if (ParameterDiscriminator)
1406 Stream <<
'_' << ParameterDiscriminator;
1410 unsigned Discriminator = BD->getBlockManglingNumber();
1412 Discriminator = Context.getBlockId(BD,
false);
1417 unsigned ParameterDiscriminator = 0;
1418 if (
const auto *MC = BD->getBlockManglingContextDecl())
1419 if (
const auto *P = dyn_cast<ParmVarDecl>(MC))
1420 if (
const auto *F = dyn_cast<FunctionDecl>(P->getDeclContext()))
1421 ParameterDiscriminator =
1422 F->getNumParams() - P->getFunctionScopeIndex();
1424 DC = getEffectiveDeclContext(BD);
1427 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1428 ParameterDiscriminator));
1433 if (
const auto *MC = BD->getBlockManglingContextDecl())
1435 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1436 mangleUnqualifiedName(ND);
1440 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1449 if (PointersAre64Bit)
1452 mangleArtificialTagType(TagTypeKind::Struct,
1453 Discriminate(
"__block_literal", Discriminator,
1454 ParameterDiscriminator));
1462 }
else if (
const ObjCMethodDecl *
Method = dyn_cast<ObjCMethodDecl>(DC)) {
1466 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1467 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1470 mangleUnqualifiedName(ND);
1473 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1483void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1498 llvm_unreachable(
"not expecting a COMDAT");
1500 llvm_unreachable(
"not expecting a unified dtor type");
1502 llvm_unreachable(
"Unsupported dtor type?");
1506 SourceLocation Loc) {
1511 case OO_New:
Out <<
"?2";
break;
1513 case OO_Delete:
Out <<
"?3";
break;
1515 case OO_Equal:
Out <<
"?4";
break;
1517 case OO_GreaterGreater:
Out <<
"?5";
break;
1519 case OO_LessLess:
Out <<
"?6";
break;
1521 case OO_Exclaim:
Out <<
"?7";
break;
1523 case OO_EqualEqual:
Out <<
"?8";
break;
1525 case OO_ExclaimEqual:
Out <<
"?9";
break;
1527 case OO_Subscript:
Out <<
"?A";
break;
1530 case OO_Arrow:
Out <<
"?C";
break;
1532 case OO_Star:
Out <<
"?D";
break;
1534 case OO_PlusPlus:
Out <<
"?E";
break;
1536 case OO_MinusMinus:
Out <<
"?F";
break;
1538 case OO_Minus:
Out <<
"?G";
break;
1540 case OO_Plus:
Out <<
"?H";
break;
1542 case OO_Amp:
Out <<
"?I";
break;
1544 case OO_ArrowStar:
Out <<
"?J";
break;
1546 case OO_Slash:
Out <<
"?K";
break;
1548 case OO_Percent:
Out <<
"?L";
break;
1550 case OO_Less:
Out <<
"?M";
break;
1552 case OO_LessEqual:
Out <<
"?N";
break;
1554 case OO_Greater:
Out <<
"?O";
break;
1556 case OO_GreaterEqual:
Out <<
"?P";
break;
1558 case OO_Comma:
Out <<
"?Q";
break;
1560 case OO_Call:
Out <<
"?R";
break;
1562 case OO_Tilde:
Out <<
"?S";
break;
1564 case OO_Caret:
Out <<
"?T";
break;
1566 case OO_Pipe:
Out <<
"?U";
break;
1568 case OO_AmpAmp:
Out <<
"?V";
break;
1570 case OO_PipePipe:
Out <<
"?W";
break;
1572 case OO_StarEqual:
Out <<
"?X";
break;
1574 case OO_PlusEqual:
Out <<
"?Y";
break;
1576 case OO_MinusEqual:
Out <<
"?Z";
break;
1578 case OO_SlashEqual:
Out <<
"?_0";
break;
1580 case OO_PercentEqual:
Out <<
"?_1";
break;
1582 case OO_GreaterGreaterEqual:
Out <<
"?_2";
break;
1584 case OO_LessLessEqual:
Out <<
"?_3";
break;
1586 case OO_AmpEqual:
Out <<
"?_4";
break;
1588 case OO_PipeEqual:
Out <<
"?_5";
break;
1590 case OO_CaretEqual:
Out <<
"?_6";
break;
1619 case OO_Array_New:
Out <<
"?_U";
break;
1621 case OO_Array_Delete:
Out <<
"?_V";
break;
1623 case OO_Coawait:
Out <<
"?__L";
break;
1625 case OO_Spaceship:
Out <<
"?__M";
break;
1627 case OO_Conditional: {
1628 Error(Loc,
"conditional operator");
1634 llvm_unreachable(
"Not an overloaded operator");
1638void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1640 BackRefVec::iterator
Found = llvm::find(NameBackReferences, Name);
1641 if (
Found == NameBackReferences.end()) {
1642 if (NameBackReferences.size() < 10)
1643 NameBackReferences.push_back(std::string(Name));
1646 Out << (
Found - NameBackReferences.begin());
1650void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1651 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1654void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1655 GlobalDecl GD,
const TemplateArgumentList &TemplateArgs) {
1661 ArgBackRefMap OuterFunArgsContext;
1662 ArgBackRefMap OuterTemplateArgsContext;
1663 BackRefVec OuterTemplateContext;
1664 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1665 NameBackReferences.swap(OuterTemplateContext);
1666 FunArgBackReferences.swap(OuterFunArgsContext);
1667 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1668 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1670 mangleUnscopedTemplateName(GD);
1674 NameBackReferences.swap(OuterTemplateContext);
1675 FunArgBackReferences.swap(OuterFunArgsContext);
1676 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1677 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1680void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {
1683 mangleUnqualifiedName(GD);
1686void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1687 const llvm::APSInt &
Value,
const NonTypeTemplateParmDecl *PD,
1688 QualType TemplateArgType) {
1697 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1698 LangOptions::MSVC2019) &&
1700 !TemplateArgType.
isNull()) {
1702 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
1707 mangleNumber(
Value);
1710void MicrosoftCXXNameMangler::mangleExpression(
1711 const Expr *E,
const NonTypeTemplateParmDecl *PD) {
1713 if (std::optional<llvm::APSInt>
Value =
1724void MicrosoftCXXNameMangler::mangleTemplateArgs(
1725 const TemplateDecl *TD,
const TemplateArgumentList &TemplateArgs) {
1728 assert(TPL->
size() == TemplateArgs.
size() &&
1729 "size mismatch between args and parms!");
1731 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1732 const TemplateArgument &TA = TemplateArgs[i];
1739 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1747 if (!
T->isPointerType() || !
V.isLValue() || !
V.hasLValuePath() ||
1751 QualType BaseT =
V.getLValueBase().getType();
1752 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1753 V.getLValuePath()[0].getAsArrayIndex() != 0)
1756 V.getLValueBase().dyn_cast<const ValueDecl *>());
1759void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1760 const TemplateArgument &TA,
1761 const NamedDecl *Parm) {
1799 llvm_unreachable(
"Can't mangle null template arguments!");
1801 llvm_unreachable(
"Can't mangle template expansion arguments!");
1804 mangleType(
T, SourceRange(), QMM_Escape);
1810 mangleMemberDataPointer(
1814 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1815 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1827 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1828 TPO->getValue(), TplArgKind::ClassNTTP);
1829 }
else if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1845 if (
const MemberPointerType *MPT =
T->
getAs<MemberPointerType>()) {
1846 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1847 if (MPT->isMemberFunctionPointerType() &&
1849 mangleMemberFunctionPointer(RD,
nullptr,
nullptr, QualType());
1852 if (MPT->isMemberDataPointer()) {
1854 mangleMemberDataPointer(RD,
nullptr,
nullptr, QualType());
1864 mangleIntegerLiteral(llvm::APSInt::get(-1),
1870 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1880 return mangleTemplateArg(
1886 ->getContainedDeducedType()) {
1892 TplArgKind::StructuralValue,
1900 if (TemplateArgs.empty()) {
1905 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(
1906 LangOptions::MSVC2015)
1912 llvm_unreachable(
"unexpected template parameter decl!");
1914 for (
const TemplateArgument &PA : TemplateArgs)
1915 mangleTemplateArg(TD, PA, Parm);
1920 const NamedDecl *ND =
1922 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1928 llvm_unreachable(
"unexpected template template NamedDecl!");
1935void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType
T,
1938 bool WithScalarType) {
1939 switch (
V.getKind()) {
1945 mangleType(
T, SourceRange(), QMM_Escape);
1951 mangleType(
T, SourceRange(), QMM_Escape);
1953 mangleNumber(
V.getInt());
1958 mangleType(
T, SourceRange(), QMM_Escape);
1959 mangleFloat(
V.getFloat());
1964 mangleType(
T, SourceRange(), QMM_Escape);
1966 APValue::LValueBase
Base =
V.getLValueBase();
1970 if (
V.isLValueOnePastTheEnd()) {
1972 auto *VD =
Base.dyn_cast<
const ValueDecl *>();
1979 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1981 if (
Base.isNull()) {
1987 mangleNumber(
V.getLValueOffset().getQuantity());
1988 }
else if (!
V.hasLValuePath()) {
1990 Error(
"template argument (extension not comaptible with ms mangler)");
1992 }
else if (
auto *VD =
Base.dyn_cast<
const ValueDecl*>()) {
1996 Error(
"template argument (undeclared base)");
2003 SmallVector<char, 2> EntryTypes;
2005 QualType ET =
Base.getType();
2006 for (APValue::LValuePathEntry E :
V.getLValuePath()) {
2008 EntryTypes.push_back(
'C');
2009 EntryManglers.push_back([
this, I = E.getAsArrayIndex()] {
2014 ET = AT->getElementType();
2018 const Decl *D = E.getAsBaseOrMember().getPointer();
2019 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2031 EntryTypes.push_back(
'6');
2032 EntryManglers.push_back([
this, D] {
2038 for (
auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
2041 auto *VD =
Base.dyn_cast<
const ValueDecl*>();
2043 Error(
"template argument (null value decl)");
2046 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
2060 mangleType(
T, SourceRange(), QMM_Escape);
2062 const CXXRecordDecl *RD =
2063 T->
castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
2064 const ValueDecl *D =
V.getMemberPointerDecl();
2065 if (TAK == TplArgKind::ClassNTTP) {
2067 mangleMemberDataPointerInClassNTTP(RD, D);
2069 mangleMemberFunctionPointerInClassNTTP(RD,
2070 cast_or_null<CXXMethodDecl>(D));
2073 mangleMemberDataPointer(RD, D,
nullptr, QualType(),
"");
2075 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D),
nullptr,
2083 mangleType(
T, SourceRange(), QMM_Escape);
2085 assert(RD &&
"unexpected type for record value");
2087 unsigned BaseIndex = 0;
2088 for (
const CXXBaseSpecifier &B : RD->
bases())
2089 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
2090 for (
const FieldDecl *FD : RD->
fields())
2091 if (!FD->isUnnamedBitField())
2092 mangleTemplateArgValue(FD->
getType(),
2093 V.getStructField(FD->getFieldIndex()), TAK,
2101 mangleType(
T, SourceRange(), QMM_Escape);
2102 if (
const FieldDecl *FD =
V.getUnionField()) {
2103 mangleUnqualifiedName(FD);
2104 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
2112 mangleType(
T, SourceRange(), QMM_Escape);
2114 mangleNumber(
V.getComplexIntReal());
2116 mangleNumber(
V.getComplexIntImag());
2122 mangleType(
T, SourceRange(), QMM_Escape);
2123 mangleFloat(
V.getComplexFloatReal());
2124 mangleFloat(
V.getComplexFloatImag());
2130 QualType ElemT = getASTContext().getAsArrayType(
T)->getElementType();
2131 mangleType(ElemT, SourceRange(), QMM_Escape);
2132 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
2133 const APValue &ElemV = I <
V.getArrayInitializedElts()
2134 ?
V.getArrayInitializedElt(I)
2135 :
V.getArrayFiller();
2136 mangleTemplateArgValue(ElemT, ElemV, TAK);
2147 mangleType(
T, SourceRange(), QMM_Escape);
2149 QualType ElemT =
T->
castAs<VectorType>()->getElementType();
2150 mangleType(ElemT, SourceRange(), QMM_Escape);
2151 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
2153 mangleTemplateArgValue(ElemT, ElemV, TAK);
2161 Error(
"template argument (value type: address label diff)");
2166 Error(
"template argument (value type: fixed point)");
2172void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2173 llvm::SmallString<64> TemplateMangling;
2174 llvm::raw_svector_ostream Stream(TemplateMangling);
2175 MicrosoftCXXNameMangler
Extra(Context, Stream);
2178 Extra.mangleSourceName(
"Protocol");
2179 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2181 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2184void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType
Type,
2186 SourceRange Range) {
2187 llvm::SmallString<64> TemplateMangling;
2188 llvm::raw_svector_ostream Stream(TemplateMangling);
2189 MicrosoftCXXNameMangler
Extra(Context, Stream);
2197 Extra.mangleSourceName(
"Autoreleasing");
2200 Extra.mangleSourceName(
"Strong");
2203 Extra.mangleSourceName(
"Weak");
2206 Extra.manglePointerCVQualifiers(Quals);
2207 Extra.manglePointerExtQualifiers(Quals,
Type);
2210 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2213void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *
T,
2215 SourceRange Range) {
2216 llvm::SmallString<64> TemplateMangling;
2217 llvm::raw_svector_ostream Stream(TemplateMangling);
2218 MicrosoftCXXNameMangler
Extra(Context, Stream);
2221 Extra.mangleSourceName(
"KindOf");
2222 Extra.mangleType(QualType(
T, 0)
2223 .stripObjCKindOfType(getASTContext())
2224 ->castAs<ObjCObjectType>(),
2227 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2230void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
2288 if (HasConst && HasVolatile) {
2290 }
else if (HasVolatile) {
2292 }
else if (HasConst) {
2298 if (HasConst && HasVolatile) {
2300 }
else if (HasVolatile) {
2302 }
else if (HasConst) {
2313MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2316 switch (RefQualifier) {
2330void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
2331 QualType PointeeType) {
2333 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2346void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {
2352 mangleNumber(PointerAuth.
getKey());
2357void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
2365 if (HasConst && HasVolatile) {
2367 }
else if (HasVolatile) {
2369 }
else if (HasConst) {
2376void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType
T,
2377 SourceRange Range) {
2386 if (
const auto *DT =
T->
getAs<DecayedType>()) {
2387 QualType OriginalType = DT->getOriginalType();
2390 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2391 OriginalType = getASTContext().getIncompleteArrayType(
2392 AT->getElementType(), AT->getSizeModifier(),
2393 AT->getIndexTypeCVRQualifiers());
2404 TypePtr =
T.getCanonicalType().getAsOpaquePtr();
2407 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2409 if (
Found == FunArgBackReferences.end()) {
2410 size_t OutSizeBefore =
Out.tell();
2412 mangleType(
T, Range, QMM_Drop);
2417 bool LongerThanOneChar = (
Out.tell() - OutSizeBefore > 1);
2418 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2419 size_t Size = FunArgBackReferences.size();
2420 FunArgBackReferences[TypePtr] =
Size;
2427void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2428 const PassObjectSizeAttr *POSA) {
2429 int Type = POSA->getType();
2430 bool Dynamic = POSA->isDynamic();
2432 auto Iter = PassObjectSizeArgs.insert({
Type,
Dynamic}).first;
2433 auto *TypePtr = (
const void *)&*Iter;
2434 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2436 if (
Found == FunArgBackReferences.end()) {
2438 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2439 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2442 if (FunArgBackReferences.size() < 10) {
2443 size_t Size = FunArgBackReferences.size();
2444 FunArgBackReferences[TypePtr] =
Size;
2451void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType
T,
2453 SourceRange Range) {
2468 llvm::SmallString<32> ASMangling;
2469 llvm::raw_svector_ostream Stream(ASMangling);
2470 MicrosoftCXXNameMangler
Extra(Context, Stream);
2476 Extra.mangleSourceName(
"_AS");
2477 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2481 llvm_unreachable(
"Not a language specific address space");
2482 case LangAS::opencl_global:
2483 Extra.mangleSourceName(
"_ASCLglobal");
2485 case LangAS::opencl_global_device:
2486 Extra.mangleSourceName(
"_ASCLdevice");
2488 case LangAS::opencl_global_host:
2489 Extra.mangleSourceName(
"_ASCLhost");
2491 case LangAS::opencl_local:
2492 Extra.mangleSourceName(
"_ASCLlocal");
2494 case LangAS::opencl_constant:
2495 Extra.mangleSourceName(
"_ASCLconstant");
2497 case LangAS::opencl_private:
2498 Extra.mangleSourceName(
"_ASCLprivate");
2500 case LangAS::opencl_generic:
2501 Extra.mangleSourceName(
"_ASCLgeneric");
2503 case LangAS::cuda_device:
2504 Extra.mangleSourceName(
"_ASCUdevice");
2506 case LangAS::cuda_constant:
2507 Extra.mangleSourceName(
"_ASCUconstant");
2509 case LangAS::cuda_shared:
2510 Extra.mangleSourceName(
"_ASCUshared");
2512 case LangAS::ptr32_sptr:
2513 case LangAS::ptr32_uptr:
2515 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2519 Extra.mangleType(
T, Range, QMM_Escape);
2520 mangleQualifiers(Qualifiers(),
false);
2521 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2524void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType
T,
2525 QualifierMangleMode QMM) {
2526 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2527 LangOptions::MSVC2019) &&
2528 "Cannot mangle MSVC 2017 auto return types!");
2532 Qualifiers Quals =
T.getLocalQualifiers();
2534 if (QMM == QMM_Result)
2536 if (QMM != QMM_Drop)
2537 mangleQualifiers(Quals,
false);
2538 Out << (AT->isDecltypeAuto() ?
"_T" :
"_P");
2542 T =
T.getDesugaredType(getASTContext());
2543 Qualifiers Quals =
T.getLocalQualifiers();
2550 mangleQualifiers(Quals,
false);
2553 llvm_unreachable(
"QMM_Escape unexpected");
2556 const Type *ty =
T.getTypePtr();
2558 case Type::MemberPointer:
2564 case Type::LValueReference:
2567 case Type::RValueReference:
2571 llvm_unreachable(
"Invalid type expected");
2575void MicrosoftCXXNameMangler::mangleType(QualType
T, SourceRange Range,
2576 QualifierMangleMode QMM) {
2579 T =
T.getDesugaredType(getASTContext());
2580 Qualifiers Quals =
T.getLocalQualifiers();
2582 if (
const ArrayType *AT = getASTContext().getAsArrayType(
T)) {
2585 if (QMM == QMM_Mangle)
2587 else if (QMM == QMM_Escape || QMM == QMM_Result)
2589 mangleArrayType(AT);
2602 if (
const FunctionType *FT = dyn_cast<FunctionType>(
T)) {
2604 mangleFunctionType(FT);
2607 mangleQualifiers(Quals,
false);
2610 if (!IsPointer && Quals) {
2612 mangleQualifiers(Quals,
false);
2620 if ((!IsPointer && Quals) ||
isa<TagType>(
T) || isArtificialTagType(
T)) {
2622 mangleQualifiers(Quals,
false);
2627 const Type *ty =
T.getTypePtr();
2630#define ABSTRACT_TYPE(CLASS, PARENT)
2631#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2633 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2635#define TYPE(CLASS, PARENT) \
2637 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2639#include "clang/AST/TypeNodes.inc"
2641#undef NON_CANONICAL_TYPE
2646void MicrosoftCXXNameMangler::mangleType(
const BuiltinType *
T, Qualifiers,
2647 SourceRange Range) {
2675 switch (
T->getKind()) {
2676 case BuiltinType::Void:
2679 case BuiltinType::SChar:
2682 case BuiltinType::Char_U:
2683 case BuiltinType::Char_S:
2686 case BuiltinType::UChar:
2689 case BuiltinType::Short:
2692 case BuiltinType::UShort:
2695 case BuiltinType::Int:
2698 case BuiltinType::UInt:
2701 case BuiltinType::Long:
2704 case BuiltinType::ULong:
2707 case BuiltinType::Float:
2710 case BuiltinType::Double:
2714 case BuiltinType::LongDouble:
2717 case BuiltinType::LongLong:
2720 case BuiltinType::ULongLong:
2723 case BuiltinType::Int128:
2726 case BuiltinType::UInt128:
2729 case BuiltinType::Bool:
2732 case BuiltinType::Char8:
2735 case BuiltinType::Char16:
2738 case BuiltinType::Char32:
2741 case BuiltinType::WChar_S:
2742 case BuiltinType::WChar_U:
2746#define BUILTIN_TYPE(Id, SingletonId)
2747#define PLACEHOLDER_TYPE(Id, SingletonId) \
2748 case BuiltinType::Id:
2749#include "clang/AST/BuiltinTypes.def"
2750 case BuiltinType::Dependent:
2751 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2753 case BuiltinType::ObjCId:
2754 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2756 case BuiltinType::ObjCClass:
2757 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2759 case BuiltinType::ObjCSel:
2760 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2763#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2764 case BuiltinType::Id: \
2765 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2767#include "clang/Basic/OpenCLImageTypes.def"
2768 case BuiltinType::OCLSampler:
2770 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2772 case BuiltinType::OCLEvent:
2774 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2776 case BuiltinType::OCLClkEvent:
2778 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2780 case BuiltinType::OCLQueue:
2782 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2784 case BuiltinType::OCLReserveID:
2786 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2788#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2789 case BuiltinType::Id: \
2790 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2792#include "clang/Basic/OpenCLExtensionTypes.def"
2794 case BuiltinType::NullPtr:
2798 case BuiltinType::Float16:
2799 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2802 case BuiltinType::Half:
2803 if (!getASTContext().getLangOpts().
HLSL)
2804 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2805 else if (getASTContext().getLangOpts().NativeHalfType)
2811 case BuiltinType::BFloat16:
2812 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2815 case BuiltinType::MFloat8:
2816 mangleArtificialTagType(TagTypeKind::Struct,
"__mfp8", {
"__clang"});
2819#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2820 case BuiltinType::Id: \
2821 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2822 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2825#include "clang/Basic/WebAssemblyReferenceTypes.def"
2827#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2828 case BuiltinType::Id: \
2829 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2831#include "clang/Basic/HLSLIntangibleTypes.def"
2833#define SVE_TYPE(Name, Id, SingletonId) \
2834 case BuiltinType::Id: \
2835 mangleArtificialTagType(TagTypeKind::Struct, #Name, {"__clang"}); \
2837#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits)
2838#include "clang/Basic/AArch64ACLETypes.def"
2850void MicrosoftCXXNameMangler::mangleType(
const FunctionProtoType *
T, Qualifiers,
2857 mangleFunctionType(
T,
nullptr,
true);
2860 mangleFunctionType(
T);
2863void MicrosoftCXXNameMangler::mangleType(
const FunctionNoProtoType *
T,
2864 Qualifiers, SourceRange) {
2866 mangleFunctionType(
T);
2869void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *
T,
2870 const FunctionDecl *D,
2871 bool ForceThisQuals,
2872 bool MangleExceptionSpec) {
2875 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(
T);
2880 bool IsInLambda =
false;
2881 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
2883 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
2887 HasThisQuals =
true;
2896 CC = getASTContext().getDefaultCallingConvention(
2905 manglePointerExtQualifiers(Quals, QualType());
2907 mangleQualifiers(Quals,
false);
2910 mangleCallingConvention(CC, Range);
2919 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
2928 if (IsCtorClosure) {
2938 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
2940 ->
castAs<LValueReferenceType>()
2946 llvm_unreachable(
"unexpected constructor closure!");
2952 }
else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(D)) {
2963 mangleType(ResultType, Range, QMM_Result);
2964 }
else if (IsInLambda) {
2966 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2967 "shouldn't need to mangle __auto_type!");
2971 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
2977 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2978 "shouldn't need to mangle __auto_type!");
2984 auto UseClangMangling = [](QualType ResultType) {
2985 QualType
T = ResultType;
2988 if (
T.getQualifiers().hasAddressSpace())
2994 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
2995 LangOptions::MSVC2019) &&
2996 !UseClangMangling(ResultType)) {
3005 ->
castAs<FunctionProtoType>();
3008 mangleAutoReturnType(ResultType, QMM_Result);
3014 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3020 mangleType(ResultType, Range, QMM_Result);
3036 for (
unsigned I = 0, E = Proto->
getNumParams(); I != E; ++I) {
3041 mangleFunctionArgumentType(Proto->
getParamType(I), Range);
3052 manglePassObjectSizeArg(P);
3061 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
3062 getASTContext().getLangOpts().isCompatibleWithMSVC(
3063 LangOptions::MSVC2017_5))
3064 mangleThrowSpecification(Proto);
3069void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
3094 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3104 llvm_unreachable(
"Unsupported access specifier");
3133void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC,
3134 SourceRange Range) {
3196 if (getASTContext().getLangOpts().RegCall4)
3205void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *
T,
3206 SourceRange Range) {
3210void MicrosoftCXXNameMangler::mangleThrowSpecification(
3211 const FunctionProtoType *FT) {
3220void MicrosoftCXXNameMangler::mangleType(
const UnresolvedUsingType *
T,
3221 Qualifiers, SourceRange Range) {
3232void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
3234 case TagTypeKind::Union:
3237 case TagTypeKind::Struct:
3238 case TagTypeKind::Interface:
3241 case TagTypeKind::Class:
3244 case TagTypeKind::Enum:
3249void MicrosoftCXXNameMangler::mangleType(
const EnumType *
T, Qualifiers,
3253void MicrosoftCXXNameMangler::mangleType(
const RecordType *
T, Qualifiers,
3257void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3267void MicrosoftCXXNameMangler::mangleArtificialTagType(
3269 ArrayRef<StringRef> NestedNames) {
3271 mangleTagTypeKind(TK);
3274 mangleSourceName(UnqualifiedName);
3276 for (StringRef N : llvm::reverse(NestedNames))
3277 mangleSourceName(N);
3290void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *
T) {
3293 manglePointerCVQualifiers(
T->getElementType().getQualifiers());
3294 mangleType(
T->getElementType(), SourceRange());
3296void MicrosoftCXXNameMangler::mangleType(
const ConstantArrayType *
T, Qualifiers,
3298 llvm_unreachable(
"Should have been special cased");
3300void MicrosoftCXXNameMangler::mangleType(
const VariableArrayType *
T, Qualifiers,
3302 llvm_unreachable(
"Should have been special cased");
3304void MicrosoftCXXNameMangler::mangleType(
const DependentSizedArrayType *
T,
3305 Qualifiers, SourceRange) {
3306 llvm_unreachable(
"Should have been special cased");
3308void MicrosoftCXXNameMangler::mangleType(
const IncompleteArrayType *
T,
3309 Qualifiers, SourceRange) {
3310 llvm_unreachable(
"Should have been special cased");
3312void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *
T) {
3313 QualType ElementTy(
T, 0);
3314 SmallVector<llvm::APInt, 3> Dimensions;
3316 if (ElementTy->isConstantArrayType()) {
3317 const ConstantArrayType *CAT =
3318 getASTContext().getAsConstantArrayType(ElementTy);
3319 Dimensions.push_back(CAT->
getSize());
3321 }
else if (ElementTy->isIncompleteArrayType()) {
3322 const IncompleteArrayType *IAT =
3323 getASTContext().getAsIncompleteArrayType(ElementTy);
3324 Dimensions.push_back(llvm::APInt(32, 0));
3326 }
else if (ElementTy->isVariableArrayType()) {
3327 const VariableArrayType *VAT =
3328 getASTContext().getAsVariableArrayType(ElementTy);
3329 Dimensions.push_back(llvm::APInt(32, 0));
3331 }
else if (ElementTy->isDependentSizedArrayType()) {
3333 const DependentSizedArrayType *DSAT =
3334 getASTContext().getAsDependentSizedArrayType(ElementTy);
3344 mangleNumber(Dimensions.size());
3345 for (
const llvm::APInt &Dimension : Dimensions)
3346 mangleNumber(Dimension.getLimitedValue());
3347 mangleType(ElementTy, SourceRange(), QMM_Escape);
3350void MicrosoftCXXNameMangler::mangleType(
const ArrayParameterType *
T,
3351 Qualifiers, SourceRange) {
3358void MicrosoftCXXNameMangler::mangleType(
const MemberPointerType *
T,
3359 Qualifiers Quals, SourceRange Range) {
3361 manglePointerCVQualifiers(Quals);
3362 manglePointerExtQualifiers(Quals, PointeeType);
3363 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
3365 mangleName(
T->getMostRecentCXXRecordDecl());
3366 mangleFunctionType(FPT,
nullptr,
true);
3369 mangleName(
T->getMostRecentCXXRecordDecl());
3370 mangleType(PointeeType, Range, QMM_Drop);
3374void MicrosoftCXXNameMangler::mangleType(
const TemplateTypeParmType *
T,
3375 Qualifiers, SourceRange Range) {
3378 llvm::SmallString<64> Name;
3380 Name += llvm::utostr(
T->getDepth());
3382 Name += llvm::utostr(
T->getIndex());
3384 mangleSourceName(Name);
3387void MicrosoftCXXNameMangler::mangleType(
const SubstTemplateTypeParmPackType *
T,
3388 Qualifiers, SourceRange Range) {
3392void MicrosoftCXXNameMangler::mangleType(
const SubstBuiltinTemplatePackType *
T,
3393 Qualifiers, SourceRange Range) {
3394 Error(
Range.getBegin(),
"substituted builtin template pack") <<
Range;
3400void MicrosoftCXXNameMangler::mangleType(
const PointerType *
T, Qualifiers Quals,
3401 SourceRange Range) {
3403 manglePointerCVQualifiers(Quals);
3404 manglePointerExtQualifiers(Quals, PointeeType);
3405 manglePointerAuthQualifier(Quals);
3411 mangleType(PointeeType, Range);
3413 mangleAddressSpaceType(PointeeType, PointeeType.
getQualifiers(), Range);
3416void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectPointerType *
T,
3417 Qualifiers Quals, SourceRange Range) {
3426 return mangleObjCLifetime(PointeeType, Quals, Range);
3428 manglePointerCVQualifiers(Quals);
3429 manglePointerExtQualifiers(Quals, PointeeType);
3430 mangleType(PointeeType, Range);
3436void MicrosoftCXXNameMangler::mangleType(
const LValueReferenceType *
T,
3437 Qualifiers Quals, SourceRange Range) {
3441 manglePointerExtQualifiers(Quals, PointeeType);
3442 mangleType(PointeeType, Range);
3448void MicrosoftCXXNameMangler::mangleType(
const RValueReferenceType *
T,
3449 Qualifiers Quals, SourceRange Range) {
3453 manglePointerExtQualifiers(Quals, PointeeType);
3454 mangleType(PointeeType, Range);
3457void MicrosoftCXXNameMangler::mangleType(
const ComplexType *
T, Qualifiers,
3458 SourceRange Range) {
3459 QualType ElementType =
T->getElementType();
3461 llvm::SmallString<64> TemplateMangling;
3462 llvm::raw_svector_ostream Stream(TemplateMangling);
3463 MicrosoftCXXNameMangler
Extra(Context, Stream);
3465 Extra.mangleSourceName(
"_Complex");
3466 Extra.mangleType(ElementType, Range, QMM_Escape);
3468 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3476bool MicrosoftCXXNameMangler::isArtificialTagType(QualType
T)
const {
3477 const Type *ty =
T.getTypePtr();
3482 case Type::Vector: {
3491void MicrosoftCXXNameMangler::mangleType(
const VectorType *
T, Qualifiers Quals,
3492 SourceRange Range) {
3493 QualType EltTy =
T->getElementType();
3494 const BuiltinType *ET = EltTy->
getAs<BuiltinType>();
3495 const BitIntType *BitIntTy = EltTy->
getAs<BitIntType>();
3496 assert((ET || BitIntTy) &&
3497 "vectors with non-builtin/_BitInt elements are unsupported");
3498 uint64_t Width = getASTContext().getTypeSize(
T);
3501 size_t OutSizeBefore =
Out.tell();
3503 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
3504 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3505 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3506 }
else if (Width >= 128) {
3507 if (ET->
getKind() == BuiltinType::Float)
3508 mangleArtificialTagType(TagTypeKind::Union,
3509 "__m" + llvm::utostr(Width));
3510 else if (ET->
getKind() == BuiltinType::LongLong)
3511 mangleArtificialTagType(TagTypeKind::Union,
3512 "__m" + llvm::utostr(Width) +
'i');
3513 else if (ET->
getKind() == BuiltinType::Double)
3514 mangleArtificialTagType(TagTypeKind::Struct,
3515 "__m" + llvm::utostr(Width) +
'd');
3520 bool IsBuiltin =
Out.tell() != OutSizeBefore;
3526 llvm::SmallString<64> TemplateMangling;
3527 llvm::raw_svector_ostream Stream(TemplateMangling);
3528 MicrosoftCXXNameMangler
Extra(Context, Stream);
3530 Extra.mangleSourceName(
"__vector");
3531 Extra.mangleType(QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3533 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumElements()));
3535 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3539void MicrosoftCXXNameMangler::mangleType(
const ExtVectorType *
T,
3540 Qualifiers Quals, SourceRange Range) {
3541 mangleType(
static_cast<const VectorType *
>(
T), Quals, Range);
3544void MicrosoftCXXNameMangler::mangleType(
const DependentVectorType *
T,
3545 Qualifiers, SourceRange Range) {
3549void MicrosoftCXXNameMangler::mangleType(
const DependentSizedExtVectorType *
T,
3550 Qualifiers, SourceRange Range) {
3551 Error(
Range.getBegin(),
"dependent-sized extended vector type") <<
Range;
3554void MicrosoftCXXNameMangler::mangleType(
const ConstantMatrixType *
T,
3555 Qualifiers quals, SourceRange Range) {
3556 QualType EltTy =
T->getElementType();
3558 llvm::SmallString<64> TemplateMangling;
3559 llvm::raw_svector_ostream Stream(TemplateMangling);
3560 MicrosoftCXXNameMangler
Extra(Context, Stream);
3564 Extra.mangleSourceName(
"__matrix");
3565 Extra.mangleType(EltTy, Range, QMM_Escape);
3567 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumRows()));
3568 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumColumns()));
3570 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3573void MicrosoftCXXNameMangler::mangleType(
const DependentSizedMatrixType *
T,
3574 Qualifiers quals, SourceRange Range) {
3578void MicrosoftCXXNameMangler::mangleType(
const DependentAddressSpaceType *
T,
3579 Qualifiers, SourceRange Range) {
3583void MicrosoftCXXNameMangler::mangleType(
const ObjCInterfaceType *
T, Qualifiers,
3586 mangleTagTypeKind(TagTypeKind::Struct);
3587 mangleName(
T->getDecl());
3590void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectType *
T,
3591 Qualifiers Quals, SourceRange Range) {
3592 if (
T->isKindOfType())
3593 return mangleObjCKindOfType(
T, Quals, Range);
3595 if (
T->qual_empty() && !
T->isSpecialized())
3596 return mangleType(
T->getBaseType(), Range, QMM_Drop);
3598 ArgBackRefMap OuterFunArgsContext;
3599 ArgBackRefMap OuterTemplateArgsContext;
3600 BackRefVec OuterTemplateContext;
3602 FunArgBackReferences.swap(OuterFunArgsContext);
3603 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3604 NameBackReferences.swap(OuterTemplateContext);
3606 mangleTagTypeKind(TagTypeKind::Struct);
3610 mangleSourceName(
"objc_object");
3611 else if (
T->isObjCClass())
3612 mangleSourceName(
"objc_class");
3614 mangleSourceName(
T->getInterface()->getName());
3616 for (
const auto &Q :
T->quals())
3617 mangleObjCProtocol(Q);
3619 if (
T->isSpecialized())
3620 for (
const auto &TA :
T->getTypeArgs())
3621 mangleType(TA, Range, QMM_Drop);
3627 FunArgBackReferences.swap(OuterFunArgsContext);
3628 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3629 NameBackReferences.swap(OuterTemplateContext);
3632void MicrosoftCXXNameMangler::mangleType(
const BlockPointerType *
T,
3633 Qualifiers Quals, SourceRange Range) {
3635 manglePointerCVQualifiers(Quals);
3636 manglePointerExtQualifiers(Quals, PointeeType);
3640 mangleFunctionType(PointeeType->
castAs<FunctionProtoType>());
3643void MicrosoftCXXNameMangler::mangleType(
const InjectedClassNameType *,
3644 Qualifiers, SourceRange) {
3645 llvm_unreachable(
"Cannot mangle injected class name type.");
3648void MicrosoftCXXNameMangler::mangleType(
const TemplateSpecializationType *
T,
3649 Qualifiers, SourceRange Range) {
3653void MicrosoftCXXNameMangler::mangleType(
const DependentNameType *
T, Qualifiers,
3654 SourceRange Range) {
3658void MicrosoftCXXNameMangler::mangleType(
const PackExpansionType *
T, Qualifiers,
3659 SourceRange Range) {
3663void MicrosoftCXXNameMangler::mangleType(
const PackIndexingType *
T,
3664 Qualifiers Quals, SourceRange Range) {
3665 manglePointerCVQualifiers(Quals);
3666 mangleType(
T->getSelectedType(), Range);
3669void MicrosoftCXXNameMangler::mangleType(
const TypeOfType *
T, Qualifiers,
3670 SourceRange Range) {
3674void MicrosoftCXXNameMangler::mangleType(
const TypeOfExprType *
T, Qualifiers,
3675 SourceRange Range) {
3679void MicrosoftCXXNameMangler::mangleType(
const DecltypeType *
T, Qualifiers,
3680 SourceRange Range) {
3684void MicrosoftCXXNameMangler::mangleType(
const UnaryTransformType *
T,
3685 Qualifiers, SourceRange Range) {
3689void MicrosoftCXXNameMangler::mangleType(
const AutoType *
T, Qualifiers,
3690 SourceRange Range) {
3691 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3696void MicrosoftCXXNameMangler::mangleType(
3697 const DeducedTemplateSpecializationType *
T, Qualifiers, SourceRange Range) {
3698 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3700 Error(
Range.getBegin(),
"deduced class template specialization type")
3704void MicrosoftCXXNameMangler::mangleType(
const AtomicType *
T, Qualifiers,
3705 SourceRange Range) {
3706 QualType ValueType =
T->getValueType();
3708 llvm::SmallString<64> TemplateMangling;
3709 llvm::raw_svector_ostream Stream(TemplateMangling);
3710 MicrosoftCXXNameMangler
Extra(Context, Stream);
3712 Extra.mangleSourceName(
"_Atomic");
3713 Extra.mangleType(ValueType, Range, QMM_Escape);
3715 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3718void MicrosoftCXXNameMangler::mangleType(
const PipeType *
T, Qualifiers,
3719 SourceRange Range) {
3720 QualType ElementType =
T->getElementType();
3722 llvm::SmallString<64> TemplateMangling;
3723 llvm::raw_svector_ostream Stream(TemplateMangling);
3724 MicrosoftCXXNameMangler
Extra(Context, Stream);
3726 Extra.mangleSourceName(
"ocl_pipe");
3727 Extra.mangleType(ElementType, Range, QMM_Escape);
3728 Extra.mangleIntegerLiteral(llvm::APSInt::get(
T->isReadOnly()));
3730 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3733void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
3736 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
3737 getASTContext().getSourceManager(),
3738 "Mangling declaration");
3740 msvc_hashing_ostream MHO(Out);
3742 if (
auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3744 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3745 return mangler.mangle(GD);
3748 if (
auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3750 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3751 return mangler.mangle(GD);
3754 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3755 return Mangler.mangle(GD);
3758void MicrosoftCXXNameMangler::mangleType(
const BitIntType *
T, Qualifiers,
3759 SourceRange Range) {
3760 llvm::SmallString<64> TemplateMangling;
3761 llvm::raw_svector_ostream Stream(TemplateMangling);
3762 MicrosoftCXXNameMangler
Extra(Context, Stream);
3764 if (
T->isUnsigned())
3765 Extra.mangleSourceName(
"_UBitInt");
3767 Extra.mangleSourceName(
"_BitInt");
3768 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumBits()));
3770 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3773void MicrosoftCXXNameMangler::mangleType(
const DependentBitIntType *
T,
3774 Qualifiers, SourceRange Range) {
3778void MicrosoftCXXNameMangler::mangleType(
const HLSLAttributedResourceType *
T,
3779 Qualifiers, SourceRange Range) {
3780 llvm_unreachable(
"HLSL uses Itanium name mangling");
3783void MicrosoftCXXNameMangler::mangleType(
const HLSLInlineSpirvType *
T,
3784 Qualifiers, SourceRange Range) {
3785 llvm_unreachable(
"HLSL uses Itanium name mangling");
3814 MicrosoftCXXNameMangler &Mangler,
3821 llvm_unreachable(
"Unsupported access specifier");
3832 Out <<
'R' << AccessSpec;
3833 Mangler.mangleNumber(
3835 Mangler.mangleNumber(
3837 Mangler.mangleNumber(
3839 Mangler.mangleNumber(
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3842 Mangler.mangleNumber(
3844 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3849 llvm_unreachable(
"Unsupported access specifier");
3859 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3863 llvm_unreachable(
"Unsupported access specifier");
3876void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
3877 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML,
3879 msvc_hashing_ostream MHO(Out);
3880 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3881 Mangler.getStream() <<
'?';
3882 Mangler.mangleVirtualMemPtrThunk(MD, ML);
3885void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
3886 const ThunkInfo &Thunk,
3889 msvc_hashing_ostream MHO(Out);
3890 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3891 Mangler.getStream() <<
'?';
3892 Mangler.mangleName(MD);
3901 assert(Thunk.
Method !=
nullptr &&
3902 "Thunk info should hold the overridee decl");
3904 const CXXMethodDecl *DeclForFPT = Thunk.
Method ? Thunk.
Method : MD;
3905 Mangler.mangleFunctionType(
3909void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
const CXXDestructorDecl *DD,
3911 const ThunkInfo &Thunk,
3918 msvc_hashing_ostream MHO(Out);
3919 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
3920 Mangler.getStream() <<
"??_E";
3922 auto &Adjustment = Thunk.
This;
3924 Mangler.mangleFunctionType(DD->
getType()->
castAs<FunctionProtoType>(), DD);
3927void MicrosoftMangleContextImpl::mangleCXXVFTable(
3928 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
3934 msvc_hashing_ostream MHO(Out);
3935 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3936 if (Derived->
hasAttr<DLLImportAttr>())
3937 Mangler.getStream() <<
"??_S";
3939 Mangler.getStream() <<
"??_7";
3940 Mangler.mangleName(Derived);
3941 Mangler.getStream() <<
"6B";
3942 for (
const CXXRecordDecl *RD : BasePath)
3943 Mangler.mangleName(RD);
3944 Mangler.getStream() <<
'@';
3947void MicrosoftMangleContextImpl::mangleCXXVTable(
const CXXRecordDecl *Derived,
3950 mangleCXXVFTable(Derived, {},
Out);
3953void MicrosoftMangleContextImpl::mangleCXXVBTable(
3954 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
3960 msvc_hashing_ostream MHO(Out);
3961 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3962 Mangler.getStream() <<
"??_8";
3963 Mangler.mangleName(Derived);
3964 Mangler.getStream() <<
"7B";
3965 for (
const CXXRecordDecl *RD : BasePath)
3966 Mangler.mangleName(RD);
3967 Mangler.getStream() <<
'@';
3970void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType
T, raw_ostream &Out) {
3971 msvc_hashing_ostream MHO(Out);
3972 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3973 Mangler.getStream() <<
"??_R0";
3974 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3975 Mangler.getStream() <<
"@8";
3978void MicrosoftMangleContextImpl::mangleCXXRTTIName(
3979 QualType
T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
3980 MicrosoftCXXNameMangler Mangler(*
this, Out);
3981 Mangler.getStream() <<
'.';
3982 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3985void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
3986 const CXXRecordDecl *SrcRD,
const CXXRecordDecl *DstRD, raw_ostream &Out) {
3987 msvc_hashing_ostream MHO(Out);
3988 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3989 Mangler.getStream() <<
"??_K";
3990 Mangler.mangleName(SrcRD);
3991 Mangler.getStream() <<
"$C";
3992 Mangler.mangleName(DstRD);
3995void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType
T,
bool IsConst,
3998 uint32_t NumEntries,
4000 msvc_hashing_ostream MHO(Out);
4001 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4002 Mangler.getStream() <<
"_TI";
4004 Mangler.getStream() <<
'C';
4006 Mangler.getStream() <<
'V';
4008 Mangler.getStream() <<
'U';
4009 Mangler.getStream() << NumEntries;
4010 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4013void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
4014 QualType
T, uint32_t NumEntries, raw_ostream &Out) {
4015 msvc_hashing_ostream MHO(Out);
4016 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4017 Mangler.getStream() <<
"_CTA";
4018 Mangler.getStream() << NumEntries;
4019 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4022void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4023 QualType
T,
const CXXConstructorDecl *CD,
CXXCtorType CT, uint32_t Size,
4024 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
4026 MicrosoftCXXNameMangler Mangler(*
this, Out);
4027 Mangler.getStream() <<
"_CT";
4029 llvm::SmallString<64> RTTIMangling;
4031 llvm::raw_svector_ostream Stream(RTTIMangling);
4032 msvc_hashing_ostream MHO(Stream);
4033 mangleCXXRTTI(
T, MHO);
4035 Mangler.getStream() << RTTIMangling;
4043 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4044 LangOptions::MSVC2015) &&
4045 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4046 LangOptions::MSVC2017_7);
4047 llvm::SmallString<64> CopyCtorMangling;
4048 if (!OmitCopyCtor && CD) {
4049 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4050 msvc_hashing_ostream MHO(Stream);
4051 mangleCXXName(GlobalDecl(CD, CT), MHO);
4053 Mangler.getStream() << CopyCtorMangling;
4055 Mangler.getStream() <<
Size;
4056 if (VBPtrOffset == -1) {
4058 Mangler.getStream() << NVOffset;
4061 Mangler.getStream() << NVOffset;
4062 Mangler.getStream() << VBPtrOffset;
4063 Mangler.getStream() << VBIndex;
4067void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4068 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
4069 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
4070 msvc_hashing_ostream MHO(Out);
4071 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4072 Mangler.getStream() <<
"??_R1";
4073 Mangler.mangleNumber(NVOffset);
4074 Mangler.mangleNumber(VBPtrOffset);
4075 Mangler.mangleNumber(VBTableOffset);
4076 Mangler.mangleNumber(Flags);
4077 Mangler.mangleName(Derived);
4078 Mangler.getStream() <<
"8";
4081void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4082 const CXXRecordDecl *Derived, raw_ostream &Out) {
4083 msvc_hashing_ostream MHO(Out);
4084 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4085 Mangler.getStream() <<
"??_R2";
4086 Mangler.mangleName(Derived);
4087 Mangler.getStream() <<
"8";
4090void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4091 const CXXRecordDecl *Derived, raw_ostream &Out) {
4092 msvc_hashing_ostream MHO(Out);
4093 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4094 Mangler.getStream() <<
"??_R3";
4095 Mangler.mangleName(Derived);
4096 Mangler.getStream() <<
"8";
4099void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4100 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4106 llvm::SmallString<64> VFTableMangling;
4107 llvm::raw_svector_ostream Stream(VFTableMangling);
4108 mangleCXXVFTable(Derived, BasePath, Stream);
4110 if (VFTableMangling.starts_with(
"??@")) {
4111 assert(VFTableMangling.ends_with(
"@"));
4112 Out << VFTableMangling <<
"??_R4@";
4116 assert(VFTableMangling.starts_with(
"??_7") ||
4117 VFTableMangling.starts_with(
"??_S"));
4119 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
4122void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4123 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4124 msvc_hashing_ostream MHO(Out);
4125 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4130 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
4131 Mangler.mangleName(EnclosingDecl);
4134void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4135 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4136 msvc_hashing_ostream MHO(Out);
4137 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4142 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
4143 Mangler.mangleName(EnclosingDecl);
4146void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4147 QualType
T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4150 MicrosoftCXXNameMangler Mangler(*
this, Out);
4151 Mangler.getStream() <<
'?';
4152 Mangler.mangleType(
T.getCanonicalType(), SourceRange());
4155void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4156 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
4157 msvc_hashing_ostream MHO(Out);
4158 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4160 Mangler.getStream() <<
"?";
4161 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
4162 Mangler.mangle(VD,
"");
4165void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4166 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
4167 msvc_hashing_ostream MHO(Out);
4168 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4170 Mangler.getStream() <<
"?";
4171 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
4172 Mangler.mangleNestedName(VD);
4173 Mangler.getStream() <<
"@4HA";
4176void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
4188 msvc_hashing_ostream MHO(Out);
4189 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4193 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
4195 Mangler.getStream() <<
"?$S1@";
4197 unsigned ScopeDepth = 0;
4198 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4202 Mangler.mangle(VD,
"");
4204 Mangler.mangleNestedName(VD);
4205 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
4207 Mangler.mangleNumber(ScopeDepth);
4210void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *D,
4213 msvc_hashing_ostream MHO(Out);
4214 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4215 Mangler.getStream() <<
"??__" << CharCode;
4217 Mangler.getStream() <<
'?';
4218 Mangler.mangleName(D);
4219 Mangler.mangleVariableEncoding(D);
4220 Mangler.getStream() <<
"@@";
4222 Mangler.mangleName(D);
4226 Mangler.getStream() <<
"YAXXZ";
4229void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *D,
4232 mangleInitFiniStub(D,
'E', Out);
4236MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *D,
4239 mangleInitFiniStub(D,
'F', Out);
4242void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4263 MicrosoftCXXNameMangler Mangler(*
this, Out);
4264 Mangler.getStream() <<
"??_C@_";
4272 unsigned StringLength =
4273 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4278 Mangler.getStream() <<
'1';
4280 Mangler.getStream() <<
'0';
4284 Mangler.mangleNumber(StringByteLength);
4286 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4288 if (Index / CharByteWidth >= SL->
getLength())
4289 return static_cast<char>(0);
4291 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4292 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4295 auto GetBigEndianByte = [&SL](
unsigned Index) {
4297 if (Index / CharByteWidth >= SL->
getLength())
4298 return static_cast<char>(0);
4300 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4301 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4306 for (
unsigned I = 0, E = StringByteLength; I != E; ++I)
4307 JC.update(GetLittleEndianByte(I));
4311 Mangler.mangleNumber(JC.getCRC());
4317 auto MangleByte = [&Mangler](
char Byte) {
4325 Mangler.getStream() << Byte;
4326 }
else if (
isLetter(Byte & 0x7f)) {
4327 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4329 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4330 ' ',
'\n',
'\t',
'\'',
'-'};
4331 const char *Pos = llvm::find(SpecialChars, Byte);
4332 if (Pos != std::end(SpecialChars)) {
4333 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4335 Mangler.getStream() <<
"?$";
4336 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4337 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4343 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4344 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4345 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4347 MangleByte(GetBigEndianByte(I));
4349 MangleByte(GetLittleEndianByte(I));
4352 Mangler.getStream() <<
'@';
4355void MicrosoftCXXNameMangler::mangleAutoReturnType(
const MemberPointerType *
T,
4358 manglePointerCVQualifiers(Quals);
4359 manglePointerExtQualifiers(Quals, PointeeType);
4360 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4362 mangleName(
T->getMostRecentCXXRecordDecl());
4363 mangleFunctionType(FPT,
nullptr,
true);
4366 mangleName(
T->getMostRecentCXXRecordDecl());
4367 mangleAutoReturnType(PointeeType, QMM_Drop);
4371void MicrosoftCXXNameMangler::mangleAutoReturnType(
const PointerType *
T,
4375 "Unexpected address space mangling required");
4377 manglePointerCVQualifiers(Quals);
4378 manglePointerExtQualifiers(Quals, PointeeType);
4380 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4382 mangleFunctionType(FPT);
4384 mangleAutoReturnType(PointeeType, QMM_Mangle);
4388void MicrosoftCXXNameMangler::mangleAutoReturnType(
const LValueReferenceType *
T,
4393 manglePointerExtQualifiers(Quals, PointeeType);
4394 mangleAutoReturnType(PointeeType, QMM_Mangle);
4397void MicrosoftCXXNameMangler::mangleAutoReturnType(
const RValueReferenceType *
T,
4402 manglePointerExtQualifiers(Quals, PointeeType);
4403 mangleAutoReturnType(PointeeType, QMM_Mangle);
4409 return new MicrosoftMangleContextImpl(Context, Diags, IsAux);
Enums/classes describing ABI related information about constructors, destructors and thunks.
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
static const GlobalDecl isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs)
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
llvm::MachO::Record Record
static ValueDecl * getAsArrayToPointerDecayedDecl(QualType T, const APValue &V)
If value V (with type T) represents a decayed pointer to the first element of an array,...
static void mangleThunkThisAdjustment(AccessSpecifier AS, const ThisAdjustment &Adjustment, MicrosoftCXXNameMangler &Mangler, raw_ostream &Out)
static bool hasAttr(const Decl *D, bool IgnoreImplicitAttr)
Defines the SourceManager interface.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APValue & getVectorElt(unsigned I)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
bool addressSpaceMapManglingFor(LangAS AS) const
const clang::PrintingPolicy & getPrintingPolicy() const
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
unsigned getTargetAddressSpace(LangAS AS) const
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Represents a block literal declaration, which is like an unnamed FunctionDecl.
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Decl * getLambdaContextDecl() const
Retrieve the declaration that provides additional context for a lambda, when the normal declaration c...
CXXRecordDecl * getMostRecentDecl()
bool isLambda() const
Determine whether this class describes a lambda function object.
unsigned getLambdaManglingNumber() const
If this is the closure type of a lambda expression, retrieve the number to be used for name mangling ...
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Represents a class template specialization, which refers to a class template with a given set of temp...
llvm::APInt getSize() const
Return the constant array size as an APInt.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
bool isFunctionOrMethod() const
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
@ CXXConversionFunctionName
NameKind getNameKind() const
Determine what kind of name this is.
Expr * getSizeExpr() const
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
This represents one expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isExternC() const
Determines whether this function is a function with external, C linkage.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
Qualifiers getMethodQuals() const
QualType getParamType(unsigned i) const
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
bool isVariadic() const
Whether this function prototype is variadic.
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
KernelReferenceKind getKernelReferenceKind() const
GlobalDecl getWithDecl(const Decl *D)
CXXDtorType getDtorType() const
const Decl * getDecl() const
StringRef getName() const
Return the actual identifier string.
An lvalue reference type, per C++11 [dcl.ref].
A pointer to member type per C++ 8.3.3 - Pointers to members.
static MicrosoftMangleContext * create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux=false)
MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D, bool IsAux=false)
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
bool isExternallyVisible() const
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents an Objective-C protocol declaration.
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void * getAsOpaquePtr() const
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
bool hasAddressSpace() const
PointerAuthQualifier getPointerAuth() const
bool hasObjCLifetime() const
ObjCLifetime getObjCLifetime() const
Qualifiers withoutObjCLifetime() const
LangAS getAddressSpace() const
An rvalue reference type, per C++11 [dcl.ref].
field_range fields() const
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const char * getStmtClassName() const
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
unsigned getCharByteWidth() const
Represents the declaration of a struct/union/class/enum.
TagDecl * getDefinition() const
Returns the TagDecl that actually defines this struct/union/class/enum.
TypedefNameDecl * getTypedefNameForAnonDecl() const
TagKind getTagKind() const
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
NamedDecl * getParam(unsigned Idx)
bool isBlockPointerType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
bool isMemberPointerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isFunctionType() const
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
TLSKind getTLSKind() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isStaticDataMember() const
Determines whether this is a static data member.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool isExternC() const
Determines whether this variable is a variable with external, C linkage.
Represents a variable template specialization, which refers to a variable template with a given set o...
Defines the clang::TargetInfo interface.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
CXXCtorType
C++ constructor types.
@ Ctor_DefaultClosure
Default closure variant of a ctor.
@ Ctor_CopyingClosure
Copying closure variant of a ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
RefQualifierKind
The kind of C++11 ref-qualifier associated with a function type.
@ RQ_None
No ref-qualifier was provided.
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
bool inheritanceModelHasNVOffsetField(bool IsMemberFunction, MSInheritanceModel Inheritance)
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
LanguageLinkage
Describes the different kinds of language linkage (C++ [dcl.link]) that an entity may have.
bool inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance)
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
bool inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance)
@ Result
The result type of a method or function.
const FunctionProtoType * T
CXXDtorType
C++ destructor types.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
TagTypeKind
The kind of a tag type.
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool isPtrSizeAddressSpace(LangAS AS)
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName)
Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...
int const char * function
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to.
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
uint64_t VBTableIndex
If nonzero, holds the vbtable index of the virtual base with the vfptr.
uint64_t Index
Method's index in the vftable.
A this pointer adjustment.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
const CXXMethodDecl * Method
Holds a pointer to the overridden method this thunk is for, if needed by the ABI to distinguish diffe...
ReturnAdjustment Return
The return adjustment.
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
struct clang::ThisAdjustment::VirtualAdjustment::@312251255113040203233347230177110330127151157305 Microsoft
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...