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 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
130 if (
const auto *FTD = FD->getPrimaryTemplate())
131 return FTD->getTemplatedDecl()->getCanonicalDecl();
133 return FD->getCanonicalDecl();
139 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
140 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
141 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
142 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
143 llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
144 llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
145 SmallString<16> AnonymousNamespaceHash;
148 MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags,
150 bool shouldMangleCXXName(
const NamedDecl *D)
override;
151 bool shouldMangleStringLiteral(
const StringLiteral *SL)
override;
152 void mangleCXXName(GlobalDecl GD, raw_ostream &Out)
override;
153 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
154 const MethodVFTableLocation &ML,
155 raw_ostream &Out)
override;
156 void mangleThunk(
const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
157 bool ElideOverrideInfo, raw_ostream &)
override;
159 const ThunkInfo &Thunk,
bool ElideOverrideInfo,
160 raw_ostream &)
override;
161 void mangleCXXVFTable(
const CXXRecordDecl *Derived,
162 ArrayRef<const CXXRecordDecl *> BasePath,
163 raw_ostream &Out)
override;
164 void mangleCXXVBTable(
const CXXRecordDecl *Derived,
165 ArrayRef<const CXXRecordDecl *> BasePath,
166 raw_ostream &Out)
override;
168 void mangleCXXVTable(
const CXXRecordDecl *, raw_ostream &)
override;
169 void mangleCXXVirtualDisplacementMap(
const CXXRecordDecl *SrcRD,
170 const CXXRecordDecl *DstRD,
171 raw_ostream &Out)
override;
172 void mangleCXXThrowInfo(QualType T,
bool IsConst,
bool IsVolatile,
173 bool IsUnaligned, uint32_t NumEntries,
174 raw_ostream &Out)
override;
175 void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
176 raw_ostream &Out)
override;
177 void mangleCXXCatchableType(QualType T,
const CXXConstructorDecl *CD,
179 int32_t VBPtrOffset, uint32_t VBIndex,
180 raw_ostream &Out)
override;
181 void mangleCXXRTTI(QualType T, raw_ostream &Out)
override;
182 void mangleCXXRTTIName(QualType T, raw_ostream &Out,
183 bool NormalizeIntegers)
override;
184 void mangleCXXRTTIBaseClassDescriptor(
const CXXRecordDecl *Derived,
185 uint32_t NVOffset, int32_t VBPtrOffset,
186 uint32_t VBTableOffset, uint32_t Flags,
187 raw_ostream &Out)
override;
188 void mangleCXXRTTIBaseClassArray(
const CXXRecordDecl *Derived,
189 raw_ostream &Out)
override;
190 void mangleCXXRTTIClassHierarchyDescriptor(
const CXXRecordDecl *Derived,
191 raw_ostream &Out)
override;
193 mangleCXXRTTICompleteObjectLocator(
const CXXRecordDecl *Derived,
194 ArrayRef<const CXXRecordDecl *> BasePath,
195 raw_ostream &Out)
override;
196 void mangleCanonicalTypeName(QualType T, raw_ostream &,
197 bool NormalizeIntegers)
override;
198 void mangleReferenceTemporary(
const VarDecl *,
unsigned ManglingNumber,
199 raw_ostream &)
override;
200 void mangleStaticGuardVariable(
const VarDecl *D, raw_ostream &Out)
override;
201 void mangleThreadSafeStaticGuardVariable(
const VarDecl *D,
unsigned GuardNum,
202 raw_ostream &Out)
override;
203 void mangleDynamicInitializer(
const VarDecl *D, raw_ostream &Out)
override;
204 void mangleDynamicAtExitDestructor(
const VarDecl *D,
205 raw_ostream &Out)
override;
206 void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
207 raw_ostream &Out)
override;
208 void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
209 raw_ostream &Out)
override;
210 void mangleStringLiteral(
const StringLiteral *SL, raw_ostream &Out)
override;
211 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
212 const DeclContext *DC = getEffectiveDeclContext(ND);
218 if (
const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
219 if (RD->isLambda()) {
227 disc = getASTContext().getManglingNumber(ND, isAux());
232 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
233 if (!
Tag->hasNameForLinkage() &&
234 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
235 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))
240 unsigned &discriminator = Uniquifier[ND];
242 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
243 disc = discriminator + 1;
247 std::string getLambdaString(
const CXXRecordDecl *Lambda)
override {
248 assert(Lambda->
isLambda() &&
"RD must be a lambda!");
249 std::string Name(
"<lambda_");
254 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
255 const FunctionDecl *
Func =
259 unsigned DefaultArgNo =
261 Name += llvm::utostr(DefaultArgNo);
265 if (LambdaManglingNumber)
266 LambdaId = LambdaManglingNumber;
268 LambdaId = getLambdaIdForDebugInfo(Lambda);
270 Name += llvm::utostr(LambdaId);
275 unsigned getLambdaId(
const CXXRecordDecl *RD) {
276 assert(RD->
isLambda() &&
"RD must be a lambda!");
279 "RD must not have a mangling number!");
280 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator,
bool>
281 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
282 return Result.first->second;
285 unsigned getLambdaIdForDebugInfo(
const CXXRecordDecl *RD) {
286 assert(RD->
isLambda() &&
"RD must be a lambda!");
289 "RD must not have a mangling number!");
291 return LambdaIds.lookup(RD);
296 StringRef getAnonymousNamespaceHash()
const {
297 return AnonymousNamespaceHash;
301 void mangleInitFiniStub(
const VarDecl *D,
char CharCode, raw_ostream &Out);
306class MicrosoftCXXNameMangler {
307 MicrosoftMangleContextImpl &Context;
313 const NamedDecl *Structor;
314 unsigned StructorType;
316 typedef llvm::SmallVector<std::string, 10> BackRefVec;
317 BackRefVec NameBackReferences;
319 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
320 ArgBackRefMap FunArgBackReferences;
321 ArgBackRefMap TemplateArgBackReferences;
323 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
324 TemplateArgStringMap TemplateArgStrings;
325 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
326 llvm::StringSaver TemplateArgStringStorage;
328 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
329 PassObjectSizeArgsSet PassObjectSizeArgs;
331 ASTContext &getASTContext()
const {
return Context.getASTContext(); }
333 const bool PointersAre64Bit;
335 DiagnosticBuilder
Error(SourceLocation, StringRef, StringRef);
336 DiagnosticBuilder
Error(SourceLocation, StringRef);
337 DiagnosticBuilder
Error(StringRef);
340 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
341 enum class TplArgKind { ClassNTTP, StructuralValue };
343 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_)
344 : Context(
C), Out(Out_), Structor(
nullptr), StructorType(-1),
345 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
346 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
349 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
351 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
352 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
353 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
356 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
358 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
359 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
360 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
363 raw_ostream &getStream()
const {
return Out; }
365 void mangle(GlobalDecl GD, StringRef Prefix =
"?");
366 void mangleName(GlobalDecl GD);
367 void mangleFunctionEncoding(GlobalDecl GD,
bool ShouldMangle);
368 void mangleVariableEncoding(
const VarDecl *VD);
369 void mangleMemberDataPointer(
const CXXRecordDecl *RD,
const ValueDecl *VD,
370 const NonTypeTemplateParmDecl *PD,
371 QualType TemplateArgType,
372 StringRef Prefix =
"$");
373 void mangleMemberDataPointerInClassNTTP(
const CXXRecordDecl *,
375 void mangleMemberFunctionPointer(
const CXXRecordDecl *RD,
376 const CXXMethodDecl *MD,
377 const NonTypeTemplateParmDecl *PD,
378 QualType TemplateArgType,
379 StringRef Prefix =
"$");
380 void mangleFunctionPointer(
const FunctionDecl *FD,
381 const NonTypeTemplateParmDecl *PD,
382 QualType TemplateArgType);
383 void mangleVarDecl(
const VarDecl *VD,
const NonTypeTemplateParmDecl *PD,
384 QualType TemplateArgType);
385 void mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD,
386 const CXXMethodDecl *MD);
387 void mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
388 const MethodVFTableLocation &ML);
389 void mangleNumber(int64_t Number);
390 void mangleNumber(llvm::APSInt Number);
391 void mangleFloat(llvm::APFloat Number);
392 void mangleBits(llvm::APInt Number);
394 void mangleArtificialTagType(
TagTypeKind TK, StringRef UnqualifiedName,
395 ArrayRef<StringRef> NestedNames = {});
396 void mangleAddressSpaceType(QualType T, Qualifiers Quals, SourceRange Range);
397 void mangleType(QualType T, SourceRange Range,
398 QualifierMangleMode QMM = QMM_Mangle);
399 void mangleFunctionType(
const FunctionType *T,
400 const FunctionDecl *D =
nullptr,
401 bool ForceThisQuals =
false,
402 bool MangleExceptionSpec =
true);
403 void mangleSourceName(StringRef Name);
404 void mangleNestedName(GlobalDecl GD);
406 void mangleAutoReturnType(QualType T, QualifierMangleMode QMM);
409 bool isStructorDecl(
const NamedDecl *ND)
const {
410 return ND == Structor || getStructor(ND) == Structor;
413 bool is64BitPointer(Qualifiers Quals)
const {
415 return AddrSpace == LangAS::ptr64 ||
416 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||
417 AddrSpace == LangAS::ptr32_uptr));
420 void mangleUnqualifiedName(GlobalDecl GD) {
423 void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name);
426 void mangleQualifiers(Qualifiers Quals,
bool IsMember);
428 void manglePointerCVQualifiers(Qualifiers Quals);
429 void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType);
430 void manglePointerAuthQualifier(Qualifiers Quals);
432 void mangleUnscopedTemplateName(GlobalDecl GD);
434 mangleTemplateInstantiationName(GlobalDecl GD,
435 const TemplateArgumentList &TemplateArgs);
438 void mangleFunctionArgumentType(QualType T, SourceRange Range);
439 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
441 bool isArtificialTagType(QualType T)
const;
444#define ABSTRACT_TYPE(CLASS, PARENT)
445#define NON_CANONICAL_TYPE(CLASS, PARENT)
446#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
449#include "clang/AST/TypeNodes.inc"
451#undef NON_CANONICAL_TYPE
454 void mangleType(
const TagDecl *TD);
455 void mangleDecayedArrayType(
const ArrayType *T);
456 void mangleArrayType(
const ArrayType *T);
460 void mangleIntegerLiteral(
const llvm::APSInt &Number,
471 bool WithScalarType =
false);
486MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(
ASTContext &Context,
507 uint32_t TruncatedHash = uint32_t(xxh3_64bits(FE->getName()));
508 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
511 AnonymousNamespaceHash =
"0";
515bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *D) {
516 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
519 if (FD->hasAttr<OverloadableAttr>())
531 if (FD->isMSVCRTEntryPoint())
545 if (!getASTContext().getLangOpts().
CPlusPlus)
548 const VarDecl *VD = dyn_cast<VarDecl>(D);
555 const DeclContext *DC = getEffectiveDeclContext(D);
565MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
569DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
572 DiagnosticsEngine &Diags = Context.getDiags();
573 return Diags.
Report(loc, diag::err_ms_mangle_unsupported_with_detail)
577DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
579 DiagnosticsEngine &Diags = Context.getDiags();
580 return Diags.
Report(loc, diag::err_ms_mangle_unsupported) << thingy;
583DiagnosticBuilder MicrosoftCXXNameMangler::Error(StringRef thingy) {
584 DiagnosticsEngine &Diags = Context.getDiags();
586 return Diags.
Report(diag::err_ms_mangle_unsupported) << thingy;
589void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) {
600 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
601 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
602 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
603 mangleVariableEncoding(VD);
607 Out <<
"3U__s_GUID@@B";
612 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
615void MicrosoftCXXNameMangler::mangleFunctionEncoding(GlobalDecl GD,
627 const FunctionProtoType *FT = FD->
getType()->
castAs<FunctionProtoType>();
640 mangleFunctionClass(FD);
642 mangleFunctionType(FT, FD,
false,
false);
648void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
679 mangleType(Ty, SR, QMM_Drop);
680 manglePointerExtQualifiers(
682 if (
const MemberPointerType *MPT = Ty->
getAs<MemberPointerType>()) {
683 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
686 mangleName(MPT->getMostRecentCXXRecordDecl());
689 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
691 mangleDecayedArrayType(AT);
692 if (AT->getElementType()->isArrayType())
697 mangleType(Ty, SR, QMM_Drop);
702void MicrosoftCXXNameMangler::mangleMemberDataPointer(
703 const CXXRecordDecl *RD,
const ValueDecl *VD,
704 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
718 FieldOffset = getASTContext().getFieldOffset(VD);
719 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
720 "cannot take address of bitfield");
721 FieldOffset /= getASTContext().getCharWidth();
725 if (IM == MSInheritanceModel::Virtual)
726 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
735 case MSInheritanceModel::Single: Code =
'0';
break;
736 case MSInheritanceModel::Multiple: Code =
'0';
break;
737 case MSInheritanceModel::Virtual: Code =
'F';
break;
738 case MSInheritanceModel::Unspecified: Code =
'G';
break;
744 getASTContext().getLangOpts().isCompatibleWithMSVC(
745 LangOptions::MSVC2019) &&
747 !TemplateArgType.
isNull()) {
749 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
754 mangleNumber(FieldOffset);
762 mangleNumber(VBTableOffset);
765void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
766 const CXXRecordDecl *RD,
const ValueDecl *VD) {
772 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
773 return mangleMemberDataPointer(RD, VD,
nullptr, QualType(),
"");
781 mangleNestedName(VD);
783 mangleUnqualifiedName(VD);
787void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
788 const CXXRecordDecl *RD,
const CXXMethodDecl *MD,
789 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
805 case MSInheritanceModel::Single: Code =
'1';
break;
806 case MSInheritanceModel::Multiple: Code =
'H';
break;
807 case MSInheritanceModel::Virtual: Code =
'I';
break;
808 case MSInheritanceModel::Unspecified: Code =
'J';
break;
819 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
820 LangOptions::MSVC2019) &&
822 !TemplateArgType.
isNull()) {
824 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
829 MicrosoftVTableContext *VTContext =
831 MethodVFTableLocation ML =
833 mangleVirtualMemPtrThunk(MD, ML);
837 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
842 mangleFunctionEncoding(MD,
true);
845 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
846 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
849 if (IM == MSInheritanceModel::Single) {
850 Out << Prefix <<
"0A@";
853 if (IM == MSInheritanceModel::Unspecified)
855 Out << Prefix << Code;
859 mangleNumber(
static_cast<uint32_t>(NVOffset));
861 mangleNumber(VBPtrOffset);
863 mangleNumber(VBTableOffset);
866void MicrosoftCXXNameMangler::mangleFunctionPointer(
867 const FunctionDecl *FD,
const NonTypeTemplateParmDecl *PD,
868 QualType TemplateArgType) {
875 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
876 LangOptions::MSVC2019) &&
878 !TemplateArgType.
isNull()) {
880 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
885 mangleFunctionEncoding(FD,
true);
888void MicrosoftCXXNameMangler::mangleVarDecl(
const VarDecl *VD,
889 const NonTypeTemplateParmDecl *PD,
890 QualType TemplateArgType) {
897 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
898 LangOptions::MSVC2019) &&
900 !TemplateArgType.
isNull()) {
902 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
907 mangleVariableEncoding(VD);
910void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
911 const CXXRecordDecl *RD,
const CXXMethodDecl *MD) {
919 return mangleMemberFunctionPointer(RD, MD,
nullptr, QualType(),
"");
927 MicrosoftVTableContext *VTContext =
929 MethodVFTableLocation ML =
931 mangleVirtualMemPtrThunk(MD, ML);
934 mangleFunctionEncoding(MD,
true);
938void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
939 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML) {
941 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
942 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
948 mangleNumber(OffsetInVFTable);
950 mangleCallingConvention(MD->
getType()->
castAs<FunctionProtoType>(),
954void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {
958 mangleUnqualifiedName(GD);
960 mangleNestedName(GD);
966void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
967 mangleNumber(llvm::APSInt(llvm::APInt(64, Number),
false));
970void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
975 unsigned Width = std::max(Number.getBitWidth(), 64U);
976 llvm::APInt
Value = Number.extend(Width);
984 if (
Value.isNegative()) {
991void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
994 switch (APFloat::SemanticsToEnum(Number.getSemantics())) {
995 case APFloat::S_IEEEsingle:
Out <<
'A';
break;
996 case APFloat::S_IEEEdouble:
Out <<
'B';
break;
1000 case APFloat::S_IEEEhalf:
Out <<
'V';
break;
1001 case APFloat::S_BFloat:
Out <<
'W';
break;
1002 case APFloat::S_x87DoubleExtended:
Out <<
'X';
break;
1003 case APFloat::S_IEEEquad:
Out <<
'Y';
break;
1004 case APFloat::S_PPCDoubleDouble:
Out <<
'Z';
break;
1005 case APFloat::S_PPCDoubleDoubleLegacy:
1006 case APFloat::S_Float8E5M2:
1007 case APFloat::S_Float8E4M3:
1008 case APFloat::S_Float8E4M3FN:
1009 case APFloat::S_Float8E5M2FNUZ:
1010 case APFloat::S_Float8E4M3FNUZ:
1011 case APFloat::S_Float8E4M3B11FNUZ:
1012 case APFloat::S_Float8E3M4:
1013 case APFloat::S_FloatTF32:
1014 case APFloat::S_Float8E8M0FNU:
1015 case APFloat::S_Float6E3M2FN:
1016 case APFloat::S_Float6E2M3FN:
1017 case APFloat::S_Float4E2M1FN:
1018 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
1021 mangleBits(Number.bitcastToAPInt());
1024void MicrosoftCXXNameMangler::mangleBits(llvm::APInt
Value) {
1033 llvm::SmallString<32> EncodedNumberBuffer;
1035 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
1036 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1037 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1046 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1055 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1056 TemplateArgs = &Spec->getTemplateArgs();
1057 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1062 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1063 TemplateArgs = &Spec->getTemplateArgs();
1064 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1070void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
1071 DeclarationName Name) {
1079 const TemplateArgumentList *TemplateArgs =
nullptr;
1080 if (GlobalDecl TD =
isTemplate(GD, TemplateArgs)) {
1085 mangleTemplateInstantiationName(TD, *TemplateArgs);
1108 ArgBackRefMap::iterator
Found = TemplateArgBackReferences.find(ND);
1109 if (
Found == TemplateArgBackReferences.end()) {
1111 TemplateArgStringMap::iterator
Found = TemplateArgStrings.find(ND);
1112 if (
Found == TemplateArgStrings.end()) {
1114 llvm::SmallString<64> TemplateMangling;
1115 llvm::raw_svector_ostream Stream(TemplateMangling);
1116 MicrosoftCXXNameMangler
Extra(Context, Stream);
1117 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1120 mangleSourceName(TemplateMangling);
1124 BackRefVec::iterator StringFound =
1125 llvm::find(NameBackReferences, TemplateMangling);
1126 if (StringFound != NameBackReferences.end()) {
1127 TemplateArgBackReferences[ND] =
1128 StringFound - NameBackReferences.begin();
1130 TemplateArgStrings[ND] =
1131 TemplateArgStringStorage.save(TemplateMangling.str());
1150 ->getTemplatedDecl()
1153 bool IsOCLDeviceStub =
1155 DeviceKernelAttr::isOpenCLSpelling(
1156 ND->
getAttr<DeviceKernelAttr>()) &&
1160 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1161 else if (IsOCLDeviceStub)
1163 (llvm::Twine(
"__clang_ocl_kern_imp_") + II->getName()).str());
1165 mangleSourceName(II->getName());
1170 assert(ND &&
"mangling empty name without declaration");
1172 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1173 if (NS->isAnonymousNamespace()) {
1174 llvm::SmallString<16> Name(
"?A0x");
1175 Name += Context.getAnonymousNamespaceHash();
1176 mangleSourceName(Name);
1181 if (
const DecompositionDecl *DD = dyn_cast<DecompositionDecl>(ND)) {
1184 llvm::SmallString<64> Name(
"$S");
1186 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1187 mangleSourceName(Name);
1191 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1194 assert(RD &&
"expected variable decl to have a record type");
1198 llvm::SmallString<64> Name(
"$S");
1200 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1201 mangleSourceName(Name.str());
1205 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1208 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1209 llvm::raw_svector_ostream GUIDOS(GUID);
1210 Context.mangleMSGuidDecl(GD, GUIDOS);
1211 mangleSourceName(GUID);
1215 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1217 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1218 TPO->getValue(), TplArgKind::ClassNTTP);
1226 "Typedef should not be in another decl context!");
1228 "Typedef was not named!");
1233 if (
const CXXRecordDecl *
Record = dyn_cast<CXXRecordDecl>(TD)) {
1234 if (
Record->isLambda()) {
1235 llvm::SmallString<10> Name(
"<lambda_");
1237 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1238 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1240 const ParmVarDecl *Parm =
1241 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1242 const FunctionDecl *
Func =
1246 unsigned DefaultArgNo =
1248 Name += llvm::utostr(DefaultArgNo);
1252 if (LambdaManglingNumber)
1253 LambdaId = LambdaManglingNumber;
1255 LambdaId = Context.getLambdaId(
Record);
1257 Name += llvm::utostr(LambdaId);
1260 mangleSourceName(Name);
1264 if (LambdaManglingNumber && LambdaContextDecl) {
1275 llvm::SmallString<64> Name;
1276 if (DeclaratorDecl *DD =
1280 Name +=
"<unnamed-type-";
1281 Name += DD->getName();
1282 }
else if (TypedefNameDecl *TND =
1287 Name +=
"<unnamed-type-";
1288 Name += TND->getName();
1293 Name +=
"<unnamed-enum-";
1294 Name += ED->enumerator_begin()->getName();
1297 Name +=
"<unnamed-type-$S";
1298 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1301 mangleSourceName(Name.str());
1311 llvm::SmallString<64> Name;
1312 mangleSourceName(Name.str());
1317 if (isStructorDecl(ND)) {
1331 if (isStructorDecl(ND))
1334 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1348 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1353 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1358 llvm_unreachable(
"Can't mangle a deduction guide name!");
1361 llvm_unreachable(
"Can't mangle a using directive name!");
1367void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {
1370 if (
const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1371 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1372 mangleSourceName(
"<unnamed-tag>");
1374 const DeclContext *DC = getEffectiveDeclContext(ND);
1378 if (Context.getNextDiscriminator(ND, Disc)) {
1385 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1387 [](StringRef Name,
const unsigned Discriminator,
1388 const unsigned ParameterDiscriminator) -> std::string {
1390 llvm::raw_string_ostream Stream(Buffer);
1393 Stream <<
'_' << Discriminator;
1394 if (ParameterDiscriminator)
1395 Stream <<
'_' << ParameterDiscriminator;
1399 unsigned Discriminator = BD->getBlockManglingNumber();
1401 Discriminator = Context.getBlockId(BD,
false);
1406 unsigned ParameterDiscriminator = 0;
1407 if (
const auto *MC = BD->getBlockManglingContextDecl())
1408 if (
const auto *P = dyn_cast<ParmVarDecl>(MC))
1409 if (
const auto *F = dyn_cast<FunctionDecl>(P->getDeclContext()))
1410 ParameterDiscriminator =
1411 F->getNumParams() - P->getFunctionScopeIndex();
1413 DC = getEffectiveDeclContext(BD);
1416 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1417 ParameterDiscriminator));
1422 if (
const auto *MC = BD->getBlockManglingContextDecl())
1424 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1425 mangleUnqualifiedName(ND);
1429 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1438 if (PointersAre64Bit)
1441 mangleArtificialTagType(TagTypeKind::Struct,
1442 Discriminate(
"__block_literal", Discriminator,
1443 ParameterDiscriminator));
1451 }
else if (
const ObjCMethodDecl *
Method = dyn_cast<ObjCMethodDecl>(DC)) {
1455 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1456 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1459 mangleUnqualifiedName(ND);
1462 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1472void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1488 llvm_unreachable(
"not expecting a COMDAT");
1490 llvm_unreachable(
"not expecting a unified dtor type");
1492 llvm_unreachable(
"Unsupported dtor type?");
1496 SourceLocation Loc) {
1501 case OO_New:
Out <<
"?2";
break;
1503 case OO_Delete:
Out <<
"?3";
break;
1505 case OO_Equal:
Out <<
"?4";
break;
1507 case OO_GreaterGreater:
Out <<
"?5";
break;
1509 case OO_LessLess:
Out <<
"?6";
break;
1511 case OO_Exclaim:
Out <<
"?7";
break;
1513 case OO_EqualEqual:
Out <<
"?8";
break;
1515 case OO_ExclaimEqual:
Out <<
"?9";
break;
1517 case OO_Subscript:
Out <<
"?A";
break;
1520 case OO_Arrow:
Out <<
"?C";
break;
1522 case OO_Star:
Out <<
"?D";
break;
1524 case OO_PlusPlus:
Out <<
"?E";
break;
1526 case OO_MinusMinus:
Out <<
"?F";
break;
1528 case OO_Minus:
Out <<
"?G";
break;
1530 case OO_Plus:
Out <<
"?H";
break;
1532 case OO_Amp:
Out <<
"?I";
break;
1534 case OO_ArrowStar:
Out <<
"?J";
break;
1536 case OO_Slash:
Out <<
"?K";
break;
1538 case OO_Percent:
Out <<
"?L";
break;
1540 case OO_Less:
Out <<
"?M";
break;
1542 case OO_LessEqual:
Out <<
"?N";
break;
1544 case OO_Greater:
Out <<
"?O";
break;
1546 case OO_GreaterEqual:
Out <<
"?P";
break;
1548 case OO_Comma:
Out <<
"?Q";
break;
1550 case OO_Call:
Out <<
"?R";
break;
1552 case OO_Tilde:
Out <<
"?S";
break;
1554 case OO_Caret:
Out <<
"?T";
break;
1556 case OO_Pipe:
Out <<
"?U";
break;
1558 case OO_AmpAmp:
Out <<
"?V";
break;
1560 case OO_PipePipe:
Out <<
"?W";
break;
1562 case OO_StarEqual:
Out <<
"?X";
break;
1564 case OO_PlusEqual:
Out <<
"?Y";
break;
1566 case OO_MinusEqual:
Out <<
"?Z";
break;
1568 case OO_SlashEqual:
Out <<
"?_0";
break;
1570 case OO_PercentEqual:
Out <<
"?_1";
break;
1572 case OO_GreaterGreaterEqual:
Out <<
"?_2";
break;
1574 case OO_LessLessEqual:
Out <<
"?_3";
break;
1576 case OO_AmpEqual:
Out <<
"?_4";
break;
1578 case OO_PipeEqual:
Out <<
"?_5";
break;
1580 case OO_CaretEqual:
Out <<
"?_6";
break;
1609 case OO_Array_New:
Out <<
"?_U";
break;
1611 case OO_Array_Delete:
Out <<
"?_V";
break;
1613 case OO_Coawait:
Out <<
"?__L";
break;
1615 case OO_Spaceship:
Out <<
"?__M";
break;
1617 case OO_Conditional: {
1618 Error(Loc,
"conditional operator");
1624 llvm_unreachable(
"Not an overloaded operator");
1628void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1630 BackRefVec::iterator
Found = llvm::find(NameBackReferences, Name);
1631 if (
Found == NameBackReferences.end()) {
1632 if (NameBackReferences.size() < 10)
1633 NameBackReferences.push_back(std::string(Name));
1636 Out << (
Found - NameBackReferences.begin());
1640void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1641 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1644void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1645 GlobalDecl GD,
const TemplateArgumentList &TemplateArgs) {
1651 ArgBackRefMap OuterFunArgsContext;
1652 ArgBackRefMap OuterTemplateArgsContext;
1653 BackRefVec OuterTemplateContext;
1654 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1655 NameBackReferences.swap(OuterTemplateContext);
1656 FunArgBackReferences.swap(OuterFunArgsContext);
1657 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1658 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1660 mangleUnscopedTemplateName(GD);
1664 NameBackReferences.swap(OuterTemplateContext);
1665 FunArgBackReferences.swap(OuterFunArgsContext);
1666 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1667 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1670void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {
1673 mangleUnqualifiedName(GD);
1676void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1677 const llvm::APSInt &
Value,
const NonTypeTemplateParmDecl *PD,
1678 QualType TemplateArgType) {
1687 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1688 LangOptions::MSVC2019) &&
1690 !TemplateArgType.
isNull()) {
1692 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
1697 mangleNumber(
Value);
1700void MicrosoftCXXNameMangler::mangleExpression(
1701 const Expr *E,
const NonTypeTemplateParmDecl *PD) {
1703 if (std::optional<llvm::APSInt>
Value =
1714void MicrosoftCXXNameMangler::mangleTemplateArgs(
1715 const TemplateDecl *TD,
const TemplateArgumentList &TemplateArgs) {
1718 assert(TPL->
size() == TemplateArgs.
size() &&
1719 "size mismatch between args and parms!");
1721 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1722 const TemplateArgument &TA = TemplateArgs[i];
1729 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1737 if (!T->isPointerType() || !
V.isLValue() || !
V.hasLValuePath() ||
1741 QualType BaseT =
V.getLValueBase().getType();
1742 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1743 V.getLValuePath()[0].getAsArrayIndex() != 0)
1746 V.getLValueBase().dyn_cast<const ValueDecl *>());
1749void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1750 const TemplateArgument &TA,
1751 const NamedDecl *Parm) {
1789 llvm_unreachable(
"Can't mangle null template arguments!");
1791 llvm_unreachable(
"Can't mangle template expansion arguments!");
1794 mangleType(T, SourceRange(), QMM_Escape);
1800 mangleMemberDataPointer(
1804 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1805 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1817 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1818 TPO->getValue(), TplArgKind::ClassNTTP);
1819 }
else if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1835 if (
const MemberPointerType *MPT = T->
getAs<MemberPointerType>()) {
1836 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1837 if (MPT->isMemberFunctionPointerType() &&
1839 mangleMemberFunctionPointer(RD,
nullptr,
nullptr, QualType());
1842 if (MPT->isMemberDataPointer()) {
1844 mangleMemberDataPointer(RD,
nullptr,
nullptr, QualType());
1854 mangleIntegerLiteral(llvm::APSInt::get(-1),
1860 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1870 return mangleTemplateArg(
1876 ->getContainedDeducedType()) {
1882 TplArgKind::StructuralValue,
1890 if (TemplateArgs.empty()) {
1895 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(
1896 LangOptions::MSVC2015)
1902 llvm_unreachable(
"unexpected template parameter decl!");
1904 for (
const TemplateArgument &PA : TemplateArgs)
1905 mangleTemplateArg(TD, PA, Parm);
1910 const NamedDecl *ND =
1912 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1918 llvm_unreachable(
"unexpected template template NamedDecl!");
1925void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
1928 bool WithScalarType) {
1929 switch (
V.getKind()) {
1935 mangleType(T, SourceRange(), QMM_Escape);
1941 mangleType(T, SourceRange(), QMM_Escape);
1943 mangleNumber(
V.getInt());
1948 mangleType(T, SourceRange(), QMM_Escape);
1949 mangleFloat(
V.getFloat());
1954 mangleType(T, SourceRange(), QMM_Escape);
1956 APValue::LValueBase
Base =
V.getLValueBase();
1960 if (
V.isLValueOnePastTheEnd()) {
1962 auto *VD =
Base.dyn_cast<
const ValueDecl *>();
1969 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1971 if (
Base.isNull()) {
1977 mangleNumber(
V.getLValueOffset().getQuantity());
1978 }
else if (!
V.hasLValuePath()) {
1980 Error(
"template argument (extension not comaptible with ms mangler)");
1982 }
else if (
auto *VD =
Base.dyn_cast<
const ValueDecl*>()) {
1986 Error(
"template argument (undeclared base)");
1993 SmallVector<char, 2> EntryTypes;
1995 QualType ET =
Base.getType();
1996 for (APValue::LValuePathEntry E :
V.getLValuePath()) {
1998 EntryTypes.push_back(
'C');
1999 EntryManglers.push_back([
this, I = E.getAsArrayIndex()] {
2004 ET = AT->getElementType();
2008 const Decl *D = E.getAsBaseOrMember().getPointer();
2009 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
2021 EntryTypes.push_back(
'6');
2022 EntryManglers.push_back([
this, D] {
2028 for (
auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
2031 auto *VD =
Base.dyn_cast<
const ValueDecl*>();
2033 Error(
"template argument (null value decl)");
2036 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
2050 mangleType(T, SourceRange(), QMM_Escape);
2052 const CXXRecordDecl *RD =
2053 T->
castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
2054 const ValueDecl *D =
V.getMemberPointerDecl();
2055 if (TAK == TplArgKind::ClassNTTP) {
2057 mangleMemberDataPointerInClassNTTP(RD, D);
2059 mangleMemberFunctionPointerInClassNTTP(RD,
2060 cast_or_null<CXXMethodDecl>(D));
2063 mangleMemberDataPointer(RD, D,
nullptr, QualType(),
"");
2065 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D),
nullptr,
2073 mangleType(T, SourceRange(), QMM_Escape);
2075 assert(RD &&
"unexpected type for record value");
2077 unsigned BaseIndex = 0;
2078 for (
const CXXBaseSpecifier &B : RD->
bases())
2079 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
2080 for (
const FieldDecl *FD : RD->
fields())
2081 if (!FD->isUnnamedBitField())
2082 mangleTemplateArgValue(FD->
getType(),
2083 V.getStructField(FD->getFieldIndex()), TAK,
2091 mangleType(T, SourceRange(), QMM_Escape);
2092 if (
const FieldDecl *FD =
V.getUnionField()) {
2093 mangleUnqualifiedName(FD);
2094 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
2102 mangleType(T, SourceRange(), QMM_Escape);
2104 mangleNumber(
V.getComplexIntReal());
2106 mangleNumber(
V.getComplexIntImag());
2112 mangleType(T, SourceRange(), QMM_Escape);
2113 mangleFloat(
V.getComplexFloatReal());
2114 mangleFloat(
V.getComplexFloatImag());
2120 QualType ElemT = getASTContext().getAsArrayType(T)->getElementType();
2121 mangleType(ElemT, SourceRange(), QMM_Escape);
2122 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
2123 const APValue &ElemV = I <
V.getArrayInitializedElts()
2124 ?
V.getArrayInitializedElt(I)
2125 :
V.getArrayFiller();
2126 mangleTemplateArgValue(ElemT, ElemV, TAK);
2137 mangleType(T, SourceRange(), QMM_Escape);
2139 QualType ElemT = T->
castAs<VectorType>()->getElementType();
2140 mangleType(ElemT, SourceRange(), QMM_Escape);
2141 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
2143 mangleTemplateArgValue(ElemT, ElemV, TAK);
2151 Error(
"template argument (value type: matrix)");
2156 Error(
"template argument (value type: address label diff)");
2161 Error(
"template argument (value type: fixed point)");
2167void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2168 llvm::SmallString<64> TemplateMangling;
2169 llvm::raw_svector_ostream Stream(TemplateMangling);
2170 MicrosoftCXXNameMangler
Extra(Context, Stream);
2173 Extra.mangleSourceName(
"Protocol");
2174 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2176 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2179void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType
Type,
2181 SourceRange Range) {
2182 llvm::SmallString<64> TemplateMangling;
2183 llvm::raw_svector_ostream Stream(TemplateMangling);
2184 MicrosoftCXXNameMangler
Extra(Context, Stream);
2192 Extra.mangleSourceName(
"Autoreleasing");
2195 Extra.mangleSourceName(
"Strong");
2198 Extra.mangleSourceName(
"Weak");
2201 Extra.manglePointerCVQualifiers(Quals);
2202 Extra.manglePointerExtQualifiers(Quals,
Type);
2205 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2208void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *T,
2210 SourceRange Range) {
2211 llvm::SmallString<64> TemplateMangling;
2212 llvm::raw_svector_ostream Stream(TemplateMangling);
2213 MicrosoftCXXNameMangler
Extra(Context, Stream);
2216 Extra.mangleSourceName(
"KindOf");
2217 Extra.mangleType(QualType(T, 0)
2218 .stripObjCKindOfType(getASTContext())
2219 ->castAs<ObjCObjectType>(),
2222 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2225void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
2283 if (HasConst && HasVolatile) {
2285 }
else if (HasVolatile) {
2287 }
else if (HasConst) {
2293 if (HasConst && HasVolatile) {
2295 }
else if (HasVolatile) {
2297 }
else if (HasConst) {
2308MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2311 switch (RefQualifier) {
2325void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
2326 QualType PointeeType) {
2328 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2341void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {
2347 mangleNumber(PointerAuth.
getKey());
2352void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
2360 if (HasConst && HasVolatile) {
2362 }
else if (HasVolatile) {
2364 }
else if (HasConst) {
2371void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType T,
2372 SourceRange Range) {
2381 if (
const auto *DT = T->
getAs<DecayedType>()) {
2382 QualType OriginalType = DT->getOriginalType();
2385 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2386 OriginalType = getASTContext().getIncompleteArrayType(
2387 AT->getElementType(), AT->getSizeModifier(),
2388 AT->getIndexTypeCVRQualifiers());
2402 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2404 if (
Found == FunArgBackReferences.end()) {
2405 size_t OutSizeBefore =
Out.tell();
2407 mangleType(T, Range, QMM_Drop);
2412 bool LongerThanOneChar = (
Out.tell() - OutSizeBefore > 1);
2413 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2414 size_t Size = FunArgBackReferences.size();
2415 FunArgBackReferences[TypePtr] =
Size;
2422void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2423 const PassObjectSizeAttr *POSA) {
2424 int Type = POSA->getType();
2425 bool Dynamic = POSA->isDynamic();
2427 auto Iter = PassObjectSizeArgs.insert({
Type,
Dynamic}).first;
2428 auto *TypePtr = (
const void *)&*Iter;
2429 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2431 if (
Found == FunArgBackReferences.end()) {
2433 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2434 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2437 if (FunArgBackReferences.size() < 10) {
2438 size_t Size = FunArgBackReferences.size();
2439 FunArgBackReferences[TypePtr] =
Size;
2446void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
2448 SourceRange Range) {
2463 llvm::SmallString<32> ASMangling;
2464 llvm::raw_svector_ostream Stream(ASMangling);
2465 MicrosoftCXXNameMangler
Extra(Context, Stream);
2471 Extra.mangleSourceName(
"_AS");
2472 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2476 llvm_unreachable(
"Not a language specific address space");
2477 case LangAS::opencl_global:
2478 Extra.mangleSourceName(
"_ASCLglobal");
2480 case LangAS::opencl_global_device:
2481 Extra.mangleSourceName(
"_ASCLdevice");
2483 case LangAS::opencl_global_host:
2484 Extra.mangleSourceName(
"_ASCLhost");
2486 case LangAS::opencl_local:
2487 Extra.mangleSourceName(
"_ASCLlocal");
2489 case LangAS::opencl_constant:
2490 Extra.mangleSourceName(
"_ASCLconstant");
2492 case LangAS::opencl_private:
2493 Extra.mangleSourceName(
"_ASCLprivate");
2495 case LangAS::opencl_generic:
2496 Extra.mangleSourceName(
"_ASCLgeneric");
2498 case LangAS::cuda_device:
2499 Extra.mangleSourceName(
"_ASCUdevice");
2501 case LangAS::cuda_constant:
2502 Extra.mangleSourceName(
"_ASCUconstant");
2504 case LangAS::cuda_shared:
2505 Extra.mangleSourceName(
"_ASCUshared");
2507 case LangAS::ptr32_sptr:
2508 case LangAS::ptr32_uptr:
2510 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2514 Extra.mangleType(T, Range, QMM_Escape);
2515 mangleQualifiers(Qualifiers(),
false);
2516 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2519void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T,
2520 QualifierMangleMode QMM) {
2521 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2522 LangOptions::MSVC2019) &&
2523 "Cannot mangle MSVC 2017 auto return types!");
2529 if (QMM == QMM_Result)
2531 if (QMM != QMM_Drop)
2532 mangleQualifiers(Quals,
false);
2533 Out << (AT->isDecltypeAuto() ?
"_T" :
"_P");
2545 mangleQualifiers(Quals,
false);
2548 llvm_unreachable(
"QMM_Escape unexpected");
2553 case Type::MemberPointer:
2559 case Type::LValueReference:
2562 case Type::RValueReference:
2566 llvm_unreachable(
"Invalid type expected");
2570void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
2571 QualifierMangleMode QMM) {
2577 if (
const ArrayType *AT = getASTContext().getAsArrayType(T)) {
2580 if (QMM == QMM_Mangle)
2582 else if (QMM == QMM_Escape || QMM == QMM_Result)
2584 mangleArrayType(AT);
2597 if (
const FunctionType *FT = dyn_cast<FunctionType>(T)) {
2599 mangleFunctionType(FT);
2602 mangleQualifiers(Quals,
false);
2605 if (!IsPointer && Quals) {
2607 mangleQualifiers(Quals,
false);
2615 if ((!IsPointer && Quals) ||
isa<TagType>(T) || isArtificialTagType(T)) {
2617 mangleQualifiers(Quals,
false);
2625#define ABSTRACT_TYPE(CLASS, PARENT)
2626#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2628 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2630#define TYPE(CLASS, PARENT) \
2632 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2634#include "clang/AST/TypeNodes.inc"
2636#undef NON_CANONICAL_TYPE
2641void MicrosoftCXXNameMangler::mangleType(
const BuiltinType *T, Qualifiers,
2642 SourceRange Range) {
2671 case BuiltinType::Void:
2674 case BuiltinType::SChar:
2677 case BuiltinType::Char_U:
2678 case BuiltinType::Char_S:
2681 case BuiltinType::UChar:
2684 case BuiltinType::Short:
2687 case BuiltinType::UShort:
2690 case BuiltinType::Int:
2693 case BuiltinType::UInt:
2696 case BuiltinType::Long:
2699 case BuiltinType::ULong:
2702 case BuiltinType::Float:
2705 case BuiltinType::Double:
2709 case BuiltinType::LongDouble:
2712 case BuiltinType::LongLong:
2715 case BuiltinType::ULongLong:
2718 case BuiltinType::Int128:
2721 case BuiltinType::UInt128:
2724 case BuiltinType::Bool:
2727 case BuiltinType::Char8:
2730 case BuiltinType::Char16:
2733 case BuiltinType::Char32:
2736 case BuiltinType::WChar_S:
2737 case BuiltinType::WChar_U:
2741#define BUILTIN_TYPE(Id, SingletonId)
2742#define PLACEHOLDER_TYPE(Id, SingletonId) \
2743 case BuiltinType::Id:
2744#include "clang/AST/BuiltinTypes.def"
2745 case BuiltinType::Dependent:
2746 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2748 case BuiltinType::ObjCId:
2749 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2751 case BuiltinType::ObjCClass:
2752 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2754 case BuiltinType::ObjCSel:
2755 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2758#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2759 case BuiltinType::Id: \
2760 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2762#include "clang/Basic/OpenCLImageTypes.def"
2763 case BuiltinType::OCLSampler:
2765 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2767 case BuiltinType::OCLEvent:
2769 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2771 case BuiltinType::OCLClkEvent:
2773 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2775 case BuiltinType::OCLQueue:
2777 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2779 case BuiltinType::OCLReserveID:
2781 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2783#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2784 case BuiltinType::Id: \
2785 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2787#include "clang/Basic/OpenCLExtensionTypes.def"
2789 case BuiltinType::NullPtr:
2793 case BuiltinType::Float16:
2794 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2797 case BuiltinType::Half:
2798 if (!getASTContext().getLangOpts().
HLSL)
2799 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2800 else if (getASTContext().getLangOpts().NativeHalfType)
2806 case BuiltinType::BFloat16:
2807 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2810 case BuiltinType::MFloat8:
2811 mangleArtificialTagType(TagTypeKind::Struct,
"__mfp8", {
"__clang"});
2814#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2815 case BuiltinType::Id: \
2816 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2817 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2820#include "clang/Basic/WebAssemblyReferenceTypes.def"
2822#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2823 case BuiltinType::Id: \
2824 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2826#include "clang/Basic/HLSLIntangibleTypes.def"
2828#define SVE_TYPE(Name, Id, SingletonId) \
2829 case BuiltinType::Id: \
2830 mangleArtificialTagType(TagTypeKind::Struct, #Name, {"__clang"}); \
2832#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits)
2833#include "clang/Basic/AArch64ACLETypes.def"
2845void MicrosoftCXXNameMangler::mangleType(
const FunctionProtoType *T, Qualifiers,
2852 mangleFunctionType(T,
nullptr,
true);
2855 mangleFunctionType(T);
2858void MicrosoftCXXNameMangler::mangleType(
const FunctionNoProtoType *T,
2859 Qualifiers, SourceRange) {
2861 mangleFunctionType(T);
2864void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *T,
2865 const FunctionDecl *D,
2866 bool ForceThisQuals,
2867 bool MangleExceptionSpec) {
2870 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);
2875 bool IsInLambda =
false;
2876 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
2878 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
2882 HasThisQuals =
true;
2891 CC = getASTContext().getDefaultCallingConvention(
2900 manglePointerExtQualifiers(Quals, QualType());
2902 mangleQualifiers(Quals,
false);
2905 mangleCallingConvention(CC, Range);
2917 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
2926 if (IsCtorClosure) {
2936 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
2938 ->
castAs<LValueReferenceType>()
2944 llvm_unreachable(
"unexpected constructor closure!");
2950 }
else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(D)) {
2961 mangleType(ResultType, Range, QMM_Result);
2962 }
else if (IsInLambda) {
2964 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2965 "shouldn't need to mangle __auto_type!");
2969 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
2975 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2976 "shouldn't need to mangle __auto_type!");
2982 auto UseClangMangling = [](QualType ResultType) {
2983 QualType T = ResultType;
2992 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
2993 LangOptions::MSVC2019) &&
2994 !UseClangMangling(ResultType)) {
3003 ->
castAs<FunctionProtoType>();
3006 mangleAutoReturnType(ResultType, QMM_Result);
3012 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3018 mangleType(ResultType, Range, QMM_Result);
3034 for (
unsigned I = 0, E = Proto->
getNumParams(); I != E; ++I) {
3039 mangleFunctionArgumentType(Proto->
getParamType(I), Range);
3050 manglePassObjectSizeArg(P);
3059 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
3060 getASTContext().getLangOpts().isCompatibleWithMSVC(
3061 LangOptions::MSVC2017_5))
3062 mangleThrowSpecification(Proto);
3067void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
3092 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3102 llvm_unreachable(
"Unsupported access specifier");
3131void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC,
3132 SourceRange Range) {
3194 if (getASTContext().getLangOpts().RegCall4)
3203void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *T,
3204 SourceRange Range) {
3208void MicrosoftCXXNameMangler::mangleThrowSpecification(
3209 const FunctionProtoType *FT) {
3218void MicrosoftCXXNameMangler::mangleType(
const UnresolvedUsingType *T,
3219 Qualifiers, SourceRange Range) {
3230void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
3232 case TagTypeKind::Union:
3235 case TagTypeKind::Struct:
3236 case TagTypeKind::Interface:
3239 case TagTypeKind::Class:
3242 case TagTypeKind::Enum:
3247void MicrosoftCXXNameMangler::mangleType(
const EnumType *T, Qualifiers,
3251void MicrosoftCXXNameMangler::mangleType(
const RecordType *T, Qualifiers,
3255void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3265void MicrosoftCXXNameMangler::mangleArtificialTagType(
3267 ArrayRef<StringRef> NestedNames) {
3269 mangleTagTypeKind(TK);
3272 mangleSourceName(UnqualifiedName);
3274 for (StringRef N : llvm::reverse(NestedNames))
3275 mangleSourceName(N);
3288void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *T) {
3294void MicrosoftCXXNameMangler::mangleType(
const ConstantArrayType *T, Qualifiers,
3296 llvm_unreachable(
"Should have been special cased");
3298void MicrosoftCXXNameMangler::mangleType(
const VariableArrayType *T, Qualifiers,
3300 llvm_unreachable(
"Should have been special cased");
3302void MicrosoftCXXNameMangler::mangleType(
const DependentSizedArrayType *T,
3303 Qualifiers, SourceRange) {
3304 llvm_unreachable(
"Should have been special cased");
3306void MicrosoftCXXNameMangler::mangleType(
const IncompleteArrayType *T,
3307 Qualifiers, SourceRange) {
3308 llvm_unreachable(
"Should have been special cased");
3310void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *T) {
3311 QualType ElementTy(T, 0);
3312 SmallVector<llvm::APInt, 3> Dimensions;
3314 if (ElementTy->isConstantArrayType()) {
3315 const ConstantArrayType *CAT =
3316 getASTContext().getAsConstantArrayType(ElementTy);
3317 Dimensions.push_back(CAT->
getSize());
3319 }
else if (ElementTy->isIncompleteArrayType()) {
3320 const IncompleteArrayType *IAT =
3321 getASTContext().getAsIncompleteArrayType(ElementTy);
3322 Dimensions.push_back(llvm::APInt(32, 0));
3324 }
else if (ElementTy->isVariableArrayType()) {
3325 const VariableArrayType *VAT =
3326 getASTContext().getAsVariableArrayType(ElementTy);
3327 Dimensions.push_back(llvm::APInt(32, 0));
3329 }
else if (ElementTy->isDependentSizedArrayType()) {
3331 const DependentSizedArrayType *DSAT =
3332 getASTContext().getAsDependentSizedArrayType(ElementTy);
3342 mangleNumber(Dimensions.size());
3343 for (
const llvm::APInt &Dimension : Dimensions)
3344 mangleNumber(Dimension.getLimitedValue());
3345 mangleType(ElementTy, SourceRange(), QMM_Escape);
3348void MicrosoftCXXNameMangler::mangleType(
const ArrayParameterType *T,
3349 Qualifiers, SourceRange) {
3356void MicrosoftCXXNameMangler::mangleType(
const MemberPointerType *T,
3357 Qualifiers Quals, SourceRange Range) {
3359 manglePointerCVQualifiers(Quals);
3360 manglePointerExtQualifiers(Quals, PointeeType);
3361 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
3364 mangleFunctionType(FPT,
nullptr,
true);
3368 mangleType(PointeeType, Range, QMM_Drop);
3372void MicrosoftCXXNameMangler::mangleType(
const TemplateTypeParmType *T,
3373 Qualifiers, SourceRange Range) {
3376 llvm::SmallString<64> Name;
3378 Name += llvm::utostr(T->getDepth());
3380 Name += llvm::utostr(T->getIndex());
3382 mangleSourceName(Name);
3385void MicrosoftCXXNameMangler::mangleType(
const SubstTemplateTypeParmPackType *T,
3386 Qualifiers, SourceRange Range) {
3390void MicrosoftCXXNameMangler::mangleType(
const SubstBuiltinTemplatePackType *T,
3391 Qualifiers, SourceRange Range) {
3392 Error(
Range.getBegin(),
"substituted builtin template pack") <<
Range;
3398void MicrosoftCXXNameMangler::mangleType(
const PointerType *T, Qualifiers Quals,
3399 SourceRange Range) {
3401 manglePointerCVQualifiers(Quals);
3402 manglePointerExtQualifiers(Quals, PointeeType);
3403 manglePointerAuthQualifier(Quals);
3409 mangleType(PointeeType, Range);
3411 mangleAddressSpaceType(PointeeType, PointeeType.
getQualifiers(), Range);
3414void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectPointerType *T,
3415 Qualifiers Quals, SourceRange Range) {
3424 return mangleObjCLifetime(PointeeType, Quals, Range);
3426 manglePointerCVQualifiers(Quals);
3427 manglePointerExtQualifiers(Quals, PointeeType);
3428 mangleType(PointeeType, Range);
3434void MicrosoftCXXNameMangler::mangleType(
const LValueReferenceType *T,
3435 Qualifiers Quals, SourceRange Range) {
3439 manglePointerExtQualifiers(Quals, PointeeType);
3440 mangleType(PointeeType, Range);
3446void MicrosoftCXXNameMangler::mangleType(
const RValueReferenceType *T,
3447 Qualifiers Quals, SourceRange Range) {
3451 manglePointerExtQualifiers(Quals, PointeeType);
3452 mangleType(PointeeType, Range);
3455void MicrosoftCXXNameMangler::mangleType(
const ComplexType *T, Qualifiers,
3456 SourceRange Range) {
3459 llvm::SmallString<64> TemplateMangling;
3460 llvm::raw_svector_ostream Stream(TemplateMangling);
3461 MicrosoftCXXNameMangler
Extra(Context, Stream);
3463 Extra.mangleSourceName(
"_Complex");
3464 Extra.mangleType(ElementType, Range, QMM_Escape);
3466 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3474bool MicrosoftCXXNameMangler::isArtificialTagType(QualType T)
const {
3480 case Type::Vector: {
3489void MicrosoftCXXNameMangler::mangleType(
const VectorType *T, Qualifiers Quals,
3490 SourceRange Range) {
3492 const BuiltinType *ET = EltTy->
getAs<BuiltinType>();
3493 const BitIntType *BitIntTy = EltTy->
getAs<BitIntType>();
3494 assert((ET || BitIntTy) &&
3495 "vectors with non-builtin/_BitInt elements are unsupported");
3496 uint64_t Width = getASTContext().getTypeSize(T);
3499 size_t OutSizeBefore =
Out.tell();
3501 if (getASTContext().getTargetInfo().
getTriple().isX86() && ET) {
3502 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3503 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3504 }
else if (Width >= 128) {
3505 if (ET->
getKind() == BuiltinType::Float)
3506 mangleArtificialTagType(TagTypeKind::Union,
3507 "__m" + llvm::utostr(Width));
3508 else if (ET->
getKind() == BuiltinType::LongLong)
3509 mangleArtificialTagType(TagTypeKind::Union,
3510 "__m" + llvm::utostr(Width) +
'i');
3511 else if (ET->
getKind() == BuiltinType::Double)
3512 mangleArtificialTagType(TagTypeKind::Struct,
3513 "__m" + llvm::utostr(Width) +
'd');
3518 bool IsBuiltin =
Out.tell() != OutSizeBefore;
3524 llvm::SmallString<64> TemplateMangling;
3525 llvm::raw_svector_ostream Stream(TemplateMangling);
3526 MicrosoftCXXNameMangler
Extra(Context, Stream);
3528 Extra.mangleSourceName(
"__vector");
3529 Extra.mangleType(QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3533 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3537void MicrosoftCXXNameMangler::mangleType(
const ExtVectorType *T,
3538 Qualifiers Quals, SourceRange Range) {
3539 mangleType(
static_cast<const VectorType *
>(T), Quals, Range);
3542void MicrosoftCXXNameMangler::mangleType(
const DependentVectorType *T,
3543 Qualifiers, SourceRange Range) {
3547void MicrosoftCXXNameMangler::mangleType(
const DependentSizedExtVectorType *T,
3548 Qualifiers, SourceRange Range) {
3549 Error(
Range.getBegin(),
"dependent-sized extended vector type") <<
Range;
3552void MicrosoftCXXNameMangler::mangleType(
const ConstantMatrixType *T,
3553 Qualifiers quals, SourceRange Range) {
3556 llvm::SmallString<64> TemplateMangling;
3557 llvm::raw_svector_ostream Stream(TemplateMangling);
3558 MicrosoftCXXNameMangler
Extra(Context, Stream);
3562 Extra.mangleSourceName(
"__matrix");
3563 Extra.mangleType(EltTy, Range, QMM_Escape);
3565 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->
getNumRows()));
3568 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3571void MicrosoftCXXNameMangler::mangleType(
const DependentSizedMatrixType *T,
3572 Qualifiers quals, SourceRange Range) {
3576void MicrosoftCXXNameMangler::mangleType(
const DependentAddressSpaceType *T,
3577 Qualifiers, SourceRange Range) {
3581void MicrosoftCXXNameMangler::mangleType(
const ObjCInterfaceType *T, Qualifiers,
3584 mangleTagTypeKind(TagTypeKind::Struct);
3588void MicrosoftCXXNameMangler::mangleType(
const ObjCObjectType *T,
3589 Qualifiers Quals, SourceRange Range) {
3590 if (T->isKindOfType())
3591 return mangleObjCKindOfType(T, Quals, Range);
3593 if (T->qual_empty() && !T->isSpecialized())
3594 return mangleType(T->getBaseType(), Range, QMM_Drop);
3596 ArgBackRefMap OuterFunArgsContext;
3597 ArgBackRefMap OuterTemplateArgsContext;
3598 BackRefVec OuterTemplateContext;
3600 FunArgBackReferences.swap(OuterFunArgsContext);
3601 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3602 NameBackReferences.swap(OuterTemplateContext);
3604 mangleTagTypeKind(TagTypeKind::Struct);
3608 mangleSourceName(
"objc_object");
3609 else if (T->isObjCClass())
3610 mangleSourceName(
"objc_class");
3612 mangleSourceName(T->getInterface()->getName());
3614 for (
const auto &Q : T->quals())
3615 mangleObjCProtocol(Q);
3617 if (T->isSpecialized())
3618 for (
const auto &TA : T->getTypeArgs())
3619 mangleType(TA, Range, QMM_Drop);
3625 FunArgBackReferences.swap(OuterFunArgsContext);
3626 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3627 NameBackReferences.swap(OuterTemplateContext);
3630void MicrosoftCXXNameMangler::mangleType(
const BlockPointerType *T,
3631 Qualifiers Quals, SourceRange Range) {
3633 manglePointerCVQualifiers(Quals);
3634 manglePointerExtQualifiers(Quals, PointeeType);
3638 mangleFunctionType(PointeeType->
castAs<FunctionProtoType>());
3641void MicrosoftCXXNameMangler::mangleType(
const InjectedClassNameType *,
3642 Qualifiers, SourceRange) {
3643 llvm_unreachable(
"Cannot mangle injected class name type.");
3646void MicrosoftCXXNameMangler::mangleType(
const TemplateSpecializationType *T,
3647 Qualifiers, SourceRange Range) {
3651void MicrosoftCXXNameMangler::mangleType(
const DependentNameType *T, Qualifiers,
3652 SourceRange Range) {
3656void MicrosoftCXXNameMangler::mangleType(
const PackExpansionType *T, Qualifiers,
3657 SourceRange Range) {
3661void MicrosoftCXXNameMangler::mangleType(
const PackIndexingType *T,
3662 Qualifiers Quals, SourceRange Range) {
3663 manglePointerCVQualifiers(Quals);
3664 mangleType(T->getSelectedType(), Range);
3667void MicrosoftCXXNameMangler::mangleType(
const TypeOfType *T, Qualifiers,
3668 SourceRange Range) {
3672void MicrosoftCXXNameMangler::mangleType(
const TypeOfExprType *T, Qualifiers,
3673 SourceRange Range) {
3677void MicrosoftCXXNameMangler::mangleType(
const DecltypeType *T, Qualifiers,
3678 SourceRange Range) {
3682void MicrosoftCXXNameMangler::mangleType(
const UnaryTransformType *T,
3683 Qualifiers, SourceRange Range) {
3687void MicrosoftCXXNameMangler::mangleType(
const AutoType *T, Qualifiers,
3688 SourceRange Range) {
3689 assert(T->getDeducedType().isNull() &&
"expecting a dependent type!");
3694void MicrosoftCXXNameMangler::mangleType(
3695 const DeducedTemplateSpecializationType *T, Qualifiers, SourceRange Range) {
3696 assert(T->getDeducedType().isNull() &&
"expecting a dependent type!");
3698 Error(
Range.getBegin(),
"deduced class template specialization type")
3702void MicrosoftCXXNameMangler::mangleType(
const AtomicType *T, Qualifiers,
3703 SourceRange Range) {
3706 llvm::SmallString<64> TemplateMangling;
3707 llvm::raw_svector_ostream Stream(TemplateMangling);
3708 MicrosoftCXXNameMangler
Extra(Context, Stream);
3710 Extra.mangleSourceName(
"_Atomic");
3711 Extra.mangleType(ValueType, Range, QMM_Escape);
3713 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3716void MicrosoftCXXNameMangler::mangleType(
const PipeType *T, Qualifiers,
3717 SourceRange Range) {
3720 llvm::SmallString<64> TemplateMangling;
3721 llvm::raw_svector_ostream Stream(TemplateMangling);
3722 MicrosoftCXXNameMangler
Extra(Context, Stream);
3724 Extra.mangleSourceName(
"ocl_pipe");
3725 Extra.mangleType(ElementType, Range, QMM_Escape);
3728 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3731void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
3734 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
3735 getASTContext().getSourceManager(),
3736 "Mangling declaration");
3738 msvc_hashing_ostream MHO(Out);
3740 if (
auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3742 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3743 return mangler.mangle(GD);
3746 if (
auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3748 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3749 return mangler.mangle(GD);
3752 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3753 return Mangler.mangle(GD);
3756void MicrosoftCXXNameMangler::mangleType(
const BitIntType *T, Qualifiers,
3757 SourceRange Range) {
3758 llvm::SmallString<64> TemplateMangling;
3759 llvm::raw_svector_ostream Stream(TemplateMangling);
3760 MicrosoftCXXNameMangler
Extra(Context, Stream);
3763 Extra.mangleSourceName(
"_UBitInt");
3765 Extra.mangleSourceName(
"_BitInt");
3766 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->
getNumBits()));
3768 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3771void MicrosoftCXXNameMangler::mangleType(
const DependentBitIntType *T,
3772 Qualifiers, SourceRange Range) {
3776void MicrosoftCXXNameMangler::mangleType(
const HLSLAttributedResourceType *T,
3777 Qualifiers, SourceRange Range) {
3778 llvm_unreachable(
"HLSL uses Itanium name mangling");
3781void MicrosoftCXXNameMangler::mangleType(
const HLSLInlineSpirvType *T,
3782 Qualifiers, SourceRange Range) {
3783 llvm_unreachable(
"HLSL uses Itanium name mangling");
3786void MicrosoftCXXNameMangler::mangleType(
const OverflowBehaviorType *T,
3787 Qualifiers, SourceRange Range) {
3788 QualType UnderlyingType = T->getUnderlyingType();
3790 llvm::SmallString<64> TemplateMangling;
3791 llvm::raw_svector_ostream Stream(TemplateMangling);
3792 MicrosoftCXXNameMangler
Extra(Context, Stream);
3794 if (T->isWrapKind()) {
3795 Extra.mangleSourceName(
"ObtWrap_");
3797 Extra.mangleSourceName(
"ObtTrap_");
3799 Extra.mangleType(UnderlyingType, Range, QMM_Escape);
3801 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3830 MicrosoftCXXNameMangler &Mangler,
3837 llvm_unreachable(
"Unsupported access specifier");
3848 Out <<
'R' << AccessSpec;
3849 Mangler.mangleNumber(
3851 Mangler.mangleNumber(
3853 Mangler.mangleNumber(
3855 Mangler.mangleNumber(
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3858 Mangler.mangleNumber(
3860 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3865 llvm_unreachable(
"Unsupported access specifier");
3875 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3879 llvm_unreachable(
"Unsupported access specifier");
3892void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
3893 const CXXMethodDecl *MD,
const MethodVFTableLocation &ML,
3895 msvc_hashing_ostream MHO(Out);
3896 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3897 Mangler.getStream() <<
'?';
3898 Mangler.mangleVirtualMemPtrThunk(MD, ML);
3901void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
3902 const ThunkInfo &Thunk,
3905 msvc_hashing_ostream MHO(Out);
3906 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3907 Mangler.getStream() <<
'?';
3908 Mangler.mangleName(MD);
3917 assert(Thunk.
Method !=
nullptr &&
3918 "Thunk info should hold the overridee decl");
3920 const CXXMethodDecl *DeclForFPT = Thunk.
Method ? Thunk.
Method : MD;
3921 Mangler.mangleFunctionType(
3925void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
const CXXDestructorDecl *DD,
3927 const ThunkInfo &Thunk,
3934 msvc_hashing_ostream MHO(Out);
3935 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
3936 Mangler.getStream() <<
"??_E";
3938 auto &Adjustment = Thunk.
This;
3940 Mangler.mangleFunctionType(DD->
getType()->
castAs<FunctionProtoType>(), DD);
3943void MicrosoftMangleContextImpl::mangleCXXVFTable(
3944 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
3950 msvc_hashing_ostream MHO(Out);
3951 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3952 if (Derived->
hasAttr<DLLImportAttr>())
3953 Mangler.getStream() <<
"??_S";
3955 Mangler.getStream() <<
"??_7";
3956 Mangler.mangleName(Derived);
3957 Mangler.getStream() <<
"6B";
3958 for (
const CXXRecordDecl *RD : BasePath)
3959 Mangler.mangleName(RD);
3960 Mangler.getStream() <<
'@';
3963void MicrosoftMangleContextImpl::mangleCXXVTable(
const CXXRecordDecl *Derived,
3966 mangleCXXVFTable(Derived, {},
Out);
3969void MicrosoftMangleContextImpl::mangleCXXVBTable(
3970 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
3976 msvc_hashing_ostream MHO(Out);
3977 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3978 Mangler.getStream() <<
"??_8";
3979 Mangler.mangleName(Derived);
3980 Mangler.getStream() <<
"7B";
3981 for (
const CXXRecordDecl *RD : BasePath)
3982 Mangler.mangleName(RD);
3983 Mangler.getStream() <<
'@';
3986void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
3987 msvc_hashing_ostream MHO(Out);
3988 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3989 Mangler.getStream() <<
"??_R0";
3990 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3991 Mangler.getStream() <<
"@8";
3994void MicrosoftMangleContextImpl::mangleCXXRTTIName(
3995 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
3996 MicrosoftCXXNameMangler Mangler(*
this, Out);
3997 Mangler.getStream() <<
'.';
3998 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4001void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
4002 const CXXRecordDecl *SrcRD,
const CXXRecordDecl *DstRD, raw_ostream &Out) {
4003 msvc_hashing_ostream MHO(Out);
4004 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4005 Mangler.getStream() <<
"??_K";
4006 Mangler.mangleName(SrcRD);
4007 Mangler.getStream() <<
"$C";
4008 Mangler.mangleName(DstRD);
4011void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T,
bool IsConst,
4014 uint32_t NumEntries,
4016 msvc_hashing_ostream MHO(Out);
4017 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4018 Mangler.getStream() <<
"_TI";
4020 Mangler.getStream() <<
'C';
4022 Mangler.getStream() <<
'V';
4024 Mangler.getStream() <<
'U';
4025 Mangler.getStream() << NumEntries;
4026 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4029void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
4030 QualType T, uint32_t NumEntries, raw_ostream &Out) {
4031 msvc_hashing_ostream MHO(Out);
4032 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4033 Mangler.getStream() <<
"_CTA";
4034 Mangler.getStream() << NumEntries;
4035 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4038void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4039 QualType T,
const CXXConstructorDecl *CD,
CXXCtorType CT, uint32_t Size,
4040 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
4042 MicrosoftCXXNameMangler Mangler(*
this, Out);
4043 Mangler.getStream() <<
"_CT";
4045 llvm::SmallString<64> RTTIMangling;
4047 llvm::raw_svector_ostream Stream(RTTIMangling);
4048 msvc_hashing_ostream MHO(Stream);
4049 mangleCXXRTTI(T, MHO);
4051 Mangler.getStream() << RTTIMangling;
4059 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4060 LangOptions::MSVC2015) &&
4061 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4062 LangOptions::MSVC2017_7);
4063 llvm::SmallString<64> CopyCtorMangling;
4064 if (!OmitCopyCtor && CD) {
4065 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4066 msvc_hashing_ostream MHO(Stream);
4067 mangleCXXName(GlobalDecl(CD, CT), MHO);
4069 Mangler.getStream() << CopyCtorMangling;
4071 Mangler.getStream() <<
Size;
4072 if (VBPtrOffset == -1) {
4074 Mangler.getStream() << NVOffset;
4077 Mangler.getStream() << NVOffset;
4078 Mangler.getStream() << VBPtrOffset;
4079 Mangler.getStream() << VBIndex;
4083void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4084 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
4085 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
4086 msvc_hashing_ostream MHO(Out);
4087 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4088 Mangler.getStream() <<
"??_R1";
4089 Mangler.mangleNumber(NVOffset);
4090 Mangler.mangleNumber(VBPtrOffset);
4091 Mangler.mangleNumber(VBTableOffset);
4092 Mangler.mangleNumber(Flags);
4093 Mangler.mangleName(Derived);
4094 Mangler.getStream() <<
"8";
4097void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4098 const CXXRecordDecl *Derived, raw_ostream &Out) {
4099 msvc_hashing_ostream MHO(Out);
4100 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4101 Mangler.getStream() <<
"??_R2";
4102 Mangler.mangleName(Derived);
4103 Mangler.getStream() <<
"8";
4106void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4107 const CXXRecordDecl *Derived, raw_ostream &Out) {
4108 msvc_hashing_ostream MHO(Out);
4109 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4110 Mangler.getStream() <<
"??_R3";
4111 Mangler.mangleName(Derived);
4112 Mangler.getStream() <<
"8";
4115void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4116 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4122 llvm::SmallString<64> VFTableMangling;
4123 llvm::raw_svector_ostream Stream(VFTableMangling);
4124 mangleCXXVFTable(Derived, BasePath, Stream);
4126 if (VFTableMangling.starts_with(
"??@")) {
4127 assert(VFTableMangling.ends_with(
"@"));
4128 Out << VFTableMangling <<
"??_R4@";
4132 assert(VFTableMangling.starts_with(
"??_7") ||
4133 VFTableMangling.starts_with(
"??_S"));
4135 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
4138void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4139 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4140 msvc_hashing_ostream MHO(Out);
4141 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4146 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
4147 Mangler.mangleName(EnclosingDecl);
4150void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4151 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4152 msvc_hashing_ostream MHO(Out);
4153 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4158 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
4159 Mangler.mangleName(EnclosingDecl);
4162void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4163 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4166 MicrosoftCXXNameMangler Mangler(*
this, Out);
4167 Mangler.getStream() <<
'?';
4171void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4172 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
4173 msvc_hashing_ostream MHO(Out);
4174 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4176 Mangler.getStream() <<
"?";
4177 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
4178 Mangler.mangle(VD,
"");
4181void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4182 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
4183 msvc_hashing_ostream MHO(Out);
4184 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4186 Mangler.getStream() <<
"?";
4187 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
4188 Mangler.mangleNestedName(VD);
4189 Mangler.getStream() <<
"@4HA";
4192void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
4204 msvc_hashing_ostream MHO(Out);
4205 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4209 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
4211 Mangler.getStream() <<
"?$S1@";
4213 unsigned ScopeDepth = 0;
4214 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4218 Mangler.mangle(VD,
"");
4220 Mangler.mangleNestedName(VD);
4221 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
4223 Mangler.mangleNumber(ScopeDepth);
4226void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *D,
4229 msvc_hashing_ostream MHO(Out);
4230 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4231 Mangler.getStream() <<
"??__" << CharCode;
4233 Mangler.getStream() <<
'?';
4234 Mangler.mangleName(D);
4235 Mangler.mangleVariableEncoding(D);
4236 Mangler.getStream() <<
"@@";
4238 Mangler.mangleName(D);
4242 Mangler.getStream() <<
"YAXXZ";
4245void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *D,
4248 mangleInitFiniStub(D,
'E', Out);
4252MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *D,
4255 mangleInitFiniStub(D,
'F', Out);
4258void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4279 MicrosoftCXXNameMangler Mangler(*
this, Out);
4280 Mangler.getStream() <<
"??_C@_";
4288 unsigned StringLength =
4289 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4294 Mangler.getStream() <<
'1';
4296 Mangler.getStream() <<
'0';
4300 Mangler.mangleNumber(StringByteLength);
4302 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4304 if (Index / CharByteWidth >= SL->
getLength())
4305 return static_cast<char>(0);
4307 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4308 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4311 auto GetBigEndianByte = [&SL](
unsigned Index) {
4313 if (Index / CharByteWidth >= SL->
getLength())
4314 return static_cast<char>(0);
4316 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4317 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4322 for (
unsigned I = 0, E = StringByteLength; I != E; ++I)
4323 JC.update(GetLittleEndianByte(I));
4327 Mangler.mangleNumber(JC.getCRC());
4333 auto MangleByte = [&Mangler](
char Byte) {
4341 Mangler.getStream() << Byte;
4342 }
else if (
isLetter(Byte & 0x7f)) {
4343 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4345 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4346 ' ',
'\n',
'\t',
'\'',
'-'};
4347 const char *Pos = llvm::find(SpecialChars, Byte);
4348 if (Pos != std::end(SpecialChars)) {
4349 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4351 Mangler.getStream() <<
"?$";
4352 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4353 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4359 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4360 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4361 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4363 MangleByte(GetBigEndianByte(I));
4365 MangleByte(GetLittleEndianByte(I));
4368 Mangler.getStream() <<
'@';
4371void MicrosoftCXXNameMangler::mangleAutoReturnType(
const MemberPointerType *T,
4374 manglePointerCVQualifiers(Quals);
4375 manglePointerExtQualifiers(Quals, PointeeType);
4376 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4379 mangleFunctionType(FPT,
nullptr,
true);
4383 mangleAutoReturnType(PointeeType, QMM_Drop);
4387void MicrosoftCXXNameMangler::mangleAutoReturnType(
const PointerType *T,
4391 "Unexpected address space mangling required");
4393 manglePointerCVQualifiers(Quals);
4394 manglePointerExtQualifiers(Quals, PointeeType);
4396 if (
const FunctionProtoType *FPT = PointeeType->
getAs<FunctionProtoType>()) {
4398 mangleFunctionType(FPT);
4400 mangleAutoReturnType(PointeeType, QMM_Mangle);
4404void MicrosoftCXXNameMangler::mangleAutoReturnType(
const LValueReferenceType *T,
4409 manglePointerExtQualifiers(Quals, PointeeType);
4410 mangleAutoReturnType(PointeeType, QMM_Mangle);
4413void MicrosoftCXXNameMangler::mangleAutoReturnType(
const RValueReferenceType *T,
4418 manglePointerExtQualifiers(Quals, PointeeType);
4419 mangleAutoReturnType(PointeeType, QMM_Mangle);
4425 return new MicrosoftMangleContextImpl(Context, Diags, IsAux);
Enums/classes describing ABI related information about constructors, destructors and thunks.
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
static const GlobalDecl isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs)
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
llvm::MachO::Record Record
static ValueDecl * getAsArrayToPointerDecayedDecl(QualType T, const APValue &V)
If value V (with type T) represents a decayed pointer to the first element of an array,...
static void mangleThunkThisAdjustment(AccessSpecifier AS, const ThisAdjustment &Adjustment, MicrosoftCXXNameMangler &Mangler, raw_ostream &Out)
static StringRef getTriple(const Command &Job)
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 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...
void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName, bool useDirectABI)
Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
LanguageLinkage
Describes the different kinds of language linkage (C++ [dcl.link]) that an entity may have.
bool inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance)
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
bool inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance)
@ Result
The result type of a method or function.
CXXDtorType
C++ destructor types.
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
TagTypeKind
The kind of a tag type.
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool isPtrSizeAddressSpace(LangAS AS)
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
int const char * function
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...