32#include "llvm/ADT/SmallVector.h"
33#include "llvm/ADT/StringExtras.h"
34#include "llvm/Support/CRC.h"
35#include "llvm/Support/MD5.h"
36#include "llvm/Support/StringSaver.h"
37#include "llvm/Support/xxhash.h"
48 if (
auto *CD = dyn_cast<CXXConstructorDecl>(DC))
50 else if (
auto *DD = dyn_cast<CXXDestructorDecl>(DC))
57struct msvc_hashing_ostream :
public llvm::raw_svector_ostream {
59 llvm::SmallString<64> Buffer;
61 msvc_hashing_ostream(raw_ostream &OS)
62 : llvm::raw_svector_ostream(Buffer), OS(OS) {}
63 ~msvc_hashing_ostream()
override {
64 StringRef MangledName = str();
65 bool StartsWithEscape = MangledName.starts_with(
"\01");
67 MangledName = MangledName.drop_front(1);
68 if (MangledName.size() < 4096) {
74 llvm::MD5::MD5Result Hash;
75 Hasher.update(MangledName);
78 SmallString<32> HexString;
79 llvm::MD5::stringifyResult(Hash, HexString);
83 OS <<
"??@" << HexString <<
'@';
88getLambdaDefaultArgumentDeclContext(
const Decl *D) {
89 if (
const auto *RD = dyn_cast<CXXRecordDecl>(D))
91 if (
const auto *Parm =
92 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
93 return Parm->getDeclContext();
106 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))
110 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
112 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
113 return ContextParam->getDeclContext();
119 return getEffectiveDeclContext(
cast<Decl>(DC));
126 return getEffectiveDeclContext(
cast<Decl>(DC));
130 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
134 if (
const auto *FTD = FD->getPrimaryTemplate())
135 return FTD->getTemplatedDecl()->getCanonicalDecl();
137 return FD->getCanonicalDecl();
143 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
144 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
145 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
146 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
147 llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
148 llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
149 SmallString<16> AnonymousNamespaceHash;
152 MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags,
154 bool shouldMangleCXXName(
const NamedDecl *D)
override;
155 bool shouldMangleStringLiteral(
const StringLiteral *SL)
override;
156 void mangleCXXName(GlobalDecl GD, raw_ostream &Out)
override;
157 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
158 const MethodVFTableLocation &ML,
159 raw_ostream &Out)
override;
160 void mangleThunk(
const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
161 bool ElideOverrideInfo, raw_ostream &)
override;
163 const ThunkInfo &Thunk,
bool ElideOverrideInfo,
164 raw_ostream &)
override;
165 void mangleCXXVFTable(
const CXXRecordDecl *Derived,
166 ArrayRef<const CXXRecordDecl *> BasePath,
167 raw_ostream &Out)
override;
168 void mangleCXXVBTable(
const CXXRecordDecl *Derived,
169 ArrayRef<const CXXRecordDecl *> BasePath,
170 raw_ostream &Out)
override;
172 void mangleCXXVTable(
const CXXRecordDecl *, raw_ostream &)
override;
173 void mangleCXXVirtualDisplacementMap(
const CXXRecordDecl *SrcRD,
174 const CXXRecordDecl *DstRD,
175 raw_ostream &Out)
override;
176 void mangleCXXThrowInfo(QualType T,
bool IsConst,
bool IsVolatile,
177 bool IsUnaligned, uint32_t NumEntries,
178 raw_ostream &Out)
override;
179 void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
180 raw_ostream &Out)
override;
181 void mangleCXXCatchableType(QualType T,
const CXXConstructorDecl *CD,
183 int32_t VBPtrOffset, uint32_t VBIndex,
184 raw_ostream &Out)
override;
185 void mangleCXXRTTI(QualType T, raw_ostream &Out)
override;
186 void mangleCXXRTTIName(QualType T, raw_ostream &Out,
187 bool NormalizeIntegers)
override;
188 void mangleCXXRTTIBaseClassDescriptor(
const CXXRecordDecl *Derived,
189 uint32_t NVOffset, int32_t VBPtrOffset,
190 uint32_t VBTableOffset, uint32_t Flags,
191 raw_ostream &Out)
override;
192 void mangleCXXRTTIBaseClassArray(
const CXXRecordDecl *Derived,
193 raw_ostream &Out)
override;
194 void mangleCXXRTTIClassHierarchyDescriptor(
const CXXRecordDecl *Derived,
195 raw_ostream &Out)
override;
197 mangleCXXRTTICompleteObjectLocator(
const CXXRecordDecl *Derived,
198 ArrayRef<const CXXRecordDecl *> BasePath,
199 raw_ostream &Out)
override;
200 void mangleCanonicalTypeName(QualType T, raw_ostream &,
201 bool NormalizeIntegers)
override;
202 void mangleReferenceTemporary(
const VarDecl *,
unsigned ManglingNumber,
203 raw_ostream &)
override;
204 void mangleStaticGuardVariable(
const VarDecl *D, raw_ostream &Out)
override;
205 void mangleThreadSafeStaticGuardVariable(
const VarDecl *D,
unsigned GuardNum,
206 raw_ostream &Out)
override;
207 void mangleDynamicInitializer(
const VarDecl *D, raw_ostream &Out)
override;
208 void mangleDynamicAtExitDestructor(
const VarDecl *D,
209 raw_ostream &Out)
override;
210 void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
211 raw_ostream &Out)
override;
212 void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
213 raw_ostream &Out)
override;
214 void mangleStringLiteral(
const StringLiteral *SL, raw_ostream &Out)
override;
215 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
216 const DeclContext *DC = getEffectiveDeclContext(ND);
222 if (
const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
223 if (RD->isLambda()) {
231 disc = getASTContext().getManglingNumber(ND, isAux());
236 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
237 if (!
Tag->hasNameForLinkage() &&
238 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
239 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))
244 unsigned &discriminator = Uniquifier[ND];
246 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
247 disc = discriminator + 1;
251 std::string getLambdaString(
const CXXRecordDecl *Lambda)
override {
252 assert(Lambda->
isLambda() &&
"RD must be a lambda!");
253 std::string Name(
"<lambda_");
258 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
259 const FunctionDecl *
Func =
263 unsigned DefaultArgNo =
265 Name += llvm::utostr(DefaultArgNo);
269 if (LambdaManglingNumber)
270 LambdaId = LambdaManglingNumber;
272 LambdaId = getLambdaIdForDebugInfo(Lambda);
274 Name += llvm::utostr(LambdaId);
279 unsigned getLambdaId(
const CXXRecordDecl *RD) {
280 assert(RD->
isLambda() &&
"RD must be a lambda!");
283 "RD must not have a mangling number!");
284 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator,
bool>
285 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
286 return Result.first->second;
289 unsigned getLambdaIdForDebugInfo(
const CXXRecordDecl *RD) {
290 assert(RD->
isLambda() &&
"RD must be a lambda!");
293 "RD must not have a mangling number!");
295 return LambdaIds.lookup(RD);
300 StringRef getAnonymousNamespaceHash()
const {
301 return AnonymousNamespaceHash;
305 void mangleInitFiniStub(
const VarDecl *D,
char CharCode, raw_ostream &Out);
310class MicrosoftCXXNameMangler {
311 MicrosoftMangleContextImpl &Context;
317 const NamedDecl *Structor;
318 unsigned StructorType;
320 typedef llvm::SmallVector<std::string, 10> BackRefVec;
321 BackRefVec NameBackReferences;
323 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
324 ArgBackRefMap FunArgBackReferences;
325 ArgBackRefMap TemplateArgBackReferences;
327 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
328 TemplateArgStringMap TemplateArgStrings;
329 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
330 llvm::StringSaver TemplateArgStringStorage;
332 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
333 PassObjectSizeArgsSet PassObjectSizeArgs;
335 ASTContext &getASTContext()
const {
return Context.getASTContext(); }
337 const bool PointersAre64Bit;
339 DiagnosticBuilder
Error(SourceLocation, StringRef, StringRef);
340 DiagnosticBuilder
Error(SourceLocation, StringRef);
341 DiagnosticBuilder
Error(StringRef);
344 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
345 enum class TplArgKind { ClassNTTP, StructuralValue };
347 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_)
348 : Context(
C), Out(Out_), Structor(
nullptr), StructorType(-1),
349 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
350 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
353 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
355 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
356 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
357 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
360 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
362 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
363 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
364 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
367 raw_ostream &getStream()
const {
return Out; }
369 void mangle(GlobalDecl GD, StringRef Prefix =
"?");
370 void mangleName(GlobalDecl GD);
371 void mangleFunctionEncoding(GlobalDecl GD,
bool ShouldMangle);
372 void mangleVariableEncoding(
const VarDecl *VD);
373 void mangleMemberDataPointer(
const CXXRecordDecl *RD,
const ValueDecl *VD,
374 const NonTypeTemplateParmDecl *PD,
375 QualType TemplateArgType,
376 StringRef Prefix =
"$");
377 void mangleMemberDataPointerInClassNTTP(
const CXXRecordDecl *,
379 void mangleMemberFunctionPointer(
const CXXRecordDecl *RD,
380 const CXXMethodDecl *MD,
381 const NonTypeTemplateParmDecl *PD,
382 QualType TemplateArgType,
383 StringRef Prefix =
"$");
384 void mangleFunctionPointer(
const FunctionDecl *FD,
385 const NonTypeTemplateParmDecl *PD,
386 QualType TemplateArgType);
387 void mangleVarDecl(
const VarDecl *VD,
const NonTypeTemplateParmDecl *PD,
388 QualType TemplateArgType);
389 void mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD,
390 const CXXMethodDecl *MD);
391 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
392 const MethodVFTableLocation &ML);
393 void mangleNumber(int64_t Number);
394 void mangleNumber(llvm::APSInt Number);
395 void mangleFloat(llvm::APFloat Number);
396 void mangleBits(llvm::APInt Number);
398 void mangleArtificialTagType(
TagTypeKind TK, StringRef UnqualifiedName,
399 ArrayRef<StringRef> NestedNames = {});
400 void mangleAddressSpaceType(QualType T, Qualifiers Quals, SourceRange Range);
401 void mangleType(QualType T, SourceRange Range,
402 QualifierMangleMode QMM = QMM_Mangle);
403 void mangleFunctionType(
const FunctionType *T,
404 const FunctionDecl *D =
nullptr,
405 bool ForceThisQuals =
false,
406 bool MangleExceptionSpec =
true);
407 void mangleSourceName(StringRef Name);
408 void mangleNestedName(GlobalDecl GD);
410 void mangleAutoReturnType(QualType T, QualifierMangleMode QMM);
413 bool isStructorDecl(
const NamedDecl *ND)
const {
414 return ND == Structor || getStructor(ND) == Structor;
417 bool is64BitPointer(Qualifiers Quals)
const {
419 return AddrSpace == LangAS::ptr64 ||
420 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||
421 AddrSpace == LangAS::ptr32_uptr));
424 void mangleUnqualifiedName(GlobalDecl GD) {
427 void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name);
430 void mangleQualifiers(Qualifiers Quals,
bool IsMember);
432 void manglePointerCVQualifiers(Qualifiers Quals);
433 void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType);
434 void manglePointerAuthQualifier(Qualifiers Quals);
436 void mangleUnscopedTemplateName(GlobalDecl GD);
438 mangleTemplateInstantiationName(GlobalDecl GD,
439 const TemplateArgumentList &TemplateArgs);
442 void mangleFunctionArgumentType(QualType T, SourceRange Range);
443 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
445 bool isArtificialTagType(QualType T)
const;
448#define ABSTRACT_TYPE(CLASS, PARENT)
449#define NON_CANONICAL_TYPE(CLASS, PARENT)
450#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
453#include "clang/AST/TypeNodes.inc"
455#undef NON_CANONICAL_TYPE
458 void mangleType(
const TagDecl *TD);
459 void mangleDecayedArrayType(
const ArrayType *T);
460 void mangleArrayType(
const ArrayType *T);
464 void mangleIntegerLiteral(
const llvm::APSInt &Number,
475 bool WithScalarType =
false);
490MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(
ASTContext &Context,
511 uint32_t TruncatedHash = uint32_t(xxh3_64bits(FE->getName()));
512 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
515 AnonymousNamespaceHash =
"0";
519bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *D) {
520 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
523 if (FD->hasAttr<OverloadableAttr>())
535 if (FD->isMSVCRTEntryPoint())
549 if (!getASTContext().getLangOpts().
CPlusPlus)
552 const VarDecl *VD = dyn_cast<VarDecl>(D);
559 const DeclContext *DC = getEffectiveDeclContext(D);
563 DC = getEffectiveParentContext(DC);
574MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
578DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
581 DiagnosticsEngine &Diags = Context.getDiags();
582 return Diags.
Report(loc, diag::err_ms_mangle_unsupported_with_detail)
586DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
588 DiagnosticsEngine &Diags = Context.getDiags();
589 return Diags.
Report(loc, diag::err_ms_mangle_unsupported) << thingy;
592DiagnosticBuilder MicrosoftCXXNameMangler::Error(StringRef thingy) {
593 DiagnosticsEngine &Diags = Context.getDiags();
595 return Diags.
Report(diag::err_ms_mangle_unsupported) << thingy;
598void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) {
609 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
610 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
611 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
612 mangleVariableEncoding(VD);
616 Out <<
"3U__s_GUID@@B";
621 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
624void MicrosoftCXXNameMangler::mangleFunctionEncoding(GlobalDecl GD,
636 const FunctionProtoType *FT = FD->
getType()->
castAs<FunctionProtoType>();
649 mangleFunctionClass(FD);
651 mangleFunctionType(FT, FD,
false,
false);
657void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
688 mangleType(Ty, SR, QMM_Drop);
689 manglePointerExtQualifiers(
691 if (
const MemberPointerType *MPT = Ty->
getAs<MemberPointerType>()) {
692 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
695 mangleName(MPT->getMostRecentCXXRecordDecl());
698 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
700 mangleDecayedArrayType(AT);
701 if (AT->getElementType()->isArrayType())
706 mangleType(Ty, SR, QMM_Drop);
711void MicrosoftCXXNameMangler::mangleMemberDataPointer(
712 const CXXRecordDecl *RD,
const ValueDecl *VD,
713 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
727 FieldOffset = getASTContext().getFieldOffset(VD);
728 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
729 "cannot take address of bitfield");
730 FieldOffset /= getASTContext().getCharWidth();
734 if (IM == MSInheritanceModel::Virtual)
735 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
744 case MSInheritanceModel::Single: Code =
'0';
break;
745 case MSInheritanceModel::Multiple: Code =
'0';
break;
746 case MSInheritanceModel::Virtual: Code =
'F';
break;
747 case MSInheritanceModel::Unspecified: Code =
'G';
break;
753 getASTContext().getLangOpts().isCompatibleWithMSVC(
754 LangOptions::MSVC2019) &&
756 !TemplateArgType.
isNull()) {
758 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
763 mangleNumber(FieldOffset);
771 mangleNumber(VBTableOffset);
774void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
775 const CXXRecordDecl *RD,
const ValueDecl *VD) {
781 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
782 return mangleMemberDataPointer(RD, VD,
nullptr, QualType(),
"");
790 mangleNestedName(VD);
792 mangleUnqualifiedName(VD);
796void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
797 const CXXRecordDecl *RD,
const CXXMethodDecl *MD,
798 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
814 case MSInheritanceModel::Single: Code =
'1';
break;
815 case MSInheritanceModel::Multiple: Code =
'H';
break;
816 case MSInheritanceModel::Virtual: Code =
'I';
break;
817 case MSInheritanceModel::Unspecified: Code =
'J';
break;
828 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
829 LangOptions::MSVC2019) &&
831 !TemplateArgType.
isNull()) {
833 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
838 MicrosoftVTableContext *VTContext =
840 MethodVFTableLocation ML =
842 mangleVirtualMemPtrThunk(MD, ML);
846 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
851 mangleFunctionEncoding(MD,
true);
854 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
855 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
858 if (IM == MSInheritanceModel::Single) {
859 Out << Prefix <<
"0A@";
862 if (IM == MSInheritanceModel::Unspecified)
864 Out << Prefix << Code;
868 mangleNumber(
static_cast<uint32_t>(NVOffset));
870 mangleNumber(VBPtrOffset);
872 mangleNumber(VBTableOffset);
875void MicrosoftCXXNameMangler::mangleFunctionPointer(
876 const FunctionDecl *FD,
const NonTypeTemplateParmDecl *PD,
877 QualType TemplateArgType) {
884 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
885 LangOptions::MSVC2019) &&
887 !TemplateArgType.
isNull()) {
889 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
894 mangleFunctionEncoding(FD,
true);
897void MicrosoftCXXNameMangler::mangleVarDecl(
const VarDecl *VD,
898 const NonTypeTemplateParmDecl *PD,
899 QualType TemplateArgType) {
906 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
907 LangOptions::MSVC2019) &&
909 !TemplateArgType.
isNull()) {
911 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
916 mangleVariableEncoding(VD);
919void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
920 const CXXRecordDecl *RD,
const CXXMethodDecl *MD) {
928 return mangleMemberFunctionPointer(RD, MD,
nullptr, QualType(),
"");
936 MicrosoftVTableContext *VTContext =
938 MethodVFTableLocation ML =
940 mangleVirtualMemPtrThunk(MD, ML);
943 mangleFunctionEncoding(MD,
true);
947void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
948 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML) {
950 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
951 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
957 mangleNumber(OffsetInVFTable);
959 mangleCallingConvention(MD->
getType()->
castAs<FunctionProtoType>(),
963void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {
967 mangleUnqualifiedName(GD);
969 mangleNestedName(GD);
975void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
976 mangleNumber(llvm::APSInt(llvm::APInt(64, Number),
false));
979void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
984 unsigned Width = std::max(Number.getBitWidth(), 64U);
985 llvm::APInt
Value = Number.extend(Width);
993 if (
Value.isNegative()) {
1000void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
1001 using llvm::APFloat;
1003 switch (APFloat::SemanticsToEnum(Number.getSemantics())) {
1004 case APFloat::S_IEEEsingle:
Out <<
'A';
break;
1005 case APFloat::S_IEEEdouble:
Out <<
'B';
break;
1009 case APFloat::S_IEEEhalf:
Out <<
'V';
break;
1010 case APFloat::S_BFloat:
Out <<
'W';
break;
1011 case APFloat::S_x87DoubleExtended:
Out <<
'X';
break;
1012 case APFloat::S_IEEEquad:
Out <<
'Y';
break;
1013 case APFloat::S_PPCDoubleDouble:
Out <<
'Z';
break;
1014 case APFloat::S_PPCDoubleDoubleLegacy:
1015 case APFloat::S_Float8E5M2:
1016 case APFloat::S_Float8E4M3:
1017 case APFloat::S_Float8E4M3FN:
1018 case APFloat::S_Float8E5M2FNUZ:
1019 case APFloat::S_Float8E4M3FNUZ:
1020 case APFloat::S_Float8E4M3B11FNUZ:
1021 case APFloat::S_Float8E3M4:
1022 case APFloat::S_FloatTF32:
1023 case APFloat::S_Float8E8M0FNU:
1024 case APFloat::S_Float6E3M2FN:
1025 case APFloat::S_Float6E2M3FN:
1026 case APFloat::S_Float4E2M1FN:
1027 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
1030 mangleBits(Number.bitcastToAPInt());
1033void MicrosoftCXXNameMangler::mangleBits(llvm::APInt
Value) {
1042 llvm::SmallString<32> EncodedNumberBuffer;
1044 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
1045 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1046 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1055 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1064 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1065 TemplateArgs = &Spec->getTemplateArgs();
1066 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1071 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1072 TemplateArgs = &Spec->getTemplateArgs();
1073 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1079void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
1080 DeclarationName Name) {
1088 const TemplateArgumentList *TemplateArgs =
nullptr;
1089 if (GlobalDecl TD =
isTemplate(GD, TemplateArgs)) {
1094 mangleTemplateInstantiationName(TD, *TemplateArgs);
1117 ArgBackRefMap::iterator
Found = TemplateArgBackReferences.find(ND);
1118 if (
Found == TemplateArgBackReferences.end()) {
1120 TemplateArgStringMap::iterator
Found = TemplateArgStrings.find(ND);
1121 if (
Found == TemplateArgStrings.end()) {
1123 llvm::SmallString<64> TemplateMangling;
1124 llvm::raw_svector_ostream Stream(TemplateMangling);
1125 MicrosoftCXXNameMangler
Extra(Context, Stream);
1126 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1129 mangleSourceName(TemplateMangling);
1133 BackRefVec::iterator StringFound =
1134 llvm::find(NameBackReferences, TemplateMangling);
1135 if (StringFound != NameBackReferences.end()) {
1136 TemplateArgBackReferences[ND] =
1137 StringFound - NameBackReferences.begin();
1139 TemplateArgStrings[ND] =
1140 TemplateArgStringStorage.save(TemplateMangling.str());
1159 ->getTemplatedDecl()
1162 bool IsOCLDeviceStub =
1164 DeviceKernelAttr::isOpenCLSpelling(
1165 ND->
getAttr<DeviceKernelAttr>()) &&
1169 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1170 else if (IsOCLDeviceStub)
1172 (llvm::Twine(
"__clang_ocl_kern_imp_") + II->getName()).str());
1174 mangleSourceName(II->getName());
1179 assert(ND &&
"mangling empty name without declaration");
1181 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1182 if (NS->isAnonymousNamespace()) {
1183 Out <<
"?A0x" << Context.getAnonymousNamespaceHash() <<
'@';
1188 if (
const DecompositionDecl *DD = dyn_cast<DecompositionDecl>(ND)) {
1191 llvm::SmallString<64> Name(
"$S");
1193 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1194 mangleSourceName(Name);
1198 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1201 assert(RD &&
"expected variable decl to have a record type");
1205 llvm::SmallString<64> Name(
"$S");
1207 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1208 mangleSourceName(Name.str());
1212 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1215 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1216 llvm::raw_svector_ostream GUIDOS(GUID);
1217 Context.mangleMSGuidDecl(GD, GUIDOS);
1218 mangleSourceName(GUID);
1222 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1224 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1225 TPO->getValue(), TplArgKind::ClassNTTP);
1233 "Typedef should not be in another decl context!");
1235 "Typedef was not named!");
1240 if (
const CXXRecordDecl *
Record = dyn_cast<CXXRecordDecl>(TD)) {
1241 if (
Record->isLambda()) {
1242 llvm::SmallString<10> Name(
"<lambda_");
1244 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1245 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1247 const ParmVarDecl *Parm =
1248 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1249 const FunctionDecl *
Func =
1253 unsigned DefaultArgNo =
1255 Name += llvm::utostr(DefaultArgNo);
1259 if (LambdaManglingNumber)
1260 LambdaId = LambdaManglingNumber;
1262 LambdaId = Context.getLambdaId(
Record);
1264 Name += llvm::utostr(LambdaId);
1267 mangleSourceName(Name);
1271 if (LambdaManglingNumber && LambdaContextDecl) {
1282 llvm::SmallString<64> Name;
1283 if (DeclaratorDecl *DD =
1287 Name +=
"<unnamed-type-";
1288 Name += DD->getName();
1289 }
else if (TypedefNameDecl *TND =
1294 Name +=
"<unnamed-type-";
1295 Name += TND->getName();
1300 Name +=
"<unnamed-enum-";
1301 Name += ED->enumerator_begin()->getName();
1304 Name +=
"<unnamed-type-$S";
1305 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1308 mangleSourceName(Name.str());
1318 llvm::SmallString<64> Name;
1319 mangleSourceName(Name.str());
1324 if (isStructorDecl(ND)) {
1338 if (isStructorDecl(ND))
1341 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1355 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1360 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1365 llvm_unreachable(
"Can't mangle a deduction guide name!");
1368 llvm_unreachable(
"Can't mangle a using directive name!");
1374void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {
1377 if (
const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1378 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1379 mangleSourceName(
"<unnamed-tag>");
1381 const DeclContext *DC = getEffectiveDeclContext(ND);
1385 if (Context.getNextDiscriminator(ND, Disc)) {
1392 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1394 [](StringRef Name,
const unsigned Discriminator,
1395 const unsigned ParameterDiscriminator) -> std::string {
1397 llvm::raw_string_ostream Stream(Buffer);
1400 Stream <<
'_' << Discriminator;
1401 if (ParameterDiscriminator)
1402 Stream <<
'_' << ParameterDiscriminator;
1406 unsigned Discriminator = BD->getBlockManglingNumber();
1408 Discriminator = Context.getBlockId(BD,
false);
1413 unsigned ParameterDiscriminator = 0;
1414 if (
const auto *MC = BD->getBlockManglingContextDecl())
1415 if (
const auto *P = dyn_cast<ParmVarDecl>(MC))
1416 if (
const auto *F = dyn_cast<FunctionDecl>(P->getDeclContext()))
1417 ParameterDiscriminator =
1418 F->getNumParams() - P->getFunctionScopeIndex();
1420 DC = getEffectiveDeclContext(BD);
1423 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1424 ParameterDiscriminator));
1429 if (
const auto *MC = BD->getBlockManglingContextDecl())
1431 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1432 mangleUnqualifiedName(ND);
1436 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1445 if (PointersAre64Bit)
1448 mangleArtificialTagType(TagTypeKind::Struct,
1449 Discriminate(
"__block_literal", Discriminator,
1450 ParameterDiscriminator));
1458 }
else if (
const ObjCMethodDecl *
Method = dyn_cast<ObjCMethodDecl>(DC)) {
1462 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1463 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1466 mangleUnqualifiedName(ND);
1469 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1479void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1495 llvm_unreachable(
"not expecting a COMDAT");
1497 llvm_unreachable(
"not expecting a unified dtor type");
1499 llvm_unreachable(
"Unsupported dtor type?");
1503 SourceLocation Loc) {
1508 case OO_New:
Out <<
"?2";
break;
1510 case OO_Delete:
Out <<
"?3";
break;
1512 case OO_Equal:
Out <<
"?4";
break;
1514 case OO_GreaterGreater:
Out <<
"?5";
break;
1516 case OO_LessLess:
Out <<
"?6";
break;
1518 case OO_Exclaim:
Out <<
"?7";
break;
1520 case OO_EqualEqual:
Out <<
"?8";
break;
1522 case OO_ExclaimEqual:
Out <<
"?9";
break;
1524 case OO_Subscript:
Out <<
"?A";
break;
1527 case OO_Arrow:
Out <<
"?C";
break;
1529 case OO_Star:
Out <<
"?D";
break;
1531 case OO_PlusPlus:
Out <<
"?E";
break;
1533 case OO_MinusMinus:
Out <<
"?F";
break;
1535 case OO_Minus:
Out <<
"?G";
break;
1537 case OO_Plus:
Out <<
"?H";
break;
1539 case OO_Amp:
Out <<
"?I";
break;
1541 case OO_ArrowStar:
Out <<
"?J";
break;
1543 case OO_Slash:
Out <<
"?K";
break;
1545 case OO_Percent:
Out <<
"?L";
break;
1547 case OO_Less:
Out <<
"?M";
break;
1549 case OO_LessEqual:
Out <<
"?N";
break;
1551 case OO_Greater:
Out <<
"?O";
break;
1553 case OO_GreaterEqual:
Out <<
"?P";
break;
1555 case OO_Comma:
Out <<
"?Q";
break;
1557 case OO_Call:
Out <<
"?R";
break;
1559 case OO_Tilde:
Out <<
"?S";
break;
1561 case OO_Caret:
Out <<
"?T";
break;
1563 case OO_Pipe:
Out <<
"?U";
break;
1565 case OO_AmpAmp:
Out <<
"?V";
break;
1567 case OO_PipePipe:
Out <<
"?W";
break;
1569 case OO_StarEqual:
Out <<
"?X";
break;
1571 case OO_PlusEqual:
Out <<
"?Y";
break;
1573 case OO_MinusEqual:
Out <<
"?Z";
break;
1575 case OO_SlashEqual:
Out <<
"?_0";
break;
1577 case OO_PercentEqual:
Out <<
"?_1";
break;
1579 case OO_GreaterGreaterEqual:
Out <<
"?_2";
break;
1581 case OO_LessLessEqual:
Out <<
"?_3";
break;
1583 case OO_AmpEqual:
Out <<
"?_4";
break;
1585 case OO_PipeEqual:
Out <<
"?_5";
break;
1587 case OO_CaretEqual:
Out <<
"?_6";
break;
1616 case OO_Array_New:
Out <<
"?_U";
break;
1618 case OO_Array_Delete:
Out <<
"?_V";
break;
1620 case OO_Coawait:
Out <<
"?__L";
break;
1622 case OO_Spaceship:
Out <<
"?__M";
break;
1624 case OO_Conditional: {
1625 Error(Loc,
"conditional operator");
1631 llvm_unreachable(
"Not an overloaded operator");
1635void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1637 BackRefVec::iterator
Found = llvm::find(NameBackReferences, Name);
1638 if (
Found == NameBackReferences.end()) {
1639 if (NameBackReferences.size() < 10)
1640 NameBackReferences.push_back(std::string(Name));
1643 Out << (
Found - NameBackReferences.begin());
1647void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1648 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1651void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1652 GlobalDecl GD,
const TemplateArgumentList &TemplateArgs) {
1658 ArgBackRefMap OuterFunArgsContext;
1659 ArgBackRefMap OuterTemplateArgsContext;
1660 BackRefVec OuterTemplateContext;
1661 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1662 NameBackReferences.swap(OuterTemplateContext);
1663 FunArgBackReferences.swap(OuterFunArgsContext);
1664 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1665 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1667 mangleUnscopedTemplateName(GD);
1671 NameBackReferences.swap(OuterTemplateContext);
1672 FunArgBackReferences.swap(OuterFunArgsContext);
1673 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1674 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1677void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {
1680 mangleUnqualifiedName(GD);
1683void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1684 const llvm::APSInt &
Value,
const NonTypeTemplateParmDecl *PD,
1685 QualType TemplateArgType) {
1694 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1695 LangOptions::MSVC2019) &&
1697 !TemplateArgType.
isNull()) {
1699 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
1704 mangleNumber(
Value);
1707void MicrosoftCXXNameMangler::mangleExpression(
1708 const Expr *E,
const NonTypeTemplateParmDecl *PD) {
1710 if (std::optional<llvm::APSInt>
Value =
1721void MicrosoftCXXNameMangler::mangleTemplateArgs(
1722 const TemplateDecl *TD,
const TemplateArgumentList &TemplateArgs) {
1725 assert(TPL->
size() == TemplateArgs.
size() &&
1726 "size mismatch between args and parms!");
1728 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1729 const TemplateArgument &TA = TemplateArgs[i];
1736 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1744 if (!T->isPointerType() || !
V.isLValue() || !
V.hasLValuePath() ||
1748 QualType BaseT =
V.getLValueBase().getType();
1749 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1750 V.getLValuePath()[0].getAsArrayIndex() != 0)
1753 V.getLValueBase().dyn_cast<const ValueDecl *>());
1756void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1757 const TemplateArgument &TA,
1758 const NamedDecl *Parm) {
1796 llvm_unreachable(
"Can't mangle null template arguments!");
1798 llvm_unreachable(
"Can't mangle template expansion arguments!");
1801 mangleType(T, SourceRange(), QMM_Escape);
1807 mangleMemberDataPointer(
1811 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1812 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1824 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1825 TPO->getValue(), TplArgKind::ClassNTTP);
1826 }
else if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1842 if (
const MemberPointerType *MPT = T->
getAs<MemberPointerType>()) {
1843 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1844 if (MPT->isMemberFunctionPointerType() &&
1846 mangleMemberFunctionPointer(RD,
nullptr,
nullptr, QualType());
1849 if (MPT->isMemberDataPointer()) {
1851 mangleMemberDataPointer(RD,
nullptr,
nullptr, QualType());
1861 mangleIntegerLiteral(llvm::APSInt::get(-1),
1867 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1877 return mangleTemplateArg(
1883 ->getContainedDeducedType()) {
1889 TplArgKind::StructuralValue,
1897 if (TemplateArgs.empty()) {
1902 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(
1903 LangOptions::MSVC2015)
1909 llvm_unreachable(
"unexpected template parameter decl!");
1911 for (
const TemplateArgument &PA : TemplateArgs)
1912 mangleTemplateArg(TD, PA, Parm);
1917 const NamedDecl *ND =
1919 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1925 llvm_unreachable(
"unexpected template template NamedDecl!");
1932void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
1935 bool WithScalarType) {
1936 switch (
V.getKind()) {
1942 mangleType(T, SourceRange(), QMM_Escape);
1948 mangleType(T, SourceRange(), QMM_Escape);
1950 mangleNumber(
V.getInt());
1955 mangleType(T, SourceRange(), QMM_Escape);
1956 mangleFloat(
V.getFloat());
1961 mangleType(T, SourceRange(), QMM_Escape);
1963 APValue::LValueBase
Base =
V.getLValueBase();
1967 if (
V.isLValueOnePastTheEnd()) {
1969 auto *VD =
Base.dyn_cast<
const ValueDecl *>();
1976 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1978 if (
Base.isNull()) {
1984 mangleNumber(
V.getLValueOffset().getQuantity());
1985 }
else if (!
V.hasLValuePath()) {
1987 Error(
"template argument (extension not comaptible with ms mangler)");
1989 }
else if (
auto *VD =
Base.dyn_cast<
const ValueDecl*>()) {
1993 Error(
"template argument (undeclared base)");
2000 SmallVector<char, 2> EntryTypes;
2002 QualType ET =
Base.getType();
2003 for (APValue::LValuePathEntry E :
V.getLValuePath()) {
2005 EntryTypes.push_back(
'C');
2006 EntryManglers.push_back([
this, I = E.getAsArrayIndex()] {
2011 ET = AT->getElementType();
2015 const Decl *D = E.getAsBaseOrMember().getPointer();
2016 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2028 EntryTypes.push_back(
'6');
2029 EntryManglers.push_back([
this, D] {
2035 for (
auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
2038 auto *VD =
Base.dyn_cast<
const ValueDecl*>();
2040 Error(
"template argument (null value decl)");
2043 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
2057 mangleType(T, SourceRange(), QMM_Escape);
2059 const CXXRecordDecl *RD =
2060 T->
castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
2061 const ValueDecl *D =
V.getMemberPointerDecl();
2062 if (TAK == TplArgKind::ClassNTTP) {
2064 mangleMemberDataPointerInClassNTTP(RD, D);
2066 mangleMemberFunctionPointerInClassNTTP(RD,
2067 cast_or_null<CXXMethodDecl>(D));
2070 mangleMemberDataPointer(RD, D,
nullptr, QualType(),
"");
2072 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D),
nullptr,
2080 mangleType(T, SourceRange(), QMM_Escape);
2082 assert(RD &&
"unexpected type for record value");
2084 unsigned BaseIndex = 0;
2085 for (
const CXXBaseSpecifier &B : RD->
bases())
2086 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
2087 for (
const FieldDecl *FD : RD->
fields())
2088 if (!FD->isUnnamedBitField())
2089 mangleTemplateArgValue(FD->
getType(),
2090 V.getStructField(FD->getFieldIndex()), TAK,
2098 mangleType(T, SourceRange(), QMM_Escape);
2099 if (
const FieldDecl *FD =
V.getUnionField()) {
2100 mangleUnqualifiedName(FD);
2101 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
2109 mangleType(T, SourceRange(), QMM_Escape);
2111 mangleNumber(
V.getComplexIntReal());
2113 mangleNumber(
V.getComplexIntImag());
2119 mangleType(T, SourceRange(), QMM_Escape);
2120 mangleFloat(
V.getComplexFloatReal());
2121 mangleFloat(
V.getComplexFloatImag());
2127 QualType ElemT = getASTContext().getAsArrayType(T)->getElementType();
2128 mangleType(ElemT, SourceRange(), QMM_Escape);
2129 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
2130 const APValue &ElemV = I <
V.getArrayInitializedElts()
2131 ?
V.getArrayInitializedElt(I)
2132 :
V.getArrayFiller();
2133 mangleTemplateArgValue(ElemT, ElemV, TAK);
2144 mangleType(T, SourceRange(), QMM_Escape);
2146 QualType ElemT = T->
castAs<VectorType>()->getElementType();
2147 mangleType(ElemT, SourceRange(), QMM_Escape);
2148 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
2150 mangleTemplateArgValue(ElemT, ElemV, TAK);
2158 Error(
"template argument (value type: matrix)");
2163 Error(
"template argument (value type: address label diff)");
2168 Error(
"template argument (value type: fixed point)");
2174void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2175 llvm::SmallString<64> TemplateMangling;
2176 llvm::raw_svector_ostream Stream(TemplateMangling);
2177 MicrosoftCXXNameMangler
Extra(Context, Stream);
2180 Extra.mangleSourceName(
"Protocol");
2181 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2183 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2186void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType
Type,
2188 SourceRange Range) {
2189 llvm::SmallString<64> TemplateMangling;
2190 llvm::raw_svector_ostream Stream(TemplateMangling);
2191 MicrosoftCXXNameMangler
Extra(Context, Stream);
2199 Extra.mangleSourceName(
"Autoreleasing");
2202 Extra.mangleSourceName(
"Strong");
2205 Extra.mangleSourceName(
"Weak");
2208 Extra.manglePointerCVQualifiers(Quals);
2209 Extra.manglePointerExtQualifiers(Quals,
Type);
2212 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2215void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *T,
2217 SourceRange Range) {
2218 llvm::SmallString<64> TemplateMangling;
2219 llvm::raw_svector_ostream Stream(TemplateMangling);
2220 MicrosoftCXXNameMangler
Extra(Context, Stream);
2223 Extra.mangleSourceName(
"KindOf");
2224 Extra.mangleType(QualType(T, 0)
2225 .stripObjCKindOfType(getASTContext())
2226 ->castAs<ObjCObjectType>(),
2229 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2232void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
2290 if (HasConst && HasVolatile) {
2292 }
else if (HasVolatile) {
2294 }
else if (HasConst) {
2300 if (HasConst && HasVolatile) {
2302 }
else if (HasVolatile) {
2304 }
else if (HasConst) {
2315MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2318 switch (RefQualifier) {
2332void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
2333 QualType PointeeType) {
2335 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2348void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {
2354 mangleNumber(PointerAuth.
getKey());
2359void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
2367 if (HasConst && HasVolatile) {
2369 }
else if (HasVolatile) {
2371 }
else if (HasConst) {
2378void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType T,
2379 SourceRange Range) {
2388 if (
const auto *DT = T->
getAs<DecayedType>()) {
2389 QualType OriginalType = DT->getOriginalType();
2392 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2393 OriginalType = getASTContext().getIncompleteArrayType(
2394 AT->getElementType(), AT->getSizeModifier(),
2395 AT->getIndexTypeCVRQualifiers());
2409 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2411 if (
Found == FunArgBackReferences.end()) {
2412 size_t OutSizeBefore =
Out.tell();
2414 mangleType(T, Range, QMM_Drop);
2419 bool LongerThanOneChar = (
Out.tell() - OutSizeBefore > 1);
2420 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2421 size_t Size = FunArgBackReferences.size();
2422 FunArgBackReferences[TypePtr] =
Size;
2429void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2430 const PassObjectSizeAttr *POSA) {
2431 int Type = POSA->getType();
2432 bool Dynamic = POSA->isDynamic();
2434 auto Iter = PassObjectSizeArgs.insert({
Type,
Dynamic}).first;
2435 auto *TypePtr = (
const void *)&*Iter;
2436 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2438 if (
Found == FunArgBackReferences.end()) {
2440 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2441 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2444 if (FunArgBackReferences.size() < 10) {
2445 size_t Size = FunArgBackReferences.size();
2446 FunArgBackReferences[TypePtr] =
Size;
2453void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
2455 SourceRange Range) {
2470 llvm::SmallString<32> ASMangling;
2471 llvm::raw_svector_ostream Stream(ASMangling);
2472 MicrosoftCXXNameMangler
Extra(Context, Stream);
2478 Extra.mangleSourceName(
"_AS");
2479 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2483 llvm_unreachable(
"Not a language specific address space");
2484 case LangAS::opencl_global:
2485 Extra.mangleSourceName(
"_ASCLglobal");
2487 case LangAS::opencl_global_device:
2488 Extra.mangleSourceName(
"_ASCLdevice");
2490 case LangAS::opencl_global_host:
2491 Extra.mangleSourceName(
"_ASCLhost");
2493 case LangAS::opencl_local:
2494 Extra.mangleSourceName(
"_ASCLlocal");
2496 case LangAS::opencl_constant:
2497 Extra.mangleSourceName(
"_ASCLconstant");
2499 case LangAS::opencl_private:
2500 Extra.mangleSourceName(
"_ASCLprivate");
2502 case LangAS::opencl_generic:
2503 Extra.mangleSourceName(
"_ASCLgeneric");
2505 case LangAS::cuda_device:
2506 Extra.mangleSourceName(
"_ASCUdevice");
2508 case LangAS::cuda_constant:
2509 Extra.mangleSourceName(
"_ASCUconstant");
2511 case LangAS::cuda_shared:
2512 Extra.mangleSourceName(
"_ASCUshared");
2514 case LangAS::ptr32_sptr:
2515 case LangAS::ptr32_uptr:
2517 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2521 Extra.mangleType(T, Range, QMM_Escape);
2522 mangleQualifiers(Qualifiers(),
false);
2523 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2526void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T,
2527 QualifierMangleMode QMM) {
2528 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2529 LangOptions::MSVC2019) &&
2530 "Cannot mangle MSVC 2017 auto return types!");
2536 if (QMM == QMM_Result)
2538 if (QMM != QMM_Drop)
2539 mangleQualifiers(Quals,
false);
2540 Out << (AT->isDecltypeAuto() ?
"_T" :
"_P");
2552 mangleQualifiers(Quals,
false);
2555 llvm_unreachable(
"QMM_Escape unexpected");
2560 case Type::MemberPointer:
2566 case Type::LValueReference:
2569 case Type::RValueReference:
2573 llvm_unreachable(
"Invalid type expected");
2577void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
2578 QualifierMangleMode QMM) {
2584 if (
const ArrayType *AT = getASTContext().getAsArrayType(T)) {
2587 if (QMM == QMM_Mangle)
2589 else if (QMM == QMM_Escape || QMM == QMM_Result)
2591 mangleArrayType(AT);
2604 if (
const FunctionType *FT = dyn_cast<FunctionType>(T)) {
2606 mangleFunctionType(FT);
2609 mangleQualifiers(Quals,
false);
2612 if (!IsPointer && Quals) {
2614 mangleQualifiers(Quals,
false);
2622 if ((!IsPointer && Quals) ||
isa<TagType>(T) || isArtificialTagType(T)) {
2624 mangleQualifiers(Quals,
false);
2632#define ABSTRACT_TYPE(CLASS, PARENT)
2633#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2635 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2637#define TYPE(CLASS, PARENT) \
2639 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2641#include "clang/AST/TypeNodes.inc"
2643#undef NON_CANONICAL_TYPE
2648void MicrosoftCXXNameMangler::mangleType(
const BuiltinType *T, Qualifiers,
2649 SourceRange Range) {
2678 case BuiltinType::Void:
2681 case BuiltinType::SChar:
2684 case BuiltinType::Char_U:
2685 case BuiltinType::Char_S:
2688 case BuiltinType::UChar:
2691 case BuiltinType::Short:
2694 case BuiltinType::UShort:
2697 case BuiltinType::Int:
2700 case BuiltinType::UInt:
2703 case BuiltinType::Long:
2706 case BuiltinType::ULong:
2709 case BuiltinType::Float:
2712 case BuiltinType::Double:
2716 case BuiltinType::LongDouble:
2719 case BuiltinType::LongLong:
2722 case BuiltinType::ULongLong:
2725 case BuiltinType::Int128:
2728 case BuiltinType::UInt128:
2731 case BuiltinType::Bool:
2734 case BuiltinType::Char8:
2737 case BuiltinType::Char16:
2740 case BuiltinType::Char32:
2743 case BuiltinType::WChar_S:
2744 case BuiltinType::WChar_U:
2748#define BUILTIN_TYPE(Id, SingletonId)
2749#define PLACEHOLDER_TYPE(Id, SingletonId) \
2750 case BuiltinType::Id:
2751#include "clang/AST/BuiltinTypes.def"
2752 case BuiltinType::Dependent:
2753 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2755 case BuiltinType::ObjCId:
2756 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2758 case BuiltinType::ObjCClass:
2759 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2761 case BuiltinType::ObjCSel:
2762 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2765#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2766 case BuiltinType::Id: \
2767 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2769#include "clang/Basic/OpenCLImageTypes.def"
2770 case BuiltinType::OCLSampler:
2772 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2774 case BuiltinType::OCLEvent:
2776 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2778 case BuiltinType::OCLClkEvent:
2780 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2782 case BuiltinType::OCLQueue:
2784 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2786 case BuiltinType::OCLReserveID:
2788 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2790#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2791 case BuiltinType::Id: \
2792 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2794#include "clang/Basic/OpenCLExtensionTypes.def"
2796 case BuiltinType::NullPtr:
2800 case BuiltinType::Float16:
2801 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2804 case BuiltinType::Half:
2805 if (!getASTContext().getLangOpts().
HLSL)
2806 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2807 else if (getASTContext().getLangOpts().NativeHalfType)
2813 case BuiltinType::BFloat16:
2814 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2817 case BuiltinType::MFloat8:
2818 mangleArtificialTagType(TagTypeKind::Struct,
"__mfp8", {
"__clang"});
2821#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2822 case BuiltinType::Id: \
2823 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2824 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2827#include "clang/Basic/WebAssemblyReferenceTypes.def"
2829#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2830 case BuiltinType::Id: \
2831 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2833#include "clang/Basic/HLSLIntangibleTypes.def"
2835#define SVE_TYPE(Name, Id, SingletonId) \
2836 case BuiltinType::Id: \
2837 mangleArtificialTagType(TagTypeKind::Struct, #Name, {"__clang"}); \
2839#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits)
2840#include "clang/Basic/AArch64ACLETypes.def"
2852void MicrosoftCXXNameMangler::mangleType(
const FunctionProtoType *T, Qualifiers,
2859 mangleFunctionType(T,
nullptr,
true);
2862 mangleFunctionType(T);
2865void MicrosoftCXXNameMangler::mangleType(
const FunctionNoProtoType *T,
2866 Qualifiers, SourceRange) {
2868 mangleFunctionType(T);
2871void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *T,
2872 const FunctionDecl *D,
2873 bool ForceThisQuals,
2874 bool MangleExceptionSpec) {
2877 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);
2882 bool IsInLambda =
false;
2883 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
2885 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
2889 HasThisQuals =
true;
2898 CC = getASTContext().getDefaultCallingConvention(
2907 manglePointerExtQualifiers(Quals, QualType());
2909 mangleQualifiers(Quals,
false);
2912 mangleCallingConvention(CC, Range);
2924 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
2933 if (IsCtorClosure) {
2943 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
2945 ->
castAs<LValueReferenceType>()
2951 llvm_unreachable(
"unexpected constructor closure!");
2957 }
else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(D)) {
2968 mangleType(ResultType, Range, QMM_Result);
2969 }
else if (IsInLambda) {
2971 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2972 "shouldn't need to mangle __auto_type!");
2976 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
2982 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2983 "shouldn't need to mangle __auto_type!");
2989 auto UseClangMangling = [](QualType ResultType) {
2990 QualType T = ResultType;
2999 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
3000 LangOptions::MSVC2019) &&
3001 !UseClangMangling(ResultType)) {
3010 ->
castAs<FunctionProtoType>();
3013 mangleAutoReturnType(ResultType, QMM_Result);
3019 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3025 mangleType(ResultType, Range, QMM_Result);
3041 for (
unsigned I = 0, E = Proto->
getNumParams(); I != E; ++I) {
3046 mangleFunctionArgumentType(Proto->
getParamType(I), Range);
3057 manglePassObjectSizeArg(P);
3066 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
3067 getASTContext().getLangOpts().isCompatibleWithMSVC(
3068 LangOptions::MSVC2017_5))
3069 mangleThrowSpecification(Proto);
3074void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
3099 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3109 llvm_unreachable(
"Unsupported access specifier");
3138void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC,
3139 SourceRange Range) {
3201 if (getASTContext().getLangOpts().RegCall4)
3210void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *T,
3211 SourceRange Range) {
3215void MicrosoftCXXNameMangler::mangleThrowSpecification(
3216 const FunctionProtoType *FT) {
3225void MicrosoftCXXNameMangler::mangleType(
const UnresolvedUsingType *T,
3226 Qualifiers, SourceRange Range) {
3237void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
3239 case TagTypeKind::Union:
3242 case TagTypeKind::Struct:
3243 case TagTypeKind::Interface:
3246 case TagTypeKind::Class:
3249 case TagTypeKind::Enum:
3254void MicrosoftCXXNameMangler::mangleType(
const EnumType *T, Qualifiers,
3258void MicrosoftCXXNameMangler::mangleType(
const RecordType *T, Qualifiers,
3262void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3272void MicrosoftCXXNameMangler::mangleArtificialTagType(
3274 ArrayRef<StringRef> NestedNames) {
3276 mangleTagTypeKind(TK);
3279 mangleSourceName(UnqualifiedName);
3281 for (StringRef N : llvm::reverse(NestedNames))
3282 mangleSourceName(N);
3295void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *T) {
3301void MicrosoftCXXNameMangler::mangleType(
const ConstantArrayType *T, Qualifiers,
3303 llvm_unreachable(
"Should have been special cased");
3305void MicrosoftCXXNameMangler::mangleType(
const VariableArrayType *T, Qualifiers,
3307 llvm_unreachable(
"Should have been special cased");
3309void MicrosoftCXXNameMangler::mangleType(
const DependentSizedArrayType *T,
3310 Qualifiers, SourceRange) {
3311 llvm_unreachable(
"Should have been special cased");
3313void MicrosoftCXXNameMangler::mangleType(
const IncompleteArrayType *T,
3314 Qualifiers, SourceRange) {
3315 llvm_unreachable(
"Should have been special cased");
3317void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *T) {
3318 QualType ElementTy(T, 0);
3319 SmallVector<llvm::APInt, 3> Dimensions;
3321 if (ElementTy->isConstantArrayType()) {
3322 const ConstantArrayType *CAT =
3323 getASTContext().getAsConstantArrayType(ElementTy);
3324 Dimensions.push_back(CAT->
getSize());
3326 }
else if (ElementTy->isIncompleteArrayType()) {
3327 const IncompleteArrayType *IAT =
3328 getASTContext().getAsIncompleteArrayType(ElementTy);
3329 Dimensions.push_back(llvm::APInt(32, 0));
3331 }
else if (ElementTy->isVariableArrayType()) {
3332 const VariableArrayType *VAT =
3333 getASTContext().getAsVariableArrayType(ElementTy);
3334 Dimensions.push_back(llvm::APInt(32, 0));
3336 }
else if (ElementTy->isDependentSizedArrayType()) {
3338 const DependentSizedArrayType *DSAT =
3339 getASTContext().getAsDependentSizedArrayType(ElementTy);
3349 mangleNumber(Dimensions.size());
3350 for (
const llvm::APInt &Dimension : Dimensions)
3351 mangleNumber(Dimension.getLimitedValue());
3352 mangleType(ElementTy, SourceRange(), QMM_Escape);
3355void MicrosoftCXXNameMangler::mangleType(
const ArrayParameterType *T,
3356 Qualifiers, SourceRange) {
3363void MicrosoftCXXNameMangler::mangleType(
const MemberPointerType *T,
3364 Qualifiers Quals, SourceRange Range) {
3366 manglePointerCVQualifiers(Quals);
3367 manglePointerExtQualifiers(Quals, PointeeType);
3368 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
3371 mangleFunctionType(FPT,
nullptr,
true);
3375 mangleType(PointeeType, Range, QMM_Drop);
3379void MicrosoftCXXNameMangler::mangleType(
const TemplateTypeParmType *T,
3380 Qualifiers, SourceRange Range) {
3383 llvm::SmallString<64> Name;
3385 Name += llvm::utostr(T->getDepth());
3387 Name += llvm::utostr(T->getIndex());
3389 mangleSourceName(Name);
3392void MicrosoftCXXNameMangler::mangleType(
const SubstTemplateTypeParmPackType *T,
3393 Qualifiers, SourceRange Range) {
3397void MicrosoftCXXNameMangler::mangleType(
const SubstBuiltinTemplatePackType *T,
3398 Qualifiers, SourceRange Range) {
3399 Error(
Range.getBegin(),
"substituted builtin template pack") <<
Range;
3405void MicrosoftCXXNameMangler::mangleType(
const PointerType *T, Qualifiers Quals,
3406 SourceRange Range) {
3408 manglePointerCVQualifiers(Quals);
3409 manglePointerExtQualifiers(Quals, PointeeType);
3410 manglePointerAuthQualifier(Quals);
3416 mangleType(PointeeType, Range);
3418 mangleAddressSpaceType(PointeeType, PointeeType.
getQualifiers(), Range);
3421void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectPointerType *T,
3422 Qualifiers Quals, SourceRange Range) {
3431 return mangleObjCLifetime(PointeeType, Quals, Range);
3433 manglePointerCVQualifiers(Quals);
3434 manglePointerExtQualifiers(Quals, PointeeType);
3435 mangleType(PointeeType, Range);
3441void MicrosoftCXXNameMangler::mangleType(
const LValueReferenceType *T,
3442 Qualifiers Quals, SourceRange Range) {
3446 manglePointerExtQualifiers(Quals, PointeeType);
3447 mangleType(PointeeType, Range);
3453void MicrosoftCXXNameMangler::mangleType(
const RValueReferenceType *T,
3454 Qualifiers Quals, SourceRange Range) {
3458 manglePointerExtQualifiers(Quals, PointeeType);
3459 mangleType(PointeeType, Range);
3462void MicrosoftCXXNameMangler::mangleType(
const ComplexType *T, Qualifiers,
3463 SourceRange Range) {
3466 llvm::SmallString<64> TemplateMangling;
3467 llvm::raw_svector_ostream Stream(TemplateMangling);
3468 MicrosoftCXXNameMangler
Extra(Context, Stream);
3470 Extra.mangleSourceName(
"_Complex");
3471 Extra.mangleType(ElementType, Range, QMM_Escape);
3473 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3481bool MicrosoftCXXNameMangler::isArtificialTagType(QualType T)
const {
3487 case Type::Vector: {
3496void MicrosoftCXXNameMangler::mangleType(
const VectorType *T, Qualifiers Quals,
3497 SourceRange Range) {
3499 const BuiltinType *ET = EltTy->
getAs<BuiltinType>();
3500 const BitIntType *BitIntTy = EltTy->
getAs<BitIntType>();
3501 assert((ET || BitIntTy) &&
3502 "vectors with non-builtin/_BitInt elements are unsupported");
3503 uint64_t Width = getASTContext().getTypeSize(T);
3506 size_t OutSizeBefore =
Out.tell();
3508 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
3509 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3510 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3511 }
else if (Width >= 128) {
3512 if (ET->
getKind() == BuiltinType::Float)
3513 mangleArtificialTagType(TagTypeKind::Union,
3514 "__m" + llvm::utostr(Width));
3515 else if (ET->
getKind() == BuiltinType::LongLong)
3516 mangleArtificialTagType(TagTypeKind::Union,
3517 "__m" + llvm::utostr(Width) +
'i');
3518 else if (ET->
getKind() == BuiltinType::Double)
3519 mangleArtificialTagType(TagTypeKind::Struct,
3520 "__m" + llvm::utostr(Width) +
'd');
3525 bool IsBuiltin =
Out.tell() != OutSizeBefore;
3531 llvm::SmallString<64> TemplateMangling;
3532 llvm::raw_svector_ostream Stream(TemplateMangling);
3533 MicrosoftCXXNameMangler
Extra(Context, Stream);
3535 Extra.mangleSourceName(
"__vector");
3536 Extra.mangleType(QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3540 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3544void MicrosoftCXXNameMangler::mangleType(
const ExtVectorType *T,
3545 Qualifiers Quals, SourceRange Range) {
3546 mangleType(
static_cast<const VectorType *
>(T), Quals, Range);
3549void MicrosoftCXXNameMangler::mangleType(
const DependentVectorType *T,
3550 Qualifiers, SourceRange Range) {
3554void MicrosoftCXXNameMangler::mangleType(
const DependentSizedExtVectorType *T,
3555 Qualifiers, SourceRange Range) {
3556 Error(
Range.getBegin(),
"dependent-sized extended vector type") <<
Range;
3559void MicrosoftCXXNameMangler::mangleType(
const ConstantMatrixType *T,
3560 Qualifiers quals, SourceRange Range) {
3563 llvm::SmallString<64> TemplateMangling;
3564 llvm::raw_svector_ostream Stream(TemplateMangling);
3565 MicrosoftCXXNameMangler
Extra(Context, Stream);
3569 Extra.mangleSourceName(
"__matrix");
3570 Extra.mangleType(EltTy, Range, QMM_Escape);
3572 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->
getNumRows()));
3575 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3578void MicrosoftCXXNameMangler::mangleType(
const DependentSizedMatrixType *T,
3579 Qualifiers quals, SourceRange Range) {
3583void MicrosoftCXXNameMangler::mangleType(
const DependentAddressSpaceType *T,
3584 Qualifiers, SourceRange Range) {
3588void MicrosoftCXXNameMangler::mangleType(
const ObjCInterfaceType *T, Qualifiers,
3591 mangleTagTypeKind(TagTypeKind::Struct);
3595void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectType *T,
3596 Qualifiers Quals, SourceRange Range) {
3597 if (T->isKindOfType())
3598 return mangleObjCKindOfType(T, Quals, Range);
3600 if (T->qual_empty() && !T->isSpecialized())
3601 return mangleType(T->getBaseType(), Range, QMM_Drop);
3603 ArgBackRefMap OuterFunArgsContext;
3604 ArgBackRefMap OuterTemplateArgsContext;
3605 BackRefVec OuterTemplateContext;
3607 FunArgBackReferences.swap(OuterFunArgsContext);
3608 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3609 NameBackReferences.swap(OuterTemplateContext);
3611 mangleTagTypeKind(TagTypeKind::Struct);
3615 mangleSourceName(
"objc_object");
3616 else if (T->isObjCClass())
3617 mangleSourceName(
"objc_class");
3619 mangleSourceName(T->getInterface()->getName());
3621 for (
const auto &Q : T->quals())
3622 mangleObjCProtocol(Q);
3624 if (T->isSpecialized())
3625 for (
const auto &TA : T->getTypeArgs())
3626 mangleType(TA, Range, QMM_Drop);
3632 FunArgBackReferences.swap(OuterFunArgsContext);
3633 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3634 NameBackReferences.swap(OuterTemplateContext);
3637void MicrosoftCXXNameMangler::mangleType(
const BlockPointerType *T,
3638 Qualifiers Quals, SourceRange Range) {
3640 manglePointerCVQualifiers(Quals);
3641 manglePointerExtQualifiers(Quals, PointeeType);
3645 mangleFunctionType(PointeeType->
castAs<FunctionProtoType>());
3648void MicrosoftCXXNameMangler::mangleType(
const InjectedClassNameType *,
3649 Qualifiers, SourceRange) {
3650 llvm_unreachable(
"Cannot mangle injected class name type.");
3653void MicrosoftCXXNameMangler::mangleType(
const TemplateSpecializationType *T,
3654 Qualifiers, SourceRange Range) {
3658void MicrosoftCXXNameMangler::mangleType(
const DependentNameType *T, Qualifiers,
3659 SourceRange Range) {
3663void MicrosoftCXXNameMangler::mangleType(
const PackExpansionType *T, Qualifiers,
3664 SourceRange Range) {
3668void MicrosoftCXXNameMangler::mangleType(
const PackIndexingType *T,
3669 Qualifiers Quals, SourceRange Range) {
3670 manglePointerCVQualifiers(Quals);
3671 mangleType(T->getSelectedType(), Range);
3674void MicrosoftCXXNameMangler::mangleType(
const TypeOfType *T, Qualifiers,
3675 SourceRange Range) {
3679void MicrosoftCXXNameMangler::mangleType(
const TypeOfExprType *T, Qualifiers,
3680 SourceRange Range) {
3684void MicrosoftCXXNameMangler::mangleType(
const DecltypeType *T, Qualifiers,
3685 SourceRange Range) {
3689void MicrosoftCXXNameMangler::mangleType(
const UnaryTransformType *T,
3690 Qualifiers, SourceRange Range) {
3694void MicrosoftCXXNameMangler::mangleType(
const AutoType *T, Qualifiers,
3695 SourceRange Range) {
3696 assert(T->getDeducedType().isNull() &&
"expecting a dependent type!");
3701void MicrosoftCXXNameMangler::mangleType(
3702 const DeducedTemplateSpecializationType *T, Qualifiers, SourceRange Range) {
3703 assert(T->getDeducedType().isNull() &&
"expecting a dependent type!");
3705 Error(
Range.getBegin(),
"deduced class template specialization type")
3709void MicrosoftCXXNameMangler::mangleType(
const AtomicType *T, Qualifiers,
3710 SourceRange Range) {
3713 llvm::SmallString<64> TemplateMangling;
3714 llvm::raw_svector_ostream Stream(TemplateMangling);
3715 MicrosoftCXXNameMangler
Extra(Context, Stream);
3717 Extra.mangleSourceName(
"_Atomic");
3718 Extra.mangleType(ValueType, Range, QMM_Escape);
3720 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3723void MicrosoftCXXNameMangler::mangleType(
const PipeType *T, Qualifiers,
3724 SourceRange Range) {
3727 llvm::SmallString<64> TemplateMangling;
3728 llvm::raw_svector_ostream Stream(TemplateMangling);
3729 MicrosoftCXXNameMangler
Extra(Context, Stream);
3731 Extra.mangleSourceName(
"ocl_pipe");
3732 Extra.mangleType(ElementType, Range, QMM_Escape);
3735 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3738void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
3741 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
3742 getASTContext().getSourceManager(),
3743 "Mangling declaration");
3745 msvc_hashing_ostream MHO(Out);
3747 if (
auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3749 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3750 return mangler.mangle(GD);
3753 if (
auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3755 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3756 return mangler.mangle(GD);
3759 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3760 return Mangler.mangle(GD);
3763void MicrosoftCXXNameMangler::mangleType(
const BitIntType *T, Qualifiers,
3764 SourceRange Range) {
3765 llvm::SmallString<64> TemplateMangling;
3766 llvm::raw_svector_ostream Stream(TemplateMangling);
3767 MicrosoftCXXNameMangler
Extra(Context, Stream);
3770 Extra.mangleSourceName(
"_UBitInt");
3772 Extra.mangleSourceName(
"_BitInt");
3773 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->
getNumBits()));
3775 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3778void MicrosoftCXXNameMangler::mangleType(
const DependentBitIntType *T,
3779 Qualifiers, SourceRange Range) {
3783void MicrosoftCXXNameMangler::mangleType(
const HLSLAttributedResourceType *T,
3784 Qualifiers, SourceRange Range) {
3785 llvm_unreachable(
"HLSL uses Itanium name mangling");
3788void MicrosoftCXXNameMangler::mangleType(
const HLSLInlineSpirvType *T,
3789 Qualifiers, SourceRange Range) {
3790 llvm_unreachable(
"HLSL uses Itanium name mangling");
3793void MicrosoftCXXNameMangler::mangleType(
const OverflowBehaviorType *T,
3794 Qualifiers, SourceRange Range) {
3795 QualType UnderlyingType = T->getUnderlyingType();
3797 llvm::SmallString<64> TemplateMangling;
3798 llvm::raw_svector_ostream Stream(TemplateMangling);
3799 MicrosoftCXXNameMangler
Extra(Context, Stream);
3801 if (T->isWrapKind()) {
3802 Extra.mangleSourceName(
"ObtWrap_");
3804 Extra.mangleSourceName(
"ObtTrap_");
3806 Extra.mangleType(UnderlyingType, Range, QMM_Escape);
3808 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3837 MicrosoftCXXNameMangler &Mangler,
3844 llvm_unreachable(
"Unsupported access specifier");
3855 Out <<
'R' << AccessSpec;
3856 Mangler.mangleNumber(
3858 Mangler.mangleNumber(
3860 Mangler.mangleNumber(
3862 Mangler.mangleNumber(
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3865 Mangler.mangleNumber(
3867 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3872 llvm_unreachable(
"Unsupported access specifier");
3882 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3886 llvm_unreachable(
"Unsupported access specifier");
3899void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
3900 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML,
3902 msvc_hashing_ostream MHO(Out);
3903 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3904 Mangler.getStream() <<
'?';
3905 Mangler.mangleVirtualMemPtrThunk(MD, ML);
3908void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
3909 const ThunkInfo &Thunk,
3912 msvc_hashing_ostream MHO(Out);
3913 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3914 Mangler.getStream() <<
'?';
3915 Mangler.mangleName(MD);
3924 assert(Thunk.
Method !=
nullptr &&
3925 "Thunk info should hold the overridee decl");
3927 const CXXMethodDecl *DeclForFPT = Thunk.
Method ? Thunk.
Method : MD;
3928 Mangler.mangleFunctionType(
3932void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
const CXXDestructorDecl *DD,
3934 const ThunkInfo &Thunk,
3941 msvc_hashing_ostream MHO(Out);
3942 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
3943 Mangler.getStream() <<
"??_E";
3945 auto &Adjustment = Thunk.
This;
3947 Mangler.mangleFunctionType(DD->
getType()->
castAs<FunctionProtoType>(), DD);
3950void MicrosoftMangleContextImpl::mangleCXXVFTable(
3951 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
3957 msvc_hashing_ostream MHO(Out);
3958 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3959 if (Derived->
hasAttr<DLLImportAttr>())
3960 Mangler.getStream() <<
"??_S";
3962 Mangler.getStream() <<
"??_7";
3963 Mangler.mangleName(Derived);
3964 Mangler.getStream() <<
"6B";
3965 for (
const CXXRecordDecl *RD : BasePath)
3966 Mangler.mangleName(RD);
3967 Mangler.getStream() <<
'@';
3970void MicrosoftMangleContextImpl::mangleCXXVTable(
const CXXRecordDecl *Derived,
3973 mangleCXXVFTable(Derived, {},
Out);
3976void MicrosoftMangleContextImpl::mangleCXXVBTable(
3977 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
3983 msvc_hashing_ostream MHO(Out);
3984 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3985 Mangler.getStream() <<
"??_8";
3986 Mangler.mangleName(Derived);
3987 Mangler.getStream() <<
"7B";
3988 for (
const CXXRecordDecl *RD : BasePath)
3989 Mangler.mangleName(RD);
3990 Mangler.getStream() <<
'@';
3993void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
3994 msvc_hashing_ostream MHO(Out);
3995 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3996 Mangler.getStream() <<
"??_R0";
3997 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3998 Mangler.getStream() <<
"@8";
4001void MicrosoftMangleContextImpl::mangleCXXRTTIName(
4002 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4003 MicrosoftCXXNameMangler Mangler(*
this, Out);
4004 Mangler.getStream() <<
'.';
4005 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4008void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
4009 const CXXRecordDecl *SrcRD,
const CXXRecordDecl *DstRD, raw_ostream &Out) {
4010 msvc_hashing_ostream MHO(Out);
4011 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4012 Mangler.getStream() <<
"??_K";
4013 Mangler.mangleName(SrcRD);
4014 Mangler.getStream() <<
"$C";
4015 Mangler.mangleName(DstRD);
4018void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T,
bool IsConst,
4021 uint32_t NumEntries,
4023 msvc_hashing_ostream MHO(Out);
4024 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4025 Mangler.getStream() <<
"_TI";
4027 Mangler.getStream() <<
'C';
4029 Mangler.getStream() <<
'V';
4031 Mangler.getStream() <<
'U';
4032 Mangler.getStream() << NumEntries;
4033 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4036void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
4037 QualType T, uint32_t NumEntries, raw_ostream &Out) {
4038 msvc_hashing_ostream MHO(Out);
4039 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4040 Mangler.getStream() <<
"_CTA";
4041 Mangler.getStream() << NumEntries;
4042 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4045void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4046 QualType T,
const CXXConstructorDecl *CD,
CXXCtorType CT, uint32_t Size,
4047 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
4049 MicrosoftCXXNameMangler Mangler(*
this, Out);
4050 Mangler.getStream() <<
"_CT";
4052 llvm::SmallString<64> RTTIMangling;
4054 llvm::raw_svector_ostream Stream(RTTIMangling);
4055 msvc_hashing_ostream MHO(Stream);
4056 mangleCXXRTTI(T, MHO);
4058 Mangler.getStream() << RTTIMangling;
4066 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4067 LangOptions::MSVC2015) &&
4068 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4069 LangOptions::MSVC2017_7);
4070 llvm::SmallString<64> CopyCtorMangling;
4071 if (!OmitCopyCtor && CD) {
4072 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4073 msvc_hashing_ostream MHO(Stream);
4074 mangleCXXName(GlobalDecl(CD, CT), MHO);
4076 Mangler.getStream() << CopyCtorMangling;
4078 Mangler.getStream() <<
Size;
4079 if (VBPtrOffset == -1) {
4081 Mangler.getStream() << NVOffset;
4084 Mangler.getStream() << NVOffset;
4085 Mangler.getStream() << VBPtrOffset;
4086 Mangler.getStream() << VBIndex;
4090void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4091 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
4092 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
4093 msvc_hashing_ostream MHO(Out);
4094 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4095 Mangler.getStream() <<
"??_R1";
4096 Mangler.mangleNumber(NVOffset);
4097 Mangler.mangleNumber(VBPtrOffset);
4098 Mangler.mangleNumber(VBTableOffset);
4099 Mangler.mangleNumber(Flags);
4100 Mangler.mangleName(Derived);
4101 Mangler.getStream() <<
"8";
4104void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4105 const CXXRecordDecl *Derived, raw_ostream &Out) {
4106 msvc_hashing_ostream MHO(Out);
4107 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4108 Mangler.getStream() <<
"??_R2";
4109 Mangler.mangleName(Derived);
4110 Mangler.getStream() <<
"8";
4113void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4114 const CXXRecordDecl *Derived, raw_ostream &Out) {
4115 msvc_hashing_ostream MHO(Out);
4116 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4117 Mangler.getStream() <<
"??_R3";
4118 Mangler.mangleName(Derived);
4119 Mangler.getStream() <<
"8";
4122void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4123 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4129 llvm::SmallString<64> VFTableMangling;
4130 llvm::raw_svector_ostream Stream(VFTableMangling);
4131 mangleCXXVFTable(Derived, BasePath, Stream);
4133 if (VFTableMangling.starts_with(
"??@")) {
4134 assert(VFTableMangling.ends_with(
"@"));
4135 Out << VFTableMangling <<
"??_R4@";
4139 assert(VFTableMangling.starts_with(
"??_7") ||
4140 VFTableMangling.starts_with(
"??_S"));
4142 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
4145void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4146 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4147 msvc_hashing_ostream MHO(Out);
4148 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4153 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
4154 Mangler.mangleName(EnclosingDecl);
4157void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4158 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4159 msvc_hashing_ostream MHO(Out);
4160 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4165 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
4166 Mangler.mangleName(EnclosingDecl);
4169void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4170 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4173 MicrosoftCXXNameMangler Mangler(*
this, Out);
4174 Mangler.getStream() <<
'?';
4178void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4179 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
4180 msvc_hashing_ostream MHO(Out);
4181 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4183 Mangler.getStream() <<
"?";
4184 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
4185 Mangler.mangle(VD,
"");
4188void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4189 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
4190 msvc_hashing_ostream MHO(Out);
4191 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4193 Mangler.getStream() <<
"?";
4194 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
4195 Mangler.mangleNestedName(VD);
4196 Mangler.getStream() <<
"@4HA";
4199void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
4211 msvc_hashing_ostream MHO(Out);
4212 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4216 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
4218 Mangler.getStream() <<
"?$S1@";
4220 unsigned ScopeDepth = 0;
4221 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4225 Mangler.mangle(VD,
"");
4227 Mangler.mangleNestedName(VD);
4228 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
4230 Mangler.mangleNumber(ScopeDepth);
4233void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *D,
4236 msvc_hashing_ostream MHO(Out);
4237 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4238 Mangler.getStream() <<
"??__" << CharCode;
4240 Mangler.getStream() <<
'?';
4241 Mangler.mangleName(D);
4242 Mangler.mangleVariableEncoding(D);
4243 Mangler.getStream() <<
"@@";
4245 Mangler.mangleName(D);
4249 Mangler.getStream() <<
"YAXXZ";
4252void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *D,
4255 mangleInitFiniStub(D,
'E', Out);
4259MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *D,
4262 mangleInitFiniStub(D,
'F', Out);
4265void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4286 MicrosoftCXXNameMangler Mangler(*
this, Out);
4287 Mangler.getStream() <<
"??_C@_";
4295 unsigned StringLength =
4296 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4301 Mangler.getStream() <<
'1';
4303 Mangler.getStream() <<
'0';
4307 Mangler.mangleNumber(StringByteLength);
4309 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4311 if (Index / CharByteWidth >= SL->
getLength())
4312 return static_cast<char>(0);
4314 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4315 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4318 auto GetBigEndianByte = [&SL](
unsigned Index) {
4320 if (Index / CharByteWidth >= SL->
getLength())
4321 return static_cast<char>(0);
4323 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4324 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4329 for (
unsigned I = 0, E = StringByteLength; I != E; ++I)
4330 JC.update(GetLittleEndianByte(I));
4334 Mangler.mangleNumber(JC.getCRC());
4340 auto MangleByte = [&Mangler](
char Byte) {
4348 Mangler.getStream() << Byte;
4349 }
else if (
isLetter(Byte & 0x7f)) {
4350 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4352 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4353 ' ',
'\n',
'\t',
'\'',
'-'};
4354 const char *Pos = llvm::find(SpecialChars, Byte);
4355 if (Pos != std::end(SpecialChars)) {
4356 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4358 Mangler.getStream() <<
"?$";
4359 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4360 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4366 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4367 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4368 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4370 MangleByte(GetBigEndianByte(I));
4372 MangleByte(GetLittleEndianByte(I));
4375 Mangler.getStream() <<
'@';
4378void MicrosoftCXXNameMangler::mangleAutoReturnType(
const MemberPointerType *T,
4381 manglePointerCVQualifiers(Quals);
4382 manglePointerExtQualifiers(Quals, PointeeType);
4383 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4386 mangleFunctionType(FPT,
nullptr,
true);
4390 mangleAutoReturnType(PointeeType, QMM_Drop);
4394void MicrosoftCXXNameMangler::mangleAutoReturnType(
const PointerType *T,
4398 "Unexpected address space mangling required");
4400 manglePointerCVQualifiers(Quals);
4401 manglePointerExtQualifiers(Quals, PointeeType);
4403 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4405 mangleFunctionType(FPT);
4407 mangleAutoReturnType(PointeeType, QMM_Mangle);
4411void MicrosoftCXXNameMangler::mangleAutoReturnType(
const LValueReferenceType *T,
4416 manglePointerExtQualifiers(Quals, PointeeType);
4417 mangleAutoReturnType(PointeeType, QMM_Mangle);
4420void MicrosoftCXXNameMangler::mangleAutoReturnType(
const RValueReferenceType *T,
4425 manglePointerExtQualifiers(Quals, PointeeType);
4426 mangleAutoReturnType(PointeeType, QMM_Mangle);
4432 return new MicrosoftMangleContextImpl(Context, Diags, IsAux);
Enums/classes describing ABI related information about constructors, destructors and thunks.
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
static const GlobalDecl isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs)
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
llvm::MachO::Record Record
static ValueDecl * getAsArrayToPointerDecayedDecl(QualType T, const APValue &V)
If value V (with type T) represents a decayed pointer to the first element of an array,...
static void mangleThunkThisAdjustment(AccessSpecifier AS, const ThisAdjustment &Adjustment, MicrosoftCXXNameMangler &Mangler, raw_ostream &Out)
static bool hasAttr(const Decl *D, bool IgnoreImplicitAttr)
Defines the SourceManager interface.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APValue & getVectorElt(unsigned I)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
bool addressSpaceMapManglingFor(LangAS AS) const
const clang::PrintingPolicy & getPrintingPolicy() const
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
unsigned getTargetAddressSpace(LangAS AS) const
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
unsigned getNumBits() const
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType getPointeeType() const
StringRef getName(const PrintingPolicy &Policy) const
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Decl * getLambdaContextDecl() const
Retrieve the declaration that provides additional context for a lambda, when the normal declaration c...
CXXRecordDecl * getMostRecentDecl()
bool isLambda() const
Determine whether this class describes a lambda function object.
unsigned getLambdaManglingNumber() const
If this is the closure type of a lambda expression, retrieve the number to be used for name mangling ...
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Represents a class template specialization, which refers to a class template with a given set of temp...
QualType getElementType() const
llvm::APInt getSize() const
Return the constant array size as an APInt.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
bool isFunctionOrMethod() const
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
@ CXXConversionFunctionName
NameKind getNameKind() const
Determine what kind of name this is.
Expr * getSizeExpr() const
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
This represents one expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isExternC() const
Determines whether this function is a function with external, C linkage.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
Qualifiers getMethodQuals() const
QualType getParamType(unsigned i) const
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
bool isVariadic() const
Whether this function prototype is variadic.
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
KernelReferenceKind getKernelReferenceKind() const
GlobalDecl getWithDecl(const Decl *D)
CXXDtorType getDtorType() const
const Decl * getDecl() const
StringRef getName() const
Return the actual identifier string.
An lvalue reference type, per C++11 [dcl.ref].
QualType getElementType() const
Returns type of the elements being stored in the matrix.
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
static MicrosoftMangleContext * create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux=false)
MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D, bool IsAux=false)
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
bool isExternallyVisible() const
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Represents an Objective-C protocol declaration.
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
QualType getElementType() const
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void * getAsOpaquePtr() const
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
bool hasAddressSpace() const
PointerAuthQualifier getPointerAuth() const
bool hasObjCLifetime() const
ObjCLifetime getObjCLifetime() const
Qualifiers withoutObjCLifetime() const
LangAS getAddressSpace() const
An rvalue reference type, per C++11 [dcl.ref].
field_range fields() const
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
QualType getPointeeType() const
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const char * getStmtClassName() const
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
unsigned getCharByteWidth() const
Represents the declaration of a struct/union/class/enum.
TagDecl * getDefinition() const
Returns the TagDecl that actually defines this struct/union/class/enum.
TypedefNameDecl * getTypedefNameForAnonDecl() const
TagKind getTagKind() const
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
NamedDecl * getParam(unsigned Idx)
bool isBlockPointerType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isMemberDataPointerType() const
bool isMemberPointerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isFunctionType() const
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
TLSKind getTLSKind() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isStaticDataMember() const
Determines whether this is a static data member.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool isExternC() const
Determines whether this variable is a variable with external, C linkage.
Represents a variable template specialization, which refers to a variable template with a given set o...
unsigned getNumElements() const
QualType getElementType() const
Defines the clang::TargetInfo interface.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
CXXCtorType
C++ constructor types.
@ Ctor_DefaultClosure
Default closure variant of a ctor.
@ Ctor_CopyingClosure
Copying closure variant of a ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
RefQualifierKind
The kind of C++11 ref-qualifier associated with a function type.
@ RQ_None
No ref-qualifier was provided.
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
bool inheritanceModelHasNVOffsetField(bool IsMemberFunction, MSInheritanceModel Inheritance)
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
LanguageLinkage
Describes the different kinds of language linkage (C++ [dcl.link]) that an entity may have.
bool inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance)
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
bool inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance)
@ Result
The result type of a method or function.
CXXDtorType
C++ destructor types.
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
TagTypeKind
The kind of a tag type.
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool isPtrSizeAddressSpace(LangAS AS)
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName)
Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...
int const char * function
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to.
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
uint64_t VBTableIndex
If nonzero, holds the vbtable index of the virtual base with the vfptr.
uint64_t Index
Method's index in the vftable.
A this pointer adjustment.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
const CXXMethodDecl * Method
Holds a pointer to the overridden method this thunk is for, if needed by the ABI to distinguish diffe...
ReturnAdjustment Return
The return adjustment.
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
struct clang::ThisAdjustment::VirtualAdjustment::@312251255113040203233347230177110330127151157305 Microsoft
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...