31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/StringExtras.h"
33#include "llvm/Support/CRC.h"
34#include "llvm/Support/MD5.h"
35#include "llvm/Support/StringSaver.h"
36#include "llvm/Support/xxhash.h"
47 if (
auto *CD = dyn_cast<CXXConstructorDecl>(DC))
49 else if (
auto *DD = dyn_cast<CXXDestructorDecl>(DC))
56struct msvc_hashing_ostream :
public llvm::raw_svector_ostream {
60 msvc_hashing_ostream(raw_ostream &OS)
61 :
llvm::raw_svector_ostream(Buffer), OS(OS) {}
62 ~msvc_hashing_ostream()
override {
63 StringRef MangledName = str();
64 bool StartsWithEscape = MangledName.starts_with(
"\01");
66 MangledName = MangledName.drop_front(1);
67 if (MangledName.size() < 4096) {
73 llvm::MD5::MD5Result Hash;
74 Hasher.update(MangledName);
78 llvm::MD5::stringifyResult(Hash, HexString);
82 OS <<
"??@" << HexString <<
'@';
87getLambdaDefaultArgumentDeclContext(
const Decl *
D) {
88 if (
const auto *RD = dyn_cast<CXXRecordDecl>(
D))
90 if (
const auto *Parm =
91 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
92 return Parm->getDeclContext();
105 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(
D))
109 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(
D)) {
111 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
112 return ContextParam->getDeclContext();
116 if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||
117 isa<OMPDeclareMapperDecl>(DC)) {
118 return getEffectiveDeclContext(cast<Decl>(DC));
125 return getEffectiveDeclContext(cast<Decl>(DC));
129 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
132 const auto *FD = cast<FunctionDecl>(ND);
133 if (
const auto *FTD = FD->getPrimaryTemplate())
134 return FTD->getTemplatedDecl()->getCanonicalDecl();
136 return FD->getCanonicalDecl();
142 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
143 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
144 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
145 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
146 llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
147 llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
158 raw_ostream &Out)
override;
160 bool ElideOverrideInfo, raw_ostream &)
override;
162 const ThunkInfo &Thunk,
bool ElideOverrideInfo,
163 raw_ostream &)
override;
166 raw_ostream &Out)
override;
169 raw_ostream &Out)
override;
174 raw_ostream &Out)
override;
176 bool IsUnaligned, uint32_t NumEntries,
177 raw_ostream &Out)
override;
179 raw_ostream &Out)
override;
182 int32_t VBPtrOffset, uint32_t VBIndex,
183 raw_ostream &Out)
override;
186 bool NormalizeIntegers)
override;
188 uint32_t NVOffset, int32_t VBPtrOffset,
189 uint32_t VBTableOffset, uint32_t Flags,
190 raw_ostream &Out)
override;
192 raw_ostream &Out)
override;
194 raw_ostream &Out)
override;
198 raw_ostream &Out)
override;
200 bool NormalizeIntegers)
override;
202 raw_ostream &)
override;
205 raw_ostream &Out)
override;
208 raw_ostream &Out)
override;
210 raw_ostream &Out)
override;
212 raw_ostream &Out)
override;
214 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
215 const DeclContext *DC = getEffectiveDeclContext(ND);
221 if (
const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
222 if (RD->isLambda()) {
235 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
236 if (!
Tag->hasNameForLinkage() &&
237 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
243 unsigned &discriminator = Uniquifier[ND];
245 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
246 disc = discriminator + 1;
251 assert(Lambda->
isLambda() &&
"RD must be a lambda!");
252 std::string Name(
"<lambda_");
257 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
262 unsigned DefaultArgNo =
264 Name += llvm::utostr(DefaultArgNo);
268 if (LambdaManglingNumber)
269 LambdaId = LambdaManglingNumber;
271 LambdaId = getLambdaIdForDebugInfo(Lambda);
273 Name += llvm::utostr(LambdaId);
279 assert(RD->
isLambda() &&
"RD must be a lambda!");
282 "RD must not have a mangling number!");
283 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator,
bool>
284 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
285 return Result.first->second;
289 assert(RD->
isLambda() &&
"RD must be a lambda!");
292 "RD must not have a mangling number!");
294 return LambdaIds.lookup(RD);
299 StringRef getAnonymousNamespaceHash()
const {
300 return AnonymousNamespaceHash;
304 void mangleInitFiniStub(
const VarDecl *
D,
char CharCode, raw_ostream &Out);
309class MicrosoftCXXNameMangler {
310 MicrosoftMangleContextImpl &Context;
317 unsigned StructorType;
320 BackRefVec NameBackReferences;
322 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
323 ArgBackRefMap FunArgBackReferences;
324 ArgBackRefMap TemplateArgBackReferences;
326 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
327 TemplateArgStringMap TemplateArgStrings;
328 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
329 llvm::StringSaver TemplateArgStringStorage;
331 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
332 PassObjectSizeArgsSet PassObjectSizeArgs;
334 ASTContext &getASTContext()
const {
return Context.getASTContext(); }
336 const bool PointersAre64Bit;
343 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
344 enum class TplArgKind { ClassNTTP, StructuralValue };
346 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_)
347 : Context(
C), Out(Out_), Structor(nullptr), StructorType(-1),
348 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
349 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
352 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
354 : Context(
C), Out(Out_), Structor(getStructor(
D)), StructorType(
Type),
355 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
356 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
359 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
361 : Context(
C), Out(Out_), Structor(getStructor(
D)), StructorType(
Type),
362 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
363 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
366 raw_ostream &getStream()
const {
return Out; }
368 void mangle(
GlobalDecl GD, StringRef Prefix =
"?");
370 void mangleFunctionEncoding(
GlobalDecl GD,
bool ShouldMangle);
371 void mangleVariableEncoding(
const VarDecl *VD);
375 StringRef Prefix =
"$");
376 void mangleMemberDataPointerInClassNTTP(
const CXXRecordDecl *,
382 StringRef Prefix =
"$");
388 void mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD,
392 void mangleNumber(int64_t Number);
393 void mangleNumber(llvm::APSInt Number);
394 void mangleFloat(llvm::APFloat Number);
395 void mangleBits(llvm::APInt Number);
397 void mangleArtificialTagType(
TagTypeKind TK, StringRef UnqualifiedName,
401 QualifierMangleMode QMM = QMM_Mangle);
404 bool ForceThisQuals =
false,
405 bool MangleExceptionSpec =
true);
406 void mangleSourceName(StringRef Name);
409 void mangleAutoReturnType(
QualType T, QualifierMangleMode QMM);
412 bool isStructorDecl(
const NamedDecl *ND)
const {
413 return ND == Structor || getStructor(ND) == Structor;
418 return AddrSpace == LangAS::ptr64 ||
419 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||
420 AddrSpace == LangAS::ptr32_uptr));
424 mangleUnqualifiedName(GD, cast<NamedDecl>(GD.
getDecl())->getDeclName());
429 void mangleQualifiers(
Qualifiers Quals,
bool IsMember);
431 void manglePointerCVQualifiers(
Qualifiers Quals);
433 void manglePointerAuthQualifier(
Qualifiers Quals);
435 void mangleUnscopedTemplateName(
GlobalDecl GD);
437 mangleTemplateInstantiationName(
GlobalDecl GD,
442 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
444 bool isArtificialTagType(
QualType T)
const;
447#define ABSTRACT_TYPE(CLASS, PARENT)
448#define NON_CANONICAL_TYPE(CLASS, PARENT)
449#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
452#include "clang/AST/TypeNodes.inc"
454#undef NON_CANONICAL_TYPE
457 void mangleType(
const TagDecl *TD);
458 void mangleDecayedArrayType(
const ArrayType *
T);
463 void mangleIntegerLiteral(
const llvm::APSInt &Number,
474 bool WithScalarType =
false);
489MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(
ASTContext &Context,
511 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
514 AnonymousNamespaceHash =
"0";
518bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *
D) {
522 if (FD->hasAttr<OverloadableAttr>())
534 if (FD->isMSVCRTEntryPoint())
548 if (!getASTContext().getLangOpts().
CPlusPlus)
551 const VarDecl *VD = dyn_cast<VarDecl>(
D);
552 if (VD && !isa<DecompositionDecl>(
D)) {
562 DC = getEffectiveParentContext(DC);
565 !isa<VarTemplateSpecializationDecl>(
D) &&
D->getIdentifier() !=
nullptr)
573MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
582 "cannot mangle this %0 %1 yet");
583 return Diags.
Report(loc, DiagID) << thing1 << thing2;
590 "cannot mangle this %0 yet");
591 return Diags.
Report(loc, DiagID) << thingy;
598 "cannot mangle this %0 yet");
599 return Diags.
Report(DiagID) << thingy;
602void MicrosoftCXXNameMangler::mangle(
GlobalDecl GD, StringRef Prefix) {
614 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
615 else if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
616 mangleVariableEncoding(VD);
617 else if (isa<MSGuidDecl>(
D))
620 Out <<
"3U__s_GUID@@B";
621 else if (isa<TemplateParamObjectDecl>(
D)) {
625 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
628void MicrosoftCXXNameMangler::mangleFunctionEncoding(
GlobalDecl GD,
653 mangleFunctionClass(FD);
655 mangleFunctionType(FT, FD,
false,
false);
661void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
692 mangleType(Ty, SR, QMM_Drop);
693 manglePointerExtQualifiers(
696 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
699 mangleName(MPT->getMostRecentCXXRecordDecl());
702 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
704 mangleDecayedArrayType(AT);
705 if (AT->getElementType()->isArrayType())
710 mangleType(Ty, SR, QMM_Drop);
715void MicrosoftCXXNameMangler::mangleMemberDataPointer(
731 FieldOffset = getASTContext().getFieldOffset(VD);
732 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
733 "cannot take address of bitfield");
734 FieldOffset /= getASTContext().getCharWidth();
738 if (IM == MSInheritanceModel::Virtual)
739 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
748 case MSInheritanceModel::Single: Code =
'0';
break;
749 case MSInheritanceModel::Multiple: Code =
'0';
break;
750 case MSInheritanceModel::Virtual: Code =
'F';
break;
751 case MSInheritanceModel::Unspecified: Code =
'G';
break;
757 getASTContext().getLangOpts().isCompatibleWithMSVC(
758 LangOptions::MSVC2019) &&
760 !TemplateArgType.
isNull()) {
762 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
767 mangleNumber(FieldOffset);
775 mangleNumber(VBTableOffset);
778void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
785 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
786 return mangleMemberDataPointer(RD, VD,
nullptr,
QualType(),
"");
794 mangleNestedName(VD);
796 mangleUnqualifiedName(VD);
800void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
818 case MSInheritanceModel::Single: Code =
'1';
break;
819 case MSInheritanceModel::Multiple: Code =
'H';
break;
820 case MSInheritanceModel::Virtual: Code =
'I';
break;
821 case MSInheritanceModel::Unspecified: Code =
'J';
break;
832 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
833 LangOptions::MSVC2019) &&
835 !TemplateArgType.
isNull()) {
837 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
843 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
846 mangleVirtualMemPtrThunk(MD, ML);
850 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
855 mangleFunctionEncoding(MD,
true);
858 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
859 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
862 if (IM == MSInheritanceModel::Single) {
863 Out << Prefix <<
"0A@";
866 if (IM == MSInheritanceModel::Unspecified)
868 Out << Prefix << Code;
872 mangleNumber(
static_cast<uint32_t>(NVOffset));
874 mangleNumber(VBPtrOffset);
876 mangleNumber(VBTableOffset);
879void MicrosoftCXXNameMangler::mangleFunctionPointer(
888 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
889 LangOptions::MSVC2019) &&
891 !TemplateArgType.
isNull()) {
893 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
898 mangleFunctionEncoding(FD,
true);
901void MicrosoftCXXNameMangler::mangleVarDecl(
const VarDecl *VD,
910 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
911 LangOptions::MSVC2019) &&
913 !TemplateArgType.
isNull()) {
915 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
920 mangleVariableEncoding(VD);
923void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
932 return mangleMemberFunctionPointer(RD, MD,
nullptr,
QualType(),
"");
941 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
944 mangleVirtualMemPtrThunk(MD, ML);
947 mangleFunctionEncoding(MD,
true);
951void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
954 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
955 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
961 mangleNumber(OffsetInVFTable);
967void MicrosoftCXXNameMangler::mangleName(
GlobalDecl GD) {
971 mangleUnqualifiedName(GD);
973 mangleNestedName(GD);
979void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
980 mangleNumber(llvm::APSInt(llvm::APInt(64, Number),
false));
983void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
988 unsigned Width = std::max(Number.getBitWidth(), 64U);
989 llvm::APInt
Value = Number.extend(Width);
997 if (
Value.isNegative()) {
1004void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
1005 using llvm::APFloat;
1007 switch (APFloat::SemanticsToEnum(Number.getSemantics())) {
1008 case APFloat::S_IEEEsingle: Out <<
'A';
break;
1009 case APFloat::S_IEEEdouble: Out <<
'B';
break;
1013 case APFloat::S_IEEEhalf: Out <<
'V';
break;
1014 case APFloat::S_BFloat: Out <<
'W';
break;
1015 case APFloat::S_x87DoubleExtended: Out <<
'X';
break;
1016 case APFloat::S_IEEEquad: Out <<
'Y';
break;
1017 case APFloat::S_PPCDoubleDouble: Out <<
'Z';
break;
1018 case APFloat::S_PPCDoubleDoubleLegacy:
1019 case APFloat::S_Float8E5M2:
1020 case APFloat::S_Float8E4M3:
1021 case APFloat::S_Float8E4M3FN:
1022 case APFloat::S_Float8E5M2FNUZ:
1023 case APFloat::S_Float8E4M3FNUZ:
1024 case APFloat::S_Float8E4M3B11FNUZ:
1025 case APFloat::S_Float8E3M4:
1026 case APFloat::S_FloatTF32:
1027 case APFloat::S_Float8E8M0FNU:
1028 case APFloat::S_Float6E3M2FN:
1029 case APFloat::S_Float6E2M3FN:
1030 case APFloat::S_Float4E2M1FN:
1031 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
1034 mangleBits(Number.bitcastToAPInt());
1037void MicrosoftCXXNameMangler::mangleBits(llvm::APInt
Value) {
1048 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
1049 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1050 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1059 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1068 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1069 TemplateArgs = &Spec->getTemplateArgs();
1070 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1075 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1076 TemplateArgs = &Spec->getTemplateArgs();
1077 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1083void MicrosoftCXXNameMangler::mangleUnqualifiedName(
GlobalDecl GD,
1097 if (isa<FunctionTemplateDecl>(TD.getDecl())) {
1098 mangleTemplateInstantiationName(TD, *TemplateArgs);
1121 ArgBackRefMap::iterator
Found = TemplateArgBackReferences.find(ND);
1122 if (
Found == TemplateArgBackReferences.end()) {
1124 TemplateArgStringMap::iterator
Found = TemplateArgStrings.find(ND);
1125 if (
Found == TemplateArgStrings.end()) {
1128 llvm::raw_svector_ostream Stream(TemplateMangling);
1129 MicrosoftCXXNameMangler
Extra(Context, Stream);
1130 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1133 mangleSourceName(TemplateMangling);
1137 BackRefVec::iterator StringFound =
1138 llvm::find(NameBackReferences, TemplateMangling);
1139 if (StringFound != NameBackReferences.end()) {
1140 TemplateArgBackReferences[ND] =
1141 StringFound - NameBackReferences.begin();
1143 TemplateArgStrings[ND] =
1144 TemplateArgStringStorage.save(TemplateMangling.str());
1147 Out <<
Found->second <<
'@';
1150 Out <<
Found->second;
1155 switch (Name.getNameKind()) {
1160 ((isa<FunctionDecl>(ND) && ND->
hasAttr<CUDAGlobalAttr>()) ||
1161 (isa<FunctionTemplateDecl>(ND) &&
1162 cast<FunctionTemplateDecl>(ND)
1163 ->getTemplatedDecl()
1164 ->hasAttr<CUDAGlobalAttr>())) &&
1166 bool IsOCLDeviceStub =
1167 ND && isa<FunctionDecl>(ND) &&
1168 DeviceKernelAttr::isOpenCLSpelling(
1169 ND->
getAttr<DeviceKernelAttr>()) &&
1173 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1174 else if (IsOCLDeviceStub)
1176 (llvm::Twine(
"__clang_ocl_kern_imp_") + II->getName()).str());
1178 mangleSourceName(II->getName());
1183 assert(ND &&
"mangling empty name without declaration");
1185 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1186 if (NS->isAnonymousNamespace()) {
1187 Out <<
"?A0x" << Context.getAnonymousNamespaceHash() <<
'@';
1197 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1198 mangleSourceName(Name);
1202 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1205 assert(RD &&
"expected variable decl to have a record type");
1211 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1212 mangleSourceName(Name.str());
1216 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1219 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1220 llvm::raw_svector_ostream GUIDOS(GUID);
1221 Context.mangleMSGuidDecl(GD, GUIDOS);
1222 mangleSourceName(GUID);
1226 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1228 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1229 TPO->getValue(), TplArgKind::ClassNTTP);
1234 const TagDecl *TD = cast<TagDecl>(ND);
1237 "Typedef should not be in another decl context!");
1238 assert(
D->getDeclName().getAsIdentifierInfo() &&
1239 "Typedef was not named!");
1240 mangleSourceName(
D->getDeclName().getAsIdentifierInfo()->getName());
1245 if (
Record->isLambda()) {
1248 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1249 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1252 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1257 unsigned DefaultArgNo =
1259 Name += llvm::utostr(DefaultArgNo);
1263 if (LambdaManglingNumber)
1264 LambdaId = LambdaManglingNumber;
1266 LambdaId = Context.getLambdaId(
Record);
1268 Name += llvm::utostr(LambdaId);
1271 mangleSourceName(Name);
1275 if (LambdaManglingNumber && LambdaContextDecl) {
1276 if ((isa<VarDecl>(LambdaContextDecl) ||
1277 isa<FieldDecl>(LambdaContextDecl)) &&
1278 !isa<ParmVarDecl>(LambdaContextDecl)) {
1279 mangleUnqualifiedName(cast<NamedDecl>(LambdaContextDecl));
1291 Name +=
"<unnamed-type-";
1292 Name += DD->getName();
1298 Name +=
"<unnamed-type-";
1299 Name += TND->getName();
1300 }
else if (isa<EnumDecl>(TD) &&
1301 !cast<EnumDecl>(TD)->enumerators().empty()) {
1303 auto *ED = cast<EnumDecl>(TD);
1304 Name +=
"<unnamed-enum-";
1305 Name += ED->enumerator_begin()->getName();
1308 Name +=
"<unnamed-type-$S";
1309 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1312 mangleSourceName(Name.str());
1323 mangleSourceName(Name.str());
1328 if (isStructorDecl(ND)) {
1342 if (isStructorDecl(ND))
1345 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1359 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1364 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1369 llvm_unreachable(
"Can't mangle a deduction guide name!");
1372 llvm_unreachable(
"Can't mangle a using directive name!");
1378void MicrosoftCXXNameMangler::mangleNestedName(
GlobalDecl GD) {
1381 if (
const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1382 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1383 mangleSourceName(
"<unnamed-tag>");
1385 const DeclContext *DC = getEffectiveDeclContext(ND);
1387 if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
1389 if (Context.getNextDiscriminator(ND, Disc)) {
1396 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1398 [](StringRef Name,
const unsigned Discriminator,
1399 const unsigned ParameterDiscriminator) -> std::string {
1401 llvm::raw_string_ostream Stream(Buffer);
1404 Stream <<
'_' << Discriminator;
1405 if (ParameterDiscriminator)
1406 Stream <<
'_' << ParameterDiscriminator;
1410 unsigned Discriminator = BD->getBlockManglingNumber();
1412 Discriminator = Context.getBlockId(BD,
false);
1417 unsigned ParameterDiscriminator = 0;
1418 if (
const auto *MC = BD->getBlockManglingContextDecl())
1419 if (
const auto *
P = dyn_cast<ParmVarDecl>(MC))
1420 if (
const auto *F = dyn_cast<FunctionDecl>(
P->getDeclContext()))
1421 ParameterDiscriminator =
1422 F->getNumParams() -
P->getFunctionScopeIndex();
1424 DC = getEffectiveDeclContext(BD);
1427 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1428 ParameterDiscriminator));
1433 if (
const auto *MC = BD->getBlockManglingContextDecl())
1434 if (!isa<ParmVarDecl>(MC))
1435 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1436 mangleUnqualifiedName(ND);
1440 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1449 if (PointersAre64Bit)
1452 mangleArtificialTagType(TagTypeKind::Struct,
1453 Discriminate(
"__block_literal", Discriminator,
1454 ParameterDiscriminator));
1459 if (isa<RecordDecl>(DC))
1462 }
else if (
const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
1464 }
else if (isa<NamedDecl>(DC)) {
1465 ND = cast<NamedDecl>(DC);
1466 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1467 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1470 mangleUnqualifiedName(ND);
1473 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1483void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1498 llvm_unreachable(
"not expecting a COMDAT");
1500 llvm_unreachable(
"Unsupported dtor type?");
1509 case OO_New: Out <<
"?2";
break;
1511 case OO_Delete: Out <<
"?3";
break;
1513 case OO_Equal: Out <<
"?4";
break;
1515 case OO_GreaterGreater: Out <<
"?5";
break;
1517 case OO_LessLess: Out <<
"?6";
break;
1519 case OO_Exclaim: Out <<
"?7";
break;
1521 case OO_EqualEqual: Out <<
"?8";
break;
1523 case OO_ExclaimEqual: Out <<
"?9";
break;
1525 case OO_Subscript: Out <<
"?A";
break;
1528 case OO_Arrow: Out <<
"?C";
break;
1530 case OO_Star: Out <<
"?D";
break;
1532 case OO_PlusPlus: Out <<
"?E";
break;
1534 case OO_MinusMinus: Out <<
"?F";
break;
1536 case OO_Minus: Out <<
"?G";
break;
1538 case OO_Plus: Out <<
"?H";
break;
1540 case OO_Amp: Out <<
"?I";
break;
1542 case OO_ArrowStar: Out <<
"?J";
break;
1544 case OO_Slash: Out <<
"?K";
break;
1546 case OO_Percent: Out <<
"?L";
break;
1548 case OO_Less: Out <<
"?M";
break;
1550 case OO_LessEqual: Out <<
"?N";
break;
1552 case OO_Greater: Out <<
"?O";
break;
1554 case OO_GreaterEqual: Out <<
"?P";
break;
1556 case OO_Comma: Out <<
"?Q";
break;
1558 case OO_Call: Out <<
"?R";
break;
1560 case OO_Tilde: Out <<
"?S";
break;
1562 case OO_Caret: Out <<
"?T";
break;
1564 case OO_Pipe: Out <<
"?U";
break;
1566 case OO_AmpAmp: Out <<
"?V";
break;
1568 case OO_PipePipe: Out <<
"?W";
break;
1570 case OO_StarEqual: Out <<
"?X";
break;
1572 case OO_PlusEqual: Out <<
"?Y";
break;
1574 case OO_MinusEqual: Out <<
"?Z";
break;
1576 case OO_SlashEqual: Out <<
"?_0";
break;
1578 case OO_PercentEqual: Out <<
"?_1";
break;
1580 case OO_GreaterGreaterEqual: Out <<
"?_2";
break;
1582 case OO_LessLessEqual: Out <<
"?_3";
break;
1584 case OO_AmpEqual: Out <<
"?_4";
break;
1586 case OO_PipeEqual: Out <<
"?_5";
break;
1588 case OO_CaretEqual: Out <<
"?_6";
break;
1617 case OO_Array_New: Out <<
"?_U";
break;
1619 case OO_Array_Delete: Out <<
"?_V";
break;
1621 case OO_Coawait: Out <<
"?__L";
break;
1623 case OO_Spaceship: Out <<
"?__M";
break;
1625 case OO_Conditional: {
1626 Error(
Loc,
"conditional operator");
1632 llvm_unreachable(
"Not an overloaded operator");
1636void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1638 BackRefVec::iterator
Found = llvm::find(NameBackReferences, Name);
1639 if (
Found == NameBackReferences.end()) {
1640 if (NameBackReferences.size() < 10)
1641 NameBackReferences.push_back(std::string(Name));
1644 Out << (
Found - NameBackReferences.begin());
1648void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1649 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1652void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1659 ArgBackRefMap OuterFunArgsContext;
1660 ArgBackRefMap OuterTemplateArgsContext;
1661 BackRefVec OuterTemplateContext;
1662 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1663 NameBackReferences.swap(OuterTemplateContext);
1664 FunArgBackReferences.swap(OuterFunArgsContext);
1665 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1666 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1668 mangleUnscopedTemplateName(GD);
1669 mangleTemplateArgs(cast<TemplateDecl>(GD.
getDecl()), TemplateArgs);
1672 NameBackReferences.swap(OuterTemplateContext);
1673 FunArgBackReferences.swap(OuterFunArgsContext);
1674 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1675 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1678void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(
GlobalDecl GD) {
1681 mangleUnqualifiedName(GD);
1684void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1695 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1696 LangOptions::MSVC2019) &&
1698 !TemplateArgType.
isNull()) {
1700 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
1705 mangleNumber(
Value);
1708void MicrosoftCXXNameMangler::mangleExpression(
1711 if (std::optional<llvm::APSInt>
Value =
1722void MicrosoftCXXNameMangler::mangleTemplateArgs(
1726 assert(TPL->
size() == TemplateArgs.
size() &&
1727 "size mismatch between args and parms!");
1729 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1737 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1749 QualType BaseT =
V.getLValueBase().getType();
1750 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1751 V.getLValuePath()[0].getAsArrayIndex() != 0)
1754 V.getLValueBase().dyn_cast<
const ValueDecl *>());
1757void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1797 llvm_unreachable(
"Can't mangle null template arguments!");
1799 llvm_unreachable(
"Can't mangle template expansion arguments!");
1807 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1808 mangleMemberDataPointer(
1810 cast<ValueDecl>(ND), cast<NonTypeTemplateParmDecl>(Parm),
1812 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1816 cast<NonTypeTemplateParmDecl>(Parm),
1819 mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),
1824 auto *TPO = cast<TemplateParamObjectDecl>(ND);
1825 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1826 TPO->getValue(), TplArgKind::ClassNTTP);
1827 }
else if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1828 mangleVarDecl(VD, cast<NonTypeTemplateParmDecl>(Parm),
1838 cast<NonTypeTemplateParmDecl>(Parm),
T);
1844 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1845 if (MPT->isMemberFunctionPointerType() &&
1846 !isa<FunctionTemplateDecl>(TD)) {
1847 mangleMemberFunctionPointer(RD,
nullptr,
nullptr,
QualType());
1850 if (MPT->isMemberDataPointer()) {
1851 if (!isa<FunctionTemplateDecl>(TD)) {
1852 mangleMemberDataPointer(RD,
nullptr,
nullptr,
QualType());
1862 mangleIntegerLiteral(llvm::APSInt::get(-1),
1863 cast<NonTypeTemplateParmDecl>(Parm),
T);
1868 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1869 cast<NonTypeTemplateParmDecl>(Parm),
T);
1878 return mangleTemplateArg(
1882 if (cast<NonTypeTemplateParmDecl>(Parm)
1884 ->getContainedDeducedType()) {
1890 TplArgKind::StructuralValue,
1894 mangleExpression(TA.
getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
1898 if (TemplateArgs.empty()) {
1899 if (isa<TemplateTypeParmDecl>(Parm) ||
1900 isa<TemplateTemplateParmDecl>(Parm))
1904 LangOptions::MSVC2015)
1907 else if (isa<NonTypeTemplateParmDecl>(Parm))
1910 llvm_unreachable(
"unexpected template parameter decl!");
1913 mangleTemplateArg(TD, PA, Parm);
1920 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1922 }
else if (isa<TypeAliasDecl>(ND)) {
1926 llvm_unreachable(
"unexpected template template NamedDecl!");
1933void MicrosoftCXXNameMangler::mangleTemplateArgValue(
QualType T,
1936 bool WithScalarType) {
1937 switch (
V.getKind()) {
1951 mangleNumber(
V.getInt());
1957 mangleFloat(
V.getFloat());
1968 if (
V.isLValueOnePastTheEnd()) {
1977 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1979 if (
Base.isNull()) {
1985 mangleNumber(
V.getLValueOffset().getQuantity());
1986 }
else if (!
V.hasLValuePath()) {
1988 Error(
"template argument (extension not comaptible with ms mangler)");
1994 Error(
"template argument (undeclared base)");
2006 EntryTypes.push_back(
'C');
2007 EntryManglers.push_back([
this, I =
E.getAsArrayIndex()] {
2012 ET = AT->getElementType();
2016 const Decl *
D =
E.getAsBaseOrMember().getPointer();
2017 if (
auto *FD = dyn_cast<FieldDecl>(
D)) {
2023 ET = getASTContext().getCanonicalTagType(cast<CXXRecordDecl>(
D));
2029 EntryTypes.push_back(
'6');
2030 EntryManglers.push_back([
this,
D] {
2031 mangleUnqualifiedName(cast<NamedDecl>(
D));
2036 for (
auto I = EntryTypes.rbegin(),
E = EntryTypes.rend(); I !=
E; ++I)
2041 Error(
"template argument (null value decl)");
2044 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
2063 if (TAK == TplArgKind::ClassNTTP) {
2065 mangleMemberDataPointerInClassNTTP(RD,
D);
2067 mangleMemberFunctionPointerInClassNTTP(RD,
2068 cast_or_null<CXXMethodDecl>(
D));
2071 mangleMemberDataPointer(RD,
D,
nullptr,
QualType(),
"");
2073 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(
D),
nullptr,
2083 assert(RD &&
"unexpected type for record value");
2085 unsigned BaseIndex = 0;
2087 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
2089 if (!FD->isUnnamedBitField())
2090 mangleTemplateArgValue(FD->
getType(),
2091 V.getStructField(FD->getFieldIndex()), TAK,
2100 if (
const FieldDecl *FD =
V.getUnionField()) {
2101 mangleUnqualifiedName(FD);
2102 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
2112 mangleNumber(
V.getComplexIntReal());
2114 mangleNumber(
V.getComplexIntImag());
2121 mangleFloat(
V.getComplexFloatReal());
2122 mangleFloat(
V.getComplexFloatImag());
2128 QualType ElemT = getASTContext().getAsArrayType(
T)->getElementType();
2130 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
2131 const APValue &ElemV = I <
V.getArrayInitializedElts()
2132 ?
V.getArrayInitializedElt(I)
2133 :
V.getArrayFiller();
2134 mangleTemplateArgValue(ElemT, ElemV, TAK);
2149 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
2150 const APValue &ElemV =
V.getVectorElt(I);
2151 mangleTemplateArgValue(ElemT, ElemV, TAK);
2159 Error(
"template argument (value type: address label diff)");
2164 Error(
"template argument (value type: fixed point)");
2170void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2172 llvm::raw_svector_ostream Stream(TemplateMangling);
2173 MicrosoftCXXNameMangler
Extra(Context, Stream);
2176 Extra.mangleSourceName(
"Protocol");
2177 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2179 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2182void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType Type,
2186 llvm::raw_svector_ostream Stream(TemplateMangling);
2187 MicrosoftCXXNameMangler
Extra(Context, Stream);
2195 Extra.mangleSourceName(
"Autoreleasing");
2198 Extra.mangleSourceName(
"Strong");
2201 Extra.mangleSourceName(
"Weak");
2204 Extra.manglePointerCVQualifiers(Quals);
2205 Extra.manglePointerExtQualifiers(Quals,
Type);
2208 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2211void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *
T,
2215 llvm::raw_svector_ostream Stream(TemplateMangling);
2216 MicrosoftCXXNameMangler
Extra(Context, Stream);
2219 Extra.mangleSourceName(
"KindOf");
2221 .stripObjCKindOfType(getASTContext())
2222 ->castAs<ObjCObjectType>(),
2225 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2228void MicrosoftCXXNameMangler::mangleQualifiers(
Qualifiers Quals,
2286 if (HasConst && HasVolatile) {
2288 }
else if (HasVolatile) {
2290 }
else if (HasConst) {
2296 if (HasConst && HasVolatile) {
2298 }
else if (HasVolatile) {
2300 }
else if (HasConst) {
2311MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2314 switch (RefQualifier) {
2328void MicrosoftCXXNameMangler::manglePointerExtQualifiers(
Qualifiers Quals,
2331 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2344void MicrosoftCXXNameMangler::manglePointerAuthQualifier(
Qualifiers Quals) {
2350 mangleNumber(PointerAuth.
getKey());
2355void MicrosoftCXXNameMangler::manglePointerCVQualifiers(
Qualifiers Quals) {
2363 if (HasConst && HasVolatile) {
2365 }
else if (HasVolatile) {
2367 }
else if (HasConst) {
2374void MicrosoftCXXNameMangler::mangleFunctionArgumentType(
QualType T,
2385 QualType OriginalType = DT->getOriginalType();
2388 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2389 OriginalType = getASTContext().getIncompleteArrayType(
2390 AT->getElementType(), AT->getSizeModifier(),
2391 AT->getIndexTypeCVRQualifiers());
2402 TypePtr =
T.getCanonicalType().getAsOpaquePtr();
2405 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2407 if (
Found == FunArgBackReferences.end()) {
2408 size_t OutSizeBefore = Out.tell();
2410 mangleType(
T,
Range, QMM_Drop);
2415 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);
2416 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2417 size_t Size = FunArgBackReferences.size();
2418 FunArgBackReferences[TypePtr] =
Size;
2421 Out <<
Found->second;
2425void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2426 const PassObjectSizeAttr *POSA) {
2427 int Type = POSA->getType();
2428 bool Dynamic = POSA->isDynamic();
2431 auto *TypePtr = (
const void *)&*
Iter;
2432 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2434 if (
Found == FunArgBackReferences.end()) {
2436 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2437 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2440 if (FunArgBackReferences.size() < 10) {
2441 size_t Size = FunArgBackReferences.size();
2442 FunArgBackReferences[TypePtr] =
Size;
2445 Out <<
Found->second;
2449void MicrosoftCXXNameMangler::mangleAddressSpaceType(
QualType T,
2467 llvm::raw_svector_ostream Stream(ASMangling);
2468 MicrosoftCXXNameMangler
Extra(Context, Stream);
2474 Extra.mangleSourceName(
"_AS");
2475 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2479 llvm_unreachable(
"Not a language specific address space");
2480 case LangAS::opencl_global:
2481 Extra.mangleSourceName(
"_ASCLglobal");
2483 case LangAS::opencl_global_device:
2484 Extra.mangleSourceName(
"_ASCLdevice");
2486 case LangAS::opencl_global_host:
2487 Extra.mangleSourceName(
"_ASCLhost");
2489 case LangAS::opencl_local:
2490 Extra.mangleSourceName(
"_ASCLlocal");
2492 case LangAS::opencl_constant:
2493 Extra.mangleSourceName(
"_ASCLconstant");
2495 case LangAS::opencl_private:
2496 Extra.mangleSourceName(
"_ASCLprivate");
2498 case LangAS::opencl_generic:
2499 Extra.mangleSourceName(
"_ASCLgeneric");
2501 case LangAS::cuda_device:
2502 Extra.mangleSourceName(
"_ASCUdevice");
2504 case LangAS::cuda_constant:
2505 Extra.mangleSourceName(
"_ASCUconstant");
2507 case LangAS::cuda_shared:
2508 Extra.mangleSourceName(
"_ASCUshared");
2510 case LangAS::ptr32_sptr:
2511 case LangAS::ptr32_uptr:
2513 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2519 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2522void MicrosoftCXXNameMangler::mangleAutoReturnType(
QualType T,
2523 QualifierMangleMode QMM) {
2524 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2525 LangOptions::MSVC2019) &&
2526 "Cannot mangle MSVC 2017 auto return types!");
2528 if (isa<AutoType>(
T)) {
2532 if (QMM == QMM_Result)
2534 if (QMM != QMM_Drop)
2535 mangleQualifiers(Quals,
false);
2536 Out << (AT->isDecltypeAuto() ?
"_T" :
"_P");
2540 T =
T.getDesugaredType(getASTContext());
2548 mangleQualifiers(Quals,
false);
2551 llvm_unreachable(
"QMM_Escape unexpected");
2554 const Type *ty =
T.getTypePtr();
2556 case Type::MemberPointer:
2557 mangleAutoReturnType(cast<MemberPointerType>(ty), Quals);
2560 mangleAutoReturnType(cast<PointerType>(ty), Quals);
2562 case Type::LValueReference:
2563 mangleAutoReturnType(cast<LValueReferenceType>(ty), Quals);
2565 case Type::RValueReference:
2566 mangleAutoReturnType(cast<RValueReferenceType>(ty), Quals);
2569 llvm_unreachable(
"Invalid type expected");
2574 QualifierMangleMode QMM) {
2577 T =
T.getDesugaredType(getASTContext());
2580 if (
const ArrayType *AT = getASTContext().getAsArrayType(
T)) {
2583 if (QMM == QMM_Mangle)
2585 else if (QMM == QMM_Escape || QMM == QMM_Result)
2587 mangleArrayType(AT);
2602 mangleFunctionType(FT);
2605 mangleQualifiers(Quals,
false);
2608 if (!IsPointer && Quals) {
2610 mangleQualifiers(Quals,
false);
2618 if ((!IsPointer && Quals) || isa<TagType>(
T) || isArtificialTagType(
T)) {
2620 mangleQualifiers(Quals,
false);
2625 const Type *ty =
T.getTypePtr();
2628#define ABSTRACT_TYPE(CLASS, PARENT)
2629#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2631 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2633#define TYPE(CLASS, PARENT) \
2635 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2637#include "clang/AST/TypeNodes.inc"
2639#undef NON_CANONICAL_TYPE
2673 switch (
T->getKind()) {
2674 case BuiltinType::Void:
2677 case BuiltinType::SChar:
2680 case BuiltinType::Char_U:
2681 case BuiltinType::Char_S:
2684 case BuiltinType::UChar:
2687 case BuiltinType::Short:
2690 case BuiltinType::UShort:
2693 case BuiltinType::Int:
2696 case BuiltinType::UInt:
2699 case BuiltinType::Long:
2702 case BuiltinType::ULong:
2705 case BuiltinType::Float:
2708 case BuiltinType::Double:
2712 case BuiltinType::LongDouble:
2715 case BuiltinType::LongLong:
2718 case BuiltinType::ULongLong:
2721 case BuiltinType::Int128:
2724 case BuiltinType::UInt128:
2727 case BuiltinType::Bool:
2730 case BuiltinType::Char8:
2733 case BuiltinType::Char16:
2736 case BuiltinType::Char32:
2739 case BuiltinType::WChar_S:
2740 case BuiltinType::WChar_U:
2744#define BUILTIN_TYPE(Id, SingletonId)
2745#define PLACEHOLDER_TYPE(Id, SingletonId) \
2746 case BuiltinType::Id:
2747#include "clang/AST/BuiltinTypes.def"
2748 case BuiltinType::Dependent:
2749 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2751 case BuiltinType::ObjCId:
2752 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2754 case BuiltinType::ObjCClass:
2755 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2757 case BuiltinType::ObjCSel:
2758 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2761#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2762 case BuiltinType::Id: \
2763 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2765#include "clang/Basic/OpenCLImageTypes.def"
2766 case BuiltinType::OCLSampler:
2768 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2770 case BuiltinType::OCLEvent:
2772 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2774 case BuiltinType::OCLClkEvent:
2776 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2778 case BuiltinType::OCLQueue:
2780 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2782 case BuiltinType::OCLReserveID:
2784 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2786#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2787 case BuiltinType::Id: \
2788 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2790#include "clang/Basic/OpenCLExtensionTypes.def"
2792 case BuiltinType::NullPtr:
2796 case BuiltinType::Float16:
2797 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2800 case BuiltinType::Half:
2801 if (!getASTContext().getLangOpts().
HLSL)
2802 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2803 else if (getASTContext().getLangOpts().NativeHalfType)
2809 case BuiltinType::BFloat16:
2810 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2813 case BuiltinType::MFloat8:
2814 mangleArtificialTagType(TagTypeKind::Struct,
"__mfp8", {
"__clang"});
2817#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2818 case BuiltinType::Id: \
2819 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2820 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2823#include "clang/Basic/WebAssemblyReferenceTypes.def"
2825#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2826 case BuiltinType::Id: \
2827 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2829#include "clang/Basic/HLSLIntangibleTypes.def"
2831#define SVE_TYPE(Name, Id, SingletonId) \
2832 case BuiltinType::Id: \
2833 mangleArtificialTagType(TagTypeKind::Struct, #Name, {"__clang"}); \
2835#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits)
2836#include "clang/Basic/AArch64ACLETypes.def"
2855 mangleFunctionType(
T,
nullptr,
true);
2858 mangleFunctionType(
T);
2864 mangleFunctionType(
T);
2867void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *
T,
2869 bool ForceThisQuals,
2870 bool MangleExceptionSpec) {
2878 bool IsInLambda =
false;
2879 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
2881 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(
D)) {
2885 HasThisQuals =
true;
2886 if (isa<CXXDestructorDecl>(MD)) {
2888 }
else if (isa<CXXConstructorDecl>(MD)) {
2894 CC = getASTContext().getDefaultCallingConvention(
2903 manglePointerExtQualifiers(Quals,
QualType());
2905 mangleQualifiers(Quals,
false);
2908 mangleCallingConvention(CC,
Range);
2913 if (isa<CXXDestructorDecl>(
D) && isStructorDecl(
D)) {
2917 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
2926 if (IsCtorClosure) {
2936 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
2944 llvm_unreachable(
"unexpected constructor closure!");
2950 }
else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(
D)) {
2957 if (IsInLambda && isa<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) {
2984 while (isa<PointerType>(
T.getTypePtr())) {
2986 if (
T.getQualifiers().hasAddressSpace())
2992 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
2993 LangOptions::MSVC2019) &&
2994 !UseClangMangling(ResultType)) {
2995 if (
D && !
D->getPrimaryTemplate()) {
2998 if (
D &&
D->getPrimaryTemplate()) {
3000 ->getTemplatedDecl()
3006 mangleAutoReturnType(ResultType, QMM_Result);
3012 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3018 mangleType(ResultType,
Range, QMM_Result);
3036 if (I == 0 &&
D &&
D->getParamDecl(I)->isExplicitObjectParameter())
3049 if (
const auto *
P =
D->getParamDecl(I)->
getAttr<PassObjectSizeAttr>())
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)) {
3096 if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
3102 llvm_unreachable(
"Unsupported access specifier");
3131void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC,
3194 if (getASTContext().getLangOpts().RegCall4)
3203void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *
T,
3208void MicrosoftCXXNameMangler::mangleThrowSpecification(
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:
3249 mangleType(cast<TagType>(
T)->getOriginalDecl());
3253 mangleType(cast<TagType>(
T)->getOriginalDecl());
3255void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3265void MicrosoftCXXNameMangler::mangleArtificialTagType(
3269 mangleTagTypeKind(TK);
3272 mangleSourceName(UnqualifiedName);
3274 for (StringRef N : llvm::reverse(NestedNames))
3275 mangleSourceName(N);
3288void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *
T) {
3291 manglePointerCVQualifiers(
T->getElementType().getQualifiers());
3296 llvm_unreachable(
"Should have been special cased");
3300 llvm_unreachable(
"Should have been special cased");
3304 llvm_unreachable(
"Should have been special cased");
3308 llvm_unreachable(
"Should have been special cased");
3310void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *
T) {
3314 if (ElementTy->isConstantArrayType()) {
3316 getASTContext().getAsConstantArrayType(ElementTy);
3317 Dimensions.push_back(CAT->
getSize());
3319 }
else if (ElementTy->isIncompleteArrayType()) {
3321 getASTContext().getAsIncompleteArrayType(ElementTy);
3322 Dimensions.push_back(llvm::APInt(32, 0));
3324 }
else if (ElementTy->isVariableArrayType()) {
3326 getASTContext().getAsVariableArrayType(ElementTy);
3327 Dimensions.push_back(llvm::APInt(32, 0));
3329 }
else if (ElementTy->isDependentSizedArrayType()) {
3332 getASTContext().getAsDependentSizedArrayType(ElementTy);
3342 mangleNumber(Dimensions.size());
3343 for (
const llvm::APInt &Dimension : Dimensions)
3344 mangleNumber(Dimension.getLimitedValue());
3350 mangleArrayType(cast<ConstantArrayType>(
T));
3359 manglePointerCVQualifiers(Quals);
3360 manglePointerExtQualifiers(Quals, PointeeType);
3363 mangleName(
T->getMostRecentCXXRecordDecl());
3364 mangleFunctionType(FPT,
nullptr,
true);
3367 mangleName(
T->getMostRecentCXXRecordDecl());
3368 mangleType(PointeeType,
Range, QMM_Drop);
3378 Name += llvm::utostr(
T->getDepth());
3380 Name += llvm::utostr(
T->getIndex());
3382 mangleSourceName(Name);
3401 manglePointerCVQualifiers(Quals);
3402 manglePointerExtQualifiers(Quals, PointeeType);
3403 manglePointerAuthQualifier(Quals);
3409 mangleType(PointeeType,
Range);
3424 return mangleObjCLifetime(PointeeType, Quals,
Range);
3426 manglePointerCVQualifiers(Quals);
3427 manglePointerExtQualifiers(Quals, PointeeType);
3428 mangleType(PointeeType,
Range);
3439 manglePointerExtQualifiers(Quals, PointeeType);
3440 mangleType(PointeeType,
Range);
3451 manglePointerExtQualifiers(Quals, PointeeType);
3452 mangleType(PointeeType,
Range);
3457 QualType ElementType =
T->getElementType();
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 {
3475 const Type *ty =
T.getTypePtr();
3480 case Type::Vector: {
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();
3500 if (!isa<ExtVectorType>(
T)) {
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;
3525 llvm::raw_svector_ostream Stream(TemplateMangling);
3526 MicrosoftCXXNameMangler
Extra(Context, Stream);
3528 Extra.mangleSourceName(
"__vector");
3531 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumElements()));
3533 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3557 llvm::raw_svector_ostream Stream(TemplateMangling);
3558 MicrosoftCXXNameMangler
Extra(Context, Stream);
3562 Extra.mangleSourceName(
"__matrix");
3565 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumRows()));
3566 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumColumns()));
3568 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3584 mangleTagTypeKind(TagTypeKind::Struct);
3585 mangleName(
T->getDecl());
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);
3633 manglePointerCVQualifiers(Quals);
3634 manglePointerExtQualifiers(Quals, PointeeType);
3643 llvm_unreachable(
"Cannot mangle injected class name type.");
3656void MicrosoftCXXNameMangler::mangleType(
3669 manglePointerCVQualifiers(Quals);
3670 mangleType(
T->getSelectedType(),
Range);
3695 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3700void MicrosoftCXXNameMangler::mangleType(
3702 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3713 llvm::raw_svector_ostream Stream(TemplateMangling);
3714 MicrosoftCXXNameMangler
Extra(Context, Stream);
3716 Extra.mangleSourceName(
"_Atomic");
3717 Extra.mangleType(ValueType,
Range, QMM_Escape);
3719 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3724 QualType ElementType =
T->getElementType();
3727 llvm::raw_svector_ostream Stream(TemplateMangling);
3728 MicrosoftCXXNameMangler
Extra(Context, Stream);
3730 Extra.mangleSourceName(
"ocl_pipe");
3731 Extra.mangleType(ElementType,
Range, QMM_Escape);
3732 Extra.mangleIntegerLiteral(llvm::APSInt::get(
T->isReadOnly()));
3734 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3737void MicrosoftMangleContextImpl::mangleCXXName(
GlobalDecl GD,
3741 getASTContext().getSourceManager(),
3742 "Mangling declaration");
3744 msvc_hashing_ostream MHO(Out);
3746 if (
auto *CD = dyn_cast<CXXConstructorDecl>(
D)) {
3748 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3749 return mangler.mangle(GD);
3752 if (
auto *DD = dyn_cast<CXXDestructorDecl>(
D)) {
3754 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3755 return mangler.mangle(GD);
3758 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3759 return Mangler.mangle(GD);
3765 llvm::raw_svector_ostream Stream(TemplateMangling);
3766 MicrosoftCXXNameMangler
Extra(Context, Stream);
3768 if (
T->isUnsigned())
3769 Extra.mangleSourceName(
"_UBitInt");
3771 Extra.mangleSourceName(
"_BitInt");
3772 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumBits()));
3774 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3784 llvm_unreachable(
"HLSL uses Itanium name mangling");
3789 llvm_unreachable(
"HLSL uses Itanium name mangling");
3818 MicrosoftCXXNameMangler &Mangler,
3825 llvm_unreachable(
"Unsupported access specifier");
3836 Out <<
'R' << AccessSpec;
3837 Mangler.mangleNumber(
3839 Mangler.mangleNumber(
3841 Mangler.mangleNumber(
3843 Mangler.mangleNumber(
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3846 Mangler.mangleNumber(
3848 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3853 llvm_unreachable(
"Unsupported access specifier");
3863 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3867 llvm_unreachable(
"Unsupported access specifier");
3880void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
3883 msvc_hashing_ostream MHO(Out);
3884 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3885 Mangler.getStream() <<
'?';
3886 Mangler.mangleVirtualMemPtrThunk(MD, ML);
3889void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
3893 msvc_hashing_ostream MHO(Out);
3894 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3895 Mangler.getStream() <<
'?';
3896 Mangler.mangleName(MD);
3905 assert(Thunk.
Method !=
nullptr &&
3906 "Thunk info should hold the overridee decl");
3909 Mangler.mangleFunctionType(
3922 msvc_hashing_ostream MHO(Out);
3923 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
3924 Mangler.getStream() <<
"??_E";
3926 auto &Adjustment = Thunk.
This;
3931void MicrosoftMangleContextImpl::mangleCXXVFTable(
3938 msvc_hashing_ostream MHO(Out);
3939 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3940 if (Derived->
hasAttr<DLLImportAttr>())
3941 Mangler.getStream() <<
"??_S";
3943 Mangler.getStream() <<
"??_7";
3944 Mangler.mangleName(Derived);
3945 Mangler.getStream() <<
"6B";
3947 Mangler.mangleName(RD);
3948 Mangler.getStream() <<
'@';
3951void MicrosoftMangleContextImpl::mangleCXXVTable(
const CXXRecordDecl *Derived,
3954 mangleCXXVFTable(Derived, {}, Out);
3957void MicrosoftMangleContextImpl::mangleCXXVBTable(
3964 msvc_hashing_ostream MHO(Out);
3965 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3966 Mangler.getStream() <<
"??_8";
3967 Mangler.mangleName(Derived);
3968 Mangler.getStream() <<
"7B";
3970 Mangler.mangleName(RD);
3971 Mangler.getStream() <<
'@';
3974void MicrosoftMangleContextImpl::mangleCXXRTTI(
QualType T, raw_ostream &Out) {
3975 msvc_hashing_ostream MHO(Out);
3976 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3977 Mangler.getStream() <<
"??_R0";
3978 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3979 Mangler.getStream() <<
"@8";
3982void MicrosoftMangleContextImpl::mangleCXXRTTIName(
3983 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
3984 MicrosoftCXXNameMangler Mangler(*
this, Out);
3985 Mangler.getStream() <<
'.';
3986 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3989void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
3991 msvc_hashing_ostream MHO(Out);
3992 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3993 Mangler.getStream() <<
"??_K";
3994 Mangler.mangleName(SrcRD);
3995 Mangler.getStream() <<
"$C";
3996 Mangler.mangleName(DstRD);
3999void MicrosoftMangleContextImpl::mangleCXXThrowInfo(
QualType T,
bool IsConst,
4002 uint32_t NumEntries,
4004 msvc_hashing_ostream MHO(Out);
4005 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4006 Mangler.getStream() <<
"_TI";
4008 Mangler.getStream() <<
'C';
4010 Mangler.getStream() <<
'V';
4012 Mangler.getStream() <<
'U';
4013 Mangler.getStream() << NumEntries;
4014 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4017void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
4018 QualType T, uint32_t NumEntries, raw_ostream &Out) {
4019 msvc_hashing_ostream MHO(Out);
4020 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4021 Mangler.getStream() <<
"_CTA";
4022 Mangler.getStream() << NumEntries;
4023 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4026void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4028 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
4030 MicrosoftCXXNameMangler Mangler(*
this, Out);
4031 Mangler.getStream() <<
"_CT";
4035 llvm::raw_svector_ostream Stream(RTTIMangling);
4036 msvc_hashing_ostream MHO(Stream);
4037 mangleCXXRTTI(
T, MHO);
4039 Mangler.getStream() << RTTIMangling;
4047 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4048 LangOptions::MSVC2015) &&
4049 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4050 LangOptions::MSVC2017_7);
4052 if (!OmitCopyCtor && CD) {
4053 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4054 msvc_hashing_ostream MHO(Stream);
4057 Mangler.getStream() << CopyCtorMangling;
4059 Mangler.getStream() <<
Size;
4060 if (VBPtrOffset == -1) {
4062 Mangler.getStream() << NVOffset;
4065 Mangler.getStream() << NVOffset;
4066 Mangler.getStream() << VBPtrOffset;
4067 Mangler.getStream() << VBIndex;
4071void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4072 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
4073 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
4074 msvc_hashing_ostream MHO(Out);
4075 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4076 Mangler.getStream() <<
"??_R1";
4077 Mangler.mangleNumber(NVOffset);
4078 Mangler.mangleNumber(VBPtrOffset);
4079 Mangler.mangleNumber(VBTableOffset);
4080 Mangler.mangleNumber(Flags);
4081 Mangler.mangleName(Derived);
4082 Mangler.getStream() <<
"8";
4085void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4087 msvc_hashing_ostream MHO(Out);
4088 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4089 Mangler.getStream() <<
"??_R2";
4090 Mangler.mangleName(Derived);
4091 Mangler.getStream() <<
"8";
4094void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4096 msvc_hashing_ostream MHO(Out);
4097 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4098 Mangler.getStream() <<
"??_R3";
4099 Mangler.mangleName(Derived);
4100 Mangler.getStream() <<
"8";
4103void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4111 llvm::raw_svector_ostream Stream(VFTableMangling);
4112 mangleCXXVFTable(Derived, BasePath, Stream);
4114 if (VFTableMangling.starts_with(
"??@")) {
4115 assert(VFTableMangling.ends_with(
"@"));
4116 Out << VFTableMangling <<
"??_R4@";
4120 assert(VFTableMangling.starts_with(
"??_7") ||
4121 VFTableMangling.starts_with(
"??_S"));
4123 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
4126void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4127 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4128 msvc_hashing_ostream MHO(Out);
4129 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4134 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
4135 Mangler.mangleName(EnclosingDecl);
4138void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4139 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4140 msvc_hashing_ostream MHO(Out);
4141 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4146 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
4147 Mangler.mangleName(EnclosingDecl);
4150void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4151 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4154 MicrosoftCXXNameMangler Mangler(*
this, Out);
4155 Mangler.getStream() <<
'?';
4156 Mangler.mangleType(
T.getCanonicalType(),
SourceRange());
4159void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4160 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
4161 msvc_hashing_ostream MHO(Out);
4162 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4164 Mangler.getStream() <<
"?";
4165 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
4166 Mangler.mangle(VD,
"");
4169void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4170 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
4171 msvc_hashing_ostream MHO(Out);
4172 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4174 Mangler.getStream() <<
"?";
4175 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
4176 Mangler.mangleNestedName(VD);
4177 Mangler.getStream() <<
"@4HA";
4180void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
4192 msvc_hashing_ostream MHO(Out);
4193 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4197 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
4199 Mangler.getStream() <<
"?$S1@";
4201 unsigned ScopeDepth = 0;
4202 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4206 Mangler.mangle(VD,
"");
4208 Mangler.mangleNestedName(VD);
4209 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
4211 Mangler.mangleNumber(ScopeDepth);
4214void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *
D,
4217 msvc_hashing_ostream MHO(Out);
4218 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4219 Mangler.getStream() <<
"??__" << CharCode;
4220 if (
D->isStaticDataMember()) {
4221 Mangler.getStream() <<
'?';
4222 Mangler.mangleName(
D);
4223 Mangler.mangleVariableEncoding(
D);
4224 Mangler.getStream() <<
"@@";
4226 Mangler.mangleName(
D);
4230 Mangler.getStream() <<
"YAXXZ";
4233void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *
D,
4236 mangleInitFiniStub(
D,
'E', Out);
4240MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *
D,
4243 mangleInitFiniStub(
D,
'F', Out);
4246void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4267 MicrosoftCXXNameMangler Mangler(*
this, Out);
4268 Mangler.getStream() <<
"??_C@_";
4276 unsigned StringLength =
4277 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4282 Mangler.getStream() <<
'1';
4284 Mangler.getStream() <<
'0';
4288 Mangler.mangleNumber(StringByteLength);
4290 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4292 if (Index / CharByteWidth >= SL->
getLength())
4293 return static_cast<char>(0);
4295 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4296 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4299 auto GetBigEndianByte = [&SL](
unsigned Index) {
4301 if (Index / CharByteWidth >= SL->
getLength())
4302 return static_cast<char>(0);
4304 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4305 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4310 for (
unsigned I = 0,
E = StringByteLength; I !=
E; ++I)
4311 JC.update(GetLittleEndianByte(I));
4315 Mangler.mangleNumber(JC.getCRC());
4321 auto MangleByte = [&Mangler](
char Byte) {
4329 Mangler.getStream() << Byte;
4330 }
else if (
isLetter(Byte & 0x7f)) {
4331 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4333 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4334 ' ',
'\n',
'\t',
'\'',
'-'};
4335 const char *Pos = llvm::find(SpecialChars, Byte);
4336 if (Pos != std::end(SpecialChars)) {
4337 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4339 Mangler.getStream() <<
"?$";
4340 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4341 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4347 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4348 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4349 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4351 MangleByte(GetBigEndianByte(I));
4353 MangleByte(GetLittleEndianByte(I));
4356 Mangler.getStream() <<
'@';
4362 manglePointerCVQualifiers(Quals);
4363 manglePointerExtQualifiers(Quals, PointeeType);
4366 mangleName(
T->getMostRecentCXXRecordDecl());
4367 mangleFunctionType(FPT,
nullptr,
true);
4370 mangleName(
T->getMostRecentCXXRecordDecl());
4371 mangleAutoReturnType(PointeeType, QMM_Drop);
4375void MicrosoftCXXNameMangler::mangleAutoReturnType(
const PointerType *
T,
4379 "Unexpected address space mangling required");
4381 manglePointerCVQualifiers(Quals);
4382 manglePointerExtQualifiers(Quals, PointeeType);
4386 mangleFunctionType(FPT);
4388 mangleAutoReturnType(PointeeType, QMM_Mangle);
4397 manglePointerExtQualifiers(Quals, PointeeType);
4398 mangleAutoReturnType(PointeeType, QMM_Mangle);
4406 manglePointerExtQualifiers(Quals, PointeeType);
4407 mangleAutoReturnType(PointeeType, QMM_Mangle);
4413 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 unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
llvm::MachO::Record Record
static GlobalDecl isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs)
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)
Defines the SourceManager interface.
A non-discriminated union of a base, field, or array index.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
@ 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 ...
SourceManager & getSourceManager()
unsigned getManglingNumber(const NamedDecl *ND, bool ForAuxTarget=false) const
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
const LangOptions & getLangOpts() const
bool addressSpaceMapManglingFor(LangAS AS) const
const clang::PrintingPolicy & getPrintingPolicy() const
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
unsigned getTargetAddressSpace(LangAS AS) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
A fixed int type of a specified bitwidth.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
This class is used for builtin types like 'int'.
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
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.
Represents a C++ struct/union/class.
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...
CharUnits - This is an opaque type for sizes expressed in character units.
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...
Complex values, per C99 6.2.5p11.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
Represents a concrete matrix type with constant number of rows and columns.
Represents a pointer type decayed from an array or function type.
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
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
@ CXXConversionFunctionName
Represents a ValueDecl that came out of a declarator.
Represents the type decltype(expr) (C++11).
A decomposition declaration.
Represents a C++17 deduced template specialization type.
Represents an extended address space qualifier where the input address space value is dependent.
Represents a qualified type name for which the type name is dependent.
Represents an array type in C++ whose size is a value-dependent expression.
Expr * getSizeExpr() const
Represents an extended vector type where either the type or size is dependent.
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Represents a template specialization type whose template cannot be resolved, e.g.
Represents a vector type where either the type or size is dependent.
A little helper class used to produce diagnostics.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
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...
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
Represents a function declaration or definition.
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 K&R-style 'int foo()' function, which has no information available about its arguments.
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.
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
Represents an arbitrary, user-specified SPIR-V type instruction.
One of these records is kept for each identifier that is lexed.
Represents a C array with an unspecified size.
The injected class name of a C++ class template or class template partial specialization.
An lvalue reference type, per C++11 [dcl.ref].
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThunkInfo &Thunk, bool ElideOverrideInfo, raw_ostream &)=0
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
virtual std::string getLambdaString(const CXXRecordDecl *Lambda)=0
virtual bool shouldMangleStringLiteral(const StringLiteral *SL)=0
ASTContext & getASTContext() const
virtual void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &)=0
virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, bool ElideOverrideInfo, raw_ostream &)=0
virtual void mangleCanonicalTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing.
virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &)=0
virtual void mangleCXXName(GlobalDecl GD, raw_ostream &)=0
virtual void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber, raw_ostream &)=0
virtual bool shouldMangleCXXName(const NamedDecl *D)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &)=0
virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &)=0
virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &)=0
A pointer to member type per C++ 8.3.3 - Pointers to members.
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, ArrayRef< const CXXRecordDecl * > BasePath, raw_ostream &Out)=0
Mangle vftable symbols.
virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, const MethodVFTableLocation &ML, raw_ostream &Out)=0
virtual void mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived, ArrayRef< const CXXRecordDecl * > BasePath, raw_ostream &Out)=0
virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, bool IsUnaligned, uint32_t NumEntries, raw_ostream &Out)=0
virtual void mangleCXXVBTable(const CXXRecordDecl *Derived, ArrayRef< const CXXRecordDecl * > BasePath, raw_ostream &Out)=0
Mangle vbtable symbols.
virtual void mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived, raw_ostream &Out)=0
virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD, unsigned GuardNum, raw_ostream &Out)=0
static MicrosoftMangleContext * create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux=false)
virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries, raw_ostream &Out)=0
virtual void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out)=0
virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD, CXXCtorType CT, uint32_t Size, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex, raw_ostream &Out)=0
virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived, raw_ostream &Out)=0
virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD, const CXXRecordDecl *DstRD, raw_ostream &Out)=0
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.
bool isExternallyVisible() const
Represent a C++ namespace.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Interfaces are the core concept in Objective-C for object oriented design.
ObjCMethodDecl - Represents an instance or class method declaration.
Represents a pointer to an Objective C object.
Represents a class type in Objective C.
Represents an Objective-C protocol declaration.
Represents a pack expansion of types.
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
Pointer-authentication qualifiers.
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
PrettyStackTraceDecl - If a crash occurs, indicate that it happened when doing something to a specifi...
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void * getAsOpaquePtr() const
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
bool hasAddressSpace() const
PointerAuthQualifier getPointerAuth() const
bool hasObjCLifetime() const
ObjCLifetime getObjCLifetime() const
Qualifiers withoutObjCLifetime() const
LangAS getAddressSpace() const
An rvalue reference type, per C++11 [dcl.ref].
field_range fields() const
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
QualType getPointeeType() const
Encodes a location in the source.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const char * getStmtClassName() const
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
unsigned getCharByteWidth() const
Represents the result of substituting a builtin template as a pack.
Represents the result of substituting a set of types for a template type parameter pack.
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.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
Represents a type template specialization; the template must be a class template, a type alias templa...
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
The base class of the type hierarchy.
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
Base class for declarations which introduce a typedef-name.
Represents the dependent type named by a dependently-scoped typename using declaration,...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
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...
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
Defines the clang::TargetInfo interface.
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.
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...
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)
CXXDtorType
C++ destructor types.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
TagTypeKind
The kind of a tag type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool isPtrSizeAddressSpace(LangAS AS)
const FunctionProtoType * T
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName)
Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...
Diagnostic wrappers for TextAPI types for error reporting.
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.
The this pointer adjustment as well as an optional return adjustment for a thunk.
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.
struct clang::ThisAdjustment::VirtualAdjustment::@182 Microsoft
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
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...