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 {
60 llvm::SmallString<64> Buffer;
62 msvc_hashing_ostream(raw_ostream &OS)
63 : llvm::raw_svector_ostream(Buffer), OS(OS) {}
64 ~msvc_hashing_ostream()
override {
65 StringRef MangledName = str();
66 bool StartsWithEscape = MangledName.starts_with(
"\01");
68 MangledName = MangledName.drop_front(1);
69 if (MangledName.size() < 4096) {
75 llvm::MD5::MD5Result Hash;
76 Hasher.update(MangledName);
79 SmallString<32> HexString;
80 llvm::MD5::stringifyResult(Hash, HexString);
84 OS <<
"??@" << HexString <<
'@';
89getLambdaDefaultArgumentDeclContext(
const Decl *D) {
90 if (
const auto *RD = dyn_cast<CXXRecordDecl>(D))
92 if (
const auto *Parm =
93 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
94 return Parm->getDeclContext();
107 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))
111 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
113 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
114 return ContextParam->getDeclContext();
120 return getEffectiveDeclContext(
cast<Decl>(DC));
127 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
131 if (
const auto *FTD = FD->getPrimaryTemplate())
132 return FTD->getTemplatedDecl()->getCanonicalDecl();
134 return FD->getCanonicalDecl();
140 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
141 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
142 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
143 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
144 llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
145 llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
146 SmallString<16> AnonymousNamespaceHash;
149 MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags,
151 bool shouldMangleCXXName(
const NamedDecl *D)
override;
152 bool shouldMangleStringLiteral(
const StringLiteral *SL)
override;
153 void mangleCXXName(GlobalDecl GD, raw_ostream &Out)
override;
154 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
155 const MethodVFTableLocation &ML,
156 raw_ostream &Out)
override;
157 void mangleThunk(
const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
158 bool ElideOverrideInfo, raw_ostream &)
override;
160 const ThunkInfo &Thunk,
bool ElideOverrideInfo,
161 raw_ostream &)
override;
162 void mangleCXXVFTable(
const CXXRecordDecl *Derived,
163 ArrayRef<const CXXRecordDecl *> BasePath,
164 raw_ostream &Out)
override;
165 void mangleCXXVBTable(
const CXXRecordDecl *Derived,
166 ArrayRef<const CXXRecordDecl *> BasePath,
167 raw_ostream &Out)
override;
169 void mangleCXXVTable(
const CXXRecordDecl *, raw_ostream &)
override;
170 void mangleCXXVirtualDisplacementMap(
const CXXRecordDecl *SrcRD,
171 const CXXRecordDecl *DstRD,
172 raw_ostream &Out)
override;
173 void mangleCXXThrowInfo(QualType T,
bool IsConst,
bool IsVolatile,
174 bool IsUnaligned,
uint32_t NumEntries,
175 raw_ostream &Out)
override;
176 void mangleCXXCatchableTypeArray(QualType T,
uint32_t NumEntries,
177 raw_ostream &Out)
override;
178 void mangleCXXCatchableType(QualType T,
const CXXConstructorDecl *CD,
181 raw_ostream &Out)
override;
182 void mangleCXXRTTI(QualType T, raw_ostream &Out)
override;
183 void mangleCXXRTTIName(QualType T, raw_ostream &Out,
184 bool NormalizeIntegers)
override;
185 void mangleCXXRTTIBaseClassDescriptor(
const CXXRecordDecl *Derived,
188 raw_ostream &Out)
override;
189 void mangleCXXRTTIBaseClassArray(
const CXXRecordDecl *Derived,
190 raw_ostream &Out)
override;
191 void mangleCXXRTTIClassHierarchyDescriptor(
const CXXRecordDecl *Derived,
192 raw_ostream &Out)
override;
194 mangleCXXRTTICompleteObjectLocator(
const CXXRecordDecl *Derived,
195 ArrayRef<const CXXRecordDecl *> BasePath,
196 raw_ostream &Out)
override;
197 void mangleCanonicalTypeName(QualType T, raw_ostream &,
198 bool NormalizeIntegers)
override;
199 void mangleReferenceTemporary(
const VarDecl *,
unsigned ManglingNumber,
200 raw_ostream &)
override;
201 void mangleStaticGuardVariable(
const VarDecl *D, raw_ostream &Out)
override;
202 void mangleThreadSafeStaticGuardVariable(
const VarDecl *D,
unsigned GuardNum,
203 raw_ostream &Out)
override;
204 void mangleDynamicInitializer(
const VarDecl *D, raw_ostream &Out)
override;
205 void mangleDynamicAtExitDestructor(
const VarDecl *D,
206 raw_ostream &Out)
override;
207 void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
208 raw_ostream &Out)
override;
209 void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
210 raw_ostream &Out)
override;
211 void mangleStringLiteral(
const StringLiteral *SL, raw_ostream &Out)
override;
212 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
213 const DeclContext *DC = getEffectiveDeclContext(ND);
219 if (
const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
220 if (RD->isLambda()) {
228 disc = getASTContext().getManglingNumber(ND, isAux());
233 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
234 if (!
Tag->hasNameForLinkage() &&
235 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
236 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))
241 unsigned &discriminator = Uniquifier[ND];
243 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
244 disc = discriminator + 1;
248 std::string getLambdaString(
const CXXRecordDecl *Lambda)
override {
249 assert(Lambda->
isLambda() &&
"RD must be a lambda!");
250 std::string Name(
"<lambda_");
255 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
256 const FunctionDecl *
Func =
260 unsigned DefaultArgNo =
262 Name += llvm::utostr(DefaultArgNo);
266 if (LambdaManglingNumber)
267 LambdaId = LambdaManglingNumber;
269 LambdaId = getLambdaIdForDebugInfo(Lambda);
271 Name += llvm::utostr(LambdaId);
276 unsigned getLambdaId(
const CXXRecordDecl *RD) {
277 assert(RD->
isLambda() &&
"RD must be a lambda!");
280 "RD must not have a mangling number!");
281 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator,
bool>
282 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
283 return Result.first->second;
286 unsigned getLambdaIdForDebugInfo(
const CXXRecordDecl *RD) {
287 assert(RD->
isLambda() &&
"RD must be a lambda!");
290 "RD must not have a mangling number!");
292 return LambdaIds.lookup(RD);
297 StringRef getAnonymousNamespaceHash()
const {
298 return AnonymousNamespaceHash;
302 void mangleInitFiniStub(
const VarDecl *D,
char CharCode, raw_ostream &Out);
307class MicrosoftCXXNameMangler {
308 MicrosoftMangleContextImpl &Context;
314 const NamedDecl *Structor;
315 unsigned StructorType;
317 typedef llvm::SmallVector<std::string, 10> BackRefVec;
318 BackRefVec NameBackReferences;
320 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
321 ArgBackRefMap FunArgBackReferences;
322 ArgBackRefMap TemplateArgBackReferences;
324 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
325 TemplateArgStringMap TemplateArgStrings;
326 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
327 llvm::StringSaver TemplateArgStringStorage;
329 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
330 PassObjectSizeArgsSet PassObjectSizeArgs;
332 ASTContext &getASTContext()
const {
return Context.getASTContext(); }
334 const bool PointersAre64Bit;
336 DiagnosticBuilder
Error(SourceLocation, StringRef, StringRef);
337 DiagnosticBuilder
Error(SourceLocation, StringRef);
338 DiagnosticBuilder
Error(StringRef);
341 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
342 enum class TplArgKind { ClassNTTP, StructuralValue };
344 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_)
345 : Context(
C), Out(Out_), Structor(
nullptr), StructorType(-1),
346 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
347 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
350 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
352 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
353 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
354 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
357 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
359 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
360 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
361 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
364 raw_ostream &getStream()
const {
return Out; }
366 void mangle(GlobalDecl GD, StringRef Prefix =
"?");
367 void mangleName(GlobalDecl GD);
368 void mangleFunctionEncoding(GlobalDecl GD,
bool ShouldMangle);
369 void mangleVariableEncoding(
const VarDecl *VD);
370 void mangleMemberDataPointer(
const CXXRecordDecl *RD,
const ValueDecl *VD,
371 const NonTypeTemplateParmDecl *PD,
372 QualType TemplateArgType,
373 StringRef Prefix =
"$");
374 void mangleMemberDataPointerInClassNTTP(
const CXXRecordDecl *,
376 void mangleMemberFunctionPointer(
const CXXRecordDecl *RD,
377 const CXXMethodDecl *MD,
378 const NonTypeTemplateParmDecl *PD,
379 QualType TemplateArgType,
380 StringRef Prefix =
"$");
381 void mangleFunctionPointer(
const FunctionDecl *FD,
382 const NonTypeTemplateParmDecl *PD,
383 QualType TemplateArgType);
384 void mangleVarDecl(
const VarDecl *VD,
const NonTypeTemplateParmDecl *PD,
385 QualType TemplateArgType);
386 void mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD,
387 const CXXMethodDecl *MD);
388 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
389 const MethodVFTableLocation &ML);
390 void mangleNumber(int64_t Number);
391 void mangleNumber(llvm::APSInt Number);
392 void mangleFloat(llvm::APFloat Number);
393 void mangleBits(llvm::APInt Number);
395 void mangleArtificialTagType(
TagTypeKind TK, StringRef UnqualifiedName,
396 ArrayRef<StringRef> NestedNames = {});
397 void mangleAddressSpaceType(QualType T, Qualifiers Quals, SourceRange Range);
398 void mangleType(QualType T, SourceRange Range,
399 QualifierMangleMode QMM = QMM_Mangle);
400 void mangleFunctionType(
const FunctionType *T,
401 const FunctionDecl *D =
nullptr,
402 bool ForceThisQuals =
false,
403 bool MangleExceptionSpec =
true);
404 void mangleSourceName(StringRef Name);
405 void mangleNestedName(GlobalDecl GD);
407 void mangleAutoReturnType(QualType T, QualifierMangleMode QMM);
410 bool isStructorDecl(
const NamedDecl *ND)
const {
411 return ND == Structor || getStructor(ND) == Structor;
414 bool is64BitPointer(Qualifiers Quals)
const {
416 return AddrSpace == LangAS::ptr64 ||
417 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||
418 AddrSpace == LangAS::ptr32_uptr));
421 void mangleUnqualifiedName(GlobalDecl GD) {
424 void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name);
427 void mangleQualifiers(Qualifiers Quals,
bool IsMember);
429 void manglePointerCVQualifiers(Qualifiers Quals);
430 void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType);
431 void manglePointerAuthQualifier(Qualifiers Quals);
433 void mangleUnscopedTemplateName(GlobalDecl GD);
435 mangleTemplateInstantiationName(GlobalDecl GD,
436 const TemplateArgumentList &TemplateArgs);
439 void mangleFunctionArgumentType(QualType T, SourceRange Range);
440 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
442 bool isArtificialTagType(QualType T)
const;
445#define ABSTRACT_TYPE(CLASS, PARENT)
446#define NON_CANONICAL_TYPE(CLASS, PARENT)
447#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
450#include "clang/AST/TypeNodes.inc"
452#undef NON_CANONICAL_TYPE
455 void mangleType(
const TagDecl *TD);
456 void mangleDecayedArrayType(
const ArrayType *T);
457 void mangleArrayType(
const ArrayType *T);
461 void mangleIntegerLiteral(
const llvm::APSInt &Number,
472 bool WithScalarType =
false);
487MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(
ASTContext &Context,
507 SmallString<256> Path(FE->getName());
509 clang::Preprocessor::processPathForFileMacro(Path, Context.getLangOpts(),
510 Context.getTargetInfo());
513 uint32_t TruncatedHash = uint32_t(xxh3_64bits(Path));
514 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
517 AnonymousNamespaceHash =
"0";
521bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *D) {
522 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
525 if (FD->hasAttr<OverloadableAttr>())
537 if (FD->isMSVCRTEntryPoint())
551 if (!getASTContext().getLangOpts().
CPlusPlus)
554 const VarDecl *VD = dyn_cast<VarDecl>(D);
561 const DeclContext *DC = getEffectiveDeclContext(D);
571MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
575DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
578 DiagnosticsEngine &Diags = Context.getDiags();
579 return Diags.
Report(loc, diag::err_ms_mangle_unsupported_with_detail)
583DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
585 DiagnosticsEngine &Diags = Context.getDiags();
586 return Diags.
Report(loc, diag::err_ms_mangle_unsupported) << thingy;
589DiagnosticBuilder MicrosoftCXXNameMangler::Error(StringRef thingy) {
590 DiagnosticsEngine &Diags = Context.getDiags();
592 return Diags.
Report(diag::err_ms_mangle_unsupported) << thingy;
595void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) {
606 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
607 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
608 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
609 mangleVariableEncoding(VD);
613 Out <<
"3U__s_GUID@@B";
618 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
621void MicrosoftCXXNameMangler::mangleFunctionEncoding(GlobalDecl GD,
633 const FunctionProtoType *FT = FD->
getType()->
castAs<FunctionProtoType>();
646 mangleFunctionClass(FD);
648 mangleFunctionType(FT, FD,
false,
false);
654void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
685 mangleType(Ty, SR, QMM_Drop);
686 manglePointerExtQualifiers(
688 if (
const MemberPointerType *MPT = Ty->
getAs<MemberPointerType>()) {
689 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
692 mangleName(MPT->getMostRecentCXXRecordDecl());
695 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
697 mangleDecayedArrayType(AT);
698 if (AT->getElementType()->isArrayType())
703 mangleType(Ty, SR, QMM_Drop);
708void MicrosoftCXXNameMangler::mangleMemberDataPointer(
709 const CXXRecordDecl *RD,
const ValueDecl *VD,
710 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
724 FieldOffset = getASTContext().getFieldOffset(VD);
725 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
726 "cannot take address of bitfield");
727 FieldOffset /= getASTContext().getCharWidth();
731 if (IM == MSInheritanceModel::Virtual)
732 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
741 case MSInheritanceModel::Single: Code =
'0';
break;
742 case MSInheritanceModel::Multiple: Code =
'0';
break;
743 case MSInheritanceModel::Virtual: Code =
'F';
break;
744 case MSInheritanceModel::Unspecified: Code =
'G';
break;
750 getASTContext().getLangOpts().isCompatibleWithMSVC(
751 LangOptions::MSVC2019) &&
753 !TemplateArgType.
isNull()) {
755 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
760 mangleNumber(FieldOffset);
768 mangleNumber(VBTableOffset);
771void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
772 const CXXRecordDecl *RD,
const ValueDecl *VD) {
778 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
779 return mangleMemberDataPointer(RD, VD,
nullptr, QualType(),
"");
787 mangleNestedName(VD);
789 mangleUnqualifiedName(VD);
793void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
794 const CXXRecordDecl *RD,
const CXXMethodDecl *MD,
795 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
811 case MSInheritanceModel::Single: Code =
'1';
break;
812 case MSInheritanceModel::Multiple: Code =
'H';
break;
813 case MSInheritanceModel::Virtual: Code =
'I';
break;
814 case MSInheritanceModel::Unspecified: Code =
'J';
break;
825 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
826 LangOptions::MSVC2019) &&
828 !TemplateArgType.
isNull()) {
830 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
835 MicrosoftVTableContext *VTContext =
837 MethodVFTableLocation ML =
839 mangleVirtualMemPtrThunk(MD, ML);
843 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
848 mangleFunctionEncoding(MD,
true);
851 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
852 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
855 if (IM == MSInheritanceModel::Single) {
856 Out << Prefix <<
"0A@";
859 if (IM == MSInheritanceModel::Unspecified)
861 Out << Prefix << Code;
865 mangleNumber(
static_cast<uint32_t>(NVOffset));
867 mangleNumber(VBPtrOffset);
869 mangleNumber(VBTableOffset);
872void MicrosoftCXXNameMangler::mangleFunctionPointer(
873 const FunctionDecl *FD,
const NonTypeTemplateParmDecl *PD,
874 QualType TemplateArgType) {
881 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
882 LangOptions::MSVC2019) &&
884 !TemplateArgType.
isNull()) {
886 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
891 mangleFunctionEncoding(FD,
true);
894void MicrosoftCXXNameMangler::mangleVarDecl(
const VarDecl *VD,
895 const NonTypeTemplateParmDecl *PD,
896 QualType TemplateArgType) {
903 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
904 LangOptions::MSVC2019) &&
906 !TemplateArgType.
isNull()) {
908 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
913 mangleVariableEncoding(VD);
916void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
917 const CXXRecordDecl *RD,
const CXXMethodDecl *MD) {
925 return mangleMemberFunctionPointer(RD, MD,
nullptr, QualType(),
"");
933 MicrosoftVTableContext *VTContext =
935 MethodVFTableLocation ML =
937 mangleVirtualMemPtrThunk(MD, ML);
940 mangleFunctionEncoding(MD,
true);
944void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
945 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML) {
947 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
948 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
954 mangleNumber(OffsetInVFTable);
956 mangleCallingConvention(MD->
getType()->
castAs<FunctionProtoType>(),
960void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {
964 mangleUnqualifiedName(GD);
966 mangleNestedName(GD);
972void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
973 mangleNumber(llvm::APSInt(llvm::APInt(64, Number),
false));
976void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
981 unsigned Width = std::max(
Number.getBitWidth(), 64U);
990 if (
Value.isNegative()) {
997void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
1000 switch (APFloat::SemanticsToEnum(
Number.getSemantics())) {
1001 case APFloat::S_IEEEsingle:
Out <<
'A';
break;
1002 case APFloat::S_IEEEdouble:
Out <<
'B';
break;
1006 case APFloat::S_IEEEhalf:
Out <<
'V';
break;
1007 case APFloat::S_BFloat:
Out <<
'W';
break;
1008 case APFloat::S_x87DoubleExtended:
Out <<
'X';
break;
1009 case APFloat::S_IEEEquad:
Out <<
'Y';
break;
1010 case APFloat::S_PPCDoubleDouble:
Out <<
'Z';
break;
1011 case APFloat::S_PPCDoubleDoubleLegacy:
1012 case APFloat::S_Float8E5M2:
1013 case APFloat::S_Float8E4M3:
1014 case APFloat::S_Float8E4M3FN:
1015 case APFloat::S_Float8E5M2FNUZ:
1016 case APFloat::S_Float8E4M3FNUZ:
1017 case APFloat::S_Float8E4M3B11FNUZ:
1018 case APFloat::S_Float8E3M4:
1019 case APFloat::S_FloatTF32:
1020 case APFloat::S_Float8E8M0FNU:
1021 case APFloat::S_Float6E3M2FN:
1022 case APFloat::S_Float6E2M3FN:
1023 case APFloat::S_Float4E2M1FN:
1024 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
1027 mangleBits(
Number.bitcastToAPInt());
1030void MicrosoftCXXNameMangler::mangleBits(llvm::APInt
Value) {
1039 llvm::SmallString<32> EncodedNumberBuffer;
1041 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
1042 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1043 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1052 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1061 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1062 TemplateArgs = &Spec->getTemplateArgs();
1063 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1068 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1069 TemplateArgs = &Spec->getTemplateArgs();
1070 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1076void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
1077 DeclarationName Name) {
1085 const TemplateArgumentList *TemplateArgs =
nullptr;
1086 if (GlobalDecl TD =
isTemplate(GD, TemplateArgs)) {
1091 mangleTemplateInstantiationName(TD, *TemplateArgs);
1114 ArgBackRefMap::iterator
Found = TemplateArgBackReferences.find(ND);
1115 if (
Found == TemplateArgBackReferences.end()) {
1117 TemplateArgStringMap::iterator
Found = TemplateArgStrings.find(ND);
1118 if (
Found == TemplateArgStrings.end()) {
1120 llvm::SmallString<64> TemplateMangling;
1121 llvm::raw_svector_ostream Stream(TemplateMangling);
1122 MicrosoftCXXNameMangler
Extra(Context, Stream);
1123 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1126 mangleSourceName(TemplateMangling);
1130 BackRefVec::iterator StringFound =
1131 llvm::find(NameBackReferences, TemplateMangling);
1132 if (StringFound != NameBackReferences.end()) {
1133 TemplateArgBackReferences[ND] =
1134 StringFound - NameBackReferences.begin();
1136 TemplateArgStrings[ND] =
1137 TemplateArgStringStorage.save(TemplateMangling.str());
1156 ->getTemplatedDecl()
1159 bool IsOCLDeviceStub =
1161 DeviceKernelAttr::isOpenCLSpelling(
1162 ND->
getAttr<DeviceKernelAttr>()) &&
1166 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1167 else if (IsOCLDeviceStub)
1169 (llvm::Twine(
"__clang_ocl_kern_imp_") + II->getName()).str());
1171 mangleSourceName(II->getName());
1176 assert(ND &&
"mangling empty name without declaration");
1178 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1179 if (NS->isAnonymousNamespace()) {
1180 llvm::SmallString<16> Name(
"?A0x");
1181 Name += Context.getAnonymousNamespaceHash();
1182 mangleSourceName(Name);
1187 if (
const DecompositionDecl *DD = dyn_cast<DecompositionDecl>(ND)) {
1190 llvm::SmallString<64> Name(
"$S");
1192 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1193 mangleSourceName(Name);
1197 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1200 assert(RD &&
"expected variable decl to have a record type");
1204 llvm::SmallString<64> Name(
"$S");
1206 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1207 mangleSourceName(Name.str());
1211 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1214 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1215 llvm::raw_svector_ostream GUIDOS(GUID);
1216 Context.mangleMSGuidDecl(GD, GUIDOS);
1217 mangleSourceName(GUID);
1221 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1223 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1224 TPO->getValue(), TplArgKind::ClassNTTP);
1232 "Typedef should not be in another decl context!");
1234 "Typedef was not named!");
1239 if (
const CXXRecordDecl *
Record = dyn_cast<CXXRecordDecl>(TD)) {
1240 if (
Record->isLambda()) {
1241 llvm::SmallString<10> Name(
"<lambda_");
1243 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1244 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1246 const ParmVarDecl *Parm =
1247 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1248 const FunctionDecl *
Func =
1252 unsigned DefaultArgNo =
1254 Name += llvm::utostr(DefaultArgNo);
1258 if (LambdaManglingNumber)
1259 LambdaId = LambdaManglingNumber;
1261 LambdaId = Context.getLambdaId(
Record);
1263 Name += llvm::utostr(LambdaId);
1266 mangleSourceName(Name);
1270 if (LambdaManglingNumber && LambdaContextDecl) {
1281 llvm::SmallString<64> Name;
1282 if (DeclaratorDecl *DD =
1286 Name +=
"<unnamed-type-";
1287 Name += DD->getName();
1288 }
else if (TypedefNameDecl *TND =
1293 Name +=
"<unnamed-type-";
1294 Name += TND->getName();
1299 Name +=
"<unnamed-enum-";
1300 Name += ED->enumerator_begin()->getName();
1303 Name +=
"<unnamed-type-$S";
1304 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1307 mangleSourceName(Name.str());
1317 llvm::SmallString<64> Name;
1318 mangleSourceName(Name.str());
1323 if (isStructorDecl(ND)) {
1337 if (isStructorDecl(ND))
1340 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1354 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1359 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1364 llvm_unreachable(
"Can't mangle a deduction guide name!");
1367 llvm_unreachable(
"Can't mangle a using directive name!");
1373void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {
1376 if (
const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1377 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1378 mangleSourceName(
"<unnamed-tag>");
1380 const DeclContext *DC = getEffectiveDeclContext(ND);
1384 if (Context.getNextDiscriminator(ND, Disc)) {
1391 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1393 [](StringRef Name,
const unsigned Discriminator,
1394 const unsigned ParameterDiscriminator) -> std::string {
1396 llvm::raw_string_ostream Stream(Buffer);
1399 Stream <<
'_' << Discriminator;
1400 if (ParameterDiscriminator)
1401 Stream <<
'_' << ParameterDiscriminator;
1405 unsigned Discriminator = BD->getBlockManglingNumber();
1407 Discriminator = Context.getBlockId(BD,
false);
1412 unsigned ParameterDiscriminator = 0;
1413 if (
const auto *MC = BD->getBlockManglingContextDecl())
1414 if (
const auto *P = dyn_cast<ParmVarDecl>(MC))
1415 if (
const auto *F = dyn_cast<FunctionDecl>(P->getDeclContext()))
1416 ParameterDiscriminator =
1417 F->getNumParams() - P->getFunctionScopeIndex();
1419 DC = getEffectiveDeclContext(BD);
1422 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1423 ParameterDiscriminator));
1428 if (
const auto *MC = BD->getBlockManglingContextDecl())
1430 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1431 mangleUnqualifiedName(ND);
1435 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1444 if (PointersAre64Bit)
1447 mangleArtificialTagType(TagTypeKind::Struct,
1448 Discriminate(
"__block_literal", Discriminator,
1449 ParameterDiscriminator));
1457 }
else if (
const ObjCMethodDecl *
Method = dyn_cast<ObjCMethodDecl>(DC)) {
1461 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1462 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1465 mangleUnqualifiedName(ND);
1468 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1478void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1494 llvm_unreachable(
"not expecting a COMDAT");
1496 llvm_unreachable(
"not expecting a unified dtor type");
1498 llvm_unreachable(
"Unsupported dtor type?");
1502 SourceLocation Loc) {
1507 case OO_New:
Out <<
"?2";
break;
1509 case OO_Delete:
Out <<
"?3";
break;
1511 case OO_Equal:
Out <<
"?4";
break;
1513 case OO_GreaterGreater:
Out <<
"?5";
break;
1515 case OO_LessLess:
Out <<
"?6";
break;
1517 case OO_Exclaim:
Out <<
"?7";
break;
1519 case OO_EqualEqual:
Out <<
"?8";
break;
1521 case OO_ExclaimEqual:
Out <<
"?9";
break;
1523 case OO_Subscript:
Out <<
"?A";
break;
1526 case OO_Arrow:
Out <<
"?C";
break;
1528 case OO_Star:
Out <<
"?D";
break;
1530 case OO_PlusPlus:
Out <<
"?E";
break;
1532 case OO_MinusMinus:
Out <<
"?F";
break;
1534 case OO_Minus:
Out <<
"?G";
break;
1536 case OO_Plus:
Out <<
"?H";
break;
1538 case OO_Amp:
Out <<
"?I";
break;
1540 case OO_ArrowStar:
Out <<
"?J";
break;
1542 case OO_Slash:
Out <<
"?K";
break;
1544 case OO_Percent:
Out <<
"?L";
break;
1546 case OO_Less:
Out <<
"?M";
break;
1548 case OO_LessEqual:
Out <<
"?N";
break;
1550 case OO_Greater:
Out <<
"?O";
break;
1552 case OO_GreaterEqual:
Out <<
"?P";
break;
1554 case OO_Comma:
Out <<
"?Q";
break;
1556 case OO_Call:
Out <<
"?R";
break;
1558 case OO_Tilde:
Out <<
"?S";
break;
1560 case OO_Caret:
Out <<
"?T";
break;
1562 case OO_Pipe:
Out <<
"?U";
break;
1564 case OO_AmpAmp:
Out <<
"?V";
break;
1566 case OO_PipePipe:
Out <<
"?W";
break;
1568 case OO_StarEqual:
Out <<
"?X";
break;
1570 case OO_PlusEqual:
Out <<
"?Y";
break;
1572 case OO_MinusEqual:
Out <<
"?Z";
break;
1574 case OO_SlashEqual:
Out <<
"?_0";
break;
1576 case OO_PercentEqual:
Out <<
"?_1";
break;
1578 case OO_GreaterGreaterEqual:
Out <<
"?_2";
break;
1580 case OO_LessLessEqual:
Out <<
"?_3";
break;
1582 case OO_AmpEqual:
Out <<
"?_4";
break;
1584 case OO_PipeEqual:
Out <<
"?_5";
break;
1586 case OO_CaretEqual:
Out <<
"?_6";
break;
1615 case OO_Array_New:
Out <<
"?_U";
break;
1617 case OO_Array_Delete:
Out <<
"?_V";
break;
1619 case OO_Coawait:
Out <<
"?__L";
break;
1621 case OO_Spaceship:
Out <<
"?__M";
break;
1623 case OO_Conditional: {
1624 Error(Loc,
"conditional operator");
1630 llvm_unreachable(
"Not an overloaded operator");
1634void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1636 BackRefVec::iterator
Found = llvm::find(NameBackReferences, Name);
1637 if (
Found == NameBackReferences.end()) {
1638 if (NameBackReferences.size() < 10)
1639 NameBackReferences.push_back(std::string(Name));
1642 Out << (
Found - NameBackReferences.begin());
1646void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1647 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1650void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1651 GlobalDecl GD,
const TemplateArgumentList &TemplateArgs) {
1657 ArgBackRefMap OuterFunArgsContext;
1658 ArgBackRefMap OuterTemplateArgsContext;
1659 BackRefVec OuterTemplateContext;
1660 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1661 NameBackReferences.swap(OuterTemplateContext);
1662 FunArgBackReferences.swap(OuterFunArgsContext);
1663 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1664 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1666 mangleUnscopedTemplateName(GD);
1670 NameBackReferences.swap(OuterTemplateContext);
1671 FunArgBackReferences.swap(OuterFunArgsContext);
1672 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1673 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1676void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {
1679 mangleUnqualifiedName(GD);
1682void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1683 const llvm::APSInt &
Value,
const NonTypeTemplateParmDecl *PD,
1684 QualType TemplateArgType) {
1693 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1694 LangOptions::MSVC2019) &&
1696 !TemplateArgType.
isNull()) {
1698 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
1703 mangleNumber(
Value);
1706void MicrosoftCXXNameMangler::mangleExpression(
1707 const Expr *E,
const NonTypeTemplateParmDecl *PD) {
1709 if (std::optional<llvm::APSInt>
Value =
1720void MicrosoftCXXNameMangler::mangleTemplateArgs(
1721 const TemplateDecl *TD,
const TemplateArgumentList &TemplateArgs) {
1724 assert(TPL->
size() == TemplateArgs.
size() &&
1725 "size mismatch between args and parms!");
1727 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1728 const TemplateArgument &TA = TemplateArgs[i];
1735 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1743 if (!T->isPointerType() || !
V.isLValue() || !
V.hasLValuePath() ||
1747 QualType BaseT =
V.getLValueBase().getType();
1748 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1749 V.getLValuePath()[0].getAsArrayIndex() != 0)
1752 V.getLValueBase().dyn_cast<const ValueDecl *>());
1755void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1756 const TemplateArgument &TA,
1757 const NamedDecl *Parm) {
1795 llvm_unreachable(
"Can't mangle null template arguments!");
1797 llvm_unreachable(
"Can't mangle template expansion arguments!");
1800 mangleType(T, SourceRange(), QMM_Escape);
1806 mangleMemberDataPointer(
1810 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1811 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1823 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1824 TPO->getValue(), TplArgKind::ClassNTTP);
1825 }
else if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1841 if (
const MemberPointerType *MPT = T->
getAs<MemberPointerType>()) {
1842 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1843 if (MPT->isMemberFunctionPointerType() &&
1845 mangleMemberFunctionPointer(RD,
nullptr,
nullptr, QualType());
1848 if (MPT->isMemberDataPointer()) {
1850 mangleMemberDataPointer(RD,
nullptr,
nullptr, QualType());
1860 mangleIntegerLiteral(llvm::APSInt::get(-1),
1866 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1876 return mangleTemplateArg(
1882 ->getContainedDeducedType()) {
1888 TplArgKind::StructuralValue,
1896 if (TemplateArgs.empty()) {
1901 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(
1902 LangOptions::MSVC2015)
1908 llvm_unreachable(
"unexpected template parameter decl!");
1910 for (
const TemplateArgument &PA : TemplateArgs)
1911 mangleTemplateArg(TD, PA, Parm);
1916 const NamedDecl *ND =
1918 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1924 llvm_unreachable(
"unexpected template template NamedDecl!");
1931void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
1934 bool WithScalarType) {
1935 switch (
V.getKind()) {
1941 mangleType(T, SourceRange(), QMM_Escape);
1947 mangleType(T, SourceRange(), QMM_Escape);
1949 mangleNumber(
V.getInt());
1954 mangleType(T, SourceRange(), QMM_Escape);
1955 mangleFloat(
V.getFloat());
1960 mangleType(T, SourceRange(), QMM_Escape);
1962 APValue::LValueBase
Base =
V.getLValueBase();
1966 if (
V.isLValueOnePastTheEnd()) {
1968 auto *VD =
Base.dyn_cast<
const ValueDecl *>();
1975 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1977 if (
Base.isNull()) {
1983 mangleNumber(
V.getLValueOffset().getQuantity());
1984 }
else if (!
V.hasLValuePath()) {
1986 Error(
"template argument (extension not comaptible with ms mangler)");
1988 }
else if (
auto *VD =
Base.dyn_cast<
const ValueDecl*>()) {
1992 Error(
"template argument (undeclared base)");
1999 SmallVector<char, 2> EntryTypes;
2001 QualType ET =
Base.getType();
2002 for (APValue::LValuePathEntry E :
V.getLValuePath()) {
2004 EntryTypes.push_back(
'C');
2005 EntryManglers.push_back([
this, I = E.getAsArrayIndex()] {
2010 ET = AT->getElementType();
2014 const Decl *D = E.getAsBaseOrMember().getPointer();
2015 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2027 EntryTypes.push_back(
'6');
2028 EntryManglers.push_back([
this, D] {
2034 for (
auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
2037 auto *VD =
Base.dyn_cast<
const ValueDecl*>();
2039 Error(
"template argument (null value decl)");
2042 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
2056 mangleType(T, SourceRange(), QMM_Escape);
2058 const CXXRecordDecl *RD =
2059 T->
castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
2060 const ValueDecl *D =
V.getMemberPointerDecl();
2061 if (TAK == TplArgKind::ClassNTTP) {
2063 mangleMemberDataPointerInClassNTTP(RD, D);
2065 mangleMemberFunctionPointerInClassNTTP(RD,
2066 cast_or_null<CXXMethodDecl>(D));
2069 mangleMemberDataPointer(RD, D,
nullptr, QualType(),
"");
2071 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D),
nullptr,
2079 mangleType(T, SourceRange(), QMM_Escape);
2081 assert(RD &&
"unexpected type for record value");
2083 unsigned BaseIndex = 0;
2084 for (
const CXXBaseSpecifier &B : RD->
bases())
2085 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
2086 for (
const FieldDecl *FD : RD->
fields())
2087 if (!FD->isUnnamedBitField())
2088 mangleTemplateArgValue(FD->
getType(),
2089 V.getStructField(FD->getFieldIndex()), TAK,
2097 mangleType(T, SourceRange(), QMM_Escape);
2098 if (
const FieldDecl *FD =
V.getUnionField()) {
2099 mangleUnqualifiedName(FD);
2100 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
2108 mangleType(T, SourceRange(), QMM_Escape);
2110 mangleNumber(
V.getComplexIntReal());
2112 mangleNumber(
V.getComplexIntImag());
2118 mangleType(T, SourceRange(), QMM_Escape);
2119 mangleFloat(
V.getComplexFloatReal());
2120 mangleFloat(
V.getComplexFloatImag());
2126 QualType ElemT = getASTContext().getAsArrayType(T)->getElementType();
2127 mangleType(ElemT, SourceRange(), QMM_Escape);
2128 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
2129 const APValue &ElemV = I <
V.getArrayInitializedElts()
2130 ?
V.getArrayInitializedElt(I)
2131 :
V.getArrayFiller();
2132 mangleTemplateArgValue(ElemT, ElemV, TAK);
2143 mangleType(T, SourceRange(), QMM_Escape);
2145 QualType ElemT = T->
castAs<VectorType>()->getElementType();
2146 mangleType(ElemT, SourceRange(), QMM_Escape);
2147 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
2149 mangleTemplateArgValue(ElemT, ElemV, TAK);
2157 Error(
"template argument (value type: matrix)");
2162 Error(
"template argument (value type: address label diff)");
2167 Error(
"template argument (value type: fixed point)");
2173void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2174 llvm::SmallString<64> TemplateMangling;
2175 llvm::raw_svector_ostream Stream(TemplateMangling);
2176 MicrosoftCXXNameMangler
Extra(Context, Stream);
2179 Extra.mangleSourceName(
"Protocol");
2180 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2182 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2185void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType
Type,
2187 SourceRange Range) {
2188 llvm::SmallString<64> TemplateMangling;
2189 llvm::raw_svector_ostream Stream(TemplateMangling);
2190 MicrosoftCXXNameMangler
Extra(Context, Stream);
2198 Extra.mangleSourceName(
"Autoreleasing");
2201 Extra.mangleSourceName(
"Strong");
2204 Extra.mangleSourceName(
"Weak");
2207 Extra.manglePointerCVQualifiers(Quals);
2208 Extra.manglePointerExtQualifiers(Quals,
Type);
2211 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2214void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *T,
2216 SourceRange Range) {
2217 llvm::SmallString<64> TemplateMangling;
2218 llvm::raw_svector_ostream Stream(TemplateMangling);
2219 MicrosoftCXXNameMangler
Extra(Context, Stream);
2222 Extra.mangleSourceName(
"KindOf");
2223 Extra.mangleType(QualType(T, 0)
2224 .stripObjCKindOfType(getASTContext())
2225 ->castAs<ObjCObjectType>(),
2228 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2231void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
2289 if (HasConst && HasVolatile) {
2291 }
else if (HasVolatile) {
2293 }
else if (HasConst) {
2299 if (HasConst && HasVolatile) {
2301 }
else if (HasVolatile) {
2303 }
else if (HasConst) {
2314MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2317 switch (RefQualifier) {
2331void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
2332 QualType PointeeType) {
2334 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2347void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {
2353 mangleNumber(PointerAuth.
getKey());
2358void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
2366 if (HasConst && HasVolatile) {
2368 }
else if (HasVolatile) {
2370 }
else if (HasConst) {
2377void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType T,
2378 SourceRange Range) {
2387 if (
const auto *DT = T->
getAs<DecayedType>()) {
2388 QualType OriginalType = DT->getOriginalType();
2391 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2392 OriginalType = getASTContext().getIncompleteArrayType(
2393 AT->getElementType(), AT->getSizeModifier(),
2394 AT->getIndexTypeCVRQualifiers());
2408 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2410 if (
Found == FunArgBackReferences.end()) {
2411 size_t OutSizeBefore =
Out.tell();
2413 mangleType(T, Range, QMM_Drop);
2418 bool LongerThanOneChar = (
Out.tell() - OutSizeBefore > 1);
2419 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2420 size_t Size = FunArgBackReferences.size();
2421 FunArgBackReferences[TypePtr] =
Size;
2428void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2429 const PassObjectSizeAttr *POSA) {
2430 int Type = POSA->getType();
2431 bool Dynamic = POSA->isDynamic();
2433 auto Iter = PassObjectSizeArgs.insert({
Type,
Dynamic}).first;
2434 auto *TypePtr = (
const void *)&*Iter;
2435 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2437 if (
Found == FunArgBackReferences.end()) {
2439 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2440 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2443 if (FunArgBackReferences.size() < 10) {
2444 size_t Size = FunArgBackReferences.size();
2445 FunArgBackReferences[TypePtr] =
Size;
2452void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
2454 SourceRange Range) {
2469 llvm::SmallString<32> ASMangling;
2470 llvm::raw_svector_ostream Stream(ASMangling);
2471 MicrosoftCXXNameMangler
Extra(Context, Stream);
2477 Extra.mangleSourceName(
"_AS");
2478 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2482 llvm_unreachable(
"Not a language specific address space");
2483 case LangAS::opencl_global:
2484 Extra.mangleSourceName(
"_ASCLglobal");
2486 case LangAS::opencl_global_device:
2487 Extra.mangleSourceName(
"_ASCLdevice");
2489 case LangAS::opencl_global_host:
2490 Extra.mangleSourceName(
"_ASCLhost");
2492 case LangAS::opencl_local:
2493 Extra.mangleSourceName(
"_ASCLlocal");
2495 case LangAS::opencl_constant:
2496 Extra.mangleSourceName(
"_ASCLconstant");
2498 case LangAS::opencl_private:
2499 Extra.mangleSourceName(
"_ASCLprivate");
2501 case LangAS::opencl_generic:
2502 Extra.mangleSourceName(
"_ASCLgeneric");
2504 case LangAS::cuda_device:
2505 Extra.mangleSourceName(
"_ASCUdevice");
2507 case LangAS::cuda_constant:
2508 Extra.mangleSourceName(
"_ASCUconstant");
2510 case LangAS::cuda_shared:
2511 Extra.mangleSourceName(
"_ASCUshared");
2513 case LangAS::ptr32_sptr:
2514 case LangAS::ptr32_uptr:
2516 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2520 Extra.mangleType(T, Range, QMM_Escape);
2521 mangleQualifiers(Qualifiers(),
false);
2522 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2525void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T,
2526 QualifierMangleMode QMM) {
2527 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2528 LangOptions::MSVC2019) &&
2529 "Cannot mangle MSVC 2017 auto return types!");
2535 if (QMM == QMM_Result)
2537 if (QMM != QMM_Drop)
2538 mangleQualifiers(Quals,
false);
2539 Out << (AT->isDecltypeAuto() ?
"_T" :
"_P");
2551 mangleQualifiers(Quals,
false);
2554 llvm_unreachable(
"QMM_Escape unexpected");
2559 case Type::MemberPointer:
2565 case Type::LValueReference:
2568 case Type::RValueReference:
2572 llvm_unreachable(
"Invalid type expected");
2576void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
2577 QualifierMangleMode QMM) {
2583 if (
const ArrayType *AT = getASTContext().getAsArrayType(T)) {
2586 if (QMM == QMM_Mangle)
2588 else if (QMM == QMM_Escape || QMM == QMM_Result)
2590 mangleArrayType(AT);
2603 if (
const FunctionType *FT = dyn_cast<FunctionType>(T)) {
2605 mangleFunctionType(FT);
2608 mangleQualifiers(Quals,
false);
2611 if (!IsPointer && Quals) {
2613 mangleQualifiers(Quals,
false);
2621 if ((!IsPointer && Quals) ||
isa<TagType>(T) || isArtificialTagType(T)) {
2623 mangleQualifiers(Quals,
false);
2631#define ABSTRACT_TYPE(CLASS, PARENT)
2632#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2634 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2636#define TYPE(CLASS, PARENT) \
2638 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2640#include "clang/AST/TypeNodes.inc"
2642#undef NON_CANONICAL_TYPE
2647void MicrosoftCXXNameMangler::mangleType(
const BuiltinType *T, Qualifiers,
2648 SourceRange Range) {
2677 case BuiltinType::Void:
2680 case BuiltinType::SChar:
2683 case BuiltinType::Char_U:
2684 case BuiltinType::Char_S:
2687 case BuiltinType::UChar:
2690 case BuiltinType::Short:
2693 case BuiltinType::UShort:
2696 case BuiltinType::Int:
2699 case BuiltinType::UInt:
2702 case BuiltinType::Long:
2705 case BuiltinType::ULong:
2708 case BuiltinType::Float:
2711 case BuiltinType::Double:
2715 case BuiltinType::LongDouble:
2718 case BuiltinType::LongLong:
2721 case BuiltinType::ULongLong:
2724 case BuiltinType::Int128:
2727 case BuiltinType::UInt128:
2730 case BuiltinType::Bool:
2733 case BuiltinType::Char8:
2736 case BuiltinType::Char16:
2739 case BuiltinType::Char32:
2742 case BuiltinType::WChar_S:
2743 case BuiltinType::WChar_U:
2747#define BUILTIN_TYPE(Id, SingletonId)
2748#define PLACEHOLDER_TYPE(Id, SingletonId) \
2749 case BuiltinType::Id:
2750#include "clang/AST/BuiltinTypes.def"
2751 case BuiltinType::Dependent:
2752 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2754 case BuiltinType::ObjCId:
2755 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2757 case BuiltinType::ObjCClass:
2758 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2760 case BuiltinType::ObjCSel:
2761 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2764#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2765 case BuiltinType::Id: \
2766 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2768#include "clang/Basic/OpenCLImageTypes.def"
2769 case BuiltinType::OCLSampler:
2771 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2773 case BuiltinType::OCLEvent:
2775 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2777 case BuiltinType::OCLClkEvent:
2779 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2781 case BuiltinType::OCLQueue:
2783 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2785 case BuiltinType::OCLReserveID:
2787 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2789#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2790 case BuiltinType::Id: \
2791 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2793#include "clang/Basic/OpenCLExtensionTypes.def"
2795 case BuiltinType::NullPtr:
2799 case BuiltinType::Float16:
2800 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2803 case BuiltinType::Half:
2804 if (!getASTContext().getLangOpts().
HLSL)
2805 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2806 else if (getASTContext().getLangOpts().NativeHalfType)
2812 case BuiltinType::BFloat16:
2813 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2816 case BuiltinType::MFloat8:
2817 mangleArtificialTagType(TagTypeKind::Struct,
"__mfp8", {
"__clang"});
2820#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2821 case BuiltinType::Id: \
2822 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2823 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2826#include "clang/Basic/WebAssemblyReferenceTypes.def"
2828#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2829 case BuiltinType::Id: \
2830 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2832#include "clang/Basic/HLSLIntangibleTypes.def"
2834 case BuiltinType::SveBool:
2838 case BuiltinType::SveInt8:
2841 case BuiltinType::SveInt16:
2844 case BuiltinType::SveInt32:
2847 case BuiltinType::SveInt64:
2851 case BuiltinType::SveUint8:
2854 case BuiltinType::SveUint16:
2857 case BuiltinType::SveUint32:
2860 case BuiltinType::SveUint64:
2864 case BuiltinType::SveBFloat16:
2867 case BuiltinType::SveFloat16:
2870 case BuiltinType::SveFloat32:
2873 case BuiltinType::SveFloat64:
2877 case BuiltinType::SveInt8x2:
2880 case BuiltinType::SveInt16x2:
2883 case BuiltinType::SveInt32x2:
2886 case BuiltinType::SveInt64x2:
2890 case BuiltinType::SveUint8x2:
2893 case BuiltinType::SveUint16x2:
2896 case BuiltinType::SveUint32x2:
2899 case BuiltinType::SveUint64x2:
2903 case BuiltinType::SveBFloat16x2:
2906 case BuiltinType::SveFloat16x2:
2909 case BuiltinType::SveFloat32x2:
2912 case BuiltinType::SveFloat64x2:
2916 case BuiltinType::SveInt8x3:
2919 case BuiltinType::SveInt16x3:
2922 case BuiltinType::SveInt32x3:
2925 case BuiltinType::SveInt64x3:
2929 case BuiltinType::SveUint8x3:
2932 case BuiltinType::SveUint16x3:
2935 case BuiltinType::SveUint32x3:
2938 case BuiltinType::SveUint64x3:
2942 case BuiltinType::SveBFloat16x3:
2945 case BuiltinType::SveFloat16x3:
2948 case BuiltinType::SveFloat32x3:
2951 case BuiltinType::SveFloat64x3:
2955 case BuiltinType::SveInt8x4:
2958 case BuiltinType::SveInt16x4:
2961 case BuiltinType::SveInt32x4:
2964 case BuiltinType::SveInt64x4:
2968 case BuiltinType::SveUint8x4:
2971 case BuiltinType::SveUint16x4:
2974 case BuiltinType::SveUint32x4:
2977 case BuiltinType::SveUint64x4:
2981 case BuiltinType::SveBFloat16x4:
2984 case BuiltinType::SveFloat16x4:
2987 case BuiltinType::SveFloat32x4:
2990 case BuiltinType::SveFloat64x4:
2996 case BuiltinType::SveMFloat8:
2997 mangleArtificialTagType(TagTypeKind::Struct,
"__SVMfloat8_t", {
"__clang"});
3000 case BuiltinType::SveMFloat8x2:
3001 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svmfloat8x2_t",
3005 case BuiltinType::SveMFloat8x3:
3006 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svmfloat8x3_t",
3010 case BuiltinType::SveMFloat8x4:
3011 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svmfloat8x4_t",
3015 case BuiltinType::SveBoolx2:
3016 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svboolx2_t",
3020 case BuiltinType::SveBoolx4:
3021 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svboolx4_t",
3025 case BuiltinType::SveCount:
3026 mangleArtificialTagType(TagTypeKind::Struct,
"__SVCount_t", {
"__clang"});
3039void MicrosoftCXXNameMangler::mangleType(
const FunctionProtoType *T, Qualifiers,
3046 mangleFunctionType(T,
nullptr,
true);
3049 mangleFunctionType(T);
3052void MicrosoftCXXNameMangler::mangleType(
const FunctionNoProtoType *T,
3053 Qualifiers, SourceRange) {
3055 mangleFunctionType(T);
3058void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *T,
3059 const FunctionDecl *D,
3060 bool ForceThisQuals,
3061 bool MangleExceptionSpec) {
3064 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);
3069 bool IsInLambda =
false;
3070 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
3072 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
3076 HasThisQuals =
true;
3085 CC = getASTContext().getDefaultCallingConvention(
3094 manglePointerExtQualifiers(Quals, QualType());
3096 mangleQualifiers(Quals,
false);
3099 mangleCallingConvention(CC, Range);
3104 Out <<
"__clang_sme_attr" << SMEAttrs;
3117 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
3126 if (IsCtorClosure) {
3136 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
3138 ->
castAs<LValueReferenceType>()
3144 llvm_unreachable(
"unexpected constructor closure!");
3150 }
else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(D)) {
3161 mangleType(ResultType, Range, QMM_Result);
3162 }
else if (IsInLambda) {
3164 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
3165 "shouldn't need to mangle __auto_type!");
3169 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3175 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
3176 "shouldn't need to mangle __auto_type!");
3182 auto UseClangMangling = [](QualType ResultType) {
3183 QualType T = ResultType;
3192 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
3193 LangOptions::MSVC2019) &&
3194 !UseClangMangling(ResultType)) {
3203 ->
castAs<FunctionProtoType>();
3206 mangleAutoReturnType(ResultType, QMM_Result);
3212 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3218 mangleType(ResultType, Range, QMM_Result);
3234 for (
unsigned I = 0, E = Proto->
getNumParams(); I != E; ++I) {
3239 mangleFunctionArgumentType(Proto->
getParamType(I), Range);
3250 manglePassObjectSizeArg(P);
3259 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
3260 getASTContext().getLangOpts().isCompatibleWithMSVC(
3261 LangOptions::MSVC2017_5))
3262 mangleThrowSpecification(Proto);
3267void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
3292 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3302 llvm_unreachable(
"Unsupported access specifier");
3331void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC,
3332 SourceRange Range) {
3394 if (getASTContext().getLangOpts().RegCall4)
3403void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *T,
3404 SourceRange Range) {
3408void MicrosoftCXXNameMangler::mangleThrowSpecification(
3409 const FunctionProtoType *FT) {
3418void MicrosoftCXXNameMangler::mangleType(
const UnresolvedUsingType *T,
3419 Qualifiers, SourceRange Range) {
3430void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
3432 case TagTypeKind::Union:
3435 case TagTypeKind::Struct:
3436 case TagTypeKind::Interface:
3439 case TagTypeKind::Class:
3442 case TagTypeKind::Enum:
3447void MicrosoftCXXNameMangler::mangleType(
const EnumType *T, Qualifiers,
3451void MicrosoftCXXNameMangler::mangleType(
const RecordType *T, Qualifiers,
3455void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3465void MicrosoftCXXNameMangler::mangleArtificialTagType(
3467 ArrayRef<StringRef> NestedNames) {
3469 mangleTagTypeKind(TK);
3472 mangleSourceName(UnqualifiedName);
3474 for (StringRef N : llvm::reverse(NestedNames))
3475 mangleSourceName(N);
3488void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *T) {
3494void MicrosoftCXXNameMangler::mangleType(
const ConstantArrayType *T, Qualifiers,
3496 llvm_unreachable(
"Should have been special cased");
3498void MicrosoftCXXNameMangler::mangleType(
const VariableArrayType *T, Qualifiers,
3500 llvm_unreachable(
"Should have been special cased");
3502void MicrosoftCXXNameMangler::mangleType(
const DependentSizedArrayType *T,
3503 Qualifiers, SourceRange) {
3504 llvm_unreachable(
"Should have been special cased");
3506void MicrosoftCXXNameMangler::mangleType(
const IncompleteArrayType *T,
3507 Qualifiers, SourceRange) {
3508 llvm_unreachable(
"Should have been special cased");
3510void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *T) {
3511 QualType ElementTy(T, 0);
3512 SmallVector<llvm::APInt, 3> Dimensions;
3514 if (ElementTy->isConstantArrayType()) {
3515 const ConstantArrayType *CAT =
3516 getASTContext().getAsConstantArrayType(ElementTy);
3517 Dimensions.push_back(CAT->
getSize());
3519 }
else if (ElementTy->isIncompleteArrayType()) {
3520 const IncompleteArrayType *IAT =
3521 getASTContext().getAsIncompleteArrayType(ElementTy);
3522 Dimensions.push_back(llvm::APInt(32, 0));
3524 }
else if (ElementTy->isVariableArrayType()) {
3525 const VariableArrayType *VAT =
3526 getASTContext().getAsVariableArrayType(ElementTy);
3527 Dimensions.push_back(llvm::APInt(32, 0));
3529 }
else if (ElementTy->isDependentSizedArrayType()) {
3531 const DependentSizedArrayType *DSAT =
3532 getASTContext().getAsDependentSizedArrayType(ElementTy);
3542 mangleNumber(Dimensions.size());
3543 for (
const llvm::APInt &Dimension : Dimensions)
3544 mangleNumber(Dimension.getLimitedValue());
3545 mangleType(ElementTy, SourceRange(), QMM_Escape);
3548void MicrosoftCXXNameMangler::mangleType(
const ArrayParameterType *T,
3549 Qualifiers, SourceRange) {
3556void MicrosoftCXXNameMangler::mangleType(
const MemberPointerType *T,
3557 Qualifiers Quals, SourceRange Range) {
3559 manglePointerCVQualifiers(Quals);
3560 manglePointerExtQualifiers(Quals, PointeeType);
3561 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
3564 mangleFunctionType(FPT,
nullptr,
true);
3568 mangleType(PointeeType, Range, QMM_Drop);
3572void MicrosoftCXXNameMangler::mangleType(
const TemplateTypeParmType *T,
3573 Qualifiers, SourceRange Range) {
3576 llvm::SmallString<64> Name;
3578 Name += llvm::utostr(T->getDepth());
3580 Name += llvm::utostr(T->getIndex());
3582 mangleSourceName(Name);
3585void MicrosoftCXXNameMangler::mangleType(
const SubstTemplateTypeParmPackType *T,
3586 Qualifiers, SourceRange Range) {
3590void MicrosoftCXXNameMangler::mangleType(
const SubstBuiltinTemplatePackType *T,
3591 Qualifiers, SourceRange Range) {
3592 Error(
Range.getBegin(),
"substituted builtin template pack") <<
Range;
3598void MicrosoftCXXNameMangler::mangleType(
const PointerType *T, Qualifiers Quals,
3599 SourceRange Range) {
3601 manglePointerCVQualifiers(Quals);
3602 manglePointerExtQualifiers(Quals, PointeeType);
3603 manglePointerAuthQualifier(Quals);
3609 mangleType(PointeeType, Range);
3611 mangleAddressSpaceType(PointeeType, PointeeType.
getQualifiers(), Range);
3614void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectPointerType *T,
3615 Qualifiers Quals, SourceRange Range) {
3624 return mangleObjCLifetime(PointeeType, Quals, Range);
3626 manglePointerCVQualifiers(Quals);
3627 manglePointerExtQualifiers(Quals, PointeeType);
3628 mangleType(PointeeType, Range);
3634void MicrosoftCXXNameMangler::mangleType(
const LValueReferenceType *T,
3635 Qualifiers Quals, SourceRange Range) {
3639 manglePointerExtQualifiers(Quals, PointeeType);
3640 mangleType(PointeeType, Range);
3646void MicrosoftCXXNameMangler::mangleType(
const RValueReferenceType *T,
3647 Qualifiers Quals, SourceRange Range) {
3651 manglePointerExtQualifiers(Quals, PointeeType);
3652 mangleType(PointeeType, Range);
3655void MicrosoftCXXNameMangler::mangleType(
const ComplexType *T, Qualifiers,
3656 SourceRange Range) {
3659 llvm::SmallString<64> TemplateMangling;
3660 llvm::raw_svector_ostream Stream(TemplateMangling);
3661 MicrosoftCXXNameMangler
Extra(Context, Stream);
3663 Extra.mangleSourceName(
"_Complex");
3664 Extra.mangleType(ElementType, Range, QMM_Escape);
3666 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3674bool MicrosoftCXXNameMangler::isArtificialTagType(QualType T)
const {
3680 case Type::Vector: {
3689void MicrosoftCXXNameMangler::mangleType(
const VectorType *T, Qualifiers Quals,
3690 SourceRange Range) {
3692 const BuiltinType *ET = EltTy->
getAs<BuiltinType>();
3693 const BitIntType *BitIntTy = EltTy->
getAs<BitIntType>();
3694 assert((ET || BitIntTy) &&
3695 "vectors with non-builtin/_BitInt elements are unsupported");
3696 uint64_t Width = getASTContext().getTypeSize(T);
3699 size_t OutSizeBefore =
Out.tell();
3701 if (getASTContext().getTargetInfo().
getTriple().isX86() && ET) {
3702 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3703 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3704 }
else if (Width >= 128) {
3705 if (ET->
getKind() == BuiltinType::Float)
3706 mangleArtificialTagType(TagTypeKind::Union,
3707 "__m" + llvm::utostr(Width));
3708 else if (ET->
getKind() == BuiltinType::LongLong)
3709 mangleArtificialTagType(TagTypeKind::Union,
3710 "__m" + llvm::utostr(Width) +
'i');
3711 else if (ET->
getKind() == BuiltinType::Double)
3712 mangleArtificialTagType(TagTypeKind::Struct,
3713 "__m" + llvm::utostr(Width) +
'd');
3718 bool IsBuiltin =
Out.tell() != OutSizeBefore;
3724 llvm::SmallString<64> TemplateMangling;
3725 llvm::raw_svector_ostream Stream(TemplateMangling);
3726 MicrosoftCXXNameMangler
Extra(Context, Stream);
3728 Extra.mangleSourceName(
"__vector");
3729 Extra.mangleType(QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3733 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3737void MicrosoftCXXNameMangler::mangleType(
const ExtVectorType *T,
3738 Qualifiers Quals, SourceRange Range) {
3739 mangleType(
static_cast<const VectorType *
>(T), Quals, Range);
3742void MicrosoftCXXNameMangler::mangleType(
const DependentVectorType *T,
3743 Qualifiers, SourceRange Range) {
3747void MicrosoftCXXNameMangler::mangleType(
const DependentSizedExtVectorType *T,
3748 Qualifiers, SourceRange Range) {
3749 Error(
Range.getBegin(),
"dependent-sized extended vector type") <<
Range;
3752void MicrosoftCXXNameMangler::mangleType(
const ConstantMatrixType *T,
3753 Qualifiers quals, SourceRange Range) {
3756 llvm::SmallString<64> TemplateMangling;
3757 llvm::raw_svector_ostream Stream(TemplateMangling);
3758 MicrosoftCXXNameMangler
Extra(Context, Stream);
3762 Extra.mangleSourceName(
"__matrix");
3763 Extra.mangleType(EltTy, Range, QMM_Escape);
3765 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->
getNumRows()));
3768 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3771void MicrosoftCXXNameMangler::mangleType(
const DependentSizedMatrixType *T,
3772 Qualifiers quals, SourceRange Range) {
3776void MicrosoftCXXNameMangler::mangleType(
const DependentAddressSpaceType *T,
3777 Qualifiers, SourceRange Range) {
3781void MicrosoftCXXNameMangler::mangleType(
const ObjCInterfaceType *T, Qualifiers,
3784 mangleTagTypeKind(TagTypeKind::Struct);
3788void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectType *T,
3789 Qualifiers Quals, SourceRange Range) {
3790 if (T->isKindOfType())
3791 return mangleObjCKindOfType(T, Quals, Range);
3793 if (T->qual_empty() && !T->isSpecialized())
3794 return mangleType(T->getBaseType(), Range, QMM_Drop);
3796 ArgBackRefMap OuterFunArgsContext;
3797 ArgBackRefMap OuterTemplateArgsContext;
3798 BackRefVec OuterTemplateContext;
3800 FunArgBackReferences.swap(OuterFunArgsContext);
3801 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3802 NameBackReferences.swap(OuterTemplateContext);
3804 mangleTagTypeKind(TagTypeKind::Struct);
3808 mangleSourceName(
"objc_object");
3809 else if (T->isObjCClass())
3810 mangleSourceName(
"objc_class");
3812 mangleSourceName(T->getInterface()->getName());
3814 for (
const auto &Q : T->quals())
3815 mangleObjCProtocol(Q);
3817 if (T->isSpecialized())
3818 for (
const auto &TA : T->getTypeArgs())
3819 mangleType(TA, Range, QMM_Drop);
3825 FunArgBackReferences.swap(OuterFunArgsContext);
3826 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3827 NameBackReferences.swap(OuterTemplateContext);
3830void MicrosoftCXXNameMangler::mangleType(
const BlockPointerType *T,
3831 Qualifiers Quals, SourceRange Range) {
3833 manglePointerCVQualifiers(Quals);
3834 manglePointerExtQualifiers(Quals, PointeeType);
3838 mangleFunctionType(PointeeType->
castAs<FunctionProtoType>());
3841void MicrosoftCXXNameMangler::mangleType(
const InjectedClassNameType *,
3842 Qualifiers, SourceRange) {
3843 llvm_unreachable(
"Cannot mangle injected class name type.");
3846void MicrosoftCXXNameMangler::mangleType(
const TemplateSpecializationType *T,
3847 Qualifiers, SourceRange Range) {
3851void MicrosoftCXXNameMangler::mangleType(
const DependentNameType *T, Qualifiers,
3852 SourceRange Range) {
3856void MicrosoftCXXNameMangler::mangleType(
const PackExpansionType *T, Qualifiers,
3857 SourceRange Range) {
3861void MicrosoftCXXNameMangler::mangleType(
const PackIndexingType *T,
3862 Qualifiers Quals, SourceRange Range) {
3863 manglePointerCVQualifiers(Quals);
3864 mangleType(T->getSelectedType(), Range);
3867void MicrosoftCXXNameMangler::mangleType(
const TypeOfType *T, Qualifiers,
3868 SourceRange Range) {
3872void MicrosoftCXXNameMangler::mangleType(
const TypeOfExprType *T, Qualifiers,
3873 SourceRange Range) {
3877void MicrosoftCXXNameMangler::mangleType(
const DecltypeType *T, Qualifiers,
3878 SourceRange Range) {
3882void MicrosoftCXXNameMangler::mangleType(
const UnaryTransformType *T,
3883 Qualifiers, SourceRange Range) {
3887void MicrosoftCXXNameMangler::mangleType(
const AutoType *T, Qualifiers,
3888 SourceRange Range) {
3889 assert(T->getDeducedType().isNull() &&
"expecting a dependent type!");
3894void MicrosoftCXXNameMangler::mangleType(
3895 const DeducedTemplateSpecializationType *T, Qualifiers, SourceRange Range) {
3896 assert(T->getDeducedType().isNull() &&
"expecting a dependent type!");
3898 Error(
Range.getBegin(),
"deduced class template specialization type")
3902void MicrosoftCXXNameMangler::mangleType(
const AtomicType *T, Qualifiers,
3903 SourceRange Range) {
3906 llvm::SmallString<64> TemplateMangling;
3907 llvm::raw_svector_ostream Stream(TemplateMangling);
3908 MicrosoftCXXNameMangler
Extra(Context, Stream);
3910 Extra.mangleSourceName(
"_Atomic");
3911 Extra.mangleType(ValueType, Range, QMM_Escape);
3913 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3916void MicrosoftCXXNameMangler::mangleType(
const PipeType *T, Qualifiers,
3917 SourceRange Range) {
3920 llvm::SmallString<64> TemplateMangling;
3921 llvm::raw_svector_ostream Stream(TemplateMangling);
3922 MicrosoftCXXNameMangler
Extra(Context, Stream);
3924 Extra.mangleSourceName(
"ocl_pipe");
3925 Extra.mangleType(ElementType, Range, QMM_Escape);
3928 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3931void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
3934 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
3935 getASTContext().getSourceManager(),
3936 "Mangling declaration");
3938 msvc_hashing_ostream MHO(Out);
3940 if (
auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3942 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3943 return mangler.mangle(GD);
3946 if (
auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3948 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3949 return mangler.mangle(GD);
3952 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3953 return Mangler.mangle(GD);
3956void MicrosoftCXXNameMangler::mangleType(
const BitIntType *T, Qualifiers,
3957 SourceRange Range) {
3958 llvm::SmallString<64> TemplateMangling;
3959 llvm::raw_svector_ostream Stream(TemplateMangling);
3960 MicrosoftCXXNameMangler
Extra(Context, Stream);
3963 Extra.mangleSourceName(
"_UBitInt");
3965 Extra.mangleSourceName(
"_BitInt");
3966 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->
getNumBits()));
3968 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3971void MicrosoftCXXNameMangler::mangleType(
const DependentBitIntType *T,
3972 Qualifiers, SourceRange Range) {
3976void MicrosoftCXXNameMangler::mangleType(
const HLSLAttributedResourceType *T,
3977 Qualifiers, SourceRange Range) {
3978 llvm_unreachable(
"HLSL uses Itanium name mangling");
3981void MicrosoftCXXNameMangler::mangleType(
const HLSLInlineSpirvType *T,
3982 Qualifiers, SourceRange Range) {
3983 llvm_unreachable(
"HLSL uses Itanium name mangling");
3986void MicrosoftCXXNameMangler::mangleType(
const OverflowBehaviorType *T,
3987 Qualifiers, SourceRange Range) {
3988 QualType UnderlyingType = T->getUnderlyingType();
3990 llvm::SmallString<64> TemplateMangling;
3991 llvm::raw_svector_ostream Stream(TemplateMangling);
3992 MicrosoftCXXNameMangler
Extra(Context, Stream);
3994 if (T->isWrapKind()) {
3995 Extra.mangleSourceName(
"ObtWrap_");
3997 Extra.mangleSourceName(
"ObtTrap_");
3999 Extra.mangleType(UnderlyingType, Range, QMM_Escape);
4001 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
4030 MicrosoftCXXNameMangler &Mangler,
4037 llvm_unreachable(
"Unsupported access specifier");
4048 Out <<
'R' << AccessSpec;
4049 Mangler.mangleNumber(
4051 Mangler.mangleNumber(
4053 Mangler.mangleNumber(
4058 Mangler.mangleNumber(
4065 llvm_unreachable(
"Unsupported access specifier");
4079 llvm_unreachable(
"Unsupported access specifier");
4092void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
4093 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML,
4095 msvc_hashing_ostream MHO(Out);
4096 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4097 Mangler.getStream() <<
'?';
4098 Mangler.mangleVirtualMemPtrThunk(MD, ML);
4101void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
4102 const ThunkInfo &Thunk,
4105 msvc_hashing_ostream MHO(Out);
4106 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4107 Mangler.getStream() <<
'?';
4108 Mangler.mangleName(MD);
4117 assert(Thunk.
Method !=
nullptr &&
4118 "Thunk info should hold the overridee decl");
4120 const CXXMethodDecl *DeclForFPT = Thunk.
Method ? Thunk.
Method : MD;
4121 Mangler.mangleFunctionType(
4125void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
const CXXDestructorDecl *DD,
4127 const ThunkInfo &Thunk,
4134 msvc_hashing_ostream MHO(Out);
4135 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
4136 Mangler.getStream() <<
"??_E";
4138 auto &Adjustment = Thunk.
This;
4140 Mangler.mangleFunctionType(DD->
getType()->
castAs<FunctionProtoType>(), DD);
4143void MicrosoftMangleContextImpl::mangleCXXVFTable(
4144 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4150 msvc_hashing_ostream MHO(Out);
4151 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4152 if (Derived->
hasAttr<DLLImportAttr>())
4153 Mangler.getStream() <<
"??_S";
4155 Mangler.getStream() <<
"??_7";
4156 Mangler.mangleName(Derived);
4157 Mangler.getStream() <<
"6B";
4158 for (
const CXXRecordDecl *RD : BasePath)
4159 Mangler.mangleName(RD);
4160 Mangler.getStream() <<
'@';
4163void MicrosoftMangleContextImpl::mangleCXXVTable(
const CXXRecordDecl *Derived,
4166 mangleCXXVFTable(Derived, {},
Out);
4169void MicrosoftMangleContextImpl::mangleCXXVBTable(
4170 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4176 msvc_hashing_ostream MHO(Out);
4177 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4178 Mangler.getStream() <<
"??_8";
4179 Mangler.mangleName(Derived);
4180 Mangler.getStream() <<
"7B";
4181 for (
const CXXRecordDecl *RD : BasePath)
4182 Mangler.mangleName(RD);
4183 Mangler.getStream() <<
'@';
4186void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
4187 msvc_hashing_ostream MHO(Out);
4188 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4189 Mangler.getStream() <<
"??_R0";
4190 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4191 Mangler.getStream() <<
"@8";
4194void MicrosoftMangleContextImpl::mangleCXXRTTIName(
4195 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4196 MicrosoftCXXNameMangler Mangler(*
this, Out);
4197 Mangler.getStream() <<
'.';
4198 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4201void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
4202 const CXXRecordDecl *SrcRD,
const CXXRecordDecl *DstRD, raw_ostream &Out) {
4203 msvc_hashing_ostream MHO(Out);
4204 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4205 Mangler.getStream() <<
"??_K";
4206 Mangler.mangleName(SrcRD);
4207 Mangler.getStream() <<
"$C";
4208 Mangler.mangleName(DstRD);
4211void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T,
bool IsConst,
4216 msvc_hashing_ostream MHO(Out);
4217 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4218 Mangler.getStream() <<
"_TI";
4220 Mangler.getStream() <<
'C';
4222 Mangler.getStream() <<
'V';
4224 Mangler.getStream() <<
'U';
4225 Mangler.getStream() << NumEntries;
4226 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4229void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
4230 QualType T,
uint32_t NumEntries, raw_ostream &Out) {
4231 msvc_hashing_ostream MHO(Out);
4232 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4233 Mangler.getStream() <<
"_CTA";
4234 Mangler.getStream() << NumEntries;
4235 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4238void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4242 MicrosoftCXXNameMangler Mangler(*
this, Out);
4243 Mangler.getStream() <<
"_CT";
4245 llvm::SmallString<64> RTTIMangling;
4247 llvm::raw_svector_ostream Stream(RTTIMangling);
4248 msvc_hashing_ostream MHO(Stream);
4249 mangleCXXRTTI(T, MHO);
4251 Mangler.getStream() << RTTIMangling;
4259 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4260 LangOptions::MSVC2015) &&
4261 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4262 LangOptions::MSVC2017_7);
4263 llvm::SmallString<64> CopyCtorMangling;
4264 if (!OmitCopyCtor && CD) {
4265 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4266 msvc_hashing_ostream MHO(Stream);
4267 mangleCXXName(GlobalDecl(CD, CT), MHO);
4269 Mangler.getStream() << CopyCtorMangling;
4271 Mangler.getStream() <<
Size;
4272 if (VBPtrOffset == -1) {
4274 Mangler.getStream() << NVOffset;
4277 Mangler.getStream() << NVOffset;
4278 Mangler.getStream() << VBPtrOffset;
4279 Mangler.getStream() << VBIndex;
4283void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4286 msvc_hashing_ostream MHO(Out);
4287 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4288 Mangler.getStream() <<
"??_R1";
4289 Mangler.mangleNumber(NVOffset);
4290 Mangler.mangleNumber(VBPtrOffset);
4291 Mangler.mangleNumber(VBTableOffset);
4292 Mangler.mangleNumber(Flags);
4293 Mangler.mangleName(Derived);
4294 Mangler.getStream() <<
"8";
4297void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4298 const CXXRecordDecl *Derived, raw_ostream &Out) {
4299 msvc_hashing_ostream MHO(Out);
4300 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4301 Mangler.getStream() <<
"??_R2";
4302 Mangler.mangleName(Derived);
4303 Mangler.getStream() <<
"8";
4306void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4307 const CXXRecordDecl *Derived, raw_ostream &Out) {
4308 msvc_hashing_ostream MHO(Out);
4309 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4310 Mangler.getStream() <<
"??_R3";
4311 Mangler.mangleName(Derived);
4312 Mangler.getStream() <<
"8";
4315void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4316 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4322 llvm::SmallString<64> VFTableMangling;
4323 llvm::raw_svector_ostream Stream(VFTableMangling);
4324 mangleCXXVFTable(Derived, BasePath, Stream);
4326 if (VFTableMangling.starts_with(
"??@")) {
4327 assert(VFTableMangling.ends_with(
"@"));
4328 Out << VFTableMangling <<
"??_R4@";
4332 assert(VFTableMangling.starts_with(
"??_7") ||
4333 VFTableMangling.starts_with(
"??_S"));
4335 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
4338void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4339 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4340 msvc_hashing_ostream MHO(Out);
4341 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4346 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
4347 Mangler.mangleName(EnclosingDecl);
4350void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4351 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4352 msvc_hashing_ostream MHO(Out);
4353 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4358 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
4359 Mangler.mangleName(EnclosingDecl);
4362void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4363 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4366 MicrosoftCXXNameMangler Mangler(*
this, Out);
4367 Mangler.getStream() <<
'?';
4371void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4372 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
4373 msvc_hashing_ostream MHO(Out);
4374 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4376 Mangler.getStream() <<
"?";
4377 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
4378 Mangler.mangle(VD,
"");
4381void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4382 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
4383 msvc_hashing_ostream MHO(Out);
4384 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4386 Mangler.getStream() <<
"?";
4387 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
4388 Mangler.mangleNestedName(VD);
4389 Mangler.getStream() <<
"@4HA";
4392void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
4404 msvc_hashing_ostream MHO(Out);
4405 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4409 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
4411 Mangler.getStream() <<
"?$S1@";
4413 unsigned ScopeDepth = 0;
4414 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4418 Mangler.mangle(VD,
"");
4420 Mangler.mangleNestedName(VD);
4421 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
4423 Mangler.mangleNumber(ScopeDepth);
4426void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *D,
4429 msvc_hashing_ostream MHO(Out);
4430 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4431 Mangler.getStream() <<
"??__" << CharCode;
4433 Mangler.getStream() <<
'?';
4434 Mangler.mangleName(D);
4435 Mangler.mangleVariableEncoding(D);
4436 Mangler.getStream() <<
"@@";
4438 Mangler.mangleName(D);
4442 Mangler.getStream() <<
"YAXXZ";
4445void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *D,
4448 mangleInitFiniStub(D,
'E', Out);
4452MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *D,
4455 mangleInitFiniStub(D,
'F', Out);
4458void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4479 MicrosoftCXXNameMangler Mangler(*
this, Out);
4480 Mangler.getStream() <<
"??_C@_";
4488 unsigned StringLength =
4489 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4494 Mangler.getStream() <<
'1';
4496 Mangler.getStream() <<
'0';
4500 Mangler.mangleNumber(StringByteLength);
4502 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4504 if (Index / CharByteWidth >= SL->
getLength())
4505 return static_cast<char>(0);
4507 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4508 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4511 auto GetBigEndianByte = [&SL](
unsigned Index) {
4513 if (Index / CharByteWidth >= SL->
getLength())
4514 return static_cast<char>(0);
4516 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4517 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4522 for (
unsigned I = 0, E = StringByteLength; I != E; ++I)
4523 JC.update(GetLittleEndianByte(I));
4527 Mangler.mangleNumber(JC.getCRC());
4533 auto MangleByte = [&Mangler](
char Byte) {
4541 Mangler.getStream() << Byte;
4542 }
else if (
isLetter(Byte & 0x7f)) {
4543 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4545 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4546 ' ',
'\n',
'\t',
'\'',
'-'};
4547 const char *Pos = llvm::find(SpecialChars, Byte);
4548 if (Pos != std::end(SpecialChars)) {
4549 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4551 Mangler.getStream() <<
"?$";
4552 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4553 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4559 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4560 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4561 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4563 MangleByte(GetBigEndianByte(I));
4565 MangleByte(GetLittleEndianByte(I));
4568 Mangler.getStream() <<
'@';
4571void MicrosoftCXXNameMangler::mangleAutoReturnType(
const MemberPointerType *T,
4574 manglePointerCVQualifiers(Quals);
4575 manglePointerExtQualifiers(Quals, PointeeType);
4576 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4579 mangleFunctionType(FPT,
nullptr,
true);
4583 mangleAutoReturnType(PointeeType, QMM_Drop);
4587void MicrosoftCXXNameMangler::mangleAutoReturnType(
const PointerType *T,
4591 "Unexpected address space mangling required");
4593 manglePointerCVQualifiers(Quals);
4594 manglePointerExtQualifiers(Quals, PointeeType);
4596 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4598 mangleFunctionType(FPT);
4600 mangleAutoReturnType(PointeeType, QMM_Mangle);
4604void MicrosoftCXXNameMangler::mangleAutoReturnType(
const LValueReferenceType *T,
4609 manglePointerExtQualifiers(Quals, PointeeType);
4610 mangleAutoReturnType(PointeeType, QMM_Mangle);
4613void MicrosoftCXXNameMangler::mangleAutoReturnType(
const RValueReferenceType *T,
4618 manglePointerExtQualifiers(Quals, PointeeType);
4619 mangleAutoReturnType(PointeeType, QMM_Mangle);
4625 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
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
unsigned getNumBits() const
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType getPointeeType() const
StringRef getName(const PrintingPolicy &Policy) const
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...
QualType getElementType() const
llvm::APInt getSize() const
Return the constant array size as an APInt.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
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].
QualType getElementType() const
Returns type of the elements being stored in the matrix.
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
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.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
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
QualType getElementType() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
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.
QualType getPointeeType() const
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...
unsigned getNumElements() const
QualType getElementType() const
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)
@ Result
The result type of a method or function.
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...