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) {
1499 llvm_unreachable(
"not expecting a COMDAT");
1501 llvm_unreachable(
"not expecting a unified dtor type");
1503 llvm_unreachable(
"Unsupported dtor type?");
1507 SourceLocation Loc) {
1512 case OO_New:
Out <<
"?2";
break;
1514 case OO_Delete:
Out <<
"?3";
break;
1516 case OO_Equal:
Out <<
"?4";
break;
1518 case OO_GreaterGreater:
Out <<
"?5";
break;
1520 case OO_LessLess:
Out <<
"?6";
break;
1522 case OO_Exclaim:
Out <<
"?7";
break;
1524 case OO_EqualEqual:
Out <<
"?8";
break;
1526 case OO_ExclaimEqual:
Out <<
"?9";
break;
1528 case OO_Subscript:
Out <<
"?A";
break;
1531 case OO_Arrow:
Out <<
"?C";
break;
1533 case OO_Star:
Out <<
"?D";
break;
1535 case OO_PlusPlus:
Out <<
"?E";
break;
1537 case OO_MinusMinus:
Out <<
"?F";
break;
1539 case OO_Minus:
Out <<
"?G";
break;
1541 case OO_Plus:
Out <<
"?H";
break;
1543 case OO_Amp:
Out <<
"?I";
break;
1545 case OO_ArrowStar:
Out <<
"?J";
break;
1547 case OO_Slash:
Out <<
"?K";
break;
1549 case OO_Percent:
Out <<
"?L";
break;
1551 case OO_Less:
Out <<
"?M";
break;
1553 case OO_LessEqual:
Out <<
"?N";
break;
1555 case OO_Greater:
Out <<
"?O";
break;
1557 case OO_GreaterEqual:
Out <<
"?P";
break;
1559 case OO_Comma:
Out <<
"?Q";
break;
1561 case OO_Call:
Out <<
"?R";
break;
1563 case OO_Tilde:
Out <<
"?S";
break;
1565 case OO_Caret:
Out <<
"?T";
break;
1567 case OO_Pipe:
Out <<
"?U";
break;
1569 case OO_AmpAmp:
Out <<
"?V";
break;
1571 case OO_PipePipe:
Out <<
"?W";
break;
1573 case OO_StarEqual:
Out <<
"?X";
break;
1575 case OO_PlusEqual:
Out <<
"?Y";
break;
1577 case OO_MinusEqual:
Out <<
"?Z";
break;
1579 case OO_SlashEqual:
Out <<
"?_0";
break;
1581 case OO_PercentEqual:
Out <<
"?_1";
break;
1583 case OO_GreaterGreaterEqual:
Out <<
"?_2";
break;
1585 case OO_LessLessEqual:
Out <<
"?_3";
break;
1587 case OO_AmpEqual:
Out <<
"?_4";
break;
1589 case OO_PipeEqual:
Out <<
"?_5";
break;
1591 case OO_CaretEqual:
Out <<
"?_6";
break;
1620 case OO_Array_New:
Out <<
"?_U";
break;
1622 case OO_Array_Delete:
Out <<
"?_V";
break;
1624 case OO_Coawait:
Out <<
"?__L";
break;
1626 case OO_Spaceship:
Out <<
"?__M";
break;
1628 case OO_Conditional: {
1629 Error(Loc,
"conditional operator");
1635 llvm_unreachable(
"Not an overloaded operator");
1639void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1641 BackRefVec::iterator
Found = llvm::find(NameBackReferences, Name);
1642 if (
Found == NameBackReferences.end()) {
1643 if (NameBackReferences.size() < 10)
1644 NameBackReferences.push_back(std::string(Name));
1647 Out << (
Found - NameBackReferences.begin());
1651void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1652 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1655void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1656 GlobalDecl GD,
const TemplateArgumentList &TemplateArgs) {
1662 ArgBackRefMap OuterFunArgsContext;
1663 ArgBackRefMap OuterTemplateArgsContext;
1664 BackRefVec OuterTemplateContext;
1665 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1666 NameBackReferences.swap(OuterTemplateContext);
1667 FunArgBackReferences.swap(OuterFunArgsContext);
1668 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1669 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1671 mangleUnscopedTemplateName(GD);
1675 NameBackReferences.swap(OuterTemplateContext);
1676 FunArgBackReferences.swap(OuterFunArgsContext);
1677 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1678 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1681void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {
1684 mangleUnqualifiedName(GD);
1687void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1688 const llvm::APSInt &
Value,
const NonTypeTemplateParmDecl *PD,
1689 QualType TemplateArgType) {
1698 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1699 LangOptions::MSVC2019) &&
1701 !TemplateArgType.
isNull()) {
1703 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
1708 mangleNumber(
Value);
1711void MicrosoftCXXNameMangler::mangleExpression(
1712 const Expr *E,
const NonTypeTemplateParmDecl *PD) {
1714 if (std::optional<llvm::APSInt>
Value =
1725void MicrosoftCXXNameMangler::mangleTemplateArgs(
1726 const TemplateDecl *TD,
const TemplateArgumentList &TemplateArgs) {
1729 assert(TPL->
size() == TemplateArgs.
size() &&
1730 "size mismatch between args and parms!");
1732 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1733 const TemplateArgument &TA = TemplateArgs[i];
1740 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1748 if (!
T->isPointerType() || !
V.isLValue() || !
V.hasLValuePath() ||
1752 QualType BaseT =
V.getLValueBase().getType();
1753 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1754 V.getLValuePath()[0].getAsArrayIndex() != 0)
1757 V.getLValueBase().dyn_cast<const ValueDecl *>());
1760void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1761 const TemplateArgument &TA,
1762 const NamedDecl *Parm) {
1800 llvm_unreachable(
"Can't mangle null template arguments!");
1802 llvm_unreachable(
"Can't mangle template expansion arguments!");
1805 mangleType(
T, SourceRange(), QMM_Escape);
1811 mangleMemberDataPointer(
1815 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1816 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1828 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1829 TPO->getValue(), TplArgKind::ClassNTTP);
1830 }
else if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1846 if (
const MemberPointerType *MPT =
T->
getAs<MemberPointerType>()) {
1847 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1848 if (MPT->isMemberFunctionPointerType() &&
1850 mangleMemberFunctionPointer(RD,
nullptr,
nullptr, QualType());
1853 if (MPT->isMemberDataPointer()) {
1855 mangleMemberDataPointer(RD,
nullptr,
nullptr, QualType());
1865 mangleIntegerLiteral(llvm::APSInt::get(-1),
1871 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1881 return mangleTemplateArg(
1887 ->getContainedDeducedType()) {
1893 TplArgKind::StructuralValue,
1901 if (TemplateArgs.empty()) {
1906 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(
1907 LangOptions::MSVC2015)
1913 llvm_unreachable(
"unexpected template parameter decl!");
1915 for (
const TemplateArgument &PA : TemplateArgs)
1916 mangleTemplateArg(TD, PA, Parm);
1921 const NamedDecl *ND =
1923 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1929 llvm_unreachable(
"unexpected template template NamedDecl!");
1936void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType
T,
1939 bool WithScalarType) {
1940 switch (
V.getKind()) {
1946 mangleType(
T, SourceRange(), QMM_Escape);
1952 mangleType(
T, SourceRange(), QMM_Escape);
1954 mangleNumber(
V.getInt());
1959 mangleType(
T, SourceRange(), QMM_Escape);
1960 mangleFloat(
V.getFloat());
1965 mangleType(
T, SourceRange(), QMM_Escape);
1967 APValue::LValueBase
Base =
V.getLValueBase();
1971 if (
V.isLValueOnePastTheEnd()) {
1973 auto *VD =
Base.dyn_cast<
const ValueDecl *>();
1980 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1982 if (
Base.isNull()) {
1988 mangleNumber(
V.getLValueOffset().getQuantity());
1989 }
else if (!
V.hasLValuePath()) {
1991 Error(
"template argument (extension not comaptible with ms mangler)");
1993 }
else if (
auto *VD =
Base.dyn_cast<
const ValueDecl*>()) {
1997 Error(
"template argument (undeclared base)");
2004 SmallVector<char, 2> EntryTypes;
2006 QualType ET =
Base.getType();
2007 for (APValue::LValuePathEntry E :
V.getLValuePath()) {
2009 EntryTypes.push_back(
'C');
2010 EntryManglers.push_back([
this, I = E.getAsArrayIndex()] {
2015 ET = AT->getElementType();
2019 const Decl *D = E.getAsBaseOrMember().getPointer();
2020 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2032 EntryTypes.push_back(
'6');
2033 EntryManglers.push_back([
this, D] {
2039 for (
auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
2042 auto *VD =
Base.dyn_cast<
const ValueDecl*>();
2044 Error(
"template argument (null value decl)");
2047 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
2061 mangleType(
T, SourceRange(), QMM_Escape);
2063 const CXXRecordDecl *RD =
2064 T->
castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
2065 const ValueDecl *D =
V.getMemberPointerDecl();
2066 if (TAK == TplArgKind::ClassNTTP) {
2068 mangleMemberDataPointerInClassNTTP(RD, D);
2070 mangleMemberFunctionPointerInClassNTTP(RD,
2071 cast_or_null<CXXMethodDecl>(D));
2074 mangleMemberDataPointer(RD, D,
nullptr, QualType(),
"");
2076 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D),
nullptr,
2084 mangleType(
T, SourceRange(), QMM_Escape);
2086 assert(RD &&
"unexpected type for record value");
2088 unsigned BaseIndex = 0;
2089 for (
const CXXBaseSpecifier &B : RD->
bases())
2090 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
2091 for (
const FieldDecl *FD : RD->
fields())
2092 if (!FD->isUnnamedBitField())
2093 mangleTemplateArgValue(FD->
getType(),
2094 V.getStructField(FD->getFieldIndex()), TAK,
2102 mangleType(
T, SourceRange(), QMM_Escape);
2103 if (
const FieldDecl *FD =
V.getUnionField()) {
2104 mangleUnqualifiedName(FD);
2105 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
2113 mangleType(
T, SourceRange(), QMM_Escape);
2115 mangleNumber(
V.getComplexIntReal());
2117 mangleNumber(
V.getComplexIntImag());
2123 mangleType(
T, SourceRange(), QMM_Escape);
2124 mangleFloat(
V.getComplexFloatReal());
2125 mangleFloat(
V.getComplexFloatImag());
2131 QualType ElemT = getASTContext().getAsArrayType(
T)->getElementType();
2132 mangleType(ElemT, SourceRange(), QMM_Escape);
2133 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
2134 const APValue &ElemV = I <
V.getArrayInitializedElts()
2135 ?
V.getArrayInitializedElt(I)
2136 :
V.getArrayFiller();
2137 mangleTemplateArgValue(ElemT, ElemV, TAK);
2148 mangleType(
T, SourceRange(), QMM_Escape);
2150 QualType ElemT =
T->
castAs<VectorType>()->getElementType();
2151 mangleType(ElemT, SourceRange(), QMM_Escape);
2152 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
2154 mangleTemplateArgValue(ElemT, ElemV, TAK);
2162 Error(
"template argument (value type: address label diff)");
2167 Error(
"template argument (value type: fixed point)");
2173void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2174 llvm::SmallString<64> TemplateMangling;
2175 llvm::raw_svector_ostream Stream(TemplateMangling);
2176 MicrosoftCXXNameMangler
Extra(Context, Stream);
2179 Extra.mangleSourceName(
"Protocol");
2180 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2182 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2185void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType
Type,
2187 SourceRange Range) {
2188 llvm::SmallString<64> TemplateMangling;
2189 llvm::raw_svector_ostream Stream(TemplateMangling);
2190 MicrosoftCXXNameMangler
Extra(Context, Stream);
2198 Extra.mangleSourceName(
"Autoreleasing");
2201 Extra.mangleSourceName(
"Strong");
2204 Extra.mangleSourceName(
"Weak");
2207 Extra.manglePointerCVQualifiers(Quals);
2208 Extra.manglePointerExtQualifiers(Quals,
Type);
2211 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2214void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *
T,
2216 SourceRange Range) {
2217 llvm::SmallString<64> TemplateMangling;
2218 llvm::raw_svector_ostream Stream(TemplateMangling);
2219 MicrosoftCXXNameMangler
Extra(Context, Stream);
2222 Extra.mangleSourceName(
"KindOf");
2223 Extra.mangleType(QualType(
T, 0)
2224 .stripObjCKindOfType(getASTContext())
2225 ->castAs<ObjCObjectType>(),
2228 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2231void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
2289 if (HasConst && HasVolatile) {
2291 }
else if (HasVolatile) {
2293 }
else if (HasConst) {
2299 if (HasConst && HasVolatile) {
2301 }
else if (HasVolatile) {
2303 }
else if (HasConst) {
2314MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2317 switch (RefQualifier) {
2331void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
2332 QualType PointeeType) {
2334 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2347void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {
2353 mangleNumber(PointerAuth.
getKey());
2358void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
2366 if (HasConst && HasVolatile) {
2368 }
else if (HasVolatile) {
2370 }
else if (HasConst) {
2377void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType
T,
2378 SourceRange Range) {
2387 if (
const auto *DT =
T->
getAs<DecayedType>()) {
2388 QualType OriginalType = DT->getOriginalType();
2391 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2392 OriginalType = getASTContext().getIncompleteArrayType(
2393 AT->getElementType(), AT->getSizeModifier(),
2394 AT->getIndexTypeCVRQualifiers());
2405 TypePtr =
T.getCanonicalType().getAsOpaquePtr();
2408 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2410 if (
Found == FunArgBackReferences.end()) {
2411 size_t OutSizeBefore =
Out.tell();
2413 mangleType(
T, Range, QMM_Drop);
2418 bool LongerThanOneChar = (
Out.tell() - OutSizeBefore > 1);
2419 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2420 size_t Size = FunArgBackReferences.size();
2421 FunArgBackReferences[TypePtr] =
Size;
2428void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2429 const PassObjectSizeAttr *POSA) {
2430 int Type = POSA->getType();
2431 bool Dynamic = POSA->isDynamic();
2433 auto Iter = PassObjectSizeArgs.insert({
Type,
Dynamic}).first;
2434 auto *TypePtr = (
const void *)&*Iter;
2435 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2437 if (
Found == FunArgBackReferences.end()) {
2439 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2440 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2443 if (FunArgBackReferences.size() < 10) {
2444 size_t Size = FunArgBackReferences.size();
2445 FunArgBackReferences[TypePtr] =
Size;
2452void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType
T,
2454 SourceRange Range) {
2469 llvm::SmallString<32> ASMangling;
2470 llvm::raw_svector_ostream Stream(ASMangling);
2471 MicrosoftCXXNameMangler
Extra(Context, Stream);
2477 Extra.mangleSourceName(
"_AS");
2478 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2482 llvm_unreachable(
"Not a language specific address space");
2483 case LangAS::opencl_global:
2484 Extra.mangleSourceName(
"_ASCLglobal");
2486 case LangAS::opencl_global_device:
2487 Extra.mangleSourceName(
"_ASCLdevice");
2489 case LangAS::opencl_global_host:
2490 Extra.mangleSourceName(
"_ASCLhost");
2492 case LangAS::opencl_local:
2493 Extra.mangleSourceName(
"_ASCLlocal");
2495 case LangAS::opencl_constant:
2496 Extra.mangleSourceName(
"_ASCLconstant");
2498 case LangAS::opencl_private:
2499 Extra.mangleSourceName(
"_ASCLprivate");
2501 case LangAS::opencl_generic:
2502 Extra.mangleSourceName(
"_ASCLgeneric");
2504 case LangAS::cuda_device:
2505 Extra.mangleSourceName(
"_ASCUdevice");
2507 case LangAS::cuda_constant:
2508 Extra.mangleSourceName(
"_ASCUconstant");
2510 case LangAS::cuda_shared:
2511 Extra.mangleSourceName(
"_ASCUshared");
2513 case LangAS::ptr32_sptr:
2514 case LangAS::ptr32_uptr:
2516 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2520 Extra.mangleType(
T, Range, QMM_Escape);
2521 mangleQualifiers(Qualifiers(),
false);
2522 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2525void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType
T,
2526 QualifierMangleMode QMM) {
2527 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2528 LangOptions::MSVC2019) &&
2529 "Cannot mangle MSVC 2017 auto return types!");
2533 Qualifiers Quals =
T.getLocalQualifiers();
2535 if (QMM == QMM_Result)
2537 if (QMM != QMM_Drop)
2538 mangleQualifiers(Quals,
false);
2539 Out << (AT->isDecltypeAuto() ?
"_T" :
"_P");
2543 T =
T.getDesugaredType(getASTContext());
2544 Qualifiers Quals =
T.getLocalQualifiers();
2551 mangleQualifiers(Quals,
false);
2554 llvm_unreachable(
"QMM_Escape unexpected");
2557 const Type *ty =
T.getTypePtr();
2559 case Type::MemberPointer:
2565 case Type::LValueReference:
2568 case Type::RValueReference:
2572 llvm_unreachable(
"Invalid type expected");
2576void MicrosoftCXXNameMangler::mangleType(QualType
T, SourceRange Range,
2577 QualifierMangleMode QMM) {
2580 T =
T.getDesugaredType(getASTContext());
2581 Qualifiers Quals =
T.getLocalQualifiers();
2583 if (
const ArrayType *AT = getASTContext().getAsArrayType(
T)) {
2586 if (QMM == QMM_Mangle)
2588 else if (QMM == QMM_Escape || QMM == QMM_Result)
2590 mangleArrayType(AT);
2603 if (
const FunctionType *FT = dyn_cast<FunctionType>(
T)) {
2605 mangleFunctionType(FT);
2608 mangleQualifiers(Quals,
false);
2611 if (!IsPointer && Quals) {
2613 mangleQualifiers(Quals,
false);
2621 if ((!IsPointer && Quals) ||
isa<TagType>(
T) || isArtificialTagType(
T)) {
2623 mangleQualifiers(Quals,
false);
2628 const Type *ty =
T.getTypePtr();
2631#define ABSTRACT_TYPE(CLASS, PARENT)
2632#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2634 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2636#define TYPE(CLASS, PARENT) \
2638 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2640#include "clang/AST/TypeNodes.inc"
2642#undef NON_CANONICAL_TYPE
2647void MicrosoftCXXNameMangler::mangleType(
const BuiltinType *
T, Qualifiers,
2648 SourceRange Range) {
2676 switch (
T->getKind()) {
2677 case BuiltinType::Void:
2680 case BuiltinType::SChar:
2683 case BuiltinType::Char_U:
2684 case BuiltinType::Char_S:
2687 case BuiltinType::UChar:
2690 case BuiltinType::Short:
2693 case BuiltinType::UShort:
2696 case BuiltinType::Int:
2699 case BuiltinType::UInt:
2702 case BuiltinType::Long:
2705 case BuiltinType::ULong:
2708 case BuiltinType::Float:
2711 case BuiltinType::Double:
2715 case BuiltinType::LongDouble:
2718 case BuiltinType::LongLong:
2721 case BuiltinType::ULongLong:
2724 case BuiltinType::Int128:
2727 case BuiltinType::UInt128:
2730 case BuiltinType::Bool:
2733 case BuiltinType::Char8:
2736 case BuiltinType::Char16:
2739 case BuiltinType::Char32:
2742 case BuiltinType::WChar_S:
2743 case BuiltinType::WChar_U:
2747#define BUILTIN_TYPE(Id, SingletonId)
2748#define PLACEHOLDER_TYPE(Id, SingletonId) \
2749 case BuiltinType::Id:
2750#include "clang/AST/BuiltinTypes.def"
2751 case BuiltinType::Dependent:
2752 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2754 case BuiltinType::ObjCId:
2755 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2757 case BuiltinType::ObjCClass:
2758 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2760 case BuiltinType::ObjCSel:
2761 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2764#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2765 case BuiltinType::Id: \
2766 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2768#include "clang/Basic/OpenCLImageTypes.def"
2769 case BuiltinType::OCLSampler:
2771 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2773 case BuiltinType::OCLEvent:
2775 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2777 case BuiltinType::OCLClkEvent:
2779 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2781 case BuiltinType::OCLQueue:
2783 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2785 case BuiltinType::OCLReserveID:
2787 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2789#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2790 case BuiltinType::Id: \
2791 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2793#include "clang/Basic/OpenCLExtensionTypes.def"
2795 case BuiltinType::NullPtr:
2799 case BuiltinType::Float16:
2800 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2803 case BuiltinType::Half:
2804 if (!getASTContext().getLangOpts().
HLSL)
2805 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2806 else if (getASTContext().getLangOpts().NativeHalfType)
2812 case BuiltinType::BFloat16:
2813 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2816 case BuiltinType::MFloat8:
2817 mangleArtificialTagType(TagTypeKind::Struct,
"__mfp8", {
"__clang"});
2820#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2821 case BuiltinType::Id: \
2822 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2823 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2826#include "clang/Basic/WebAssemblyReferenceTypes.def"
2828#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2829 case BuiltinType::Id: \
2830 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2832#include "clang/Basic/HLSLIntangibleTypes.def"
2834#define SVE_TYPE(Name, Id, SingletonId) \
2835 case BuiltinType::Id: \
2836 mangleArtificialTagType(TagTypeKind::Struct, #Name, {"__clang"}); \
2838#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits)
2839#include "clang/Basic/AArch64ACLETypes.def"
2851void MicrosoftCXXNameMangler::mangleType(
const FunctionProtoType *
T, Qualifiers,
2858 mangleFunctionType(
T,
nullptr,
true);
2861 mangleFunctionType(
T);
2864void MicrosoftCXXNameMangler::mangleType(
const FunctionNoProtoType *
T,
2865 Qualifiers, SourceRange) {
2867 mangleFunctionType(
T);
2870void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *
T,
2871 const FunctionDecl *D,
2872 bool ForceThisQuals,
2873 bool MangleExceptionSpec) {
2876 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(
T);
2881 bool IsInLambda =
false;
2882 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
2884 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
2888 HasThisQuals =
true;
2897 CC = getASTContext().getDefaultCallingConvention(
2906 manglePointerExtQualifiers(Quals, QualType());
2908 mangleQualifiers(Quals,
false);
2911 mangleCallingConvention(CC, Range);
2923 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
2932 if (IsCtorClosure) {
2942 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
2944 ->
castAs<LValueReferenceType>()
2950 llvm_unreachable(
"unexpected constructor closure!");
2956 }
else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(D)) {
2967 mangleType(ResultType, Range, QMM_Result);
2968 }
else if (IsInLambda) {
2970 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2971 "shouldn't need to mangle __auto_type!");
2975 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
2981 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2982 "shouldn't need to mangle __auto_type!");
2988 auto UseClangMangling = [](QualType ResultType) {
2989 QualType
T = ResultType;
2992 if (
T.getQualifiers().hasAddressSpace())
2998 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
2999 LangOptions::MSVC2019) &&
3000 !UseClangMangling(ResultType)) {
3009 ->
castAs<FunctionProtoType>();
3012 mangleAutoReturnType(ResultType, QMM_Result);
3018 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3024 mangleType(ResultType, Range, QMM_Result);
3040 for (
unsigned I = 0, E = Proto->
getNumParams(); I != E; ++I) {
3045 mangleFunctionArgumentType(Proto->
getParamType(I), Range);
3056 manglePassObjectSizeArg(P);
3065 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
3066 getASTContext().getLangOpts().isCompatibleWithMSVC(
3067 LangOptions::MSVC2017_5))
3068 mangleThrowSpecification(Proto);
3073void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
3098 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3108 llvm_unreachable(
"Unsupported access specifier");
3137void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC,
3138 SourceRange Range) {
3200 if (getASTContext().getLangOpts().RegCall4)
3209void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *
T,
3210 SourceRange Range) {
3214void MicrosoftCXXNameMangler::mangleThrowSpecification(
3215 const FunctionProtoType *FT) {
3224void MicrosoftCXXNameMangler::mangleType(
const UnresolvedUsingType *
T,
3225 Qualifiers, SourceRange Range) {
3236void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
3238 case TagTypeKind::Union:
3241 case TagTypeKind::Struct:
3242 case TagTypeKind::Interface:
3245 case TagTypeKind::Class:
3248 case TagTypeKind::Enum:
3253void MicrosoftCXXNameMangler::mangleType(
const EnumType *
T, Qualifiers,
3257void MicrosoftCXXNameMangler::mangleType(
const RecordType *
T, Qualifiers,
3261void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3271void MicrosoftCXXNameMangler::mangleArtificialTagType(
3273 ArrayRef<StringRef> NestedNames) {
3275 mangleTagTypeKind(TK);
3278 mangleSourceName(UnqualifiedName);
3280 for (StringRef N : llvm::reverse(NestedNames))
3281 mangleSourceName(N);
3294void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *
T) {
3297 manglePointerCVQualifiers(
T->getElementType().getQualifiers());
3298 mangleType(
T->getElementType(), SourceRange());
3300void MicrosoftCXXNameMangler::mangleType(
const ConstantArrayType *
T, Qualifiers,
3302 llvm_unreachable(
"Should have been special cased");
3304void MicrosoftCXXNameMangler::mangleType(
const VariableArrayType *
T, Qualifiers,
3306 llvm_unreachable(
"Should have been special cased");
3308void MicrosoftCXXNameMangler::mangleType(
const DependentSizedArrayType *
T,
3309 Qualifiers, SourceRange) {
3310 llvm_unreachable(
"Should have been special cased");
3312void MicrosoftCXXNameMangler::mangleType(
const IncompleteArrayType *
T,
3313 Qualifiers, SourceRange) {
3314 llvm_unreachable(
"Should have been special cased");
3316void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *
T) {
3317 QualType ElementTy(
T, 0);
3318 SmallVector<llvm::APInt, 3> Dimensions;
3320 if (ElementTy->isConstantArrayType()) {
3321 const ConstantArrayType *CAT =
3322 getASTContext().getAsConstantArrayType(ElementTy);
3323 Dimensions.push_back(CAT->
getSize());
3325 }
else if (ElementTy->isIncompleteArrayType()) {
3326 const IncompleteArrayType *IAT =
3327 getASTContext().getAsIncompleteArrayType(ElementTy);
3328 Dimensions.push_back(llvm::APInt(32, 0));
3330 }
else if (ElementTy->isVariableArrayType()) {
3331 const VariableArrayType *VAT =
3332 getASTContext().getAsVariableArrayType(ElementTy);
3333 Dimensions.push_back(llvm::APInt(32, 0));
3335 }
else if (ElementTy->isDependentSizedArrayType()) {
3337 const DependentSizedArrayType *DSAT =
3338 getASTContext().getAsDependentSizedArrayType(ElementTy);
3348 mangleNumber(Dimensions.size());
3349 for (
const llvm::APInt &Dimension : Dimensions)
3350 mangleNumber(Dimension.getLimitedValue());
3351 mangleType(ElementTy, SourceRange(), QMM_Escape);
3354void MicrosoftCXXNameMangler::mangleType(
const ArrayParameterType *
T,
3355 Qualifiers, SourceRange) {
3362void MicrosoftCXXNameMangler::mangleType(
const MemberPointerType *
T,
3363 Qualifiers Quals, SourceRange Range) {
3365 manglePointerCVQualifiers(Quals);
3366 manglePointerExtQualifiers(Quals, PointeeType);
3367 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
3369 mangleName(
T->getMostRecentCXXRecordDecl());
3370 mangleFunctionType(FPT,
nullptr,
true);
3373 mangleName(
T->getMostRecentCXXRecordDecl());
3374 mangleType(PointeeType, Range, QMM_Drop);
3378void MicrosoftCXXNameMangler::mangleType(
const TemplateTypeParmType *
T,
3379 Qualifiers, SourceRange Range) {
3382 llvm::SmallString<64> Name;
3384 Name += llvm::utostr(
T->getDepth());
3386 Name += llvm::utostr(
T->getIndex());
3388 mangleSourceName(Name);
3391void MicrosoftCXXNameMangler::mangleType(
const SubstTemplateTypeParmPackType *
T,
3392 Qualifiers, SourceRange Range) {
3396void MicrosoftCXXNameMangler::mangleType(
const SubstBuiltinTemplatePackType *
T,
3397 Qualifiers, SourceRange Range) {
3398 Error(
Range.getBegin(),
"substituted builtin template pack") <<
Range;
3404void MicrosoftCXXNameMangler::mangleType(
const PointerType *
T, Qualifiers Quals,
3405 SourceRange Range) {
3407 manglePointerCVQualifiers(Quals);
3408 manglePointerExtQualifiers(Quals, PointeeType);
3409 manglePointerAuthQualifier(Quals);
3415 mangleType(PointeeType, Range);
3417 mangleAddressSpaceType(PointeeType, PointeeType.
getQualifiers(), Range);
3420void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectPointerType *
T,
3421 Qualifiers Quals, SourceRange Range) {
3430 return mangleObjCLifetime(PointeeType, Quals, Range);
3432 manglePointerCVQualifiers(Quals);
3433 manglePointerExtQualifiers(Quals, PointeeType);
3434 mangleType(PointeeType, Range);
3440void MicrosoftCXXNameMangler::mangleType(
const LValueReferenceType *
T,
3441 Qualifiers Quals, SourceRange Range) {
3445 manglePointerExtQualifiers(Quals, PointeeType);
3446 mangleType(PointeeType, Range);
3452void MicrosoftCXXNameMangler::mangleType(
const RValueReferenceType *
T,
3453 Qualifiers Quals, SourceRange Range) {
3457 manglePointerExtQualifiers(Quals, PointeeType);
3458 mangleType(PointeeType, Range);
3461void MicrosoftCXXNameMangler::mangleType(
const ComplexType *
T, Qualifiers,
3462 SourceRange Range) {
3463 QualType ElementType =
T->getElementType();
3465 llvm::SmallString<64> TemplateMangling;
3466 llvm::raw_svector_ostream Stream(TemplateMangling);
3467 MicrosoftCXXNameMangler
Extra(Context, Stream);
3469 Extra.mangleSourceName(
"_Complex");
3470 Extra.mangleType(ElementType, Range, QMM_Escape);
3472 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3480bool MicrosoftCXXNameMangler::isArtificialTagType(QualType
T)
const {
3481 const Type *ty =
T.getTypePtr();
3486 case Type::Vector: {
3495void MicrosoftCXXNameMangler::mangleType(
const VectorType *
T, Qualifiers Quals,
3496 SourceRange Range) {
3497 QualType EltTy =
T->getElementType();
3498 const BuiltinType *ET = EltTy->
getAs<BuiltinType>();
3499 const BitIntType *BitIntTy = EltTy->
getAs<BitIntType>();
3500 assert((ET || BitIntTy) &&
3501 "vectors with non-builtin/_BitInt elements are unsupported");
3502 uint64_t Width = getASTContext().getTypeSize(
T);
3505 size_t OutSizeBefore =
Out.tell();
3507 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
3508 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3509 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3510 }
else if (Width >= 128) {
3511 if (ET->
getKind() == BuiltinType::Float)
3512 mangleArtificialTagType(TagTypeKind::Union,
3513 "__m" + llvm::utostr(Width));
3514 else if (ET->
getKind() == BuiltinType::LongLong)
3515 mangleArtificialTagType(TagTypeKind::Union,
3516 "__m" + llvm::utostr(Width) +
'i');
3517 else if (ET->
getKind() == BuiltinType::Double)
3518 mangleArtificialTagType(TagTypeKind::Struct,
3519 "__m" + llvm::utostr(Width) +
'd');
3524 bool IsBuiltin =
Out.tell() != OutSizeBefore;
3530 llvm::SmallString<64> TemplateMangling;
3531 llvm::raw_svector_ostream Stream(TemplateMangling);
3532 MicrosoftCXXNameMangler
Extra(Context, Stream);
3534 Extra.mangleSourceName(
"__vector");
3535 Extra.mangleType(QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3537 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumElements()));
3539 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3543void MicrosoftCXXNameMangler::mangleType(
const ExtVectorType *
T,
3544 Qualifiers Quals, SourceRange Range) {
3545 mangleType(
static_cast<const VectorType *
>(
T), Quals, Range);
3548void MicrosoftCXXNameMangler::mangleType(
const DependentVectorType *
T,
3549 Qualifiers, SourceRange Range) {
3553void MicrosoftCXXNameMangler::mangleType(
const DependentSizedExtVectorType *
T,
3554 Qualifiers, SourceRange Range) {
3555 Error(
Range.getBegin(),
"dependent-sized extended vector type") <<
Range;
3558void MicrosoftCXXNameMangler::mangleType(
const ConstantMatrixType *
T,
3559 Qualifiers quals, SourceRange Range) {
3560 QualType EltTy =
T->getElementType();
3562 llvm::SmallString<64> TemplateMangling;
3563 llvm::raw_svector_ostream Stream(TemplateMangling);
3564 MicrosoftCXXNameMangler
Extra(Context, Stream);
3568 Extra.mangleSourceName(
"__matrix");
3569 Extra.mangleType(EltTy, Range, QMM_Escape);
3571 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumRows()));
3572 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumColumns()));
3574 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3577void MicrosoftCXXNameMangler::mangleType(
const DependentSizedMatrixType *
T,
3578 Qualifiers quals, SourceRange Range) {
3582void MicrosoftCXXNameMangler::mangleType(
const DependentAddressSpaceType *
T,
3583 Qualifiers, SourceRange Range) {
3587void MicrosoftCXXNameMangler::mangleType(
const ObjCInterfaceType *
T, Qualifiers,
3590 mangleTagTypeKind(TagTypeKind::Struct);
3591 mangleName(
T->getDecl());
3594void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectType *
T,
3595 Qualifiers Quals, SourceRange Range) {
3596 if (
T->isKindOfType())
3597 return mangleObjCKindOfType(
T, Quals, Range);
3599 if (
T->qual_empty() && !
T->isSpecialized())
3600 return mangleType(
T->getBaseType(), Range, QMM_Drop);
3602 ArgBackRefMap OuterFunArgsContext;
3603 ArgBackRefMap OuterTemplateArgsContext;
3604 BackRefVec OuterTemplateContext;
3606 FunArgBackReferences.swap(OuterFunArgsContext);
3607 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3608 NameBackReferences.swap(OuterTemplateContext);
3610 mangleTagTypeKind(TagTypeKind::Struct);
3614 mangleSourceName(
"objc_object");
3615 else if (
T->isObjCClass())
3616 mangleSourceName(
"objc_class");
3618 mangleSourceName(
T->getInterface()->getName());
3620 for (
const auto &Q :
T->quals())
3621 mangleObjCProtocol(Q);
3623 if (
T->isSpecialized())
3624 for (
const auto &TA :
T->getTypeArgs())
3625 mangleType(TA, Range, QMM_Drop);
3631 FunArgBackReferences.swap(OuterFunArgsContext);
3632 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3633 NameBackReferences.swap(OuterTemplateContext);
3636void MicrosoftCXXNameMangler::mangleType(
const BlockPointerType *
T,
3637 Qualifiers Quals, SourceRange Range) {
3639 manglePointerCVQualifiers(Quals);
3640 manglePointerExtQualifiers(Quals, PointeeType);
3644 mangleFunctionType(PointeeType->
castAs<FunctionProtoType>());
3647void MicrosoftCXXNameMangler::mangleType(
const InjectedClassNameType *,
3648 Qualifiers, SourceRange) {
3649 llvm_unreachable(
"Cannot mangle injected class name type.");
3652void MicrosoftCXXNameMangler::mangleType(
const TemplateSpecializationType *
T,
3653 Qualifiers, SourceRange Range) {
3657void MicrosoftCXXNameMangler::mangleType(
const DependentNameType *
T, Qualifiers,
3658 SourceRange Range) {
3662void MicrosoftCXXNameMangler::mangleType(
const PackExpansionType *
T, Qualifiers,
3663 SourceRange Range) {
3667void MicrosoftCXXNameMangler::mangleType(
const PackIndexingType *
T,
3668 Qualifiers Quals, SourceRange Range) {
3669 manglePointerCVQualifiers(Quals);
3670 mangleType(
T->getSelectedType(), Range);
3673void MicrosoftCXXNameMangler::mangleType(
const TypeOfType *
T, Qualifiers,
3674 SourceRange Range) {
3678void MicrosoftCXXNameMangler::mangleType(
const TypeOfExprType *
T, Qualifiers,
3679 SourceRange Range) {
3683void MicrosoftCXXNameMangler::mangleType(
const DecltypeType *
T, Qualifiers,
3684 SourceRange Range) {
3688void MicrosoftCXXNameMangler::mangleType(
const UnaryTransformType *
T,
3689 Qualifiers, SourceRange Range) {
3693void MicrosoftCXXNameMangler::mangleType(
const AutoType *
T, Qualifiers,
3694 SourceRange Range) {
3695 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3700void MicrosoftCXXNameMangler::mangleType(
3701 const DeducedTemplateSpecializationType *
T, Qualifiers, SourceRange Range) {
3702 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3704 Error(
Range.getBegin(),
"deduced class template specialization type")
3708void MicrosoftCXXNameMangler::mangleType(
const AtomicType *
T, Qualifiers,
3709 SourceRange Range) {
3710 QualType ValueType =
T->getValueType();
3712 llvm::SmallString<64> TemplateMangling;
3713 llvm::raw_svector_ostream Stream(TemplateMangling);
3714 MicrosoftCXXNameMangler
Extra(Context, Stream);
3716 Extra.mangleSourceName(
"_Atomic");
3717 Extra.mangleType(ValueType, Range, QMM_Escape);
3719 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3722void MicrosoftCXXNameMangler::mangleType(
const PipeType *
T, Qualifiers,
3723 SourceRange Range) {
3724 QualType ElementType =
T->getElementType();
3726 llvm::SmallString<64> TemplateMangling;
3727 llvm::raw_svector_ostream Stream(TemplateMangling);
3728 MicrosoftCXXNameMangler
Extra(Context, Stream);
3730 Extra.mangleSourceName(
"ocl_pipe");
3731 Extra.mangleType(ElementType, Range, QMM_Escape);
3732 Extra.mangleIntegerLiteral(llvm::APSInt::get(
T->isReadOnly()));
3734 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3737void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
3740 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
3741 getASTContext().getSourceManager(),
3742 "Mangling declaration");
3744 msvc_hashing_ostream MHO(Out);
3746 if (
auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3748 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3749 return mangler.mangle(GD);
3752 if (
auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3754 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3755 return mangler.mangle(GD);
3758 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3759 return Mangler.mangle(GD);
3762void MicrosoftCXXNameMangler::mangleType(
const BitIntType *
T, Qualifiers,
3763 SourceRange Range) {
3764 llvm::SmallString<64> TemplateMangling;
3765 llvm::raw_svector_ostream Stream(TemplateMangling);
3766 MicrosoftCXXNameMangler
Extra(Context, Stream);
3768 if (
T->isUnsigned())
3769 Extra.mangleSourceName(
"_UBitInt");
3771 Extra.mangleSourceName(
"_BitInt");
3772 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumBits()));
3774 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3777void MicrosoftCXXNameMangler::mangleType(
const DependentBitIntType *
T,
3778 Qualifiers, SourceRange Range) {
3782void MicrosoftCXXNameMangler::mangleType(
const HLSLAttributedResourceType *
T,
3783 Qualifiers, SourceRange Range) {
3784 llvm_unreachable(
"HLSL uses Itanium name mangling");
3787void MicrosoftCXXNameMangler::mangleType(
const HLSLInlineSpirvType *
T,
3788 Qualifiers, SourceRange Range) {
3789 llvm_unreachable(
"HLSL uses Itanium name mangling");
3818 MicrosoftCXXNameMangler &Mangler,
3825 llvm_unreachable(
"Unsupported access specifier");
3836 Out <<
'R' << AccessSpec;
3837 Mangler.mangleNumber(
3839 Mangler.mangleNumber(
3841 Mangler.mangleNumber(
3843 Mangler.mangleNumber(
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3846 Mangler.mangleNumber(
3848 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3853 llvm_unreachable(
"Unsupported access specifier");
3863 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3867 llvm_unreachable(
"Unsupported access specifier");
3880void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
3881 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML,
3883 msvc_hashing_ostream MHO(Out);
3884 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3885 Mangler.getStream() <<
'?';
3886 Mangler.mangleVirtualMemPtrThunk(MD, ML);
3889void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
3890 const ThunkInfo &Thunk,
3893 msvc_hashing_ostream MHO(Out);
3894 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3895 Mangler.getStream() <<
'?';
3896 Mangler.mangleName(MD);
3905 assert(Thunk.
Method !=
nullptr &&
3906 "Thunk info should hold the overridee decl");
3908 const CXXMethodDecl *DeclForFPT = Thunk.
Method ? Thunk.
Method : MD;
3909 Mangler.mangleFunctionType(
3913void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
const CXXDestructorDecl *DD,
3915 const ThunkInfo &Thunk,
3922 msvc_hashing_ostream MHO(Out);
3923 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
3924 Mangler.getStream() <<
"??_E";
3926 auto &Adjustment = Thunk.
This;
3928 Mangler.mangleFunctionType(DD->
getType()->
castAs<FunctionProtoType>(), DD);
3931void MicrosoftMangleContextImpl::mangleCXXVFTable(
3932 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
3938 msvc_hashing_ostream MHO(Out);
3939 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3940 if (Derived->
hasAttr<DLLImportAttr>())
3941 Mangler.getStream() <<
"??_S";
3943 Mangler.getStream() <<
"??_7";
3944 Mangler.mangleName(Derived);
3945 Mangler.getStream() <<
"6B";
3946 for (
const CXXRecordDecl *RD : BasePath)
3947 Mangler.mangleName(RD);
3948 Mangler.getStream() <<
'@';
3951void MicrosoftMangleContextImpl::mangleCXXVTable(
const CXXRecordDecl *Derived,
3954 mangleCXXVFTable(Derived, {},
Out);
3957void MicrosoftMangleContextImpl::mangleCXXVBTable(
3958 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
3964 msvc_hashing_ostream MHO(Out);
3965 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3966 Mangler.getStream() <<
"??_8";
3967 Mangler.mangleName(Derived);
3968 Mangler.getStream() <<
"7B";
3969 for (
const CXXRecordDecl *RD : BasePath)
3970 Mangler.mangleName(RD);
3971 Mangler.getStream() <<
'@';
3974void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType
T, raw_ostream &Out) {
3975 msvc_hashing_ostream MHO(Out);
3976 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3977 Mangler.getStream() <<
"??_R0";
3978 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3979 Mangler.getStream() <<
"@8";
3982void MicrosoftMangleContextImpl::mangleCXXRTTIName(
3983 QualType
T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
3984 MicrosoftCXXNameMangler Mangler(*
this, Out);
3985 Mangler.getStream() <<
'.';
3986 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3989void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
3990 const CXXRecordDecl *SrcRD,
const CXXRecordDecl *DstRD, raw_ostream &Out) {
3991 msvc_hashing_ostream MHO(Out);
3992 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3993 Mangler.getStream() <<
"??_K";
3994 Mangler.mangleName(SrcRD);
3995 Mangler.getStream() <<
"$C";
3996 Mangler.mangleName(DstRD);
3999void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType
T,
bool IsConst,
4002 uint32_t NumEntries,
4004 msvc_hashing_ostream MHO(Out);
4005 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4006 Mangler.getStream() <<
"_TI";
4008 Mangler.getStream() <<
'C';
4010 Mangler.getStream() <<
'V';
4012 Mangler.getStream() <<
'U';
4013 Mangler.getStream() << NumEntries;
4014 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4017void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
4018 QualType
T, uint32_t NumEntries, raw_ostream &Out) {
4019 msvc_hashing_ostream MHO(Out);
4020 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4021 Mangler.getStream() <<
"_CTA";
4022 Mangler.getStream() << NumEntries;
4023 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4026void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4027 QualType
T,
const CXXConstructorDecl *CD,
CXXCtorType CT, uint32_t Size,
4028 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
4030 MicrosoftCXXNameMangler Mangler(*
this, Out);
4031 Mangler.getStream() <<
"_CT";
4033 llvm::SmallString<64> RTTIMangling;
4035 llvm::raw_svector_ostream Stream(RTTIMangling);
4036 msvc_hashing_ostream MHO(Stream);
4037 mangleCXXRTTI(
T, MHO);
4039 Mangler.getStream() << RTTIMangling;
4047 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4048 LangOptions::MSVC2015) &&
4049 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4050 LangOptions::MSVC2017_7);
4051 llvm::SmallString<64> CopyCtorMangling;
4052 if (!OmitCopyCtor && CD) {
4053 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4054 msvc_hashing_ostream MHO(Stream);
4055 mangleCXXName(GlobalDecl(CD, CT), MHO);
4057 Mangler.getStream() << CopyCtorMangling;
4059 Mangler.getStream() <<
Size;
4060 if (VBPtrOffset == -1) {
4062 Mangler.getStream() << NVOffset;
4065 Mangler.getStream() << NVOffset;
4066 Mangler.getStream() << VBPtrOffset;
4067 Mangler.getStream() << VBIndex;
4071void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4072 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
4073 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
4074 msvc_hashing_ostream MHO(Out);
4075 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4076 Mangler.getStream() <<
"??_R1";
4077 Mangler.mangleNumber(NVOffset);
4078 Mangler.mangleNumber(VBPtrOffset);
4079 Mangler.mangleNumber(VBTableOffset);
4080 Mangler.mangleNumber(Flags);
4081 Mangler.mangleName(Derived);
4082 Mangler.getStream() <<
"8";
4085void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4086 const CXXRecordDecl *Derived, raw_ostream &Out) {
4087 msvc_hashing_ostream MHO(Out);
4088 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4089 Mangler.getStream() <<
"??_R2";
4090 Mangler.mangleName(Derived);
4091 Mangler.getStream() <<
"8";
4094void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4095 const CXXRecordDecl *Derived, raw_ostream &Out) {
4096 msvc_hashing_ostream MHO(Out);
4097 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4098 Mangler.getStream() <<
"??_R3";
4099 Mangler.mangleName(Derived);
4100 Mangler.getStream() <<
"8";
4103void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4104 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4110 llvm::SmallString<64> VFTableMangling;
4111 llvm::raw_svector_ostream Stream(VFTableMangling);
4112 mangleCXXVFTable(Derived, BasePath, Stream);
4114 if (VFTableMangling.starts_with(
"??@")) {
4115 assert(VFTableMangling.ends_with(
"@"));
4116 Out << VFTableMangling <<
"??_R4@";
4120 assert(VFTableMangling.starts_with(
"??_7") ||
4121 VFTableMangling.starts_with(
"??_S"));
4123 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
4126void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4127 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4128 msvc_hashing_ostream MHO(Out);
4129 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4134 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
4135 Mangler.mangleName(EnclosingDecl);
4138void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4139 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4140 msvc_hashing_ostream MHO(Out);
4141 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4146 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
4147 Mangler.mangleName(EnclosingDecl);
4150void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4151 QualType
T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4154 MicrosoftCXXNameMangler Mangler(*
this, Out);
4155 Mangler.getStream() <<
'?';
4156 Mangler.mangleType(
T.getCanonicalType(), SourceRange());
4159void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4160 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
4161 msvc_hashing_ostream MHO(Out);
4162 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4164 Mangler.getStream() <<
"?";
4165 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
4166 Mangler.mangle(VD,
"");
4169void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4170 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
4171 msvc_hashing_ostream MHO(Out);
4172 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4174 Mangler.getStream() <<
"?";
4175 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
4176 Mangler.mangleNestedName(VD);
4177 Mangler.getStream() <<
"@4HA";
4180void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
4192 msvc_hashing_ostream MHO(Out);
4193 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4197 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
4199 Mangler.getStream() <<
"?$S1@";
4201 unsigned ScopeDepth = 0;
4202 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4206 Mangler.mangle(VD,
"");
4208 Mangler.mangleNestedName(VD);
4209 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
4211 Mangler.mangleNumber(ScopeDepth);
4214void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *D,
4217 msvc_hashing_ostream MHO(Out);
4218 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4219 Mangler.getStream() <<
"??__" << CharCode;
4221 Mangler.getStream() <<
'?';
4222 Mangler.mangleName(D);
4223 Mangler.mangleVariableEncoding(D);
4224 Mangler.getStream() <<
"@@";
4226 Mangler.mangleName(D);
4230 Mangler.getStream() <<
"YAXXZ";
4233void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *D,
4236 mangleInitFiniStub(D,
'E', Out);
4240MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *D,
4243 mangleInitFiniStub(D,
'F', Out);
4246void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4267 MicrosoftCXXNameMangler Mangler(*
this, Out);
4268 Mangler.getStream() <<
"??_C@_";
4276 unsigned StringLength =
4277 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4282 Mangler.getStream() <<
'1';
4284 Mangler.getStream() <<
'0';
4288 Mangler.mangleNumber(StringByteLength);
4290 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4292 if (Index / CharByteWidth >= SL->
getLength())
4293 return static_cast<char>(0);
4295 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4296 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4299 auto GetBigEndianByte = [&SL](
unsigned Index) {
4301 if (Index / CharByteWidth >= SL->
getLength())
4302 return static_cast<char>(0);
4304 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4305 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4310 for (
unsigned I = 0, E = StringByteLength; I != E; ++I)
4311 JC.update(GetLittleEndianByte(I));
4315 Mangler.mangleNumber(JC.getCRC());
4321 auto MangleByte = [&Mangler](
char Byte) {
4329 Mangler.getStream() << Byte;
4330 }
else if (
isLetter(Byte & 0x7f)) {
4331 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4333 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4334 ' ',
'\n',
'\t',
'\'',
'-'};
4335 const char *Pos = llvm::find(SpecialChars, Byte);
4336 if (Pos != std::end(SpecialChars)) {
4337 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4339 Mangler.getStream() <<
"?$";
4340 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4341 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4347 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4348 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4349 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4351 MangleByte(GetBigEndianByte(I));
4353 MangleByte(GetLittleEndianByte(I));
4356 Mangler.getStream() <<
'@';
4359void MicrosoftCXXNameMangler::mangleAutoReturnType(
const MemberPointerType *
T,
4362 manglePointerCVQualifiers(Quals);
4363 manglePointerExtQualifiers(Quals, PointeeType);
4364 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4366 mangleName(
T->getMostRecentCXXRecordDecl());
4367 mangleFunctionType(FPT,
nullptr,
true);
4370 mangleName(
T->getMostRecentCXXRecordDecl());
4371 mangleAutoReturnType(PointeeType, QMM_Drop);
4375void MicrosoftCXXNameMangler::mangleAutoReturnType(
const PointerType *
T,
4379 "Unexpected address space mangling required");
4381 manglePointerCVQualifiers(Quals);
4382 manglePointerExtQualifiers(Quals, PointeeType);
4384 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4386 mangleFunctionType(FPT);
4388 mangleAutoReturnType(PointeeType, QMM_Mangle);
4392void MicrosoftCXXNameMangler::mangleAutoReturnType(
const LValueReferenceType *
T,
4397 manglePointerExtQualifiers(Quals, PointeeType);
4398 mangleAutoReturnType(PointeeType, QMM_Mangle);
4401void MicrosoftCXXNameMangler::mangleAutoReturnType(
const RValueReferenceType *
T,
4406 manglePointerExtQualifiers(Quals, PointeeType);
4407 mangleAutoReturnType(PointeeType, QMM_Mangle);
4413 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_VectorDeleting
Vector deleting dtor.
@ 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...