33#include "llvm/ADT/SmallVector.h"
34#include "llvm/ADT/StringExtras.h"
35#include "llvm/Support/CRC.h"
36#include "llvm/Support/MD5.h"
37#include "llvm/Support/StringSaver.h"
38#include "llvm/Support/xxhash.h"
49 if (
auto *CD = dyn_cast<CXXConstructorDecl>(DC))
51 else if (
auto *DD = dyn_cast<CXXDestructorDecl>(DC))
58struct msvc_hashing_ostream :
public llvm::raw_svector_ostream {
61 llvm::SmallString<64> Buffer;
63 msvc_hashing_ostream(raw_ostream &OS,
size_t Threshold = 4096)
64 : llvm::raw_svector_ostream(Buffer), OS(OS), Threshold(Threshold) {}
65 ~msvc_hashing_ostream()
override {
66 StringRef MangledName = str();
67 bool StartsWithEscape = MangledName.starts_with(
"\01");
69 MangledName = MangledName.drop_front(1);
70 if (MangledName.size() < Threshold) {
76 llvm::MD5::MD5Result Hash;
77 Hasher.update(MangledName);
80 SmallString<32> HexString;
81 llvm::MD5::stringifyResult(Hash, HexString);
85 OS <<
"??@" << HexString <<
'@';
90getLambdaDefaultArgumentDeclContext(
const Decl *D) {
91 if (
const auto *RD = dyn_cast<CXXRecordDecl>(D))
93 if (
const auto *Parm =
94 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
95 return Parm->getDeclContext();
108 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))
112 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
114 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
115 return ContextParam->getDeclContext();
121 return getEffectiveDeclContext(
cast<Decl>(DC));
128 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
132 if (
const auto *FTD = FD->getPrimaryTemplate())
133 return FTD->getTemplatedDecl()->getCanonicalDecl();
135 return FD->getCanonicalDecl();
141 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
142 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
143 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
144 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
145 llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
146 llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
147 SmallString<16> AnonymousNamespaceHash;
150 MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags,
152 bool shouldMangleCXXName(
const NamedDecl *D)
override;
153 bool shouldMangleStringLiteral(
const StringLiteral *SL)
override;
154 void mangleCXXName(GlobalDecl GD, raw_ostream &Out)
override;
155 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
156 const MethodVFTableLocation &ML,
157 raw_ostream &Out)
override;
158 void mangleThunk(
const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
159 bool ElideOverrideInfo, raw_ostream &)
override;
161 const ThunkInfo &Thunk,
bool ElideOverrideInfo,
162 raw_ostream &)
override;
163 void mangleCXXVFTable(
const CXXRecordDecl *Derived,
164 ArrayRef<const CXXRecordDecl *> BasePath,
165 raw_ostream &Out)
override;
166 void mangleCXXVBTable(
const CXXRecordDecl *Derived,
167 ArrayRef<const CXXRecordDecl *> BasePath,
168 raw_ostream &Out)
override;
170 void mangleCXXVTable(
const CXXRecordDecl *, raw_ostream &)
override;
171 void mangleCXXVirtualDisplacementMap(
const CXXRecordDecl *SrcRD,
172 const CXXRecordDecl *DstRD,
173 raw_ostream &Out)
override;
174 void mangleCXXThrowInfo(QualType
T,
bool IsConst,
bool IsVolatile,
175 bool IsUnaligned,
uint32_t NumEntries,
176 raw_ostream &Out)
override;
177 void mangleCXXCatchableTypeArray(QualType
T,
uint32_t NumEntries,
178 raw_ostream &Out)
override;
179 void mangleCXXCatchableType(QualType
T,
const CXXConstructorDecl *CD,
182 raw_ostream &Out)
override;
183 void mangleCXXRTTI(QualType
T, raw_ostream &Out)
override;
184 void mangleCXXRTTIName(QualType
T, raw_ostream &Out,
185 bool NormalizeIntegers)
override;
186 void mangleCXXRTTIBaseClassDescriptor(
const CXXRecordDecl *Derived,
189 raw_ostream &Out)
override;
190 void mangleCXXRTTIBaseClassArray(
const CXXRecordDecl *Derived,
191 raw_ostream &Out)
override;
192 void mangleCXXRTTIClassHierarchyDescriptor(
const CXXRecordDecl *Derived,
193 raw_ostream &Out)
override;
195 mangleCXXRTTICompleteObjectLocator(
const CXXRecordDecl *Derived,
196 ArrayRef<const CXXRecordDecl *> BasePath,
197 raw_ostream &Out)
override;
198 void mangleCanonicalTypeName(QualType
T, raw_ostream &,
199 bool NormalizeIntegers)
override;
200 void mangleReferenceTemporary(
const VarDecl *,
unsigned ManglingNumber,
201 raw_ostream &)
override;
202 void mangleStaticGuardVariable(
const VarDecl *D, raw_ostream &Out)
override;
203 void mangleThreadSafeStaticGuardVariable(
const VarDecl *D,
unsigned GuardNum,
204 raw_ostream &Out)
override;
205 void mangleDynamicInitializer(
const VarDecl *D, raw_ostream &Out)
override;
206 void mangleDynamicAtExitDestructor(
const VarDecl *D,
207 raw_ostream &Out)
override;
208 void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
209 raw_ostream &Out)
override;
210 void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
211 raw_ostream &Out)
override;
212 void mangleStringLiteral(
const StringLiteral *SL, raw_ostream &Out)
override;
213 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
214 const DeclContext *DC = getEffectiveDeclContext(ND);
220 if (
const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
221 if (RD->isLambda()) {
229 disc = getASTContext().getManglingNumber(ND, isAux());
234 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
235 if (!
Tag->hasNameForLinkage() &&
236 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
237 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))
242 unsigned &discriminator = Uniquifier[ND];
244 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
245 disc = discriminator + 1;
249 std::string getLambdaString(
const CXXRecordDecl *Lambda)
override {
250 assert(Lambda->
isLambda() &&
"RD must be a lambda!");
251 std::string Name(
"<lambda_");
256 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
257 const FunctionDecl *
Func =
261 unsigned DefaultArgNo =
263 Name += llvm::utostr(DefaultArgNo);
267 if (LambdaManglingNumber)
268 LambdaId = LambdaManglingNumber;
270 LambdaId = getLambdaIdForDebugInfo(Lambda);
272 Name += llvm::utostr(LambdaId);
277 unsigned getLambdaId(
const CXXRecordDecl *RD) {
278 assert(RD->
isLambda() &&
"RD must be a lambda!");
281 "RD must not have a mangling number!");
282 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator,
bool>
283 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
284 return Result.first->second;
287 unsigned getLambdaIdForDebugInfo(
const CXXRecordDecl *RD) {
288 assert(RD->
isLambda() &&
"RD must be a lambda!");
291 "RD must not have a mangling number!");
293 return LambdaIds.lookup(RD);
298 StringRef getAnonymousNamespaceHash()
const {
299 return AnonymousNamespaceHash;
303 void mangleInitFiniStub(
const VarDecl *D,
char CharCode, raw_ostream &Out);
308class MicrosoftCXXNameMangler {
309 MicrosoftMangleContextImpl &Context;
315 const NamedDecl *Structor;
316 unsigned StructorType;
318 typedef llvm::SmallVector<std::string, 10> BackRefVec;
319 BackRefVec NameBackReferences;
321 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
322 ArgBackRefMap FunArgBackReferences;
323 ArgBackRefMap TemplateArgBackReferences;
325 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
326 TemplateArgStringMap TemplateArgStrings;
327 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
328 llvm::StringSaver TemplateArgStringStorage;
330 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
331 PassObjectSizeArgsSet PassObjectSizeArgs;
333 ASTContext &getASTContext()
const {
return Context.getASTContext(); }
335 const bool PointersAre64Bit;
337 DiagnosticBuilder
Error(SourceLocation, StringRef, StringRef);
338 DiagnosticBuilder
Error(SourceLocation, StringRef);
339 DiagnosticBuilder
Error(StringRef);
342 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
343 enum class TplArgKind { ClassNTTP, StructuralValue };
345 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_)
346 : Context(
C), Out(Out_), Structor(
nullptr), StructorType(-1),
347 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
348 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
351 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
353 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
354 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
355 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
358 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
360 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
361 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
362 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
365 raw_ostream &getStream()
const {
return Out; }
367 void mangle(GlobalDecl GD, StringRef Prefix =
"?");
368 void mangleName(GlobalDecl GD);
369 void mangleFunctionEncoding(GlobalDecl GD,
bool ShouldMangle);
370 void mangleVariableEncoding(
const VarDecl *VD);
371 void mangleMemberDataPointer(
const CXXRecordDecl *RD,
const ValueDecl *VD,
372 const NonTypeTemplateParmDecl *PD,
373 QualType TemplateArgType,
374 StringRef Prefix =
"$");
375 void mangleMemberDataPointerInClassNTTP(
const CXXRecordDecl *,
377 void mangleMemberFunctionPointer(
const CXXRecordDecl *RD,
378 const CXXMethodDecl *MD,
379 const NonTypeTemplateParmDecl *PD,
380 QualType TemplateArgType,
381 StringRef Prefix =
"$");
382 void mangleFunctionPointer(
const FunctionDecl *FD,
383 const NonTypeTemplateParmDecl *PD,
384 QualType TemplateArgType);
385 void mangleVarDecl(
const VarDecl *VD,
const NonTypeTemplateParmDecl *PD,
386 QualType TemplateArgType);
387 void mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD,
388 const CXXMethodDecl *MD);
389 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
390 const MethodVFTableLocation &ML);
391 void mangleNumber(int64_t Number);
392 void mangleNumber(llvm::APSInt Number);
393 void mangleFloat(llvm::APFloat Number);
394 void mangleBits(llvm::APInt Number);
396 void mangleArtificialTagType(
TagTypeKind TK, StringRef UnqualifiedName,
397 ArrayRef<StringRef> NestedNames = {});
398 void mangleAddressSpaceType(QualType
T, Qualifiers Quals, SourceRange Range);
399 void mangleType(QualType
T, SourceRange Range,
400 QualifierMangleMode QMM = QMM_Mangle);
401 void mangleFunctionType(
const FunctionType *
T,
402 const FunctionDecl *D =
nullptr,
403 bool ForceThisQuals =
false,
404 bool MangleExceptionSpec =
true);
405 void mangleSourceName(StringRef Name);
406 void mangleNestedName(GlobalDecl GD);
408 void mangleAutoReturnType(QualType
T, QualifierMangleMode QMM);
411 bool isStructorDecl(
const NamedDecl *ND)
const {
412 return ND == Structor || getStructor(ND) == Structor;
415 bool is64BitPointer(Qualifiers Quals)
const {
417 return AddrSpace == LangAS::ptr64 ||
418 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||
419 AddrSpace == LangAS::ptr32_uptr));
422 void mangleUnqualifiedName(GlobalDecl GD) {
425 void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name);
428 void mangleQualifiers(Qualifiers Quals,
bool IsMember);
430 void manglePointerCVQualifiers(Qualifiers Quals);
431 void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType);
432 void manglePointerAuthQualifier(Qualifiers Quals);
434 void mangleUnscopedTemplateName(GlobalDecl GD);
436 mangleTemplateInstantiationName(GlobalDecl GD,
437 const TemplateArgumentList &TemplateArgs);
440 void mangleFunctionArgumentType(QualType
T, SourceRange Range);
441 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
443 bool isArtificialTagType(QualType
T)
const;
446#define ABSTRACT_TYPE(CLASS, PARENT)
447#define NON_CANONICAL_TYPE(CLASS, PARENT)
448#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
451#include "clang/AST/TypeNodes.inc"
453#undef NON_CANONICAL_TYPE
456 void mangleType(
const TagDecl *TD);
457 void mangleDecayedArrayType(
const ArrayType *
T);
462 void mangleIntegerLiteral(
const llvm::APSInt &Number,
473 bool WithScalarType =
false);
488MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(
ASTContext &Context,
508 SmallString<256> Path(FE->getName());
510 clang::Preprocessor::processPathForFileMacro(Path, Context.getLangOpts(),
511 Context.getTargetInfo());
514 uint32_t TruncatedHash = uint32_t(xxh3_64bits(Path));
515 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
518 AnonymousNamespaceHash =
"0";
522bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *D) {
523 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
526 if (FD->hasAttr<OverloadableAttr>())
538 if (FD->isMSVCRTEntryPoint())
552 if (!getASTContext().getLangOpts().
CPlusPlus)
555 const VarDecl *VD = dyn_cast<VarDecl>(D);
562 const DeclContext *DC = getEffectiveDeclContext(D);
572MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
576DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
579 DiagnosticsEngine &Diags = Context.getDiags();
580 return Diags.
Report(loc, diag::err_ms_mangle_unsupported_with_detail)
584DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
586 DiagnosticsEngine &Diags = Context.getDiags();
587 return Diags.
Report(loc, diag::err_ms_mangle_unsupported) << thingy;
590DiagnosticBuilder MicrosoftCXXNameMangler::Error(StringRef thingy) {
591 DiagnosticsEngine &Diags = Context.getDiags();
593 return Diags.
Report(diag::err_ms_mangle_unsupported) << thingy;
596void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) {
607 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
608 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
609 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
610 mangleVariableEncoding(VD);
614 Out <<
"3U__s_GUID@@B";
619 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
622void MicrosoftCXXNameMangler::mangleFunctionEncoding(GlobalDecl GD,
634 const FunctionProtoType *FT = FD->
getType()->
castAs<FunctionProtoType>();
647 mangleFunctionClass(FD);
649 mangleFunctionType(FT, FD,
false,
false);
655void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
686 mangleType(Ty, SR, QMM_Drop);
687 manglePointerExtQualifiers(
689 if (
const MemberPointerType *MPT = Ty->
getAs<MemberPointerType>()) {
690 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
693 mangleName(MPT->getMostRecentCXXRecordDecl());
696 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
698 mangleDecayedArrayType(AT);
699 if (AT->getElementType()->isArrayType())
704 mangleType(Ty, SR, QMM_Drop);
709void MicrosoftCXXNameMangler::mangleMemberDataPointer(
710 const CXXRecordDecl *RD,
const ValueDecl *VD,
711 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
725 FieldOffset = getASTContext().getFieldOffset(VD);
726 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
727 "cannot take address of bitfield");
728 FieldOffset /= getASTContext().getCharWidth();
732 if (IM == MSInheritanceModel::Virtual)
733 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
742 case MSInheritanceModel::Single: Code =
'0';
break;
743 case MSInheritanceModel::Multiple: Code =
'0';
break;
744 case MSInheritanceModel::Virtual: Code =
'F';
break;
745 case MSInheritanceModel::Unspecified: Code =
'G';
break;
751 getASTContext().getLangOpts().isCompatibleWithMSVC(
752 LangOptions::MSVC2019) &&
754 !TemplateArgType.
isNull()) {
756 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
761 mangleNumber(FieldOffset);
769 mangleNumber(VBTableOffset);
772void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
773 const CXXRecordDecl *RD,
const ValueDecl *VD) {
779 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
780 return mangleMemberDataPointer(RD, VD,
nullptr, QualType(),
"");
788 mangleNestedName(VD);
790 mangleUnqualifiedName(VD);
794void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
795 const CXXRecordDecl *RD,
const CXXMethodDecl *MD,
796 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
812 case MSInheritanceModel::Single: Code =
'1';
break;
813 case MSInheritanceModel::Multiple: Code =
'H';
break;
814 case MSInheritanceModel::Virtual: Code =
'I';
break;
815 case MSInheritanceModel::Unspecified: Code =
'J';
break;
826 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
827 LangOptions::MSVC2019) &&
829 !TemplateArgType.
isNull()) {
831 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
836 MicrosoftVTableContext *VTContext =
838 MethodVFTableLocation ML =
840 mangleVirtualMemPtrThunk(MD, ML);
844 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
849 mangleFunctionEncoding(MD,
true);
852 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
853 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
856 if (IM == MSInheritanceModel::Single) {
857 Out << Prefix <<
"0A@";
860 if (IM == MSInheritanceModel::Unspecified)
862 Out << Prefix << Code;
866 mangleNumber(
static_cast<uint32_t>(NVOffset));
868 mangleNumber(VBPtrOffset);
870 mangleNumber(VBTableOffset);
873void MicrosoftCXXNameMangler::mangleFunctionPointer(
874 const FunctionDecl *FD,
const NonTypeTemplateParmDecl *PD,
875 QualType TemplateArgType) {
882 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
883 LangOptions::MSVC2019) &&
885 !TemplateArgType.
isNull()) {
887 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
892 mangleFunctionEncoding(FD,
true);
895void MicrosoftCXXNameMangler::mangleVarDecl(
const VarDecl *VD,
896 const NonTypeTemplateParmDecl *PD,
897 QualType TemplateArgType) {
904 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
905 LangOptions::MSVC2019) &&
907 !TemplateArgType.
isNull()) {
909 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
914 mangleVariableEncoding(VD);
917void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
918 const CXXRecordDecl *RD,
const CXXMethodDecl *MD) {
926 return mangleMemberFunctionPointer(RD, MD,
nullptr, QualType(),
"");
934 MicrosoftVTableContext *VTContext =
936 MethodVFTableLocation ML =
938 mangleVirtualMemPtrThunk(MD, ML);
941 mangleFunctionEncoding(MD,
true);
945void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
946 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML) {
948 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
949 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
955 mangleNumber(OffsetInVFTable);
957 mangleCallingConvention(MD->
getType()->
castAs<FunctionProtoType>(),
961void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {
965 mangleUnqualifiedName(GD);
967 mangleNestedName(GD);
973void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
974 mangleNumber(llvm::APSInt(llvm::APInt(64, Number),
false));
977void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
982 unsigned Width = std::max(
Number.getBitWidth(), 64U);
991 if (
Value.isNegative()) {
998void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
1001 switch (APFloat::SemanticsToEnum(
Number.getSemantics())) {
1002 case APFloat::S_IEEEsingle:
Out <<
'A';
break;
1003 case APFloat::S_IEEEdouble:
Out <<
'B';
break;
1007 case APFloat::S_IEEEhalf:
Out <<
'V';
break;
1008 case APFloat::S_BFloat:
Out <<
'W';
break;
1009 case APFloat::S_x87DoubleExtended:
Out <<
'X';
break;
1010 case APFloat::S_IEEEquad:
Out <<
'Y';
break;
1011 case APFloat::S_PPCDoubleDouble:
Out <<
'Z';
break;
1012 case APFloat::S_PPCDoubleDoubleLegacy:
1013 case APFloat::S_Float8E5M2:
1014 case APFloat::S_Float8E4M3:
1015 case APFloat::S_Float8E4M3FN:
1016 case APFloat::S_Float8E5M2FNUZ:
1017 case APFloat::S_Float8E4M3FNUZ:
1018 case APFloat::S_Float8E4M3B11FNUZ:
1019 case APFloat::S_Float8E3M4:
1020 case APFloat::S_FloatTF32:
1021 case APFloat::S_Float8E8M0FNU:
1022 case APFloat::S_Float8E5M3FNU:
1023 case APFloat::S_Float6E3M2FN:
1024 case APFloat::S_Float6E2M3FN:
1025 case APFloat::S_Float4E2M1FN:
1026 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
1029 mangleBits(
Number.bitcastToAPInt());
1032void MicrosoftCXXNameMangler::mangleBits(llvm::APInt
Value) {
1041 llvm::SmallString<32> EncodedNumberBuffer;
1043 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
1044 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1045 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1054 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1063 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1064 TemplateArgs = &Spec->getTemplateArgs();
1065 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1070 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1071 TemplateArgs = &Spec->getTemplateArgs();
1072 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1078void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
1079 DeclarationName Name) {
1087 const TemplateArgumentList *TemplateArgs =
nullptr;
1088 if (GlobalDecl TD =
isTemplate(GD, TemplateArgs)) {
1093 mangleTemplateInstantiationName(TD, *TemplateArgs);
1116 ArgBackRefMap::iterator
Found = TemplateArgBackReferences.find(ND);
1117 if (
Found == TemplateArgBackReferences.end()) {
1119 TemplateArgStringMap::iterator
Found = TemplateArgStrings.find(ND);
1120 if (
Found == TemplateArgStrings.end()) {
1122 llvm::SmallString<64> TemplateMangling;
1123 llvm::raw_svector_ostream Stream(TemplateMangling);
1124 MicrosoftCXXNameMangler
Extra(Context, Stream);
1125 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1128 mangleSourceName(TemplateMangling);
1132 BackRefVec::iterator StringFound =
1133 llvm::find(NameBackReferences, TemplateMangling);
1134 if (StringFound != NameBackReferences.end()) {
1135 TemplateArgBackReferences[ND] =
1136 StringFound - NameBackReferences.begin();
1138 TemplateArgStrings[ND] =
1139 TemplateArgStringStorage.save(TemplateMangling.str());
1158 ->getTemplatedDecl()
1161 bool IsOCLDeviceStub =
1163 DeviceKernelAttr::isOpenCLSpelling(
1164 ND->
getAttr<DeviceKernelAttr>()) &&
1168 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1169 else if (IsOCLDeviceStub)
1171 (llvm::Twine(
"__clang_ocl_kern_imp_") + II->getName()).str());
1173 mangleSourceName(II->getName());
1178 assert(ND &&
"mangling empty name without declaration");
1180 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1181 if (NS->isAnonymousNamespace()) {
1182 llvm::SmallString<16> Name(
"?A0x");
1183 Name += Context.getAnonymousNamespaceHash();
1184 mangleSourceName(Name);
1189 if (
const DecompositionDecl *DD = dyn_cast<DecompositionDecl>(ND)) {
1192 llvm::SmallString<64> Name(
"$S");
1194 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1195 mangleSourceName(Name);
1199 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1202 assert(RD &&
"expected variable decl to have a record type");
1206 llvm::SmallString<64> Name(
"$S");
1208 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1209 mangleSourceName(Name.str());
1213 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1216 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1217 llvm::raw_svector_ostream GUIDOS(GUID);
1218 Context.mangleMSGuidDecl(GD, GUIDOS);
1219 mangleSourceName(GUID);
1223 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1225 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1226 TPO->getValue(), TplArgKind::ClassNTTP);
1234 "Typedef should not be in another decl context!");
1236 "Typedef was not named!");
1241 if (
const CXXRecordDecl *
Record = dyn_cast<CXXRecordDecl>(TD)) {
1242 if (
Record->isLambda()) {
1243 llvm::SmallString<10> Name(
"<lambda_");
1245 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1246 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1248 const ParmVarDecl *Parm =
1249 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1250 const FunctionDecl *
Func =
1254 unsigned DefaultArgNo =
1256 Name += llvm::utostr(DefaultArgNo);
1260 if (LambdaManglingNumber)
1261 LambdaId = LambdaManglingNumber;
1263 LambdaId = Context.getLambdaId(
Record);
1265 Name += llvm::utostr(LambdaId);
1268 mangleSourceName(Name);
1272 if (LambdaManglingNumber && LambdaContextDecl) {
1283 llvm::SmallString<64> Name;
1284 if (DeclaratorDecl *DD =
1288 Name +=
"<unnamed-type-";
1289 Name += DD->getName();
1290 }
else if (TypedefNameDecl *TND =
1295 Name +=
"<unnamed-type-";
1296 Name += TND->getName();
1301 Name +=
"<unnamed-enum-";
1302 Name += ED->enumerator_begin()->getName();
1305 Name +=
"<unnamed-type-$S";
1306 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1309 mangleSourceName(Name.str());
1319 llvm::SmallString<64> Name;
1320 mangleSourceName(Name.str());
1325 if (isStructorDecl(ND)) {
1339 if (isStructorDecl(ND))
1342 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1356 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1361 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1366 llvm_unreachable(
"Can't mangle a deduction guide name!");
1369 llvm_unreachable(
"Can't mangle a using directive name!");
1375void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {
1378 if (
const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1379 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1380 mangleSourceName(
"<unnamed-tag>");
1382 const DeclContext *DC = getEffectiveDeclContext(ND);
1386 if (Context.getNextDiscriminator(ND, Disc)) {
1393 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1395 [](StringRef Name,
const unsigned Discriminator,
1396 const unsigned ParameterDiscriminator) -> std::string {
1398 llvm::raw_string_ostream Stream(Buffer);
1401 Stream <<
'_' << Discriminator;
1402 if (ParameterDiscriminator)
1403 Stream <<
'_' << ParameterDiscriminator;
1407 unsigned Discriminator = BD->getBlockManglingNumber();
1409 Discriminator = Context.getBlockId(BD,
false);
1414 unsigned ParameterDiscriminator = 0;
1415 if (
const auto *MC = BD->getBlockManglingContextDecl())
1416 if (
const auto *P = dyn_cast<ParmVarDecl>(MC))
1417 if (
const auto *F = dyn_cast<FunctionDecl>(P->getDeclContext()))
1418 ParameterDiscriminator =
1419 F->getNumParams() - P->getFunctionScopeIndex();
1421 DC = getEffectiveDeclContext(BD);
1424 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1425 ParameterDiscriminator));
1430 if (
const auto *MC = BD->getBlockManglingContextDecl())
1432 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1433 mangleUnqualifiedName(ND);
1437 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1446 if (PointersAre64Bit)
1449 mangleArtificialTagType(TagTypeKind::Struct,
1450 Discriminate(
"__block_literal", Discriminator,
1451 ParameterDiscriminator));
1459 }
else if (
const ObjCMethodDecl *
Method = dyn_cast<ObjCMethodDecl>(DC)) {
1463 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1464 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1467 mangleUnqualifiedName(ND);
1470 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1480void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1496 llvm_unreachable(
"not expecting a COMDAT");
1498 llvm_unreachable(
"not expecting a unified dtor type");
1500 llvm_unreachable(
"Unsupported dtor type?");
1504 SourceLocation Loc) {
1509 case OO_New:
Out <<
"?2";
break;
1511 case OO_Delete:
Out <<
"?3";
break;
1513 case OO_Equal:
Out <<
"?4";
break;
1515 case OO_GreaterGreater:
Out <<
"?5";
break;
1517 case OO_LessLess:
Out <<
"?6";
break;
1519 case OO_Exclaim:
Out <<
"?7";
break;
1521 case OO_EqualEqual:
Out <<
"?8";
break;
1523 case OO_ExclaimEqual:
Out <<
"?9";
break;
1525 case OO_Subscript:
Out <<
"?A";
break;
1528 case OO_Arrow:
Out <<
"?C";
break;
1530 case OO_Star:
Out <<
"?D";
break;
1532 case OO_PlusPlus:
Out <<
"?E";
break;
1534 case OO_MinusMinus:
Out <<
"?F";
break;
1536 case OO_Minus:
Out <<
"?G";
break;
1538 case OO_Plus:
Out <<
"?H";
break;
1540 case OO_Amp:
Out <<
"?I";
break;
1542 case OO_ArrowStar:
Out <<
"?J";
break;
1544 case OO_Slash:
Out <<
"?K";
break;
1546 case OO_Percent:
Out <<
"?L";
break;
1548 case OO_Less:
Out <<
"?M";
break;
1550 case OO_LessEqual:
Out <<
"?N";
break;
1552 case OO_Greater:
Out <<
"?O";
break;
1554 case OO_GreaterEqual:
Out <<
"?P";
break;
1556 case OO_Comma:
Out <<
"?Q";
break;
1558 case OO_Call:
Out <<
"?R";
break;
1560 case OO_Tilde:
Out <<
"?S";
break;
1562 case OO_Caret:
Out <<
"?T";
break;
1564 case OO_Pipe:
Out <<
"?U";
break;
1566 case OO_AmpAmp:
Out <<
"?V";
break;
1568 case OO_PipePipe:
Out <<
"?W";
break;
1570 case OO_StarEqual:
Out <<
"?X";
break;
1572 case OO_PlusEqual:
Out <<
"?Y";
break;
1574 case OO_MinusEqual:
Out <<
"?Z";
break;
1576 case OO_SlashEqual:
Out <<
"?_0";
break;
1578 case OO_PercentEqual:
Out <<
"?_1";
break;
1580 case OO_GreaterGreaterEqual:
Out <<
"?_2";
break;
1582 case OO_LessLessEqual:
Out <<
"?_3";
break;
1584 case OO_AmpEqual:
Out <<
"?_4";
break;
1586 case OO_PipeEqual:
Out <<
"?_5";
break;
1588 case OO_CaretEqual:
Out <<
"?_6";
break;
1617 case OO_Array_New:
Out <<
"?_U";
break;
1619 case OO_Array_Delete:
Out <<
"?_V";
break;
1621 case OO_Coawait:
Out <<
"?__L";
break;
1623 case OO_Spaceship:
Out <<
"?__M";
break;
1625 case OO_Conditional: {
1626 Error(Loc,
"conditional operator");
1632 llvm_unreachable(
"Not an overloaded operator");
1636void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1638 BackRefVec::iterator
Found = llvm::find(NameBackReferences, Name);
1639 if (
Found == NameBackReferences.end()) {
1640 if (NameBackReferences.size() < 10)
1641 NameBackReferences.push_back(std::string(Name));
1644 Out << (
Found - NameBackReferences.begin());
1648void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1649 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1652void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1653 GlobalDecl GD,
const TemplateArgumentList &TemplateArgs) {
1659 ArgBackRefMap OuterFunArgsContext;
1660 ArgBackRefMap OuterTemplateArgsContext;
1661 BackRefVec OuterTemplateContext;
1662 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1663 NameBackReferences.swap(OuterTemplateContext);
1664 FunArgBackReferences.swap(OuterFunArgsContext);
1665 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1666 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1668 mangleUnscopedTemplateName(GD);
1672 NameBackReferences.swap(OuterTemplateContext);
1673 FunArgBackReferences.swap(OuterFunArgsContext);
1674 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1675 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1678void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {
1681 mangleUnqualifiedName(GD);
1684void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1685 const llvm::APSInt &
Value,
const NonTypeTemplateParmDecl *PD,
1686 QualType TemplateArgType) {
1695 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1696 LangOptions::MSVC2019) &&
1698 !TemplateArgType.
isNull()) {
1700 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
1705 mangleNumber(
Value);
1708void MicrosoftCXXNameMangler::mangleExpression(
1709 const Expr *E,
const NonTypeTemplateParmDecl *PD) {
1711 if (std::optional<llvm::APSInt>
Value =
1722void MicrosoftCXXNameMangler::mangleTemplateArgs(
1723 const TemplateDecl *TD,
const TemplateArgumentList &TemplateArgs) {
1726 assert(TPL->
size() == TemplateArgs.
size() &&
1727 "size mismatch between args and parms!");
1729 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1730 const TemplateArgument &TA = TemplateArgs[i];
1737 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1745 if (!
T->isPointerType() || !
V.isLValue() || !
V.hasLValuePath() ||
1749 QualType BaseT =
V.getLValueBase().getType();
1750 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1751 V.getLValuePath()[0].getAsArrayIndex() != 0)
1754 V.getLValueBase().dyn_cast<const ValueDecl *>());
1757void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1758 const TemplateArgument &TA,
1759 const NamedDecl *Parm) {
1797 llvm_unreachable(
"Can't mangle null template arguments!");
1799 llvm_unreachable(
"Can't mangle template expansion arguments!");
1802 mangleType(
T, SourceRange(), QMM_Escape);
1808 mangleMemberDataPointer(
1812 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1813 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1825 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1826 TPO->getValue(), TplArgKind::ClassNTTP);
1827 }
else if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1843 if (
const MemberPointerType *MPT =
T->
getAs<MemberPointerType>()) {
1844 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1845 if (MPT->isMemberFunctionPointerType() &&
1847 mangleMemberFunctionPointer(RD,
nullptr,
nullptr, QualType());
1850 if (MPT->isMemberDataPointer()) {
1852 mangleMemberDataPointer(RD,
nullptr,
nullptr, QualType());
1862 mangleIntegerLiteral(llvm::APSInt::get(-1),
1868 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1878 return mangleTemplateArg(
1884 ->getContainedDeducedType()) {
1890 TplArgKind::StructuralValue,
1898 if (TemplateArgs.empty()) {
1903 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(
1904 LangOptions::MSVC2015)
1910 llvm_unreachable(
"unexpected template parameter decl!");
1912 for (
const TemplateArgument &PA : TemplateArgs)
1913 mangleTemplateArg(TD, PA, Parm);
1918 const NamedDecl *ND =
1920 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1926 llvm_unreachable(
"unexpected template template NamedDecl!");
1933void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType
T,
1936 bool WithScalarType) {
1937 switch (
V.getKind()) {
1943 mangleType(
T, SourceRange(), QMM_Escape);
1949 mangleType(
T, SourceRange(), QMM_Escape);
1951 mangleNumber(
V.getInt());
1956 mangleType(
T, SourceRange(), QMM_Escape);
1957 mangleFloat(
V.getFloat());
1962 mangleType(
T, SourceRange(), QMM_Escape);
1964 APValue::LValueBase
Base =
V.getLValueBase();
1968 if (
V.isLValueOnePastTheEnd()) {
1970 auto *VD =
Base.dyn_cast<
const ValueDecl *>();
1977 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1979 if (
Base.isNull()) {
1985 mangleNumber(
V.getLValueOffset().getQuantity());
1986 }
else if (!
V.hasLValuePath()) {
1988 Error(
"template argument (extension not comaptible with ms mangler)");
1990 }
else if (
auto *VD =
Base.dyn_cast<
const ValueDecl*>()) {
1994 Error(
"template argument (undeclared base)");
2001 SmallVector<char, 2> EntryTypes;
2003 QualType ET =
Base.getType();
2004 for (APValue::LValuePathEntry E :
V.getLValuePath()) {
2006 EntryTypes.push_back(
'C');
2007 EntryManglers.push_back([
this, I = E.getAsArrayIndex()] {
2012 ET = AT->getElementType();
2016 const Decl *D = E.getAsBaseOrMember().getPointer();
2017 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2029 EntryTypes.push_back(
'6');
2030 EntryManglers.push_back([
this, D] {
2036 for (
auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
2039 auto *VD =
Base.dyn_cast<
const ValueDecl*>();
2041 Error(
"template argument (null value decl)");
2044 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
2058 mangleType(
T, SourceRange(), QMM_Escape);
2060 const CXXRecordDecl *RD =
2061 T->
castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
2062 const ValueDecl *D =
V.getMemberPointerDecl();
2063 if (TAK == TplArgKind::ClassNTTP) {
2065 mangleMemberDataPointerInClassNTTP(RD, D);
2067 mangleMemberFunctionPointerInClassNTTP(RD,
2068 cast_or_null<CXXMethodDecl>(D));
2071 mangleMemberDataPointer(RD, D,
nullptr, QualType(),
"");
2073 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D),
nullptr,
2081 mangleType(
T, SourceRange(), QMM_Escape);
2083 assert(RD &&
"unexpected type for record value");
2085 unsigned BaseIndex = 0;
2086 for (
const CXXBaseSpecifier &B : RD->
bases())
2087 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
2088 for (
const FieldDecl *FD : RD->
fields())
2089 if (!FD->isUnnamedBitField())
2090 mangleTemplateArgValue(FD->
getType(),
2091 V.getStructField(FD->getFieldIndex()), TAK,
2099 mangleType(
T, SourceRange(), QMM_Escape);
2100 if (
const FieldDecl *FD =
V.getUnionField()) {
2101 mangleUnqualifiedName(FD);
2102 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
2110 mangleType(
T, SourceRange(), QMM_Escape);
2112 mangleNumber(
V.getComplexIntReal());
2114 mangleNumber(
V.getComplexIntImag());
2120 mangleType(
T, SourceRange(), QMM_Escape);
2121 mangleFloat(
V.getComplexFloatReal());
2122 mangleFloat(
V.getComplexFloatImag());
2128 QualType ElemT = getASTContext().getAsArrayType(
T)->getElementType();
2129 mangleType(ElemT, SourceRange(), QMM_Escape);
2130 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
2131 const APValue &ElemV = I <
V.getArrayInitializedElts()
2132 ?
V.getArrayInitializedElt(I)
2133 :
V.getArrayFiller();
2134 mangleTemplateArgValue(ElemT, ElemV, TAK);
2145 mangleType(
T, SourceRange(), QMM_Escape);
2147 QualType ElemT =
T->
castAs<VectorType>()->getElementType();
2148 mangleType(ElemT, SourceRange(), QMM_Escape);
2149 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
2151 mangleTemplateArgValue(ElemT, ElemV, TAK);
2159 Error(
"template argument (value type: matrix)");
2164 Error(
"template argument (value type: address label diff)");
2169 Error(
"template argument (value type: fixed point)");
2175void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2176 llvm::SmallString<64> TemplateMangling;
2177 llvm::raw_svector_ostream Stream(TemplateMangling);
2178 MicrosoftCXXNameMangler
Extra(Context, Stream);
2181 Extra.mangleSourceName(
"Protocol");
2182 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2184 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2187void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType
Type,
2189 SourceRange Range) {
2190 llvm::SmallString<64> TemplateMangling;
2191 llvm::raw_svector_ostream Stream(TemplateMangling);
2192 MicrosoftCXXNameMangler
Extra(Context, Stream);
2200 Extra.mangleSourceName(
"Autoreleasing");
2203 Extra.mangleSourceName(
"Strong");
2206 Extra.mangleSourceName(
"Weak");
2209 Extra.manglePointerCVQualifiers(Quals);
2210 Extra.manglePointerExtQualifiers(Quals,
Type);
2213 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2216void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *
T,
2218 SourceRange Range) {
2219 llvm::SmallString<64> TemplateMangling;
2220 llvm::raw_svector_ostream Stream(TemplateMangling);
2221 MicrosoftCXXNameMangler
Extra(Context, Stream);
2224 Extra.mangleSourceName(
"KindOf");
2225 Extra.mangleType(QualType(
T, 0)
2226 .stripObjCKindOfType(getASTContext())
2227 ->castAs<ObjCObjectType>(),
2230 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2233void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
2291 if (HasConst && HasVolatile) {
2293 }
else if (HasVolatile) {
2295 }
else if (HasConst) {
2301 if (HasConst && HasVolatile) {
2303 }
else if (HasVolatile) {
2305 }
else if (HasConst) {
2316MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2319 switch (RefQualifier) {
2333void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
2334 QualType PointeeType) {
2336 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2349void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {
2355 mangleNumber(PointerAuth.
getKey());
2360void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
2368 if (HasConst && HasVolatile) {
2370 }
else if (HasVolatile) {
2372 }
else if (HasConst) {
2379void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType
T,
2380 SourceRange Range) {
2389 if (
const auto *DT =
T->
getAs<DecayedType>()) {
2390 QualType OriginalType = DT->getOriginalType();
2393 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2394 OriginalType = getASTContext().getIncompleteArrayType(
2395 AT->getElementType(), AT->getSizeModifier(),
2396 AT->getIndexTypeCVRQualifiers());
2407 TypePtr =
T.getCanonicalType().getAsOpaquePtr();
2410 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2412 if (
Found == FunArgBackReferences.end()) {
2413 size_t OutSizeBefore =
Out.tell();
2415 mangleType(
T, Range, QMM_Drop);
2420 bool LongerThanOneChar = (
Out.tell() - OutSizeBefore > 1);
2421 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2422 size_t Size = FunArgBackReferences.size();
2423 FunArgBackReferences[TypePtr] =
Size;
2430void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2431 const PassObjectSizeAttr *POSA) {
2432 int Type = POSA->getType();
2433 bool Dynamic = POSA->isDynamic();
2435 auto Iter = PassObjectSizeArgs.insert({
Type,
Dynamic}).first;
2436 auto *TypePtr = (
const void *)&*Iter;
2437 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2439 if (
Found == FunArgBackReferences.end()) {
2441 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2442 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2445 if (FunArgBackReferences.size() < 10) {
2446 size_t Size = FunArgBackReferences.size();
2447 FunArgBackReferences[TypePtr] =
Size;
2454void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType
T,
2456 SourceRange Range) {
2471 llvm::SmallString<32> ASMangling;
2472 llvm::raw_svector_ostream Stream(ASMangling);
2473 MicrosoftCXXNameMangler
Extra(Context, Stream);
2479 Extra.mangleSourceName(
"_AS");
2480 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2484 llvm_unreachable(
"Not a language specific address space");
2485 case LangAS::opencl_global:
2486 Extra.mangleSourceName(
"_ASCLglobal");
2488 case LangAS::opencl_global_device:
2489 Extra.mangleSourceName(
"_ASCLdevice");
2491 case LangAS::opencl_global_host:
2492 Extra.mangleSourceName(
"_ASCLhost");
2494 case LangAS::opencl_local:
2495 Extra.mangleSourceName(
"_ASCLlocal");
2497 case LangAS::opencl_constant:
2498 Extra.mangleSourceName(
"_ASCLconstant");
2500 case LangAS::opencl_private:
2501 Extra.mangleSourceName(
"_ASCLprivate");
2503 case LangAS::opencl_generic:
2504 Extra.mangleSourceName(
"_ASCLgeneric");
2506 case LangAS::cuda_device:
2507 Extra.mangleSourceName(
"_ASCUdevice");
2509 case LangAS::cuda_constant:
2510 Extra.mangleSourceName(
"_ASCUconstant");
2512 case LangAS::cuda_shared:
2513 Extra.mangleSourceName(
"_ASCUshared");
2515 case LangAS::ptr32_sptr:
2516 case LangAS::ptr32_uptr:
2518 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2522 Extra.mangleType(
T, Range, QMM_Escape);
2523 mangleQualifiers(Qualifiers(),
false);
2524 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2527void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType
T,
2528 QualifierMangleMode QMM) {
2529 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2530 LangOptions::MSVC2019) &&
2531 "Cannot mangle MSVC 2017 auto return types!");
2535 Qualifiers Quals =
T.getLocalQualifiers();
2537 if (QMM == QMM_Result)
2539 if (QMM != QMM_Drop)
2540 mangleQualifiers(Quals,
false);
2541 Out << (AT->isDecltypeAuto() ?
"_T" :
"_P");
2545 T =
T.getDesugaredType(getASTContext());
2546 Qualifiers Quals =
T.getLocalQualifiers();
2553 mangleQualifiers(Quals,
false);
2556 llvm_unreachable(
"QMM_Escape unexpected");
2559 const Type *ty =
T.getTypePtr();
2561 case Type::MemberPointer:
2567 case Type::LValueReference:
2570 case Type::RValueReference:
2574 llvm_unreachable(
"Invalid type expected");
2578void MicrosoftCXXNameMangler::mangleType(QualType
T, SourceRange Range,
2579 QualifierMangleMode QMM) {
2582 T =
T.getDesugaredType(getASTContext());
2583 Qualifiers Quals =
T.getLocalQualifiers();
2585 if (
const ArrayType *AT = getASTContext().getAsArrayType(
T)) {
2588 if (QMM == QMM_Mangle)
2590 else if (QMM == QMM_Escape || QMM == QMM_Result)
2592 mangleArrayType(AT);
2605 if (
const FunctionType *FT = dyn_cast<FunctionType>(
T)) {
2607 mangleFunctionType(FT);
2610 mangleQualifiers(Quals,
false);
2613 if (!IsPointer && Quals) {
2615 mangleQualifiers(Quals,
false);
2623 if ((!IsPointer && Quals) ||
isa<TagType>(
T) || isArtificialTagType(
T)) {
2625 mangleQualifiers(Quals,
false);
2630 const Type *ty =
T.getTypePtr();
2633#define ABSTRACT_TYPE(CLASS, PARENT)
2634#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2636 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2638#define TYPE(CLASS, PARENT) \
2640 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2642#include "clang/AST/TypeNodes.inc"
2644#undef NON_CANONICAL_TYPE
2649void MicrosoftCXXNameMangler::mangleType(
const BuiltinType *
T, Qualifiers,
2650 SourceRange Range) {
2678 switch (
T->getKind()) {
2679 case BuiltinType::Void:
2682 case BuiltinType::SChar:
2685 case BuiltinType::Char_U:
2686 case BuiltinType::Char_S:
2689 case BuiltinType::UChar:
2692 case BuiltinType::Short:
2695 case BuiltinType::UShort:
2698 case BuiltinType::Int:
2701 case BuiltinType::UInt:
2704 case BuiltinType::Long:
2707 case BuiltinType::ULong:
2710 case BuiltinType::Float:
2713 case BuiltinType::Double:
2717 case BuiltinType::LongDouble:
2720 case BuiltinType::LongLong:
2723 case BuiltinType::ULongLong:
2726 case BuiltinType::Int128:
2729 case BuiltinType::UInt128:
2732 case BuiltinType::Bool:
2735 case BuiltinType::Char8:
2738 case BuiltinType::Char16:
2741 case BuiltinType::Char32:
2744 case BuiltinType::WChar_S:
2745 case BuiltinType::WChar_U:
2749#define BUILTIN_TYPE(Id, SingletonId)
2750#define PLACEHOLDER_TYPE(Id, SingletonId) \
2751 case BuiltinType::Id:
2752#include "clang/AST/BuiltinTypes.def"
2753 case BuiltinType::Dependent:
2754 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2756 case BuiltinType::ObjCId:
2757 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2759 case BuiltinType::ObjCClass:
2760 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2762 case BuiltinType::ObjCSel:
2763 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2766#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2767 case BuiltinType::Id: \
2768 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2770#include "clang/Basic/OpenCLImageTypes.def"
2771 case BuiltinType::OCLSampler:
2773 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2775 case BuiltinType::OCLEvent:
2777 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2779 case BuiltinType::OCLClkEvent:
2781 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2783 case BuiltinType::OCLQueue:
2785 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2787 case BuiltinType::OCLReserveID:
2789 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2791#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2792 case BuiltinType::Id: \
2793 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2795#include "clang/Basic/OpenCLExtensionTypes.def"
2797 case BuiltinType::NullPtr:
2801 case BuiltinType::Float16:
2802 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2805 case BuiltinType::Half:
2806 if (!getASTContext().getLangOpts().
HLSL)
2807 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2808 else if (getASTContext().getLangOpts().NativeHalfType)
2814 case BuiltinType::BFloat16:
2815 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2818 case BuiltinType::MFloat8:
2819 mangleArtificialTagType(TagTypeKind::Struct,
"__mfp8", {
"__clang"});
2822#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2823 case BuiltinType::Id: \
2824 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2825 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2828#include "clang/Basic/WebAssemblyReferenceTypes.def"
2830#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2831 case BuiltinType::Id: \
2832 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2834#include "clang/Basic/HLSLIntangibleTypes.def"
2836 case BuiltinType::SveBool:
2840 case BuiltinType::SveInt8:
2843 case BuiltinType::SveInt16:
2846 case BuiltinType::SveInt32:
2849 case BuiltinType::SveInt64:
2853 case BuiltinType::SveUint8:
2856 case BuiltinType::SveUint16:
2859 case BuiltinType::SveUint32:
2862 case BuiltinType::SveUint64:
2866 case BuiltinType::SveBFloat16:
2869 case BuiltinType::SveFloat16:
2872 case BuiltinType::SveFloat32:
2875 case BuiltinType::SveFloat64:
2879 case BuiltinType::SveInt8x2:
2882 case BuiltinType::SveInt16x2:
2885 case BuiltinType::SveInt32x2:
2888 case BuiltinType::SveInt64x2:
2892 case BuiltinType::SveUint8x2:
2895 case BuiltinType::SveUint16x2:
2898 case BuiltinType::SveUint32x2:
2901 case BuiltinType::SveUint64x2:
2905 case BuiltinType::SveBFloat16x2:
2908 case BuiltinType::SveFloat16x2:
2911 case BuiltinType::SveFloat32x2:
2914 case BuiltinType::SveFloat64x2:
2918 case BuiltinType::SveInt8x3:
2921 case BuiltinType::SveInt16x3:
2924 case BuiltinType::SveInt32x3:
2927 case BuiltinType::SveInt64x3:
2931 case BuiltinType::SveUint8x3:
2934 case BuiltinType::SveUint16x3:
2937 case BuiltinType::SveUint32x3:
2940 case BuiltinType::SveUint64x3:
2944 case BuiltinType::SveBFloat16x3:
2947 case BuiltinType::SveFloat16x3:
2950 case BuiltinType::SveFloat32x3:
2953 case BuiltinType::SveFloat64x3:
2957 case BuiltinType::SveInt8x4:
2960 case BuiltinType::SveInt16x4:
2963 case BuiltinType::SveInt32x4:
2966 case BuiltinType::SveInt64x4:
2970 case BuiltinType::SveUint8x4:
2973 case BuiltinType::SveUint16x4:
2976 case BuiltinType::SveUint32x4:
2979 case BuiltinType::SveUint64x4:
2983 case BuiltinType::SveBFloat16x4:
2986 case BuiltinType::SveFloat16x4:
2989 case BuiltinType::SveFloat32x4:
2992 case BuiltinType::SveFloat64x4:
2998 case BuiltinType::SveMFloat8:
2999 mangleArtificialTagType(TagTypeKind::Struct,
"__SVMfloat8_t", {
"__clang"});
3002 case BuiltinType::SveMFloat8x2:
3003 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svmfloat8x2_t",
3007 case BuiltinType::SveMFloat8x3:
3008 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svmfloat8x3_t",
3012 case BuiltinType::SveMFloat8x4:
3013 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svmfloat8x4_t",
3017 case BuiltinType::SveBoolx2:
3018 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svboolx2_t",
3022 case BuiltinType::SveBoolx4:
3023 mangleArtificialTagType(TagTypeKind::Struct,
"__clang_svboolx4_t",
3027 case BuiltinType::SveCount:
3028 mangleArtificialTagType(TagTypeKind::Struct,
"__SVCount_t", {
"__clang"});
3031#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3032#include "clang/Basic/SPIRVTypes.def"
3046void MicrosoftCXXNameMangler::mangleType(
const FunctionProtoType *
T, Qualifiers,
3053 mangleFunctionType(
T,
nullptr,
true);
3056 mangleFunctionType(
T);
3059void MicrosoftCXXNameMangler::mangleType(
const FunctionNoProtoType *
T,
3060 Qualifiers, SourceRange) {
3062 mangleFunctionType(
T);
3065void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *
T,
3066 const FunctionDecl *D,
3067 bool ForceThisQuals,
3068 bool MangleExceptionSpec) {
3071 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(
T);
3076 bool IsInLambda =
false;
3077 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
3079 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
3083 HasThisQuals =
true;
3092 CC = getASTContext().getDefaultCallingConvention(
3101 manglePointerExtQualifiers(Quals, QualType());
3103 mangleQualifiers(Quals,
false);
3106 mangleCallingConvention(CC, Range);
3111 Out <<
"__clang_sme_attr" << SMEAttrs;
3124 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
3133 if (IsCtorClosure) {
3143 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
3145 ->
castAs<LValueReferenceType>()
3151 llvm_unreachable(
"unexpected constructor closure!");
3157 }
else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(D)) {
3168 mangleType(ResultType, Range, QMM_Result);
3169 }
else if (IsInLambda) {
3171 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
3172 "shouldn't need to mangle __auto_type!");
3176 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3182 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
3183 "shouldn't need to mangle __auto_type!");
3189 auto UseClangMangling = [](QualType ResultType) {
3190 QualType
T = ResultType;
3193 if (
T.getQualifiers().hasAddressSpace())
3199 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
3200 LangOptions::MSVC2019) &&
3201 !UseClangMangling(ResultType)) {
3210 ->
castAs<FunctionProtoType>();
3213 mangleAutoReturnType(ResultType, QMM_Result);
3219 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3225 mangleType(ResultType, Range, QMM_Result);
3241 for (
unsigned I = 0, E = Proto->
getNumParams(); I != E; ++I) {
3246 mangleFunctionArgumentType(Proto->
getParamType(I), Range);
3257 manglePassObjectSizeArg(P);
3266 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
3267 getASTContext().getLangOpts().isCompatibleWithMSVC(
3268 LangOptions::MSVC2017_5))
3269 mangleThrowSpecification(Proto);
3274void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
3299 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3309 llvm_unreachable(
"Unsupported access specifier");
3338void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC,
3339 SourceRange Range) {
3401 if (getASTContext().getLangOpts().RegCall4)
3410void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *
T,
3411 SourceRange Range) {
3415void MicrosoftCXXNameMangler::mangleThrowSpecification(
3416 const FunctionProtoType *FT) {
3425void MicrosoftCXXNameMangler::mangleType(
const UnresolvedUsingType *
T,
3426 Qualifiers, SourceRange Range) {
3437void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
3439 case TagTypeKind::Union:
3442 case TagTypeKind::Struct:
3443 case TagTypeKind::Interface:
3446 case TagTypeKind::Class:
3449 case TagTypeKind::Enum:
3454void MicrosoftCXXNameMangler::mangleType(
const EnumType *
T, Qualifiers,
3458void MicrosoftCXXNameMangler::mangleType(
const RecordType *
T, Qualifiers,
3462void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3472void MicrosoftCXXNameMangler::mangleArtificialTagType(
3474 ArrayRef<StringRef> NestedNames) {
3476 mangleTagTypeKind(TK);
3479 mangleSourceName(UnqualifiedName);
3481 for (StringRef N : llvm::reverse(NestedNames))
3482 mangleSourceName(N);
3495void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *
T) {
3498 manglePointerCVQualifiers(
T->getElementType().getQualifiers());
3499 mangleType(
T->getElementType(), SourceRange());
3501void MicrosoftCXXNameMangler::mangleType(
const ConstantArrayType *
T, Qualifiers,
3503 llvm_unreachable(
"Should have been special cased");
3505void MicrosoftCXXNameMangler::mangleType(
const VariableArrayType *
T, Qualifiers,
3507 llvm_unreachable(
"Should have been special cased");
3509void MicrosoftCXXNameMangler::mangleType(
const DependentSizedArrayType *
T,
3510 Qualifiers, SourceRange) {
3511 llvm_unreachable(
"Should have been special cased");
3513void MicrosoftCXXNameMangler::mangleType(
const IncompleteArrayType *
T,
3514 Qualifiers, SourceRange) {
3515 llvm_unreachable(
"Should have been special cased");
3517void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *
T) {
3518 QualType ElementTy(
T, 0);
3519 SmallVector<llvm::APInt, 3> Dimensions;
3521 if (ElementTy->isConstantArrayType()) {
3522 const ConstantArrayType *CAT =
3523 getASTContext().getAsConstantArrayType(ElementTy);
3524 Dimensions.push_back(CAT->
getSize());
3526 }
else if (ElementTy->isIncompleteArrayType()) {
3527 const IncompleteArrayType *IAT =
3528 getASTContext().getAsIncompleteArrayType(ElementTy);
3529 Dimensions.push_back(llvm::APInt(32, 0));
3531 }
else if (ElementTy->isVariableArrayType()) {
3532 const VariableArrayType *VAT =
3533 getASTContext().getAsVariableArrayType(ElementTy);
3534 Dimensions.push_back(llvm::APInt(32, 0));
3536 }
else if (ElementTy->isDependentSizedArrayType()) {
3538 const DependentSizedArrayType *DSAT =
3539 getASTContext().getAsDependentSizedArrayType(ElementTy);
3549 mangleNumber(Dimensions.size());
3550 for (
const llvm::APInt &Dimension : Dimensions)
3551 mangleNumber(Dimension.getLimitedValue());
3552 mangleType(ElementTy, SourceRange(), QMM_Escape);
3555void MicrosoftCXXNameMangler::mangleType(
const ArrayParameterType *
T,
3556 Qualifiers, SourceRange) {
3563void MicrosoftCXXNameMangler::mangleType(
const MemberPointerType *
T,
3564 Qualifiers Quals, SourceRange Range) {
3566 manglePointerCVQualifiers(Quals);
3567 manglePointerExtQualifiers(Quals, PointeeType);
3568 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
3570 mangleName(
T->getMostRecentCXXRecordDecl());
3571 mangleFunctionType(FPT,
nullptr,
true);
3574 mangleName(
T->getMostRecentCXXRecordDecl());
3575 mangleType(PointeeType, Range, QMM_Drop);
3579void MicrosoftCXXNameMangler::mangleType(
const TemplateTypeParmType *
T,
3580 Qualifiers, SourceRange Range) {
3583 llvm::SmallString<64> Name;
3585 Name += llvm::utostr(
T->getDepth());
3587 Name += llvm::utostr(
T->getIndex());
3589 mangleSourceName(Name);
3592void MicrosoftCXXNameMangler::mangleType(
const SubstTemplateTypeParmPackType *
T,
3593 Qualifiers, SourceRange Range) {
3597void MicrosoftCXXNameMangler::mangleType(
const SubstBuiltinTemplatePackType *
T,
3598 Qualifiers, SourceRange Range) {
3599 Error(
Range.getBegin(),
"substituted builtin template pack") <<
Range;
3605void MicrosoftCXXNameMangler::mangleType(
const PointerType *
T, Qualifiers Quals,
3606 SourceRange Range) {
3608 manglePointerCVQualifiers(Quals);
3609 manglePointerExtQualifiers(Quals, PointeeType);
3610 manglePointerAuthQualifier(Quals);
3616 mangleType(PointeeType, Range);
3618 mangleAddressSpaceType(PointeeType, PointeeType.
getQualifiers(), Range);
3621void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectPointerType *
T,
3622 Qualifiers Quals, SourceRange Range) {
3631 return mangleObjCLifetime(PointeeType, Quals, Range);
3633 manglePointerCVQualifiers(Quals);
3634 manglePointerExtQualifiers(Quals, PointeeType);
3635 mangleType(PointeeType, Range);
3641void MicrosoftCXXNameMangler::mangleType(
const LValueReferenceType *
T,
3642 Qualifiers Quals, SourceRange Range) {
3646 manglePointerExtQualifiers(Quals, PointeeType);
3647 mangleType(PointeeType, Range);
3653void MicrosoftCXXNameMangler::mangleType(
const RValueReferenceType *
T,
3654 Qualifiers Quals, SourceRange Range) {
3658 manglePointerExtQualifiers(Quals, PointeeType);
3659 mangleType(PointeeType, Range);
3662void MicrosoftCXXNameMangler::mangleType(
const ComplexType *
T, Qualifiers,
3663 SourceRange Range) {
3664 QualType ElementType =
T->getElementType();
3666 llvm::SmallString<64> TemplateMangling;
3667 llvm::raw_svector_ostream Stream(TemplateMangling);
3668 MicrosoftCXXNameMangler
Extra(Context, Stream);
3670 Extra.mangleSourceName(
"_Complex");
3671 Extra.mangleType(ElementType, Range, QMM_Escape);
3673 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3681bool MicrosoftCXXNameMangler::isArtificialTagType(QualType
T)
const {
3682 const Type *ty =
T.getTypePtr();
3687 case Type::Vector: {
3696void MicrosoftCXXNameMangler::mangleType(
const VectorType *
T, Qualifiers Quals,
3697 SourceRange Range) {
3698 QualType EltTy =
T->getElementType();
3699 const BuiltinType *ET = EltTy->
getAs<BuiltinType>();
3700 const BitIntType *BitIntTy = EltTy->
getAs<BitIntType>();
3701 assert((ET || BitIntTy) &&
3702 "vectors with non-builtin/_BitInt elements are unsupported");
3703 uint64_t Width = getASTContext().getTypeSize(
T);
3706 size_t OutSizeBefore =
Out.tell();
3708 if (getASTContext().getTargetInfo().
getTriple().isX86() && ET) {
3709 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3710 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3711 }
else if (Width >= 128) {
3712 if (ET->
getKind() == BuiltinType::Float)
3713 mangleArtificialTagType(TagTypeKind::Union,
3714 "__m" + llvm::utostr(Width));
3715 else if (ET->
getKind() == BuiltinType::LongLong)
3716 mangleArtificialTagType(TagTypeKind::Union,
3717 "__m" + llvm::utostr(Width) +
'i');
3718 else if (ET->
getKind() == BuiltinType::Double)
3719 mangleArtificialTagType(TagTypeKind::Struct,
3720 "__m" + llvm::utostr(Width) +
'd');
3725 bool IsBuiltin =
Out.tell() != OutSizeBefore;
3731 llvm::SmallString<64> TemplateMangling;
3732 llvm::raw_svector_ostream Stream(TemplateMangling);
3733 MicrosoftCXXNameMangler
Extra(Context, Stream);
3735 Extra.mangleSourceName(
"__vector");
3736 Extra.mangleType(QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3738 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumElements()));
3740 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3744void MicrosoftCXXNameMangler::mangleType(
const ExtVectorType *
T,
3745 Qualifiers Quals, SourceRange Range) {
3746 mangleType(
static_cast<const VectorType *
>(
T), Quals, Range);
3749void MicrosoftCXXNameMangler::mangleType(
const DependentVectorType *
T,
3750 Qualifiers, SourceRange Range) {
3754void MicrosoftCXXNameMangler::mangleType(
const DependentSizedExtVectorType *
T,
3755 Qualifiers, SourceRange Range) {
3756 Error(
Range.getBegin(),
"dependent-sized extended vector type") <<
Range;
3759void MicrosoftCXXNameMangler::mangleType(
const ConstantMatrixType *
T,
3760 Qualifiers quals, SourceRange Range) {
3761 QualType EltTy =
T->getElementType();
3763 llvm::SmallString<64> TemplateMangling;
3764 llvm::raw_svector_ostream Stream(TemplateMangling);
3765 MicrosoftCXXNameMangler
Extra(Context, Stream);
3769 Extra.mangleSourceName(
"__matrix");
3770 Extra.mangleType(EltTy, Range, QMM_Escape);
3772 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumRows()));
3773 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumColumns()));
3775 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3778void MicrosoftCXXNameMangler::mangleType(
const DependentSizedMatrixType *
T,
3779 Qualifiers quals, SourceRange Range) {
3783void MicrosoftCXXNameMangler::mangleType(
const DependentAddressSpaceType *
T,
3784 Qualifiers, SourceRange Range) {
3788void MicrosoftCXXNameMangler::mangleType(
const ObjCInterfaceType *
T, Qualifiers,
3791 mangleTagTypeKind(TagTypeKind::Struct);
3792 mangleName(
T->getDecl());
3795void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectType *
T,
3796 Qualifiers Quals, SourceRange Range) {
3797 if (
T->isKindOfType())
3798 return mangleObjCKindOfType(
T, Quals, Range);
3800 if (
T->qual_empty() && !
T->isSpecialized())
3801 return mangleType(
T->getBaseType(), Range, QMM_Drop);
3803 ArgBackRefMap OuterFunArgsContext;
3804 ArgBackRefMap OuterTemplateArgsContext;
3805 BackRefVec OuterTemplateContext;
3807 FunArgBackReferences.swap(OuterFunArgsContext);
3808 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3809 NameBackReferences.swap(OuterTemplateContext);
3811 mangleTagTypeKind(TagTypeKind::Struct);
3815 mangleSourceName(
"objc_object");
3816 else if (
T->isObjCClass())
3817 mangleSourceName(
"objc_class");
3819 mangleSourceName(
T->getInterface()->getName());
3821 for (
const auto &Q :
T->quals())
3822 mangleObjCProtocol(Q);
3824 if (
T->isSpecialized())
3825 for (
const auto &TA :
T->getTypeArgs())
3826 mangleType(TA, Range, QMM_Drop);
3832 FunArgBackReferences.swap(OuterFunArgsContext);
3833 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3834 NameBackReferences.swap(OuterTemplateContext);
3837void MicrosoftCXXNameMangler::mangleType(
const BlockPointerType *
T,
3838 Qualifiers Quals, SourceRange Range) {
3840 manglePointerCVQualifiers(Quals);
3841 manglePointerExtQualifiers(Quals, PointeeType);
3845 mangleFunctionType(PointeeType->
castAs<FunctionProtoType>());
3848void MicrosoftCXXNameMangler::mangleType(
const InjectedClassNameType *,
3849 Qualifiers, SourceRange) {
3850 llvm_unreachable(
"Cannot mangle injected class name type.");
3853void MicrosoftCXXNameMangler::mangleType(
const TemplateSpecializationType *
T,
3854 Qualifiers, SourceRange Range) {
3858void MicrosoftCXXNameMangler::mangleType(
const DependentNameType *
T, Qualifiers,
3859 SourceRange Range) {
3863void MicrosoftCXXNameMangler::mangleType(
const PackExpansionType *
T, Qualifiers,
3864 SourceRange Range) {
3868void MicrosoftCXXNameMangler::mangleType(
const PackIndexingType *
T,
3869 Qualifiers Quals, SourceRange Range) {
3870 manglePointerCVQualifiers(Quals);
3871 mangleType(
T->getSelectedType(), Range);
3874void MicrosoftCXXNameMangler::mangleType(
const TypeOfType *
T, Qualifiers,
3875 SourceRange Range) {
3879void MicrosoftCXXNameMangler::mangleType(
const TypeOfExprType *
T, Qualifiers,
3880 SourceRange Range) {
3884void MicrosoftCXXNameMangler::mangleType(
const DecltypeType *
T, Qualifiers,
3885 SourceRange Range) {
3889void MicrosoftCXXNameMangler::mangleType(
const UnaryTransformType *
T,
3890 Qualifiers, SourceRange Range) {
3894void MicrosoftCXXNameMangler::mangleType(
const AutoType *
T, Qualifiers,
3895 SourceRange Range) {
3896 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3901void MicrosoftCXXNameMangler::mangleType(
3902 const DeducedTemplateSpecializationType *
T, Qualifiers, SourceRange Range) {
3903 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3905 Error(
Range.getBegin(),
"deduced class template specialization type")
3909void MicrosoftCXXNameMangler::mangleType(
const AtomicType *
T, Qualifiers,
3910 SourceRange Range) {
3911 QualType ValueType =
T->getValueType();
3913 llvm::SmallString<64> TemplateMangling;
3914 llvm::raw_svector_ostream Stream(TemplateMangling);
3915 MicrosoftCXXNameMangler
Extra(Context, Stream);
3917 Extra.mangleSourceName(
"_Atomic");
3918 Extra.mangleType(ValueType, Range, QMM_Escape);
3920 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3923void MicrosoftCXXNameMangler::mangleType(
const PipeType *
T, Qualifiers,
3924 SourceRange Range) {
3925 QualType ElementType =
T->getElementType();
3927 llvm::SmallString<64> TemplateMangling;
3928 llvm::raw_svector_ostream Stream(TemplateMangling);
3929 MicrosoftCXXNameMangler
Extra(Context, Stream);
3931 Extra.mangleSourceName(
"ocl_pipe");
3932 Extra.mangleType(ElementType, Range, QMM_Escape);
3933 Extra.mangleIntegerLiteral(llvm::APSInt::get(
T->isReadOnly()));
3935 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3938void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
3941 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
3942 getASTContext().getSourceManager(),
3943 "Mangling declaration");
3945 msvc_hashing_ostream MHO(Out);
3947 if (
auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3949 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3950 return mangler.mangle(GD);
3953 if (
auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3955 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3956 return mangler.mangle(GD);
3959 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3960 return Mangler.mangle(GD);
3963void MicrosoftCXXNameMangler::mangleType(
const BitIntType *
T, Qualifiers,
3964 SourceRange Range) {
3965 llvm::SmallString<64> TemplateMangling;
3966 llvm::raw_svector_ostream Stream(TemplateMangling);
3967 MicrosoftCXXNameMangler
Extra(Context, Stream);
3969 if (
T->isUnsigned())
3970 Extra.mangleSourceName(
"_UBitInt");
3972 Extra.mangleSourceName(
"_BitInt");
3973 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumBits()));
3975 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3978void MicrosoftCXXNameMangler::mangleType(
const DependentBitIntType *
T,
3979 Qualifiers, SourceRange Range) {
3983void MicrosoftCXXNameMangler::mangleType(
const HLSLAttributedResourceType *
T,
3984 Qualifiers, SourceRange Range) {
3985 llvm_unreachable(
"HLSL uses Itanium name mangling");
3988void MicrosoftCXXNameMangler::mangleType(
const HLSLInlineSpirvType *
T,
3989 Qualifiers, SourceRange Range) {
3990 llvm_unreachable(
"HLSL uses Itanium name mangling");
3993void MicrosoftCXXNameMangler::mangleType(
const OverflowBehaviorType *
T,
3994 Qualifiers, SourceRange Range) {
3995 QualType UnderlyingType =
T->getUnderlyingType();
3997 llvm::SmallString<64> TemplateMangling;
3998 llvm::raw_svector_ostream Stream(TemplateMangling);
3999 MicrosoftCXXNameMangler
Extra(Context, Stream);
4001 if (
T->isWrapKind()) {
4002 Extra.mangleSourceName(
"ObtWrap_");
4004 Extra.mangleSourceName(
"ObtTrap_");
4006 Extra.mangleType(UnderlyingType, Range, QMM_Escape);
4008 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
4037 MicrosoftCXXNameMangler &Mangler,
4044 llvm_unreachable(
"Unsupported access specifier");
4055 Out <<
'R' << AccessSpec;
4056 Mangler.mangleNumber(
4058 Mangler.mangleNumber(
4060 Mangler.mangleNumber(
4065 Mangler.mangleNumber(
4072 llvm_unreachable(
"Unsupported access specifier");
4086 llvm_unreachable(
"Unsupported access specifier");
4099void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
4100 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML,
4102 msvc_hashing_ostream MHO(Out);
4103 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4104 Mangler.getStream() <<
'?';
4105 Mangler.mangleVirtualMemPtrThunk(MD, ML);
4108void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
4109 const ThunkInfo &Thunk,
4112 msvc_hashing_ostream MHO(Out);
4113 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4114 Mangler.getStream() <<
'?';
4115 Mangler.mangleName(MD);
4124 assert(Thunk.
Method !=
nullptr &&
4125 "Thunk info should hold the overridee decl");
4127 const CXXMethodDecl *DeclForFPT = Thunk.
Method ? Thunk.
Method : MD;
4128 Mangler.mangleFunctionType(
4132void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
const CXXDestructorDecl *DD,
4134 const ThunkInfo &Thunk,
4141 msvc_hashing_ostream MHO(Out);
4142 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
4143 Mangler.getStream() <<
"??_E";
4145 auto &Adjustment = Thunk.
This;
4147 Mangler.mangleFunctionType(DD->
getType()->
castAs<FunctionProtoType>(), DD);
4150void MicrosoftMangleContextImpl::mangleCXXVFTable(
4151 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4157 msvc_hashing_ostream MHO(Out);
4158 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4159 if (Derived->
hasAttr<DLLImportAttr>())
4160 Mangler.getStream() <<
"??_S";
4162 Mangler.getStream() <<
"??_7";
4163 Mangler.mangleName(Derived);
4164 Mangler.getStream() <<
"6B";
4165 for (
const CXXRecordDecl *RD : BasePath)
4166 Mangler.mangleName(RD);
4167 Mangler.getStream() <<
'@';
4170void MicrosoftMangleContextImpl::mangleCXXVTable(
const CXXRecordDecl *Derived,
4173 mangleCXXVFTable(Derived, {},
Out);
4176void MicrosoftMangleContextImpl::mangleCXXVBTable(
4177 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4183 msvc_hashing_ostream MHO(Out);
4184 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4185 Mangler.getStream() <<
"??_8";
4186 Mangler.mangleName(Derived);
4187 Mangler.getStream() <<
"7B";
4188 for (
const CXXRecordDecl *RD : BasePath)
4189 Mangler.mangleName(RD);
4190 Mangler.getStream() <<
'@';
4193void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType
T, raw_ostream &Out) {
4194 msvc_hashing_ostream MHO(Out);
4195 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4196 Mangler.getStream() <<
"??_R0";
4197 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4198 Mangler.getStream() <<
"@8";
4201void MicrosoftMangleContextImpl::mangleCXXRTTIName(
4202 QualType
T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4208 msvc_hashing_ostream MHO(Out, 4095);
4209 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4210 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4213void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
4214 const CXXRecordDecl *SrcRD,
const CXXRecordDecl *DstRD, raw_ostream &Out) {
4215 msvc_hashing_ostream MHO(Out);
4216 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4217 Mangler.getStream() <<
"??_K";
4218 Mangler.mangleName(SrcRD);
4219 Mangler.getStream() <<
"$C";
4220 Mangler.mangleName(DstRD);
4223void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType
T,
bool IsConst,
4228 msvc_hashing_ostream MHO(Out);
4229 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4230 Mangler.getStream() <<
"_TI";
4232 Mangler.getStream() <<
'C';
4234 Mangler.getStream() <<
'V';
4236 Mangler.getStream() <<
'U';
4237 Mangler.getStream() << NumEntries;
4238 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4241void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
4242 QualType
T,
uint32_t NumEntries, raw_ostream &Out) {
4243 msvc_hashing_ostream MHO(Out);
4244 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4245 Mangler.getStream() <<
"_CTA";
4246 Mangler.getStream() << NumEntries;
4247 Mangler.mangleType(
T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4250void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4254 MicrosoftCXXNameMangler Mangler(*
this, Out);
4255 Mangler.getStream() <<
"_CT";
4257 llvm::SmallString<64> RTTIMangling;
4259 llvm::raw_svector_ostream Stream(RTTIMangling);
4260 msvc_hashing_ostream MHO(Stream);
4261 mangleCXXRTTI(
T, MHO);
4263 Mangler.getStream() << RTTIMangling;
4271 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4272 LangOptions::MSVC2015) &&
4273 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4274 LangOptions::MSVC2017_7);
4275 llvm::SmallString<64> CopyCtorMangling;
4276 if (!OmitCopyCtor && CD) {
4277 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4278 msvc_hashing_ostream MHO(Stream);
4279 mangleCXXName(GlobalDecl(CD, CT), MHO);
4281 Mangler.getStream() << CopyCtorMangling;
4283 Mangler.getStream() <<
Size;
4284 if (VBPtrOffset == -1) {
4286 Mangler.getStream() << NVOffset;
4289 Mangler.getStream() << NVOffset;
4290 Mangler.getStream() << VBPtrOffset;
4291 Mangler.getStream() << VBIndex;
4295void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4298 msvc_hashing_ostream MHO(Out);
4299 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4300 Mangler.getStream() <<
"??_R1";
4301 Mangler.mangleNumber(NVOffset);
4302 Mangler.mangleNumber(VBPtrOffset);
4303 Mangler.mangleNumber(VBTableOffset);
4304 Mangler.mangleNumber(Flags);
4305 Mangler.mangleName(Derived);
4306 Mangler.getStream() <<
"8";
4309void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4310 const CXXRecordDecl *Derived, raw_ostream &Out) {
4311 msvc_hashing_ostream MHO(Out);
4312 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4313 Mangler.getStream() <<
"??_R2";
4314 Mangler.mangleName(Derived);
4315 Mangler.getStream() <<
"8";
4318void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4319 const CXXRecordDecl *Derived, raw_ostream &Out) {
4320 msvc_hashing_ostream MHO(Out);
4321 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4322 Mangler.getStream() <<
"??_R3";
4323 Mangler.mangleName(Derived);
4324 Mangler.getStream() <<
"8";
4327void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4328 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4334 llvm::SmallString<64> VFTableMangling;
4335 llvm::raw_svector_ostream Stream(VFTableMangling);
4336 mangleCXXVFTable(Derived, BasePath, Stream);
4338 if (VFTableMangling.starts_with(
"??@")) {
4339 assert(VFTableMangling.ends_with(
"@"));
4340 Out << VFTableMangling <<
"??_R4@";
4344 assert(VFTableMangling.starts_with(
"??_7") ||
4345 VFTableMangling.starts_with(
"??_S"));
4347 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
4350void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4351 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4352 msvc_hashing_ostream MHO(Out);
4353 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4358 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
4359 Mangler.mangleName(EnclosingDecl);
4362void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4363 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4364 msvc_hashing_ostream MHO(Out);
4365 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4370 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
4371 Mangler.mangleName(EnclosingDecl);
4374void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4375 QualType
T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4378 MicrosoftCXXNameMangler Mangler(*
this, Out);
4379 Mangler.getStream() <<
'?';
4380 Mangler.mangleType(
T.getCanonicalType(), SourceRange());
4383void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4384 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
4385 msvc_hashing_ostream MHO(Out);
4386 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4388 Mangler.getStream() <<
"?";
4389 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
4390 Mangler.mangle(VD,
"");
4393void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4394 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
4395 msvc_hashing_ostream MHO(Out);
4396 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4398 Mangler.getStream() <<
"?";
4399 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
4400 Mangler.mangleNestedName(VD);
4401 Mangler.getStream() <<
"@4HA";
4404void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
4416 msvc_hashing_ostream MHO(Out);
4417 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4421 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
4423 Mangler.getStream() <<
"?$S1@";
4425 unsigned ScopeDepth = 0;
4426 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4430 Mangler.mangle(VD,
"");
4432 Mangler.mangleNestedName(VD);
4433 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
4435 Mangler.mangleNumber(ScopeDepth);
4438void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *D,
4441 msvc_hashing_ostream MHO(Out);
4442 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4443 Mangler.getStream() <<
"??__" << CharCode;
4445 Mangler.getStream() <<
'?';
4446 Mangler.mangleName(D);
4447 Mangler.mangleVariableEncoding(D);
4448 Mangler.getStream() <<
"@@";
4450 Mangler.mangleName(D);
4454 Mangler.getStream() <<
"YAXXZ";
4457void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *D,
4460 mangleInitFiniStub(D,
'E', Out);
4464MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *D,
4467 mangleInitFiniStub(D,
'F', Out);
4470void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4491 MicrosoftCXXNameMangler Mangler(*
this, Out);
4492 Mangler.getStream() <<
"??_C@_";
4500 unsigned StringLength =
4501 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4506 Mangler.getStream() <<
'1';
4508 Mangler.getStream() <<
'0';
4512 Mangler.mangleNumber(StringByteLength);
4514 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4516 if (Index / CharByteWidth >= SL->
getLength())
4517 return static_cast<char>(0);
4519 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4520 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4523 auto GetBigEndianByte = [&SL](
unsigned Index) {
4525 if (Index / CharByteWidth >= SL->
getLength())
4526 return static_cast<char>(0);
4528 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4529 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4534 for (
unsigned I = 0, E = StringByteLength; I != E; ++I)
4535 JC.update(GetLittleEndianByte(I));
4539 Mangler.mangleNumber(JC.getCRC());
4545 auto MangleByte = [&Mangler](
char Byte) {
4553 Mangler.getStream() << Byte;
4554 }
else if (
isLetter(Byte & 0x7f)) {
4555 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4557 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4558 ' ',
'\n',
'\t',
'\'',
'-'};
4559 const char *Pos = llvm::find(SpecialChars, Byte);
4560 if (Pos != std::end(SpecialChars)) {
4561 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4563 Mangler.getStream() <<
"?$";
4564 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4565 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4571 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4572 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4573 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4575 MangleByte(GetBigEndianByte(I));
4577 MangleByte(GetLittleEndianByte(I));
4580 Mangler.getStream() <<
'@';
4583void MicrosoftCXXNameMangler::mangleAutoReturnType(
const MemberPointerType *
T,
4586 manglePointerCVQualifiers(Quals);
4587 manglePointerExtQualifiers(Quals, PointeeType);
4588 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4590 mangleName(
T->getMostRecentCXXRecordDecl());
4591 mangleFunctionType(FPT,
nullptr,
true);
4594 mangleName(
T->getMostRecentCXXRecordDecl());
4595 mangleAutoReturnType(PointeeType, QMM_Drop);
4599void MicrosoftCXXNameMangler::mangleAutoReturnType(
const PointerType *
T,
4603 "Unexpected address space mangling required");
4605 manglePointerCVQualifiers(Quals);
4606 manglePointerExtQualifiers(Quals, PointeeType);
4608 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4610 mangleFunctionType(FPT);
4612 mangleAutoReturnType(PointeeType, QMM_Mangle);
4616void MicrosoftCXXNameMangler::mangleAutoReturnType(
const LValueReferenceType *
T,
4621 manglePointerExtQualifiers(Quals, PointeeType);
4622 mangleAutoReturnType(PointeeType, QMM_Mangle);
4625void MicrosoftCXXNameMangler::mangleAutoReturnType(
const RValueReferenceType *
T,
4630 manglePointerExtQualifiers(Quals, PointeeType);
4631 mangleAutoReturnType(PointeeType, QMM_Mangle);
4637 return new MicrosoftMangleContextImpl(Context, Diags, IsAux);
Enums/classes describing ABI related information about constructors, destructors and thunks.
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
static const GlobalDecl isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs)
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
llvm::MachO::Record Record
static ValueDecl * getAsArrayToPointerDecayedDecl(QualType T, const APValue &V)
If value V (with type T) represents a decayed pointer to the first element of an array,...
static void mangleThunkThisAdjustment(AccessSpecifier AS, const ThisAdjustment &Adjustment, MicrosoftCXXNameMangler &Mangler, raw_ostream &Out)
static StringRef getTriple(const Command &Job)
Defines the clang::Preprocessor interface.
static bool hasAttr(const Decl *D, bool IgnoreImplicitAttr)
Defines the SourceManager interface.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APValue & getVectorElt(unsigned I)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
bool addressSpaceMapManglingFor(LangAS AS) const
const clang::PrintingPolicy & getPrintingPolicy() const
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
unsigned getTargetAddressSpace(LangAS AS) const
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Represents a block literal declaration, which is like an unnamed FunctionDecl.
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Decl * getLambdaContextDecl() const
Retrieve the declaration that provides additional context for a lambda, when the normal declaration c...
CXXRecordDecl * getMostRecentDecl()
bool isLambda() const
Determine whether this class describes a lambda function object.
unsigned getLambdaManglingNumber() const
If this is the closure type of a lambda expression, retrieve the number to be used for name mangling ...
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Represents a class template specialization, which refers to a class template with a given set of temp...
llvm::APInt getSize() const
Return the constant array size as an APInt.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
bool isFunctionOrMethod() const
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
@ CXXConversionFunctionName
NameKind getNameKind() const
Determine what kind of name this is.
Expr * getSizeExpr() const
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
This represents one expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isExternC() const
Determines whether this function is a function with external, C linkage.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
Qualifiers getMethodQuals() const
QualType getParamType(unsigned i) const
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
bool isVariadic() const
Whether this function prototype is variadic.
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
KernelReferenceKind getKernelReferenceKind() const
GlobalDecl getWithDecl(const Decl *D)
CXXDtorType getDtorType() const
const Decl * getDecl() const
StringRef getName() const
Return the actual identifier string.
An lvalue reference type, per C++11 [dcl.ref].
A pointer to member type per C++ 8.3.3 - Pointers to members.
static MicrosoftMangleContext * create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux=false)
MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D, bool IsAux=false)
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool isExternallyVisible() const
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents an Objective-C protocol declaration.
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void * getAsOpaquePtr() const
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
bool hasAddressSpace() const
PointerAuthQualifier getPointerAuth() const
bool hasObjCLifetime() const
ObjCLifetime getObjCLifetime() const
Qualifiers withoutObjCLifetime() const
LangAS getAddressSpace() const
An rvalue reference type, per C++11 [dcl.ref].
field_range fields() const
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
This class handles loading and caching of source files into memory.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileID getMainFileID() const
Returns the FileID of the main source file.
A trivial tuple used to represent a source range.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const char * getStmtClassName() const
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
unsigned getCharByteWidth() const
Represents the declaration of a struct/union/class/enum.
TagDecl * getDefinition() const
Returns the TagDecl that actually defines this struct/union/class/enum.
TypedefNameDecl * getTypedefNameForAnonDecl() const
TagKind getTagKind() const
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
NamedDecl * getParam(unsigned Idx)
bool isBlockPointerType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
bool isMemberPointerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isFunctionType() const
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
TLSKind getTLSKind() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isStaticDataMember() const
Determines whether this is a static data member.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool isExternC() const
Determines whether this variable is a variable with external, C linkage.
Represents a variable template specialization, which refers to a variable template with a given set o...
Defines the clang::TargetInfo interface.
@ Number
Just a number, nothing else.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
Top level wrappers for InstallAPI frontend operations.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
CXXCtorType
C++ constructor types.
@ Ctor_DefaultClosure
Default closure variant of a ctor.
@ Ctor_CopyingClosure
Copying closure variant of a ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
RefQualifierKind
The kind of C++11 ref-qualifier associated with a function type.
@ RQ_None
No ref-qualifier was provided.
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
bool inheritanceModelHasNVOffsetField(bool IsMemberFunction, MSInheritanceModel Inheritance)
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName, bool useDirectABI)
Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
LanguageLinkage
Describes the different kinds of language linkage (C++ [dcl.link]) that an entity may have.
bool inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance)
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
bool inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance)
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
const FunctionProtoType * T
CXXDtorType
C++ destructor types.
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
TagTypeKind
The kind of a tag type.
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool isPtrSizeAddressSpace(LangAS AS)
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
int const char * function
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to.
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
uint64_t VBTableIndex
If nonzero, holds the vbtable index of the virtual base with the vfptr.
uint64_t Index
Method's index in the vftable.
A this pointer adjustment.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
const CXXMethodDecl * Method
Holds a pointer to the overridden method this thunk is for, if needed by the ABI to distinguish diffe...
ReturnAdjustment Return
The return adjustment.
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
struct clang::ThisAdjustment::VirtualAdjustment::@312251255113040203233347230177110330127151157305 Microsoft
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...