33#include "llvm/ADT/SmallVector.h"
34#include "llvm/ADT/StringExtras.h"
35#include "llvm/Support/CRC.h"
36#include "llvm/Support/MD5.h"
37#include "llvm/Support/StringSaver.h"
38#include "llvm/Support/xxhash.h"
49 if (
auto *CD = dyn_cast<CXXConstructorDecl>(DC))
51 else if (
auto *DD = dyn_cast<CXXDestructorDecl>(DC))
58struct msvc_hashing_ostream :
public llvm::raw_svector_ostream {
61 llvm::SmallString<64> Buffer;
63 msvc_hashing_ostream(raw_ostream &OS,
size_t Threshold = 4096)
64 : llvm::raw_svector_ostream(Buffer), OS(OS), Threshold(Threshold) {}
65 ~msvc_hashing_ostream()
override {
66 StringRef MangledName = str();
67 bool StartsWithEscape = MangledName.starts_with(
"\01");
69 MangledName = MangledName.drop_front(1);
70 if (MangledName.size() < Threshold) {
76 llvm::MD5::MD5Result Hash;
77 Hasher.update(MangledName);
80 SmallString<32> HexString;
81 llvm::MD5::stringifyResult(Hash, HexString);
85 OS <<
"??@" << HexString <<
'@';
90getLambdaDefaultArgumentDeclContext(
const Decl *D) {
91 if (
const auto *RD = dyn_cast<CXXRecordDecl>(D))
93 if (
const auto *Parm =
94 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
95 return Parm->getDeclContext();
108 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))
112 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
114 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
115 return ContextParam->getDeclContext();
121 return getEffectiveDeclContext(
cast<Decl>(DC));
128 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
132 if (
const auto *FTD = FD->getPrimaryTemplate())
133 return FTD->getTemplatedDecl()->getCanonicalDecl();
135 return FD->getCanonicalDecl();
141 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
142 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
143 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
144 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
145 llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
146 llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
147 SmallString<16> AnonymousNamespaceHash;
150 MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags,
152 bool shouldMangleCXXName(
const NamedDecl *D)
override;
153 bool shouldMangleStringLiteral(
const StringLiteral *SL)
override;
154 void mangleCXXName(GlobalDecl GD, raw_ostream &Out)
override;
155 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
156 const MethodVFTableLocation &ML,
157 raw_ostream &Out)
override;
158 void mangleThunk(
const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
159 bool ElideOverrideInfo, raw_ostream &)
override;
161 const ThunkInfo &Thunk,
bool ElideOverrideInfo,
162 raw_ostream &)
override;
163 void mangleCXXVFTable(
const CXXRecordDecl *Derived,
164 ArrayRef<const CXXRecordDecl *> BasePath,
165 raw_ostream &Out)
override;
166 void mangleCXXVBTable(
const CXXRecordDecl *Derived,
167 ArrayRef<const CXXRecordDecl *> BasePath,
168 raw_ostream &Out)
override;
170 void mangleCXXVTable(
const CXXRecordDecl *, raw_ostream &)
override;
171 void mangleCXXVirtualDisplacementMap(
const CXXRecordDecl *SrcRD,
172 const CXXRecordDecl *DstRD,
173 raw_ostream &Out)
override;
174 void mangleCXXThrowInfo(QualType
T,
bool IsConst,
bool IsVolatile,
175 bool IsUnaligned,
uint32_t NumEntries,
176 raw_ostream &Out)
override;
177 void mangleCXXCatchableTypeArray(QualType
T,
uint32_t NumEntries,
178 raw_ostream &Out)
override;
179 void mangleCXXCatchableType(QualType
T,
const CXXConstructorDecl *CD,
182 raw_ostream &Out)
override;
183 void mangleCXXRTTI(QualType
T, raw_ostream &Out)
override;
184 void mangleCXXRTTIName(QualType
T, raw_ostream &Out,
185 bool NormalizeIntegers)
override;
186 void mangleCXXRTTIBaseClassDescriptor(
const CXXRecordDecl *Derived,
189 raw_ostream &Out)
override;
190 void mangleCXXRTTIBaseClassArray(
const CXXRecordDecl *Derived,
191 raw_ostream &Out)
override;
192 void mangleCXXRTTIClassHierarchyDescriptor(
const CXXRecordDecl *Derived,
193 raw_ostream &Out)
override;
195 mangleCXXRTTICompleteObjectLocator(
const CXXRecordDecl *Derived,
196 ArrayRef<const CXXRecordDecl *> BasePath,
197 raw_ostream &Out)
override;
198 void mangleCanonicalTypeName(QualType
T, raw_ostream &,
199 bool NormalizeIntegers)
override;
200 void mangleReferenceTemporary(
const VarDecl *,
unsigned ManglingNumber,
201 raw_ostream &)
override;
202 void mangleStaticGuardVariable(
const VarDecl *D, raw_ostream &Out)
override;
203 void mangleThreadSafeStaticGuardVariable(
const VarDecl *D,
unsigned GuardNum,
204 raw_ostream &Out)
override;
205 void mangleDynamicInitializer(
const VarDecl *D, raw_ostream &Out)
override;
206 void mangleDynamicAtExitDestructor(
const VarDecl *D,
207 raw_ostream &Out)
override;
208 void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
209 raw_ostream &Out)
override;
210 void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
211 raw_ostream &Out)
override;
212 void mangleStringLiteral(
const StringLiteral *SL, raw_ostream &Out)
override;
213 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
214 const DeclContext *DC = getEffectiveDeclContext(ND);
220 if (
const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
221 if (RD->isLambda()) {
229 disc = getASTContext().getManglingNumber(ND, isAux());
234 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
235 if (!
Tag->hasNameForLinkage() &&
236 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
237 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))
242 unsigned &discriminator = Uniquifier[ND];
244 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
245 disc = discriminator + 1;
249 std::string getLambdaString(
const CXXRecordDecl *Lambda)
override {
250 assert(Lambda->
isLambda() &&
"RD must be a lambda!");
251 std::string Name(
"<lambda_");
256 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
257 const FunctionDecl *
Func =
261 unsigned DefaultArgNo =
263 Name += llvm::utostr(DefaultArgNo);
267 if (LambdaManglingNumber)
268 LambdaId = LambdaManglingNumber;
270 LambdaId = getLambdaIdForDebugInfo(Lambda);
272 Name += llvm::utostr(LambdaId);
277 unsigned getLambdaId(
const CXXRecordDecl *RD) {
278 assert(RD->
isLambda() &&
"RD must be a lambda!");
281 "RD must not have a mangling number!");
282 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator,
bool>
283 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
284 return Result.first->second;
287 unsigned getLambdaIdForDebugInfo(
const CXXRecordDecl *RD) {
288 assert(RD->
isLambda() &&
"RD must be a lambda!");
291 "RD must not have a mangling number!");
293 return LambdaIds.lookup(RD);
298 StringRef getAnonymousNamespaceHash()
const {
299 return AnonymousNamespaceHash;
303 void mangleInitFiniStub(
const VarDecl *D,
char CharCode, raw_ostream &Out);
308class MicrosoftCXXNameMangler {
309 MicrosoftMangleContextImpl &Context;
315 const NamedDecl *Structor;
316 unsigned StructorType;
318 typedef llvm::SmallVector<std::string, 10> BackRefVec;
319 BackRefVec NameBackReferences;
321 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
322 ArgBackRefMap FunArgBackReferences;
323 ArgBackRefMap TemplateArgBackReferences;
325 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
326 TemplateArgStringMap TemplateArgStrings;
327 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
328 llvm::StringSaver TemplateArgStringStorage;
330 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
331 PassObjectSizeArgsSet PassObjectSizeArgs;
333 ASTContext &getASTContext()
const {
return Context.getASTContext(); }
335 const bool PointersAre64Bit;
337 DiagnosticBuilder
Error(SourceLocation, StringRef, StringRef);
338 DiagnosticBuilder
Error(SourceLocation, StringRef);
339 DiagnosticBuilder
Error(StringRef);
342 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
343 enum class TplArgKind { ClassNTTP, StructuralValue };
345 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_)
346 : Context(
C), Out(Out_), Structor(
nullptr), StructorType(-1),
347 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
348 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
351 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
353 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
354 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
355 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
358 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
360 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
361 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
362 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
365 raw_ostream &getStream()
const {
return Out; }
367 void mangle(GlobalDecl GD, StringRef Prefix =
"?");
368 void mangleName(GlobalDecl GD);
369 void mangleFunctionEncoding(GlobalDecl GD,
bool ShouldMangle);
370 void mangleVariableEncoding(
const VarDecl *VD);
371 void mangleMemberDataPointer(
const CXXRecordDecl *RD,
const ValueDecl *VD,
372 const NonTypeTemplateParmDecl *PD,
373 QualType TemplateArgType,
374 StringRef Prefix =
"$");
375 void mangleMemberDataPointerInClassNTTP(
const CXXRecordDecl *,
377 void mangleMemberFunctionPointer(
const CXXRecordDecl *RD,
378 const CXXMethodDecl *MD,
379 const NonTypeTemplateParmDecl *PD,
380 QualType TemplateArgType,
381 StringRef Prefix =
"$");
382 void mangleFunctionPointer(
const FunctionDecl *FD,
383 const NonTypeTemplateParmDecl *PD,
384 QualType TemplateArgType);
385 void mangleVarDecl(
const VarDecl *VD,
const NonTypeTemplateParmDecl *PD,
386 QualType TemplateArgType);
387 void mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD,
388 const CXXMethodDecl *MD);
389 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
390 const MethodVFTableLocation &ML);
391 void mangleNumber(int64_t Number);
392 void mangleNumber(llvm::APSInt Number);
393 void mangleFloat(llvm::APFloat Number);
394 void mangleBits(llvm::APInt Number);
396 void mangleArtificialTagType(
TagTypeKind TK, StringRef UnqualifiedName,
397 ArrayRef<StringRef> NestedNames = {});
398 void mangleAddressSpaceType(QualType
T, Qualifiers Quals, SourceRange Range);
399 void mangleType(QualType
T, SourceRange Range,
400 QualifierMangleMode QMM = QMM_Mangle);
401 void mangleFunctionType(
const FunctionType *
T,
402 const FunctionDecl *D =
nullptr,
403 bool ForceThisQuals =
false,
404 bool MangleExceptionSpec =
true);
405 void mangleSourceName(StringRef Name);
406 void mangleNestedName(GlobalDecl GD);
408 void mangleAutoReturnType(QualType
T, QualifierMangleMode QMM);
411 bool isStructorDecl(
const NamedDecl *ND)
const {
412 return ND == Structor || getStructor(ND) == Structor;
415 bool is64BitPointer(Qualifiers Quals)
const {
417 return AddrSpace == LangAS::ptr64 ||
418 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||
419 AddrSpace == LangAS::ptr32_uptr));
422 void mangleUnqualifiedName(GlobalDecl GD) {
425 void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name);
428 void mangleQualifiers(Qualifiers Quals,
bool IsMember);
430 void manglePointerCVQualifiers(Qualifiers Quals);
431 void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType);
432 void manglePointerAuthQualifier(Qualifiers Quals);
434 void mangleUnscopedTemplateName(GlobalDecl GD);
436 mangleTemplateInstantiationName(GlobalDecl GD,
437 const TemplateArgumentList &TemplateArgs);
440 void mangleFunctionArgumentType(QualType
T, SourceRange Range);
441 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
443 bool isArtificialTagType(QualType
T)
const;
446#define ABSTRACT_TYPE(CLASS, PARENT)
447#define NON_CANONICAL_TYPE(CLASS, PARENT)
448#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
451#include "clang/AST/TypeNodes.inc"
453#undef NON_CANONICAL_TYPE
456 void mangleType(
const TagDecl *TD);
457 void mangleDecayedArrayType(
const ArrayType *
T);
462 void mangleIntegerLiteral(
const llvm::APSInt &Number,
473 bool WithScalarType =
false);
488MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(
ASTContext &Context,
508 SmallString<256> Path(FE->getName());
510 clang::Preprocessor::processPathForFileMacro(Path, Context.getLangOpts(),
511 Context.getTargetInfo());
514 uint32_t TruncatedHash = uint32_t(xxh3_64bits(Path));
515 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
518 AnonymousNamespaceHash =
"0";
522bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *D) {
523 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
526 if (FD->hasAttr<OverloadableAttr>())
538 if (FD->isMSVCRTEntryPoint())
552 if (!getASTContext().getLangOpts().
CPlusPlus)
555 const VarDecl *VD = dyn_cast<VarDecl>(D);
562 const DeclContext *DC = getEffectiveDeclContext(D);
572MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
576DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
579 DiagnosticsEngine &Diags = Context.getDiags();
580 return Diags.
Report(loc, diag::err_ms_mangle_unsupported_with_detail)
584DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
586 DiagnosticsEngine &Diags = Context.getDiags();
587 return Diags.
Report(loc, diag::err_ms_mangle_unsupported) << thingy;
590DiagnosticBuilder MicrosoftCXXNameMangler::Error(StringRef thingy) {
591 DiagnosticsEngine &Diags = Context.getDiags();
593 return Diags.
Report(diag::err_ms_mangle_unsupported) << thingy;
596void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) {
607 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
608 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
609 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
610 mangleVariableEncoding(VD);
614 Out <<
"3U__s_GUID@@B";
619 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
622void MicrosoftCXXNameMangler::mangleFunctionEncoding(GlobalDecl GD,
634 const FunctionProtoType *FT = FD->
getType()->
castAs<FunctionProtoType>();
647 mangleFunctionClass(FD);
649 mangleFunctionType(FT, FD,
false,
false);
655void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
686 mangleType(Ty, SR, QMM_Drop);
687 manglePointerExtQualifiers(
689 if (
const MemberPointerType *MPT = Ty->
getAs<MemberPointerType>()) {
690 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
693 mangleName(MPT->getMostRecentCXXRecordDecl());
696 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
698 mangleDecayedArrayType(AT);
699 if (AT->getElementType()->isArrayType())
704 mangleType(Ty, SR, QMM_Drop);
709void MicrosoftCXXNameMangler::mangleMemberDataPointer(
710 const CXXRecordDecl *RD,
const ValueDecl *VD,
711 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
725 FieldOffset = getASTContext().getFieldOffset(VD);
726 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
727 "cannot take address of bitfield");
728 FieldOffset /= getASTContext().getCharWidth();
732 if (IM == MSInheritanceModel::Virtual)
733 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
742 case MSInheritanceModel::Single: Code =
'0';
break;
743 case MSInheritanceModel::Multiple: Code =
'0';
break;
744 case MSInheritanceModel::Virtual: Code =
'F';
break;
745 case MSInheritanceModel::Unspecified: Code =
'G';
break;
751 getASTContext().getLangOpts().isCompatibleWithMSVC(
752 LangOptions::MSVC2019) &&
754 !TemplateArgType.
isNull()) {
756 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
761 mangleNumber(FieldOffset);
769 mangleNumber(VBTableOffset);
772void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
773 const CXXRecordDecl *RD,
const ValueDecl *VD) {
779 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
780 return mangleMemberDataPointer(RD, VD,
nullptr, QualType(),
"");
788 mangleNestedName(VD);
790 mangleUnqualifiedName(VD);
794void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
795 const CXXRecordDecl *RD,
const CXXMethodDecl *MD,
796 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
812 case MSInheritanceModel::Single: Code =
'1';
break;
813 case MSInheritanceModel::Multiple: Code =
'H';
break;
814 case MSInheritanceModel::Virtual: Code =
'I';
break;
815 case MSInheritanceModel::Unspecified: Code =
'J';
break;
826 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
827 LangOptions::MSVC2019) &&
829 !TemplateArgType.
isNull()) {
831 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
836 MicrosoftVTableContext *VTContext =
838 MethodVFTableLocation ML =
840 mangleVirtualMemPtrThunk(MD, ML);
844 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
849 mangleFunctionEncoding(MD,
true);
852 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
853 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
856 if (IM == MSInheritanceModel::Single) {
857 Out << Prefix <<
"0A@";
860 if (IM == MSInheritanceModel::Unspecified)
862 Out << Prefix << Code;
866 mangleNumber(
static_cast<uint32_t>(NVOffset));
868 mangleNumber(VBPtrOffset);
870 mangleNumber(VBTableOffset);
873void MicrosoftCXXNameMangler::mangleFunctionPointer(
874 const FunctionDecl *FD,
const NonTypeTemplateParmDecl *PD,
875 QualType TemplateArgType) {
882 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
883 LangOptions::MSVC2019) &&
885 !TemplateArgType.
isNull()) {
887 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
892 mangleFunctionEncoding(FD,
true);
895void MicrosoftCXXNameMangler::mangleVarDecl(
const VarDecl *VD,
896 const NonTypeTemplateParmDecl *PD,
897 QualType TemplateArgType) {
904 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
905 LangOptions::MSVC2019) &&
907 !TemplateArgType.
isNull()) {
909 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
914 mangleVariableEncoding(VD);
917void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
918 const CXXRecordDecl *RD,
const CXXMethodDecl *MD) {
926 return mangleMemberFunctionPointer(RD, MD,
nullptr, QualType(),
"");
934 MicrosoftVTableContext *VTContext =
936 MethodVFTableLocation ML =
938 mangleVirtualMemPtrThunk(MD, ML);
941 mangleFunctionEncoding(MD,
true);
945void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
946 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML) {
948 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
949 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
955 mangleNumber(OffsetInVFTable);
957 mangleCallingConvention(MD->
getType()->
castAs<FunctionProtoType>(),
961void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {
965 mangleUnqualifiedName(GD);
967 mangleNestedName(GD);
973void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
974 mangleNumber(llvm::APSInt(llvm::APInt(64, Number),
false));
977void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
982 unsigned Width = std::max(
Number.getBitWidth(), 64U);
991 if (
Value.isNegative()) {
998void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
1001 switch (APFloat::SemanticsToEnum(
Number.getSemantics())) {
1002 case APFloat::S_IEEEsingle:
Out <<
'A';
break;
1003 case APFloat::S_IEEEdouble:
Out <<
'B';
break;
1007 case APFloat::S_IEEEhalf:
Out <<
'V';
break;
1008 case APFloat::S_BFloat:
Out <<
'W';
break;
1009 case APFloat::S_x87DoubleExtended:
Out <<
'X';
break;
1010 case APFloat::S_IEEEquad:
Out <<
'Y';
break;
1011 case APFloat::S_PPCDoubleDouble:
Out <<
'Z';
break;
1012 case APFloat::S_PPCDoubleDoubleLegacy:
1013 case APFloat::S_Float8E5M2:
1014 case APFloat::S_Float8E4M3:
1015 case APFloat::S_Float8E4M3FN:
1016 case APFloat::S_Float8E5M2FNUZ:
1017 case APFloat::S_Float8E4M3FNUZ:
1018 case APFloat::S_Float8E4M3B11FNUZ:
1019 case APFloat::S_Float8E3M4:
1020 case APFloat::S_FloatTF32:
1021 case APFloat::S_Float8E8M0FNU:
1022 case APFloat::S_Float6E3M2FN:
1023 case APFloat::S_Float6E2M3FN:
1024 case APFloat::S_Float4E2M1FN:
1025 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
1028 mangleBits(
Number.bitcastToAPInt());
1031void MicrosoftCXXNameMangler::mangleBits(llvm::APInt
Value) {
1040 llvm::SmallString<32> EncodedNumberBuffer;
1042 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
1043 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1044 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1053 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1062 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1063 TemplateArgs = &Spec->getTemplateArgs();
1064 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1069 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1070 TemplateArgs = &Spec->getTemplateArgs();
1071 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1077void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
1078 DeclarationName Name) {
1086 const TemplateArgumentList *TemplateArgs =
nullptr;
1087 if (GlobalDecl TD =
isTemplate(GD, TemplateArgs)) {
1092 mangleTemplateInstantiationName(TD, *TemplateArgs);
1115 ArgBackRefMap::iterator
Found = TemplateArgBackReferences.find(ND);
1116 if (
Found == TemplateArgBackReferences.end()) {
1118 TemplateArgStringMap::iterator
Found = TemplateArgStrings.find(ND);
1119 if (
Found == TemplateArgStrings.end()) {
1121 llvm::SmallString<64> TemplateMangling;
1122 llvm::raw_svector_ostream Stream(TemplateMangling);
1123 MicrosoftCXXNameMangler
Extra(Context, Stream);
1124 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1127 mangleSourceName(TemplateMangling);
1131 BackRefVec::iterator StringFound =
1132 llvm::find(NameBackReferences, TemplateMangling);
1133 if (StringFound != NameBackReferences.end()) {
1134 TemplateArgBackReferences[ND] =
1135 StringFound - NameBackReferences.begin();
1137 TemplateArgStrings[ND] =
1138 TemplateArgStringStorage.save(TemplateMangling.str());
1157 ->getTemplatedDecl()
1160 bool IsOCLDeviceStub =
1162 DeviceKernelAttr::isOpenCLSpelling(
1163 ND->
getAttr<DeviceKernelAttr>()) &&
1167 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1168 else if (IsOCLDeviceStub)
1170 (llvm::Twine(
"__clang_ocl_kern_imp_") + II->getName()).str());
1172 mangleSourceName(II->getName());
1177 assert(ND &&
"mangling empty name without declaration");
1179 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1180 if (NS->isAnonymousNamespace()) {
1181 llvm::SmallString<16> Name(
"?A0x");
1182 Name += Context.getAnonymousNamespaceHash();
1183 mangleSourceName(Name);
1188 if (
const DecompositionDecl *DD = dyn_cast<DecompositionDecl>(ND)) {
1191 llvm::SmallString<64> Name(
"$S");
1193 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1194 mangleSourceName(Name);
1198 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1201 assert(RD &&
"expected variable decl to have a record type");
1205 llvm::SmallString<64> Name(
"$S");
1207 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1208 mangleSourceName(Name.str());
1212 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1215 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1216 llvm::raw_svector_ostream GUIDOS(GUID);
1217 Context.mangleMSGuidDecl(GD, GUIDOS);
1218 mangleSourceName(GUID);
1222 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1224 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1225 TPO->getValue(), TplArgKind::ClassNTTP);
1233 "Typedef should not be in another decl context!");
1235 "Typedef was not named!");
1240 if (
const CXXRecordDecl *
Record = dyn_cast<CXXRecordDecl>(TD)) {
1241 if (
Record->isLambda()) {
1242 llvm::SmallString<10> Name(
"<lambda_");
1244 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1245 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1247 const ParmVarDecl *Parm =
1248 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1249 const FunctionDecl *
Func =
1253 unsigned DefaultArgNo =
1255 Name += llvm::utostr(DefaultArgNo);
1259 if (LambdaManglingNumber)
1260 LambdaId = LambdaManglingNumber;
1262 LambdaId = Context.getLambdaId(
Record);
1264 Name += llvm::utostr(LambdaId);
1267 mangleSourceName(Name);
1271 if (LambdaManglingNumber && LambdaContextDecl) {
1282 llvm::SmallString<64> Name;
1283 if (DeclaratorDecl *DD =
1287 Name +=
"<unnamed-type-";
1288 Name += DD->getName();
1289 }
else if (TypedefNameDecl *TND =
1294 Name +=
"<unnamed-type-";
1295 Name += TND->getName();
1300 Name +=
"<unnamed-enum-";
1301 Name += ED->enumerator_begin()->getName();
1304 Name +=
"<unnamed-type-$S";
1305 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1308 mangleSourceName(Name.str());
1318 llvm::SmallString<64> Name;
1319 mangleSourceName(Name.str());
1324 if (isStructorDecl(ND)) {
1338 if (isStructorDecl(ND))
1341 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1355 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1360 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1365 llvm_unreachable(
"Can't mangle a deduction guide name!");
1368 llvm_unreachable(
"Can't mangle a using directive name!");
1374void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {
1377 if (
const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1378 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1379 mangleSourceName(
"<unnamed-tag>");
1381 const DeclContext *DC = getEffectiveDeclContext(ND);
1385 if (Context.getNextDiscriminator(ND, Disc)) {
1392 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1394 [](StringRef Name,
const unsigned Discriminator,
1395 const unsigned ParameterDiscriminator) -> std::string {
1397 llvm::raw_string_ostream Stream(Buffer);
1400 Stream <<
'_' << Discriminator;
1401 if (ParameterDiscriminator)
1402 Stream <<
'_' << ParameterDiscriminator;
1406 unsigned Discriminator = BD->getBlockManglingNumber();
1408 Discriminator = Context.getBlockId(BD,
false);
1413 unsigned ParameterDiscriminator = 0;
1414 if (
const auto *MC = BD->getBlockManglingContextDecl())
1415 if (
const auto *P = dyn_cast<ParmVarDecl>(MC))
1416 if (
const auto *F = dyn_cast<FunctionDecl>(P->getDeclContext()))
1417 ParameterDiscriminator =
1418 F->getNumParams() - P->getFunctionScopeIndex();
1420 DC = getEffectiveDeclContext(BD);
1423 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1424 ParameterDiscriminator));
1429 if (
const auto *MC = BD->getBlockManglingContextDecl())
1431 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1432 mangleUnqualifiedName(ND);
1436 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1445 if (PointersAre64Bit)
1448 mangleArtificialTagType(TagTypeKind::Struct,
1449 Discriminate(
"__block_literal", Discriminator,
1450 ParameterDiscriminator));
1458 }
else if (
const ObjCMethodDecl *
Method = dyn_cast<ObjCMethodDecl>(DC)) {
1462 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1463 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1466 mangleUnqualifiedName(ND);
1469 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1479void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1495 llvm_unreachable(
"not expecting a COMDAT");
1497 llvm_unreachable(
"not expecting a unified dtor type");
1499 llvm_unreachable(
"Unsupported dtor type?");
1503 SourceLocation Loc) {
1508 case OO_New:
Out <<
"?2";
break;
1510 case OO_Delete:
Out <<
"?3";
break;
1512 case OO_Equal:
Out <<
"?4";
break;
1514 case OO_GreaterGreater:
Out <<
"?5";
break;
1516 case OO_LessLess:
Out <<
"?6";
break;
1518 case OO_Exclaim:
Out <<
"?7";
break;
1520 case OO_EqualEqual:
Out <<
"?8";
break;
1522 case OO_ExclaimEqual:
Out <<
"?9";
break;
1524 case OO_Subscript:
Out <<
"?A";
break;
1527 case OO_Arrow:
Out <<
"?C";
break;
1529 case OO_Star:
Out <<
"?D";
break;
1531 case OO_PlusPlus:
Out <<
"?E";
break;
1533 case OO_MinusMinus:
Out <<
"?F";
break;
1535 case OO_Minus:
Out <<
"?G";
break;
1537 case OO_Plus:
Out <<
"?H";
break;
1539 case OO_Amp:
Out <<
"?I";
break;
1541 case OO_ArrowStar:
Out <<
"?J";
break;
1543 case OO_Slash:
Out <<
"?K";
break;
1545 case OO_Percent:
Out <<
"?L";
break;
1547 case OO_Less:
Out <<
"?M";
break;
1549 case OO_LessEqual:
Out <<
"?N";
break;
1551 case OO_Greater:
Out <<
"?O";
break;
1553 case OO_GreaterEqual:
Out <<
"?P";
break;
1555 case OO_Comma:
Out <<
"?Q";
break;
1557 case OO_Call:
Out <<
"?R";
break;
1559 case OO_Tilde:
Out <<
"?S";
break;
1561 case OO_Caret:
Out <<
"?T";
break;
1563 case OO_Pipe:
Out <<
"?U";
break;
1565 case OO_AmpAmp:
Out <<
"?V";
break;
1567 case OO_PipePipe:
Out <<
"?W";
break;
1569 case OO_StarEqual:
Out <<
"?X";
break;
1571 case OO_PlusEqual:
Out <<
"?Y";
break;
1573 case OO_MinusEqual:
Out <<
"?Z";
break;
1575 case OO_SlashEqual:
Out <<
"?_0";
break;
1577 case OO_PercentEqual:
Out <<
"?_1";
break;
1579 case OO_GreaterGreaterEqual:
Out <<
"?_2";
break;
1581 case OO_LessLessEqual:
Out <<
"?_3";
break;
1583 case OO_AmpEqual:
Out <<
"?_4";
break;
1585 case OO_PipeEqual:
Out <<
"?_5";
break;
1587 case OO_CaretEqual:
Out <<
"?_6";
break;
1616 case OO_Array_New:
Out <<
"?_U";
break;
1618 case OO_Array_Delete:
Out <<
"?_V";
break;
1620 case OO_Coawait:
Out <<
"?__L";
break;
1622 case OO_Spaceship:
Out <<
"?__M";
break;
1624 case OO_Conditional: {
1625 Error(Loc,
"conditional operator");
1631 llvm_unreachable(
"Not an overloaded operator");
1635void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1637 BackRefVec::iterator
Found = llvm::find(NameBackReferences, Name);
1638 if (
Found == NameBackReferences.end()) {
1639 if (NameBackReferences.size() < 10)
1640 NameBackReferences.push_back(std::string(Name));
1643 Out << (
Found - NameBackReferences.begin());
1647void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1648 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1651void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1652 GlobalDecl GD,
const TemplateArgumentList &TemplateArgs) {
1658 ArgBackRefMap OuterFunArgsContext;
1659 ArgBackRefMap OuterTemplateArgsContext;
1660 BackRefVec OuterTemplateContext;
1661 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1662 NameBackReferences.swap(OuterTemplateContext);
1663 FunArgBackReferences.swap(OuterFunArgsContext);
1664 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1665 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1667 mangleUnscopedTemplateName(GD);
1671 NameBackReferences.swap(OuterTemplateContext);
1672 FunArgBackReferences.swap(OuterFunArgsContext);
1673 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1674 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1677void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {
1680 mangleUnqualifiedName(GD);
1683void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1684 const llvm::APSInt &
Value,
const NonTypeTemplateParmDecl *PD,
1685 QualType TemplateArgType) {
1694 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1695 LangOptions::MSVC2019) &&
1697 !TemplateArgType.
isNull()) {
1699 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
1704 mangleNumber(
Value);
1707void MicrosoftCXXNameMangler::mangleExpression(
1708 const Expr *E,
const NonTypeTemplateParmDecl *PD) {
1710 if (std::optional<llvm::APSInt>
Value =
1721void MicrosoftCXXNameMangler::mangleTemplateArgs(
1722 const TemplateDecl *TD,
const TemplateArgumentList &TemplateArgs) {
1725 assert(TPL->
size() == TemplateArgs.
size() &&
1726 "size mismatch between args and parms!");
1728 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1729 const TemplateArgument &TA = TemplateArgs[i];
1736 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1744 if (!
T->isPointerType() || !
V.isLValue() || !
V.hasLValuePath() ||
1748 QualType BaseT =
V.getLValueBase().getType();
1749 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1750 V.getLValuePath()[0].getAsArrayIndex() != 0)
1753 V.getLValueBase().dyn_cast<const ValueDecl *>());
1756void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1757 const TemplateArgument &TA,
1758 const NamedDecl *Parm) {
1796 llvm_unreachable(
"Can't mangle null template arguments!");
1798 llvm_unreachable(
"Can't mangle template expansion arguments!");
1801 mangleType(
T, SourceRange(), QMM_Escape);
1807 mangleMemberDataPointer(
1811 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1812 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1824 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1825 TPO->getValue(), TplArgKind::ClassNTTP);
1826 }
else if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1842 if (
const MemberPointerType *MPT =
T->
getAs<MemberPointerType>()) {
1843 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1844 if (MPT->isMemberFunctionPointerType() &&
1846 mangleMemberFunctionPointer(RD,
nullptr,
nullptr, QualType());
1849 if (MPT->isMemberDataPointer()) {
1851 mangleMemberDataPointer(RD,
nullptr,
nullptr, QualType());
1861 mangleIntegerLiteral(llvm::APSInt::get(-1),
1867 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1877 return mangleTemplateArg(
1883 ->getContainedDeducedType()) {
1889 TplArgKind::StructuralValue,
1897 if (TemplateArgs.empty()) {
1902 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(
1903 LangOptions::MSVC2015)
1909 llvm_unreachable(
"unexpected template parameter decl!");
1911 for (
const TemplateArgument &PA : TemplateArgs)
1912 mangleTemplateArg(TD, PA, Parm);
1917 const NamedDecl *ND =
1919 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1925 llvm_unreachable(
"unexpected template template NamedDecl!");
1932void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType
T,
1935 bool WithScalarType) {
1936 switch (
V.getKind()) {
1942 mangleType(
T, SourceRange(), QMM_Escape);
1948 mangleType(
T, SourceRange(), QMM_Escape);
1950 mangleNumber(
V.getInt());
1955 mangleType(
T, SourceRange(), QMM_Escape);
1956 mangleFloat(
V.getFloat());
1961 mangleType(
T, SourceRange(), QMM_Escape);
1963 APValue::LValueBase
Base =
V.getLValueBase();
1967 if (
V.isLValueOnePastTheEnd()) {
1969 auto *VD =
Base.dyn_cast<
const ValueDecl *>();
1976 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1978 if (
Base.isNull()) {
1984 mangleNumber(
V.getLValueOffset().getQuantity());
1985 }
else if (!
V.hasLValuePath()) {
1987 Error(
"template argument (extension not comaptible with ms mangler)");
1989 }
else if (
auto *VD =
Base.dyn_cast<
const ValueDecl*>()) {
1993 Error(
"template argument (undeclared base)");
2000 SmallVector<char, 2> EntryTypes;
2002 QualType ET =
Base.getType();
2003 for (APValue::LValuePathEntry E :
V.getLValuePath()) {
2005 EntryTypes.push_back(
'C');
2006 EntryManglers.push_back([
this, I = E.getAsArrayIndex()] {
2011 ET = AT->getElementType();
2015 const Decl *D = E.getAsBaseOrMember().getPointer();
2016 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2028 EntryTypes.push_back(
'6');
2029 EntryManglers.push_back([
this, D] {
2035 for (
auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
2038 auto *VD =
Base.dyn_cast<
const ValueDecl*>();
2040 Error(
"template argument (null value decl)");
2043 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
2057 mangleType(
T, SourceRange(), QMM_Escape);
2059 const CXXRecordDecl *RD =
2060 T->
castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
2061 const ValueDecl *D =
V.getMemberPointerDecl();
2062 if (TAK == TplArgKind::ClassNTTP) {
2064 mangleMemberDataPointerInClassNTTP(RD, D);
2066 mangleMemberFunctionPointerInClassNTTP(RD,
2067 cast_or_null<CXXMethodDecl>(D));
2070 mangleMemberDataPointer(RD, D,
nullptr, QualType(),
"");
2072 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D),
nullptr,
2080 mangleType(
T, SourceRange(), QMM_Escape);
2082 assert(RD &&
"unexpected type for record value");
2084 unsigned BaseIndex = 0;
2085 for (
const CXXBaseSpecifier &B : RD->
bases())
2086 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
2087 for (
const FieldDecl *FD : RD->
fields())
2088 if (!FD->isUnnamedBitField())
2089 mangleTemplateArgValue(FD->
getType(),
2090 V.getStructField(FD->getFieldIndex()), TAK,
2098 mangleType(
T, SourceRange(), QMM_Escape);
2099 if (
const FieldDecl *FD =
V.getUnionField()) {
2100 mangleUnqualifiedName(FD);
2101 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
2109 mangleType(
T, SourceRange(), QMM_Escape);
2111 mangleNumber(
V.getComplexIntReal());
2113 mangleNumber(
V.getComplexIntImag());
2119 mangleType(
T, SourceRange(), QMM_Escape);
2120 mangleFloat(
V.getComplexFloatReal());
2121 mangleFloat(
V.getComplexFloatImag());
2127 QualType ElemT = getASTContext().getAsArrayType(
T)->getElementType();
2128 mangleType(ElemT, SourceRange(), QMM_Escape);
2129 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
2130 const APValue &ElemV = I <
V.getArrayInitializedElts()
2131 ?
V.getArrayInitializedElt(I)
2132 :
V.getArrayFiller();
2133 mangleTemplateArgValue(ElemT, ElemV, TAK);
2144 mangleType(
T, SourceRange(), QMM_Escape);
2146 QualType ElemT =
T->
castAs<VectorType>()->getElementType();
2147 mangleType(ElemT, SourceRange(), QMM_Escape);
2148 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
2150 mangleTemplateArgValue(ElemT, ElemV, TAK);
2158 Error(
"template argument (value type: matrix)");
2163 Error(
"template argument (value type: address label diff)");
2168 Error(
"template argument (value type: fixed point)");
2174void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2175 llvm::SmallString<64> TemplateMangling;
2176 llvm::raw_svector_ostream Stream(TemplateMangling);
2177 MicrosoftCXXNameMangler
Extra(Context, Stream);
2180 Extra.mangleSourceName(
"Protocol");
2181 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2183 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2186void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType
Type,
2188 SourceRange Range) {
2189 llvm::SmallString<64> TemplateMangling;
2190 llvm::raw_svector_ostream Stream(TemplateMangling);
2191 MicrosoftCXXNameMangler
Extra(Context, Stream);
2199 Extra.mangleSourceName(
"Autoreleasing");
2202 Extra.mangleSourceName(
"Strong");
2205 Extra.mangleSourceName(
"Weak");
2208 Extra.manglePointerCVQualifiers(Quals);
2209 Extra.manglePointerExtQualifiers(Quals,
Type);
2212 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2215void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *
T,
2217 SourceRange Range) {
2218 llvm::SmallString<64> TemplateMangling;
2219 llvm::raw_svector_ostream Stream(TemplateMangling);
2220 MicrosoftCXXNameMangler
Extra(Context, Stream);
2223 Extra.mangleSourceName(
"KindOf");
2224 Extra.mangleType(QualType(
T, 0)
2225 .stripObjCKindOfType(getASTContext())
2226 ->castAs<ObjCObjectType>(),
2229 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2232void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
2290 if (HasConst && HasVolatile) {
2292 }
else if (HasVolatile) {
2294 }
else if (HasConst) {
2300 if (HasConst && HasVolatile) {
2302 }
else if (HasVolatile) {
2304 }
else if (HasConst) {
2315MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2318 switch (RefQualifier) {
2332void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
2333 QualType PointeeType) {
2335 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2348void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {
2354 mangleNumber(PointerAuth.
getKey());
2359void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
2367 if (HasConst && HasVolatile) {
2369 }
else if (HasVolatile) {
2371 }
else if (HasConst) {
2378void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType
T,
2379 SourceRange Range) {
2388 if (
const auto *DT =
T->
getAs<DecayedType>()) {
2389 QualType OriginalType = DT->getOriginalType();
2392 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2393 OriginalType = getASTContext().getIncompleteArrayType(
2394 AT->getElementType(), AT->getSizeModifier(),
2395 AT->getIndexTypeCVRQualifiers());
2406 TypePtr =
T.getCanonicalType().getAsOpaquePtr();
2409 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2411 if (
Found == FunArgBackReferences.end()) {
2412 size_t OutSizeBefore =
Out.tell();
2414 mangleType(
T, Range, QMM_Drop);
2419 bool LongerThanOneChar = (
Out.tell() - OutSizeBefore > 1);
2420 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2421 size_t Size = FunArgBackReferences.size();
2422 FunArgBackReferences[TypePtr] =
Size;
2429void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2430 const PassObjectSizeAttr *POSA) {
2431 int Type = POSA->getType();
2432 bool Dynamic = POSA->isDynamic();
2434 auto Iter = PassObjectSizeArgs.insert({
Type,
Dynamic}).first;
2435 auto *TypePtr = (
const void *)&*Iter;
2436 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2438 if (
Found == FunArgBackReferences.end()) {
2440 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2441 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2444 if (FunArgBackReferences.size() < 10) {
2445 size_t Size = FunArgBackReferences.size();
2446 FunArgBackReferences[TypePtr] =
Size;
2453void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType
T,
2455 SourceRange Range) {
2470 llvm::SmallString<32> ASMangling;
2471 llvm::raw_svector_ostream Stream(ASMangling);
2472 MicrosoftCXXNameMangler
Extra(Context, Stream);
2478 Extra.mangleSourceName(
"_AS");
2479 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2483 llvm_unreachable(
"Not a language specific address space");
2484 case LangAS::opencl_global:
2485 Extra.mangleSourceName(
"_ASCLglobal");
2487 case LangAS::opencl_global_device:
2488 Extra.mangleSourceName(
"_ASCLdevice");
2490 case LangAS::opencl_global_host:
2491 Extra.mangleSourceName(
"_ASCLhost");
2493 case LangAS::opencl_local:
2494 Extra.mangleSourceName(
"_ASCLlocal");
2496 case LangAS::opencl_constant:
2497 Extra.mangleSourceName(
"_ASCLconstant");
2499 case LangAS::opencl_private:
2500 Extra.mangleSourceName(
"_ASCLprivate");
2502 case LangAS::opencl_generic:
2503 Extra.mangleSourceName(
"_ASCLgeneric");
2505 case LangAS::cuda_device:
2506 Extra.mangleSourceName(
"_ASCUdevice");
2508 case LangAS::cuda_constant:
2509 Extra.mangleSourceName(
"_ASCUconstant");
2511 case LangAS::cuda_shared:
2512 Extra.mangleSourceName(
"_ASCUshared");
2514 case LangAS::ptr32_sptr:
2515 case LangAS::ptr32_uptr:
2517 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2521 Extra.mangleType(
T, Range, QMM_Escape);
2522 mangleQualifiers(Qualifiers(),
false);
2523 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2526void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType
T,
2527 QualifierMangleMode QMM) {
2528 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2529 LangOptions::MSVC2019) &&
2530 "Cannot mangle MSVC 2017 auto return types!");
2534 Qualifiers Quals =
T.getLocalQualifiers();
2536 if (QMM == QMM_Result)
2538 if (QMM != QMM_Drop)
2539 mangleQualifiers(Quals,
false);
2540 Out << (AT->isDecltypeAuto() ?
"_T" :
"_P");
2544 T =
T.getDesugaredType(getASTContext());
2545 Qualifiers Quals =
T.getLocalQualifiers();
2552 mangleQualifiers(Quals,
false);
2555 llvm_unreachable(
"QMM_Escape unexpected");
2558 const Type *ty =
T.getTypePtr();
2560 case Type::MemberPointer:
2566 case Type::LValueReference:
2569 case Type::RValueReference:
2573 llvm_unreachable(
"Invalid type expected");
2577void MicrosoftCXXNameMangler::mangleType(QualType
T, SourceRange Range,
2578 QualifierMangleMode QMM) {
2581 T =
T.getDesugaredType(getASTContext());
2582 Qualifiers Quals =
T.getLocalQualifiers();
2584 if (
const ArrayType *AT = getASTContext().getAsArrayType(
T)) {
2587 if (QMM == QMM_Mangle)
2589 else if (QMM == QMM_Escape || QMM == QMM_Result)
2591 mangleArrayType(AT);
2604 if (
const FunctionType *FT = dyn_cast<FunctionType>(
T)) {
2606 mangleFunctionType(FT);
2609 mangleQualifiers(Quals,
false);
2612 if (!IsPointer && Quals) {
2614 mangleQualifiers(Quals,
false);
2622 if ((!IsPointer && Quals) ||
isa<TagType>(
T) || isArtificialTagType(
T)) {
2624 mangleQualifiers(Quals,
false);
2629 const Type *ty =
T.getTypePtr();
2632#define ABSTRACT_TYPE(CLASS, PARENT)
2633#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2635 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2637#define TYPE(CLASS, PARENT) \
2639 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2641#include "clang/AST/TypeNodes.inc"
2643#undef NON_CANONICAL_TYPE
2648void MicrosoftCXXNameMangler::mangleType(
const BuiltinType *
T, Qualifiers,
2649 SourceRange Range) {
2677 switch (
T->getKind()) {
2678 case BuiltinType::Void:
2681 case BuiltinType::SChar:
2684 case BuiltinType::Char_U:
2685 case BuiltinType::Char_S:
2688 case BuiltinType::UChar:
2691 case BuiltinType::Short:
2694 case BuiltinType::UShort:
2697 case BuiltinType::Int:
2700 case BuiltinType::UInt:
2703 case BuiltinType::Long:
2706 case BuiltinType::ULong:
2709 case BuiltinType::Float:
2712 case BuiltinType::Double:
2716 case BuiltinType::LongDouble:
2719 case BuiltinType::LongLong:
2722 case BuiltinType::ULongLong:
2725 case BuiltinType::Int128:
2728 case BuiltinType::UInt128:
2731 case BuiltinType::Bool:
2734 case BuiltinType::Char8:
2737 case BuiltinType::Char16:
2740 case BuiltinType::Char32:
2743 case BuiltinType::WChar_S:
2744 case BuiltinType::WChar_U:
2748#define BUILTIN_TYPE(Id, SingletonId)
2749#define PLACEHOLDER_TYPE(Id, SingletonId) \
2750 case BuiltinType::Id:
2751#include "clang/AST/BuiltinTypes.def"
2752 case BuiltinType::Dependent:
2753 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2755 case BuiltinType::ObjCId:
2756 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2758 case BuiltinType::ObjCClass:
2759 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2761 case BuiltinType::ObjCSel:
2762 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2765#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2766 case BuiltinType::Id: \
2767 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2769#include "clang/Basic/OpenCLImageTypes.def"
2770 case BuiltinType::OCLSampler:
2772 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2774 case BuiltinType::OCLEvent:
2776 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2778 case BuiltinType::OCLClkEvent:
2780 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2782 case BuiltinType::OCLQueue:
2784 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2786 case BuiltinType::OCLReserveID:
2788 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2790#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2791 case BuiltinType::Id: \
2792 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2794#include "clang/Basic/OpenCLExtensionTypes.def"
2796 case BuiltinType::NullPtr:
2800 case BuiltinType::Float16:
2801 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2804 case BuiltinType::Half:
2805 if (!getASTContext().getLangOpts().
HLSL)
2806 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2807 else if (getASTContext().getLangOpts().NativeHalfType)
2813 case BuiltinType::BFloat16:
2814 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2817 case BuiltinType::MFloat8:
2818 mangleArtificialTagType(TagTypeKind::Struct,
"__mfp8", {
"__clang"});
2821#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2822 case BuiltinType::Id: \
2823 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2824 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2827#include "clang/Basic/WebAssemblyReferenceTypes.def"
2829#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2830 case BuiltinType::Id: \
2831 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2833#include "clang/Basic/HLSLIntangibleTypes.def"
2835 case BuiltinType::SveBool:
2839 case BuiltinType::SveInt8:
2842 case BuiltinType::SveInt16:
2845 case BuiltinType::SveInt32:
2848 case BuiltinType::SveInt64:
2852 case BuiltinType::SveUint8:
2855 case BuiltinType::SveUint16:
2858 case BuiltinType::SveUint32:
2861 case BuiltinType::SveUint64:
2865 case BuiltinType::SveBFloat16:
2868 case BuiltinType::SveFloat16:
2871 case BuiltinType::SveFloat32:
2874 case BuiltinType::SveFloat64:
2878 case BuiltinType::SveInt8x2:
2881 case BuiltinType::SveInt16x2:
2884 case BuiltinType::SveInt32x2:
2887 case BuiltinType::SveInt64x2:
2891 case BuiltinType::SveUint8x2:
2894 case BuiltinType::SveUint16x2:
2897 case BuiltinType::SveUint32x2:
2900 case BuiltinType::SveUint64x2:
2904 case BuiltinType::SveBFloat16x2:
2907 case BuiltinType::SveFloat16x2:
2910 case BuiltinType::SveFloat32x2:
2913 case BuiltinType::SveFloat64x2:
2917 case BuiltinType::SveInt8x3:
2920 case BuiltinType::SveInt16x3:
2923 case BuiltinType::SveInt32x3:
2926 case BuiltinType::SveInt64x3:
2930 case BuiltinType::SveUint8x3:
2933 case BuiltinType::SveUint16x3:
2936 case BuiltinType::SveUint32x3:
2939 case BuiltinType::SveUint64x3:
2943 case BuiltinType::SveBFloat16x3:
2946 case BuiltinType::SveFloat16x3:
2949 case BuiltinType::SveFloat32x3:
2952 case BuiltinType::SveFloat64x3:
2956 case BuiltinType::SveInt8x4:
2959 case BuiltinType::SveInt16x4:
2962 case BuiltinType::SveInt32x4:
2965 case BuiltinType::SveInt64x4:
2969 case BuiltinType::SveUint8x4:
2972 case BuiltinType::SveUint16x4:
2975 case BuiltinType::SveUint32x4:
2978 case BuiltinType::SveUint64x4:
2982 case BuiltinType::SveBFloat16x4:
2985 case BuiltinType::SveFloat16x4:
2988 case BuiltinType::SveFloat32x4:
2991 case BuiltinType::SveFloat64x4:
2997 case BuiltinType::SveMFloat8:
2998 mangleArtificialTagType(TagTypeKind::Struct,
"__SVMfloat8_t", {
"__clang"});
3001 case BuiltinType::SveMFloat8x2:
3002 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svmfloat8x2_t",
3006 case BuiltinType::SveMFloat8x3:
3007 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svmfloat8x3_t",
3011 case BuiltinType::SveMFloat8x4:
3012 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svmfloat8x4_t",
3016 case BuiltinType::SveBoolx2:
3017 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svboolx2_t",
3021 case BuiltinType::SveBoolx4:
3022 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svboolx4_t",
3026 case BuiltinType::SveCount:
3027 mangleArtificialTagType(TagTypeKind::Struct,
"__SVCount_t", {
"__clang"});
3040void MicrosoftCXXNameMangler::mangleType(
const FunctionProtoType *
T, Qualifiers,
3047 mangleFunctionType(
T,
nullptr,
true);
3050 mangleFunctionType(
T);
3053void MicrosoftCXXNameMangler::mangleType(
const FunctionNoProtoType *
T,
3054 Qualifiers, SourceRange) {
3056 mangleFunctionType(
T);
3059void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *
T,
3060 const FunctionDecl *D,
3061 bool ForceThisQuals,
3062 bool MangleExceptionSpec) {
3065 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(
T);
3070 bool IsInLambda =
false;
3071 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
3073 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
3077 HasThisQuals =
true;
3086 CC = getASTContext().getDefaultCallingConvention(
3095 manglePointerExtQualifiers(Quals, QualType());
3097 mangleQualifiers(Quals,
false);
3100 mangleCallingConvention(CC, Range);
3105 Out <<
"__clang_sme_attr" << SMEAttrs;
3118 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
3127 if (IsCtorClosure) {
3137 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
3139 ->
castAs<LValueReferenceType>()
3145 llvm_unreachable(
"unexpected constructor closure!");
3151 }
else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(D)) {
3162 mangleType(ResultType, Range, QMM_Result);
3163 }
else if (IsInLambda) {
3165 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
3166 "shouldn't need to mangle __auto_type!");
3170 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3176 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
3177 "shouldn't need to mangle __auto_type!");
3183 auto UseClangMangling = [](QualType ResultType) {
3184 QualType
T = ResultType;
3187 if (
T.getQualifiers().hasAddressSpace())
3193 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
3194 LangOptions::MSVC2019) &&
3195 !UseClangMangling(ResultType)) {
3204 ->
castAs<FunctionProtoType>();
3207 mangleAutoReturnType(ResultType, QMM_Result);
3213 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3219 mangleType(ResultType, Range, QMM_Result);
3235 for (
unsigned I = 0, E = Proto->
getNumParams(); I != E; ++I) {
3240 mangleFunctionArgumentType(Proto->
getParamType(I), Range);
3251 manglePassObjectSizeArg(P);
3260 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
3261 getASTContext().getLangOpts().isCompatibleWithMSVC(
3262 LangOptions::MSVC2017_5))
3263 mangleThrowSpecification(Proto);
3268void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
3293 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3303 llvm_unreachable(
"Unsupported access specifier");
3332void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC,
3333 SourceRange Range) {
3395 if (getASTContext().getLangOpts().RegCall4)
3404void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *
T,
3405 SourceRange Range) {
3409void MicrosoftCXXNameMangler::mangleThrowSpecification(
3410 const FunctionProtoType *FT) {
3419void MicrosoftCXXNameMangler::mangleType(
const UnresolvedUsingType *
T,
3420 Qualifiers, SourceRange Range) {
3431void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
3433 case TagTypeKind::Union:
3436 case TagTypeKind::Struct:
3437 case TagTypeKind::Interface:
3440 case TagTypeKind::Class:
3443 case TagTypeKind::Enum:
3448void MicrosoftCXXNameMangler::mangleType(
const EnumType *
T, Qualifiers,
3452void MicrosoftCXXNameMangler::mangleType(
const RecordType *
T, Qualifiers,
3456void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3466void MicrosoftCXXNameMangler::mangleArtificialTagType(
3468 ArrayRef<StringRef> NestedNames) {
3470 mangleTagTypeKind(TK);
3473 mangleSourceName(UnqualifiedName);
3475 for (StringRef N : llvm::reverse(NestedNames))
3476 mangleSourceName(N);
3489void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *
T) {
3492 manglePointerCVQualifiers(
T->getElementType().getQualifiers());
3493 mangleType(
T->getElementType(), SourceRange());
3495void MicrosoftCXXNameMangler::mangleType(
const ConstantArrayType *
T, Qualifiers,
3497 llvm_unreachable(
"Should have been special cased");
3499void MicrosoftCXXNameMangler::mangleType(
const VariableArrayType *
T, Qualifiers,
3501 llvm_unreachable(
"Should have been special cased");
3503void MicrosoftCXXNameMangler::mangleType(
const DependentSizedArrayType *
T,
3504 Qualifiers, SourceRange) {
3505 llvm_unreachable(
"Should have been special cased");
3507void MicrosoftCXXNameMangler::mangleType(
const IncompleteArrayType *
T,
3508 Qualifiers, SourceRange) {
3509 llvm_unreachable(
"Should have been special cased");
3511void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *
T) {
3512 QualType ElementTy(
T, 0);
3513 SmallVector<llvm::APInt, 3> Dimensions;
3515 if (ElementTy->isConstantArrayType()) {
3516 const ConstantArrayType *CAT =
3517 getASTContext().getAsConstantArrayType(ElementTy);
3518 Dimensions.push_back(CAT->
getSize());
3520 }
else if (ElementTy->isIncompleteArrayType()) {
3521 const IncompleteArrayType *IAT =
3522 getASTContext().getAsIncompleteArrayType(ElementTy);
3523 Dimensions.push_back(llvm::APInt(32, 0));
3525 }
else if (ElementTy->isVariableArrayType()) {
3526 const VariableArrayType *VAT =
3527 getASTContext().getAsVariableArrayType(ElementTy);
3528 Dimensions.push_back(llvm::APInt(32, 0));
3530 }
else if (ElementTy->isDependentSizedArrayType()) {
3532 const DependentSizedArrayType *DSAT =
3533 getASTContext().getAsDependentSizedArrayType(ElementTy);
3543 mangleNumber(Dimensions.size());
3544 for (
const llvm::APInt &Dimension : Dimensions)
3545 mangleNumber(Dimension.getLimitedValue());
3546 mangleType(ElementTy, SourceRange(), QMM_Escape);
3549void MicrosoftCXXNameMangler::mangleType(
const ArrayParameterType *
T,
3550 Qualifiers, SourceRange) {
3557void MicrosoftCXXNameMangler::mangleType(
const MemberPointerType *
T,
3558 Qualifiers Quals, SourceRange Range) {
3560 manglePointerCVQualifiers(Quals);
3561 manglePointerExtQualifiers(Quals, PointeeType);
3562 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
3564 mangleName(
T->getMostRecentCXXRecordDecl());
3565 mangleFunctionType(FPT,
nullptr,
true);
3568 mangleName(
T->getMostRecentCXXRecordDecl());
3569 mangleType(PointeeType, Range, QMM_Drop);
3573void MicrosoftCXXNameMangler::mangleType(
const TemplateTypeParmType *
T,
3574 Qualifiers, SourceRange Range) {
3577 llvm::SmallString<64> Name;
3579 Name += llvm::utostr(
T->getDepth());
3581 Name += llvm::utostr(
T->getIndex());
3583 mangleSourceName(Name);
3586void MicrosoftCXXNameMangler::mangleType(
const SubstTemplateTypeParmPackType *
T,
3587 Qualifiers, SourceRange Range) {
3591void MicrosoftCXXNameMangler::mangleType(
const SubstBuiltinTemplatePackType *
T,
3592 Qualifiers, SourceRange Range) {
3593 Error(
Range.getBegin(),
"substituted builtin template pack") <<
Range;
3599void MicrosoftCXXNameMangler::mangleType(
const PointerType *
T, Qualifiers Quals,
3600 SourceRange Range) {
3602 manglePointerCVQualifiers(Quals);
3603 manglePointerExtQualifiers(Quals, PointeeType);
3604 manglePointerAuthQualifier(Quals);
3610 mangleType(PointeeType, Range);
3612 mangleAddressSpaceType(PointeeType, PointeeType.
getQualifiers(), Range);
3615void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectPointerType *
T,
3616 Qualifiers Quals, SourceRange Range) {
3625 return mangleObjCLifetime(PointeeType, Quals, Range);
3627 manglePointerCVQualifiers(Quals);
3628 manglePointerExtQualifiers(Quals, PointeeType);
3629 mangleType(PointeeType, Range);
3635void MicrosoftCXXNameMangler::mangleType(
const LValueReferenceType *
T,
3636 Qualifiers Quals, SourceRange Range) {
3640 manglePointerExtQualifiers(Quals, PointeeType);
3641 mangleType(PointeeType, Range);
3647void MicrosoftCXXNameMangler::mangleType(
const RValueReferenceType *
T,
3648 Qualifiers Quals, SourceRange Range) {
3652 manglePointerExtQualifiers(Quals, PointeeType);
3653 mangleType(PointeeType, Range);
3656void MicrosoftCXXNameMangler::mangleType(
const ComplexType *
T, Qualifiers,
3657 SourceRange Range) {
3658 QualType ElementType =
T->getElementType();
3660 llvm::SmallString<64> TemplateMangling;
3661 llvm::raw_svector_ostream Stream(TemplateMangling);
3662 MicrosoftCXXNameMangler
Extra(Context, Stream);
3664 Extra.mangleSourceName(
"_Complex");
3665 Extra.mangleType(ElementType, Range, QMM_Escape);
3667 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3675bool MicrosoftCXXNameMangler::isArtificialTagType(QualType
T)
const {
3676 const Type *ty =
T.getTypePtr();
3681 case Type::Vector: {
3690void MicrosoftCXXNameMangler::mangleType(
const VectorType *
T, Qualifiers Quals,
3691 SourceRange Range) {
3692 QualType EltTy =
T->getElementType();
3693 const BuiltinType *ET = EltTy->
getAs<BuiltinType>();
3694 const BitIntType *BitIntTy = EltTy->
getAs<BitIntType>();
3695 assert((ET || BitIntTy) &&
3696 "vectors with non-builtin/_BitInt elements are unsupported");
3697 uint64_t Width = getASTContext().getTypeSize(
T);
3700 size_t OutSizeBefore =
Out.tell();
3702 if (getASTContext().getTargetInfo().
getTriple().isX86() && ET) {
3703 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3704 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3705 }
else if (Width >= 128) {
3706 if (ET->
getKind() == BuiltinType::Float)
3707 mangleArtificialTagType(TagTypeKind::Union,
3708 "__m" + llvm::utostr(Width));
3709 else if (ET->
getKind() == BuiltinType::LongLong)
3710 mangleArtificialTagType(TagTypeKind::Union,
3711 "__m" + llvm::utostr(Width) +
'i');
3712 else if (ET->
getKind() == BuiltinType::Double)
3713 mangleArtificialTagType(TagTypeKind::Struct,
3714 "__m" + llvm::utostr(Width) +
'd');
3719 bool IsBuiltin =
Out.tell() != OutSizeBefore;
3725 llvm::SmallString<64> TemplateMangling;
3726 llvm::raw_svector_ostream Stream(TemplateMangling);
3727 MicrosoftCXXNameMangler
Extra(Context, Stream);
3729 Extra.mangleSourceName(
"__vector");
3730 Extra.mangleType(QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3732 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumElements()));
3734 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3738void MicrosoftCXXNameMangler::mangleType(
const ExtVectorType *
T,
3739 Qualifiers Quals, SourceRange Range) {
3740 mangleType(
static_cast<const VectorType *
>(
T), Quals, Range);
3743void MicrosoftCXXNameMangler::mangleType(
const DependentVectorType *
T,
3744 Qualifiers, SourceRange Range) {
3748void MicrosoftCXXNameMangler::mangleType(
const DependentSizedExtVectorType *
T,
3749 Qualifiers, SourceRange Range) {
3750 Error(
Range.getBegin(),
"dependent-sized extended vector type") <<
Range;
3753void MicrosoftCXXNameMangler::mangleType(
const ConstantMatrixType *
T,
3754 Qualifiers quals, SourceRange Range) {
3755 QualType EltTy =
T->getElementType();
3757 llvm::SmallString<64> TemplateMangling;
3758 llvm::raw_svector_ostream Stream(TemplateMangling);
3759 MicrosoftCXXNameMangler
Extra(Context, Stream);
3763 Extra.mangleSourceName(
"__matrix");
3764 Extra.mangleType(EltTy, Range, QMM_Escape);
3766 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumRows()));
3767 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumColumns()));
3769 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3772void MicrosoftCXXNameMangler::mangleType(
const DependentSizedMatrixType *
T,
3773 Qualifiers quals, SourceRange Range) {
3777void MicrosoftCXXNameMangler::mangleType(
const DependentAddressSpaceType *
T,
3778 Qualifiers, SourceRange Range) {
3782void MicrosoftCXXNameMangler::mangleType(
const ObjCInterfaceType *
T, Qualifiers,
3785 mangleTagTypeKind(TagTypeKind::Struct);
3786 mangleName(
T->getDecl());
3789void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectType *
T,
3790 Qualifiers Quals, SourceRange Range) {
3791 if (
T->isKindOfType())
3792 return mangleObjCKindOfType(
T, Quals, Range);
3794 if (
T->qual_empty() && !
T->isSpecialized())
3795 return mangleType(
T->getBaseType(), Range, QMM_Drop);
3797 ArgBackRefMap OuterFunArgsContext;
3798 ArgBackRefMap OuterTemplateArgsContext;
3799 BackRefVec OuterTemplateContext;
3801 FunArgBackReferences.swap(OuterFunArgsContext);
3802 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3803 NameBackReferences.swap(OuterTemplateContext);
3805 mangleTagTypeKind(TagTypeKind::Struct);
3809 mangleSourceName(
"objc_object");
3810 else if (
T->isObjCClass())
3811 mangleSourceName(
"objc_class");
3813 mangleSourceName(
T->getInterface()->getName());
3815 for (
const auto &Q :
T->quals())
3816 mangleObjCProtocol(Q);
3818 if (
T->isSpecialized())
3819 for (
const auto &TA :
T->getTypeArgs())
3820 mangleType(TA, Range, QMM_Drop);
3826 FunArgBackReferences.swap(OuterFunArgsContext);
3827 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3828 NameBackReferences.swap(OuterTemplateContext);
3831void MicrosoftCXXNameMangler::mangleType(
const BlockPointerType *
T,
3832 Qualifiers Quals, SourceRange Range) {
3834 manglePointerCVQualifiers(Quals);
3835 manglePointerExtQualifiers(Quals, PointeeType);
3839 mangleFunctionType(PointeeType->
castAs<FunctionProtoType>());
3842void MicrosoftCXXNameMangler::mangleType(
const InjectedClassNameType *,
3843 Qualifiers, SourceRange) {
3844 llvm_unreachable(
"Cannot mangle injected class name type.");
3847void MicrosoftCXXNameMangler::mangleType(
const TemplateSpecializationType *
T,
3848 Qualifiers, SourceRange Range) {
3852void MicrosoftCXXNameMangler::mangleType(
const DependentNameType *
T, Qualifiers,
3853 SourceRange Range) {
3857void MicrosoftCXXNameMangler::mangleType(
const PackExpansionType *
T, Qualifiers,
3858 SourceRange Range) {
3862void MicrosoftCXXNameMangler::mangleType(
const PackIndexingType *
T,
3863 Qualifiers Quals, SourceRange Range) {
3864 manglePointerCVQualifiers(Quals);
3865 mangleType(
T->getSelectedType(), Range);
3868void MicrosoftCXXNameMangler::mangleType(
const TypeOfType *
T, Qualifiers,
3869 SourceRange Range) {
3873void MicrosoftCXXNameMangler::mangleType(
const TypeOfExprType *
T, Qualifiers,
3874 SourceRange Range) {
3878void MicrosoftCXXNameMangler::mangleType(
const DecltypeType *
T, Qualifiers,
3879 SourceRange Range) {
3883void MicrosoftCXXNameMangler::mangleType(
const UnaryTransformType *
T,
3884 Qualifiers, SourceRange Range) {
3888void MicrosoftCXXNameMangler::mangleType(
const AutoType *
T, Qualifiers,
3889 SourceRange Range) {
3890 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3895void MicrosoftCXXNameMangler::mangleType(
3896 const DeducedTemplateSpecializationType *
T, Qualifiers, SourceRange Range) {
3897 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3899 Error(
Range.getBegin(),
"deduced class template specialization type")
3903void MicrosoftCXXNameMangler::mangleType(
const AtomicType *
T, Qualifiers,
3904 SourceRange Range) {
3905 QualType ValueType =
T->getValueType();
3907 llvm::SmallString<64> TemplateMangling;
3908 llvm::raw_svector_ostream Stream(TemplateMangling);
3909 MicrosoftCXXNameMangler
Extra(Context, Stream);
3911 Extra.mangleSourceName(
"_Atomic");
3912 Extra.mangleType(ValueType, Range, QMM_Escape);
3914 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3917void MicrosoftCXXNameMangler::mangleType(
const PipeType *
T, Qualifiers,
3918 SourceRange Range) {
3919 QualType ElementType =
T->getElementType();
3921 llvm::SmallString<64> TemplateMangling;
3922 llvm::raw_svector_ostream Stream(TemplateMangling);
3923 MicrosoftCXXNameMangler
Extra(Context, Stream);
3925 Extra.mangleSourceName(
"ocl_pipe");
3926 Extra.mangleType(ElementType, Range, QMM_Escape);
3927 Extra.mangleIntegerLiteral(llvm::APSInt::get(
T->isReadOnly()));
3929 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3932void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
3935 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
3936 getASTContext().getSourceManager(),
3937 "Mangling declaration");
3939 msvc_hashing_ostream MHO(Out);
3941 if (
auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3943 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3944 return mangler.mangle(GD);
3947 if (
auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3949 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3950 return mangler.mangle(GD);
3953 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3954 return Mangler.mangle(GD);
3957void MicrosoftCXXNameMangler::mangleType(
const BitIntType *
T, Qualifiers,
3958 SourceRange Range) {
3959 llvm::SmallString<64> TemplateMangling;
3960 llvm::raw_svector_ostream Stream(TemplateMangling);
3961 MicrosoftCXXNameMangler
Extra(Context, Stream);
3963 if (
T->isUnsigned())
3964 Extra.mangleSourceName(
"_UBitInt");
3966 Extra.mangleSourceName(
"_BitInt");
3967 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumBits()));
3969 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3972void MicrosoftCXXNameMangler::mangleType(
const DependentBitIntType *
T,
3973 Qualifiers, SourceRange Range) {
3977void MicrosoftCXXNameMangler::mangleType(
const HLSLAttributedResourceType *
T,
3978 Qualifiers, SourceRange Range) {
3979 llvm_unreachable(
"HLSL uses Itanium name mangling");
3982void MicrosoftCXXNameMangler::mangleType(
const HLSLInlineSpirvType *
T,
3983 Qualifiers, SourceRange Range) {
3984 llvm_unreachable(
"HLSL uses Itanium name mangling");
3987void MicrosoftCXXNameMangler::mangleType(
const OverflowBehaviorType *
T,
3988 Qualifiers, SourceRange Range) {
3989 QualType UnderlyingType =
T->getUnderlyingType();
3991 llvm::SmallString<64> TemplateMangling;
3992 llvm::raw_svector_ostream Stream(TemplateMangling);
3993 MicrosoftCXXNameMangler
Extra(Context, Stream);
3995 if (
T->isWrapKind()) {
3996 Extra.mangleSourceName(
"ObtWrap_");
3998 Extra.mangleSourceName(
"ObtTrap_");
4000 Extra.mangleType(UnderlyingType, Range, QMM_Escape);
4002 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
4031 MicrosoftCXXNameMangler &Mangler,
4038 llvm_unreachable(
"Unsupported access specifier");
4049 Out <<
'R' << AccessSpec;
4050 Mangler.mangleNumber(
4052 Mangler.mangleNumber(
4054 Mangler.mangleNumber(
4059 Mangler.mangleNumber(
4066 llvm_unreachable(
"Unsupported access specifier");
4080 llvm_unreachable(
"Unsupported access specifier");
4093void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
4094 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML,
4096 msvc_hashing_ostream MHO(Out);
4097 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4098 Mangler.getStream() <<
'?';
4099 Mangler.mangleVirtualMemPtrThunk(MD, ML);
4102void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
4103 const ThunkInfo &Thunk,
4106 msvc_hashing_ostream MHO(Out);
4107 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4108 Mangler.getStream() <<
'?';
4109 Mangler.mangleName(MD);
4118 assert(Thunk.
Method !=
nullptr &&
4119 "Thunk info should hold the overridee decl");
4121 const CXXMethodDecl *DeclForFPT = Thunk.
Method ? Thunk.
Method : MD;
4122 Mangler.mangleFunctionType(
4126void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
const CXXDestructorDecl *DD,
4128 const ThunkInfo &Thunk,
4135 msvc_hashing_ostream MHO(Out);
4136 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
4137 Mangler.getStream() <<
"??_E";
4139 auto &Adjustment = Thunk.
This;
4141 Mangler.mangleFunctionType(DD->
getType()->
castAs<FunctionProtoType>(), DD);
4144void MicrosoftMangleContextImpl::mangleCXXVFTable(
4145 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4151 msvc_hashing_ostream MHO(Out);
4152 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4153 if (Derived->
hasAttr<DLLImportAttr>())
4154 Mangler.getStream() <<
"??_S";
4156 Mangler.getStream() <<
"??_7";
4157 Mangler.mangleName(Derived);
4158 Mangler.getStream() <<
"6B";
4159 for (
const CXXRecordDecl *RD : BasePath)
4160 Mangler.mangleName(RD);
4161 Mangler.getStream() <<
'@';
4164void MicrosoftMangleContextImpl::mangleCXXVTable(
const CXXRecordDecl *Derived,
4167 mangleCXXVFTable(Derived, {},
Out);
4170void MicrosoftMangleContextImpl::mangleCXXVBTable(
4171 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4177 msvc_hashing_ostream MHO(Out);
4178 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4179 Mangler.getStream() <<
"??_8";
4180 Mangler.mangleName(Derived);
4181 Mangler.getStream() <<
"7B";
4182 for (
const CXXRecordDecl *RD : BasePath)
4183 Mangler.mangleName(RD);
4184 Mangler.getStream() <<
'@';
4187void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType
T, raw_ostream &Out) {
4188 msvc_hashing_ostream MHO(Out);
4189 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4190 Mangler.getStream() <<
"??_R0";
4191 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4192 Mangler.getStream() <<
"@8";
4195void MicrosoftMangleContextImpl::mangleCXXRTTIName(
4196 QualType
T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4202 msvc_hashing_ostream MHO(Out, 4095);
4203 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4204 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4207void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
4208 const CXXRecordDecl *SrcRD,
const CXXRecordDecl *DstRD, raw_ostream &Out) {
4209 msvc_hashing_ostream MHO(Out);
4210 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4211 Mangler.getStream() <<
"??_K";
4212 Mangler.mangleName(SrcRD);
4213 Mangler.getStream() <<
"$C";
4214 Mangler.mangleName(DstRD);
4217void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType
T,
bool IsConst,
4222 msvc_hashing_ostream MHO(Out);
4223 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4224 Mangler.getStream() <<
"_TI";
4226 Mangler.getStream() <<
'C';
4228 Mangler.getStream() <<
'V';
4230 Mangler.getStream() <<
'U';
4231 Mangler.getStream() << NumEntries;
4232 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4235void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
4236 QualType
T,
uint32_t NumEntries, raw_ostream &Out) {
4237 msvc_hashing_ostream MHO(Out);
4238 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4239 Mangler.getStream() <<
"_CTA";
4240 Mangler.getStream() << NumEntries;
4241 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4244void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4248 MicrosoftCXXNameMangler Mangler(*
this, Out);
4249 Mangler.getStream() <<
"_CT";
4251 llvm::SmallString<64> RTTIMangling;
4253 llvm::raw_svector_ostream Stream(RTTIMangling);
4254 msvc_hashing_ostream MHO(Stream);
4255 mangleCXXRTTI(
T, MHO);
4257 Mangler.getStream() << RTTIMangling;
4265 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4266 LangOptions::MSVC2015) &&
4267 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4268 LangOptions::MSVC2017_7);
4269 llvm::SmallString<64> CopyCtorMangling;
4270 if (!OmitCopyCtor && CD) {
4271 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4272 msvc_hashing_ostream MHO(Stream);
4273 mangleCXXName(GlobalDecl(CD, CT), MHO);
4275 Mangler.getStream() << CopyCtorMangling;
4277 Mangler.getStream() <<
Size;
4278 if (VBPtrOffset == -1) {
4280 Mangler.getStream() << NVOffset;
4283 Mangler.getStream() << NVOffset;
4284 Mangler.getStream() << VBPtrOffset;
4285 Mangler.getStream() << VBIndex;
4289void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4292 msvc_hashing_ostream MHO(Out);
4293 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4294 Mangler.getStream() <<
"??_R1";
4295 Mangler.mangleNumber(NVOffset);
4296 Mangler.mangleNumber(VBPtrOffset);
4297 Mangler.mangleNumber(VBTableOffset);
4298 Mangler.mangleNumber(Flags);
4299 Mangler.mangleName(Derived);
4300 Mangler.getStream() <<
"8";
4303void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4304 const CXXRecordDecl *Derived, raw_ostream &Out) {
4305 msvc_hashing_ostream MHO(Out);
4306 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4307 Mangler.getStream() <<
"??_R2";
4308 Mangler.mangleName(Derived);
4309 Mangler.getStream() <<
"8";
4312void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4313 const CXXRecordDecl *Derived, raw_ostream &Out) {
4314 msvc_hashing_ostream MHO(Out);
4315 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4316 Mangler.getStream() <<
"??_R3";
4317 Mangler.mangleName(Derived);
4318 Mangler.getStream() <<
"8";
4321void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4322 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4328 llvm::SmallString<64> VFTableMangling;
4329 llvm::raw_svector_ostream Stream(VFTableMangling);
4330 mangleCXXVFTable(Derived, BasePath, Stream);
4332 if (VFTableMangling.starts_with(
"??@")) {
4333 assert(VFTableMangling.ends_with(
"@"));
4334 Out << VFTableMangling <<
"??_R4@";
4338 assert(VFTableMangling.starts_with(
"??_7") ||
4339 VFTableMangling.starts_with(
"??_S"));
4341 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
4344void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4345 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4346 msvc_hashing_ostream MHO(Out);
4347 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4352 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
4353 Mangler.mangleName(EnclosingDecl);
4356void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4357 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4358 msvc_hashing_ostream MHO(Out);
4359 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4364 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
4365 Mangler.mangleName(EnclosingDecl);
4368void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4369 QualType
T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4372 MicrosoftCXXNameMangler Mangler(*
this, Out);
4373 Mangler.getStream() <<
'?';
4374 Mangler.mangleType(
T.getCanonicalType(), SourceRange());
4377void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4378 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
4379 msvc_hashing_ostream MHO(Out);
4380 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4382 Mangler.getStream() <<
"?";
4383 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
4384 Mangler.mangle(VD,
"");
4387void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4388 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
4389 msvc_hashing_ostream MHO(Out);
4390 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4392 Mangler.getStream() <<
"?";
4393 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
4394 Mangler.mangleNestedName(VD);
4395 Mangler.getStream() <<
"@4HA";
4398void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
4410 msvc_hashing_ostream MHO(Out);
4411 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4415 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
4417 Mangler.getStream() <<
"?$S1@";
4419 unsigned ScopeDepth = 0;
4420 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4424 Mangler.mangle(VD,
"");
4426 Mangler.mangleNestedName(VD);
4427 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
4429 Mangler.mangleNumber(ScopeDepth);
4432void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *D,
4435 msvc_hashing_ostream MHO(Out);
4436 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4437 Mangler.getStream() <<
"??__" << CharCode;
4439 Mangler.getStream() <<
'?';
4440 Mangler.mangleName(D);
4441 Mangler.mangleVariableEncoding(D);
4442 Mangler.getStream() <<
"@@";
4444 Mangler.mangleName(D);
4448 Mangler.getStream() <<
"YAXXZ";
4451void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *D,
4454 mangleInitFiniStub(D,
'E', Out);
4458MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *D,
4461 mangleInitFiniStub(D,
'F', Out);
4464void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4485 MicrosoftCXXNameMangler Mangler(*
this, Out);
4486 Mangler.getStream() <<
"??_C@_";
4494 unsigned StringLength =
4495 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4500 Mangler.getStream() <<
'1';
4502 Mangler.getStream() <<
'0';
4506 Mangler.mangleNumber(StringByteLength);
4508 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4510 if (Index / CharByteWidth >= SL->
getLength())
4511 return static_cast<char>(0);
4513 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4514 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4517 auto GetBigEndianByte = [&SL](
unsigned Index) {
4519 if (Index / CharByteWidth >= SL->
getLength())
4520 return static_cast<char>(0);
4522 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4523 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4528 for (
unsigned I = 0, E = StringByteLength; I != E; ++I)
4529 JC.update(GetLittleEndianByte(I));
4533 Mangler.mangleNumber(JC.getCRC());
4539 auto MangleByte = [&Mangler](
char Byte) {
4547 Mangler.getStream() << Byte;
4548 }
else if (
isLetter(Byte & 0x7f)) {
4549 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4551 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4552 ' ',
'\n',
'\t',
'\'',
'-'};
4553 const char *Pos = llvm::find(SpecialChars, Byte);
4554 if (Pos != std::end(SpecialChars)) {
4555 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4557 Mangler.getStream() <<
"?$";
4558 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4559 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4565 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4566 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4567 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4569 MangleByte(GetBigEndianByte(I));
4571 MangleByte(GetLittleEndianByte(I));
4574 Mangler.getStream() <<
'@';
4577void MicrosoftCXXNameMangler::mangleAutoReturnType(
const MemberPointerType *
T,
4580 manglePointerCVQualifiers(Quals);
4581 manglePointerExtQualifiers(Quals, PointeeType);
4582 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4584 mangleName(
T->getMostRecentCXXRecordDecl());
4585 mangleFunctionType(FPT,
nullptr,
true);
4588 mangleName(
T->getMostRecentCXXRecordDecl());
4589 mangleAutoReturnType(PointeeType, QMM_Drop);
4593void MicrosoftCXXNameMangler::mangleAutoReturnType(
const PointerType *
T,
4597 "Unexpected address space mangling required");
4599 manglePointerCVQualifiers(Quals);
4600 manglePointerExtQualifiers(Quals, PointeeType);
4602 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4604 mangleFunctionType(FPT);
4606 mangleAutoReturnType(PointeeType, QMM_Mangle);
4610void MicrosoftCXXNameMangler::mangleAutoReturnType(
const LValueReferenceType *
T,
4615 manglePointerExtQualifiers(Quals, PointeeType);
4616 mangleAutoReturnType(PointeeType, QMM_Mangle);
4619void MicrosoftCXXNameMangler::mangleAutoReturnType(
const RValueReferenceType *
T,
4624 manglePointerExtQualifiers(Quals, PointeeType);
4625 mangleAutoReturnType(PointeeType, QMM_Mangle);
4631 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 StringRef getTriple(const Command &Job)
Defines the clang::Preprocessor interface.
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.
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
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
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 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.
@ Number
Just a number, nothing else.
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...
void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName, bool useDirectABI)
Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...
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)
@ Default
Set to the current date and time.
@ 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)
int const char * function
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
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...