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/MathExtras.h"
37 #include "llvm/Support/StringSaver.h"
38 #include "llvm/Support/xxhash.h"
42 using namespace clang;
49 if (
auto *CD = dyn_cast<CXXConstructorDecl>(DC))
51 else if (
auto *DD = dyn_cast<CXXDestructorDecl>(DC))
58 struct msvc_hashing_ostream :
public llvm::raw_svector_ostream {
62 msvc_hashing_ostream(raw_ostream &OS)
63 :
llvm::raw_svector_ostream(Buffer), OS(OS) {}
64 ~msvc_hashing_ostream()
override {
65 StringRef MangledName = str();
66 bool StartsWithEscape = MangledName.starts_with(
"\01");
68 MangledName = MangledName.drop_front(1);
69 if (MangledName.size() < 4096) {
75 llvm::MD5::MD5Result Hash;
76 Hasher.update(MangledName);
80 llvm::MD5::stringifyResult(Hash, HexString);
84 OS <<
"??@" << HexString <<
'@';
89 getLambdaDefaultArgumentDeclContext(
const Decl *D) {
90 if (
const auto *RD = dyn_cast<CXXRecordDecl>(D))
92 if (
const auto *Parm =
93 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
94 return Parm->getDeclContext();
107 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))
111 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
113 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
114 return ContextParam->getDeclContext();
118 if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||
119 isa<OMPDeclareMapperDecl>(DC)) {
120 return getEffectiveDeclContext(cast<Decl>(DC));
127 return getEffectiveDeclContext(cast<Decl>(DC));
131 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
134 const auto *FD = cast<FunctionDecl>(ND);
135 if (
const auto *FTD = FD->getPrimaryTemplate())
136 return FTD->getTemplatedDecl()->getCanonicalDecl();
138 return FD->getCanonicalDecl();
144 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
145 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
146 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
147 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
148 llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
149 llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
155 bool shouldMangleCXXName(
const NamedDecl *D)
override;
156 bool shouldMangleStringLiteral(
const StringLiteral *SL)
override;
157 void mangleCXXName(
GlobalDecl GD, raw_ostream &Out)
override;
160 raw_ostream &Out)
override;
162 raw_ostream &)
override;
165 raw_ostream &)
override;
168 raw_ostream &Out)
override;
171 raw_ostream &Out)
override;
172 void mangleCXXVirtualDisplacementMap(
const CXXRecordDecl *SrcRD,
174 raw_ostream &Out)
override;
175 void mangleCXXThrowInfo(
QualType T,
bool IsConst,
bool IsVolatile,
176 bool IsUnaligned, uint32_t NumEntries,
177 raw_ostream &Out)
override;
178 void mangleCXXCatchableTypeArray(
QualType T, uint32_t NumEntries,
179 raw_ostream &Out)
override;
182 int32_t VBPtrOffset, uint32_t VBIndex,
183 raw_ostream &Out)
override;
184 void mangleCXXRTTI(
QualType T, raw_ostream &Out)
override;
185 void mangleCXXRTTIName(
QualType T, raw_ostream &Out,
186 bool NormalizeIntegers)
override;
187 void mangleCXXRTTIBaseClassDescriptor(
const CXXRecordDecl *Derived,
188 uint32_t NVOffset, int32_t VBPtrOffset,
189 uint32_t VBTableOffset, uint32_t Flags,
190 raw_ostream &Out)
override;
191 void mangleCXXRTTIBaseClassArray(
const CXXRecordDecl *Derived,
192 raw_ostream &Out)
override;
193 void mangleCXXRTTIClassHierarchyDescriptor(
const CXXRecordDecl *Derived,
194 raw_ostream &Out)
override;
196 mangleCXXRTTICompleteObjectLocator(
const CXXRecordDecl *Derived,
198 raw_ostream &Out)
override;
199 void mangleCanonicalTypeName(
QualType T, raw_ostream &,
200 bool NormalizeIntegers)
override;
201 void mangleReferenceTemporary(
const VarDecl *,
unsigned ManglingNumber,
202 raw_ostream &)
override;
203 void mangleStaticGuardVariable(
const VarDecl *D, raw_ostream &Out)
override;
204 void mangleThreadSafeStaticGuardVariable(
const VarDecl *D,
unsigned GuardNum,
205 raw_ostream &Out)
override;
206 void mangleDynamicInitializer(
const VarDecl *D, raw_ostream &Out)
override;
207 void mangleDynamicAtExitDestructor(
const VarDecl *D,
208 raw_ostream &Out)
override;
209 void mangleSEHFilterExpression(
GlobalDecl EnclosingDecl,
210 raw_ostream &Out)
override;
211 void mangleSEHFinallyBlock(
GlobalDecl EnclosingDecl,
212 raw_ostream &Out)
override;
213 void mangleStringLiteral(
const StringLiteral *SL, 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()) {
230 disc = getASTContext().getManglingNumber(ND, isAux());
235 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
236 if (!Tag->hasNameForLinkage() &&
237 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
238 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))
243 unsigned &discriminator = Uniquifier[ND];
245 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
246 disc = discriminator + 1;
250 std::string getLambdaString(
const CXXRecordDecl *Lambda)
override {
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);
309 class 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;
339 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
340 enum class TplArgKind { ClassNTTP, StructuralValue };
342 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
343 : Context(
C), Out(Out_), Structor(nullptr), StructorType(-1),
344 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
345 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
348 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
350 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
351 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
352 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
355 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
357 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
358 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
359 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
362 raw_ostream &getStream()
const {
return Out; }
364 void mangle(
GlobalDecl GD, StringRef Prefix =
"?");
366 void mangleFunctionEncoding(
GlobalDecl GD,
bool ShouldMangle);
367 void mangleVariableEncoding(
const VarDecl *VD);
369 StringRef Prefix =
"$");
370 void mangleMemberDataPointerInClassNTTP(
const CXXRecordDecl *,
374 StringRef Prefix =
"$");
375 void mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD,
379 void mangleNumber(
int64_t Number);
384 void mangleArtificialTagType(
TagTypeKind TK, StringRef UnqualifiedName,
388 QualifierMangleMode QMM = QMM_Mangle);
391 bool ForceThisQuals =
false,
392 bool MangleExceptionSpec =
true);
393 void mangleSourceName(StringRef Name);
397 bool isStructorDecl(
const NamedDecl *ND)
const {
398 return ND == Structor || getStructor(ND) == Structor;
409 mangleUnqualifiedName(GD, cast<NamedDecl>(GD.
getDecl())->getDeclName());
414 void mangleQualifiers(
Qualifiers Quals,
bool IsMember);
416 void manglePointerCVQualifiers(
Qualifiers Quals);
419 void mangleUnscopedTemplateName(
GlobalDecl GD);
421 mangleTemplateInstantiationName(
GlobalDecl GD,
426 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
428 bool isArtificialTagType(
QualType T)
const;
431 #define ABSTRACT_TYPE(CLASS, PARENT)
432 #define NON_CANONICAL_TYPE(CLASS, PARENT)
433 #define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
436 #include "clang/AST/TypeNodes.inc"
438 #undef NON_CANONICAL_TYPE
441 void mangleType(
const TagDecl *TD);
442 void mangleDecayedArrayType(
const ArrayType *
T);
458 bool WithScalarType =
false);
468 MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(
ASTContext &Context,
489 uint32_t TruncatedHash = uint32_t(xxh3_64bits(FE->getName()));
490 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
493 AnonymousNamespaceHash =
"0";
497 bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *D) {
498 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
501 if (FD->hasAttr<OverloadableAttr>())
513 if (FD->isMSVCRTEntryPoint())
527 if (!getASTContext().getLangOpts().
CPlusPlus)
530 const VarDecl *VD = dyn_cast<VarDecl>(D);
531 if (VD && !isa<DecompositionDecl>(D)) {
537 const DeclContext *DC = getEffectiveDeclContext(D);
541 DC = getEffectiveParentContext(DC);
544 !isa<VarTemplateSpecializationDecl>(D) && D->
getIdentifier() !=
nullptr)
552 MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
556 void MicrosoftCXXNameMangler::mangle(
GlobalDecl GD, StringRef Prefix) {
568 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
569 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
570 mangleVariableEncoding(VD);
571 else if (isa<MSGuidDecl>(D))
574 Out <<
"3U__s_GUID@@B";
575 else if (isa<TemplateParamObjectDecl>(D)) {
579 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
582 void MicrosoftCXXNameMangler::mangleFunctionEncoding(
GlobalDecl GD,
607 mangleFunctionClass(FD);
609 mangleFunctionType(FT, FD,
false,
false);
615 void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
646 mangleType(Ty, SR, QMM_Drop);
647 manglePointerExtQualifiers(
650 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
653 mangleName(MPT->getClass()->getAsCXXRecordDecl());
656 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
658 mangleDecayedArrayType(AT);
659 if (AT->getElementType()->isArrayType())
664 mangleType(Ty, SR, QMM_Drop);
669 void MicrosoftCXXNameMangler::mangleMemberDataPointer(
const CXXRecordDecl *RD,
680 FieldOffset = getASTContext().getFieldOffset(VD);
681 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
682 "cannot take address of bitfield");
683 FieldOffset /= getASTContext().getCharWidth();
687 if (IM == MSInheritanceModel::Virtual)
688 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
697 case MSInheritanceModel::Single: Code =
'0';
break;
698 case MSInheritanceModel::Multiple: Code =
'0';
break;
699 case MSInheritanceModel::Virtual: Code =
'F';
break;
700 case MSInheritanceModel::Unspecified: Code =
'G';
break;
703 Out << Prefix << Code;
705 mangleNumber(FieldOffset);
713 mangleNumber(VBTableOffset);
716 void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
723 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
724 return mangleMemberDataPointer(RD, VD,
"");
732 mangleNestedName(VD);
734 mangleUnqualifiedName(VD);
739 MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
const CXXRecordDecl *RD,
751 case MSInheritanceModel::Single: Code =
'1';
break;
752 case MSInheritanceModel::Multiple: Code =
'H';
break;
753 case MSInheritanceModel::Virtual: Code =
'I';
break;
754 case MSInheritanceModel::Unspecified: Code =
'J';
break;
763 Out << Prefix << Code <<
'?';
766 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
769 mangleVirtualMemPtrThunk(MD, ML);
773 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
778 mangleFunctionEncoding(MD,
true);
781 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
782 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
785 if (IM == MSInheritanceModel::Single) {
786 Out << Prefix <<
"0A@";
789 if (IM == MSInheritanceModel::Unspecified)
791 Out << Prefix << Code;
795 mangleNumber(
static_cast<uint32_t
>(NVOffset));
797 mangleNumber(VBPtrOffset);
799 mangleNumber(VBTableOffset);
802 void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
811 return mangleMemberFunctionPointer(RD, MD,
"");
820 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
823 mangleVirtualMemPtrThunk(MD, ML);
826 mangleFunctionEncoding(MD,
true);
830 void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
833 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
834 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
840 mangleNumber(OffsetInVFTable);
845 void MicrosoftCXXNameMangler::mangleName(
GlobalDecl GD) {
849 mangleUnqualifiedName(GD);
851 mangleNestedName(GD);
857 void MicrosoftCXXNameMangler::mangleNumber(
int64_t Number) {
861 void MicrosoftCXXNameMangler::mangleNumber(
llvm::APSInt Number) {
866 unsigned Width =
std::max(Number.getBitWidth(), 64U);
875 if (
Value.isNegative()) {
882 void MicrosoftCXXNameMangler::mangleFloat(
llvm::APFloat Number) {
885 switch (APFloat::SemanticsToEnum(Number.getSemantics())) {
886 case APFloat::S_IEEEsingle: Out <<
'A';
break;
887 case APFloat::S_IEEEdouble: Out <<
'B';
break;
891 case APFloat::S_IEEEhalf: Out <<
'V';
break;
892 case APFloat::S_BFloat: Out <<
'W';
break;
893 case APFloat::S_x87DoubleExtended: Out <<
'X';
break;
894 case APFloat::S_IEEEquad: Out <<
'Y';
break;
895 case APFloat::S_PPCDoubleDouble: Out <<
'Z';
break;
896 case APFloat::S_Float8E5M2:
897 case APFloat::S_Float8E4M3FN:
898 case APFloat::S_Float8E5M2FNUZ:
899 case APFloat::S_Float8E4M3FNUZ:
900 case APFloat::S_Float8E4M3B11FNUZ:
901 case APFloat::S_FloatTF32:
902 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
905 mangleBits(Number.bitcastToAPInt());
919 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
920 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
921 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
930 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
939 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
940 TemplateArgs = &Spec->getTemplateArgs();
941 return GD.
getWithDecl(Spec->getSpecializedTemplate());
946 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
947 TemplateArgs = &Spec->getTemplateArgs();
948 return GD.
getWithDecl(Spec->getSpecializedTemplate());
954 void MicrosoftCXXNameMangler::mangleUnqualifiedName(
GlobalDecl GD,
968 if (isa<FunctionTemplateDecl>(TD.getDecl())) {
969 mangleTemplateInstantiationName(TD, *TemplateArgs);
992 ArgBackRefMap::iterator Found = TemplateArgBackReferences.find(ND);
993 if (Found == TemplateArgBackReferences.end()) {
995 TemplateArgStringMap::iterator Found = TemplateArgStrings.find(ND);
996 if (Found == TemplateArgStrings.end()) {
999 llvm::raw_svector_ostream Stream(TemplateMangling);
1000 MicrosoftCXXNameMangler Extra(Context, Stream);
1001 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1004 mangleSourceName(TemplateMangling);
1008 BackRefVec::iterator StringFound =
1009 llvm::find(NameBackReferences, TemplateMangling);
1010 if (StringFound != NameBackReferences.end()) {
1011 TemplateArgBackReferences[ND] =
1012 StringFound - NameBackReferences.begin();
1014 TemplateArgStrings[ND] =
1015 TemplateArgStringStorage.save(TemplateMangling.str());
1018 Out << Found->second <<
'@';
1021 Out << Found->second;
1026 switch (Name.getNameKind()) {
1031 ((isa<FunctionDecl>(ND) && ND->
hasAttr<CUDAGlobalAttr>()) ||
1032 (isa<FunctionTemplateDecl>(ND) &&
1033 cast<FunctionTemplateDecl>(ND)
1034 ->getTemplatedDecl()
1035 ->hasAttr<CUDAGlobalAttr>())) &&
1039 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1041 mangleSourceName(II->getName());
1046 assert(ND &&
"mangling empty name without declaration");
1048 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1049 if (NS->isAnonymousNamespace()) {
1050 Out <<
"?A0x" << Context.getAnonymousNamespaceHash() <<
'@';
1060 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1061 mangleSourceName(Name);
1065 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1068 assert(RD &&
"expected variable decl to have a record type");
1074 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1075 mangleSourceName(Name.str());
1079 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1082 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1083 llvm::raw_svector_ostream GUIDOS(GUID);
1084 Context.mangleMSGuidDecl(GD, GUIDOS);
1085 mangleSourceName(GUID);
1089 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1091 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1092 TPO->getValue(), TplArgKind::ClassNTTP);
1097 const TagDecl *TD = cast<TagDecl>(ND);
1100 "Typedef should not be in another decl context!");
1102 "Typedef was not named!");
1108 if (
Record->isLambda()) {
1111 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1112 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1115 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1120 unsigned DefaultArgNo =
1122 Name += llvm::utostr(DefaultArgNo);
1126 if (LambdaManglingNumber)
1127 LambdaId = LambdaManglingNumber;
1129 LambdaId = Context.getLambdaId(
Record);
1131 Name += llvm::utostr(LambdaId);
1134 mangleSourceName(Name);
1138 if (LambdaManglingNumber && LambdaContextDecl) {
1139 if ((isa<VarDecl>(LambdaContextDecl) ||
1140 isa<FieldDecl>(LambdaContextDecl)) &&
1141 !isa<ParmVarDecl>(LambdaContextDecl)) {
1142 mangleUnqualifiedName(cast<NamedDecl>(LambdaContextDecl));
1154 Name +=
"<unnamed-type-";
1155 Name += DD->getName();
1161 Name +=
"<unnamed-type-";
1162 Name += TND->getName();
1163 }
else if (isa<EnumDecl>(TD) &&
1164 cast<EnumDecl>(TD)->enumerator_begin() !=
1165 cast<EnumDecl>(TD)->enumerator_end()) {
1167 auto *ED = cast<EnumDecl>(TD);
1168 Name +=
"<unnamed-enum-";
1169 Name += ED->enumerator_begin()->getName();
1172 Name +=
"<unnamed-type-$S";
1173 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1176 mangleSourceName(Name.str());
1180 case DeclarationName::ObjCZeroArgSelector:
1181 case DeclarationName::ObjCOneArgSelector:
1182 case DeclarationName::ObjCMultiArgSelector: {
1187 mangleSourceName(Name.str());
1191 case DeclarationName::CXXConstructorName:
1192 if (isStructorDecl(ND)) {
1205 case DeclarationName::CXXDestructorName:
1206 if (isStructorDecl(ND))
1209 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1216 case DeclarationName::CXXConversionFunctionName:
1222 case DeclarationName::CXXOperatorName:
1223 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1226 case DeclarationName::CXXLiteralOperatorName: {
1228 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1232 case DeclarationName::CXXDeductionGuideName:
1233 llvm_unreachable(
"Can't mangle a deduction guide name!");
1235 case DeclarationName::CXXUsingDirective:
1236 llvm_unreachable(
"Can't mangle a using directive name!");
1242 void MicrosoftCXXNameMangler::mangleNestedName(
GlobalDecl GD) {
1245 if (
const auto *
ID = dyn_cast<IndirectFieldDecl>(ND))
1246 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1247 mangleSourceName(
"<unnamed-tag>");
1249 const DeclContext *DC = getEffectiveDeclContext(ND);
1251 if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
1253 if (Context.getNextDiscriminator(ND, Disc)) {
1260 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1262 [](StringRef Name,
const unsigned Discriminator,
1263 const unsigned ParameterDiscriminator) -> std::string {
1265 llvm::raw_string_ostream Stream(Buffer);
1268 Stream <<
'_' << Discriminator;
1269 if (ParameterDiscriminator)
1270 Stream <<
'_' << ParameterDiscriminator;
1271 return Stream.str();
1274 unsigned Discriminator = BD->getBlockManglingNumber();
1276 Discriminator = Context.getBlockId(BD,
false);
1281 unsigned ParameterDiscriminator = 0;
1282 if (
const auto *MC = BD->getBlockManglingContextDecl())
1283 if (
const auto *
P = dyn_cast<ParmVarDecl>(MC))
1284 if (
const auto *F = dyn_cast<FunctionDecl>(
P->getDeclContext()))
1285 ParameterDiscriminator =
1286 F->getNumParams() -
P->getFunctionScopeIndex();
1288 DC = getEffectiveDeclContext(BD);
1291 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1292 ParameterDiscriminator));
1297 if (
const auto *MC = BD->getBlockManglingContextDecl())
1298 if (!isa<ParmVarDecl>(MC))
1299 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1300 mangleUnqualifiedName(ND);
1304 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1313 if (PointersAre64Bit)
1316 mangleArtificialTagType(TagTypeKind::Struct,
1317 Discriminate(
"__block_literal", Discriminator,
1318 ParameterDiscriminator));
1323 if (isa<RecordDecl>(DC))
1326 }
else if (
const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
1327 mangleObjCMethodName(Method);
1328 }
else if (isa<NamedDecl>(DC)) {
1329 ND = cast<NamedDecl>(DC);
1330 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1331 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1334 mangleUnqualifiedName(ND);
1337 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1347 void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1362 llvm_unreachable(
"not expecting a COMDAT");
1364 llvm_unreachable(
"Unsupported dtor type?");
1373 case OO_New: Out <<
"?2";
break;
1375 case OO_Delete: Out <<
"?3";
break;
1377 case OO_Equal: Out <<
"?4";
break;
1379 case OO_GreaterGreater: Out <<
"?5";
break;
1381 case OO_LessLess: Out <<
"?6";
break;
1383 case OO_Exclaim: Out <<
"?7";
break;
1385 case OO_EqualEqual: Out <<
"?8";
break;
1387 case OO_ExclaimEqual: Out <<
"?9";
break;
1389 case OO_Subscript: Out <<
"?A";
break;
1392 case OO_Arrow: Out <<
"?C";
break;
1394 case OO_Star: Out <<
"?D";
break;
1396 case OO_PlusPlus: Out <<
"?E";
break;
1398 case OO_MinusMinus: Out <<
"?F";
break;
1400 case OO_Minus: Out <<
"?G";
break;
1402 case OO_Plus: Out <<
"?H";
break;
1404 case OO_Amp: Out <<
"?I";
break;
1406 case OO_ArrowStar: Out <<
"?J";
break;
1408 case OO_Slash: Out <<
"?K";
break;
1410 case OO_Percent: Out <<
"?L";
break;
1412 case OO_Less: Out <<
"?M";
break;
1414 case OO_LessEqual: Out <<
"?N";
break;
1416 case OO_Greater: Out <<
"?O";
break;
1418 case OO_GreaterEqual: Out <<
"?P";
break;
1420 case OO_Comma: Out <<
"?Q";
break;
1422 case OO_Call: Out <<
"?R";
break;
1424 case OO_Tilde: Out <<
"?S";
break;
1426 case OO_Caret: Out <<
"?T";
break;
1428 case OO_Pipe: Out <<
"?U";
break;
1430 case OO_AmpAmp: Out <<
"?V";
break;
1432 case OO_PipePipe: Out <<
"?W";
break;
1434 case OO_StarEqual: Out <<
"?X";
break;
1436 case OO_PlusEqual: Out <<
"?Y";
break;
1438 case OO_MinusEqual: Out <<
"?Z";
break;
1440 case OO_SlashEqual: Out <<
"?_0";
break;
1442 case OO_PercentEqual: Out <<
"?_1";
break;
1444 case OO_GreaterGreaterEqual: Out <<
"?_2";
break;
1446 case OO_LessLessEqual: Out <<
"?_3";
break;
1448 case OO_AmpEqual: Out <<
"?_4";
break;
1450 case OO_PipeEqual: Out <<
"?_5";
break;
1452 case OO_CaretEqual: Out <<
"?_6";
break;
1481 case OO_Array_New: Out <<
"?_U";
break;
1483 case OO_Array_Delete: Out <<
"?_V";
break;
1485 case OO_Coawait: Out <<
"?__L";
break;
1487 case OO_Spaceship: Out <<
"?__M";
break;
1489 case OO_Conditional: {
1492 "cannot mangle this conditional operator yet");
1499 llvm_unreachable(
"Not an overloaded operator");
1503 void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1505 BackRefVec::iterator Found = llvm::find(NameBackReferences, Name);
1506 if (Found == NameBackReferences.end()) {
1507 if (NameBackReferences.size() < 10)
1508 NameBackReferences.push_back(std::string(Name));
1511 Out << (Found - NameBackReferences.begin());
1515 void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1516 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1519 void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1526 ArgBackRefMap OuterFunArgsContext;
1527 ArgBackRefMap OuterTemplateArgsContext;
1528 BackRefVec OuterTemplateContext;
1529 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1530 NameBackReferences.swap(OuterTemplateContext);
1531 FunArgBackReferences.swap(OuterFunArgsContext);
1532 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1533 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1535 mangleUnscopedTemplateName(GD);
1536 mangleTemplateArgs(cast<TemplateDecl>(GD.
getDecl()), TemplateArgs);
1539 NameBackReferences.swap(OuterTemplateContext);
1540 FunArgBackReferences.swap(OuterFunArgsContext);
1541 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1542 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1545 void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(
GlobalDecl GD) {
1548 mangleUnqualifiedName(GD);
1551 void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1559 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1560 LangOptions::MSVC2019) &&
1562 !TemplateArgType.
isNull()) {
1564 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
1569 mangleNumber(
Value);
1572 void MicrosoftCXXNameMangler::mangleExpression(
1575 if (std::optional<llvm::APSInt>
Value =
1589 void MicrosoftCXXNameMangler::mangleTemplateArgs(
1593 assert(TPL->
size() == TemplateArgs.
size() &&
1594 "size mismatch between args and parms!");
1596 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1600 if (i > 0 && TA.
getKind() == TemplateArgument::Pack &&
1601 TemplateArgs[i - 1].getKind() == TemplateArgument::Pack)
1604 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1616 QualType BaseT =
V.getLValueBase().getType();
1617 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1618 V.getLValuePath()[0].getAsArrayIndex() != 0)
1621 V.getLValueBase().dyn_cast<
const ValueDecl *>());
1624 void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1660 case TemplateArgument::Null:
1661 llvm_unreachable(
"Can't mangle null template arguments!");
1662 case TemplateArgument::TemplateExpansion:
1663 llvm_unreachable(
"Can't mangle template expansion arguments!");
1669 case TemplateArgument::Declaration: {
1671 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1672 mangleMemberDataPointer(cast<CXXRecordDecl>(ND->
getDeclContext())
1673 ->getMostRecentNonInjectedDecl(),
1674 cast<ValueDecl>(ND));
1675 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1678 mangleMemberFunctionPointer(
1683 mangleFunctionEncoding(FD,
true);
1687 auto *TPO = cast<TemplateParamObjectDecl>(ND);
1688 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1689 TPO->getValue(), TplArgKind::ClassNTTP);
1695 case TemplateArgument::Integral: {
1698 cast<NonTypeTemplateParmDecl>(Parm),
T);
1701 case TemplateArgument::NullPtr: {
1704 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1705 if (MPT->isMemberFunctionPointerType() &&
1706 !isa<FunctionTemplateDecl>(TD)) {
1707 mangleMemberFunctionPointer(RD,
nullptr);
1710 if (MPT->isMemberDataPointer()) {
1711 if (!isa<FunctionTemplateDecl>(TD)) {
1712 mangleMemberDataPointer(RD,
nullptr);
1722 mangleIntegerLiteral(llvm::APSInt::get(-1),
1723 cast<NonTypeTemplateParmDecl>(Parm),
T);
1728 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1729 cast<NonTypeTemplateParmDecl>(Parm),
T);
1732 case TemplateArgument::StructuralValue:
1738 return mangleTemplateArg(
1742 if (cast<NonTypeTemplateParmDecl>(Parm)
1744 ->getContainedDeducedType()) {
1750 TplArgKind::StructuralValue,
1753 case TemplateArgument::Expression:
1754 mangleExpression(TA.
getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
1756 case TemplateArgument::Pack: {
1758 if (TemplateArgs.empty()) {
1759 if (isa<TemplateTypeParmDecl>(Parm) ||
1760 isa<TemplateTemplateParmDecl>(Parm))
1764 LangOptions::MSVC2015)
1767 else if (isa<NonTypeTemplateParmDecl>(Parm))
1770 llvm_unreachable(
"unexpected template parameter decl!");
1773 mangleTemplateArg(TD, PA, Parm);
1777 case TemplateArgument::Template: {
1780 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1782 }
else if (isa<TypeAliasDecl>(ND)) {
1786 llvm_unreachable(
"unexpected template template NamedDecl!");
1793 void MicrosoftCXXNameMangler::mangleTemplateArgValue(
QualType T,
1796 bool WithScalarType) {
1797 switch (
V.getKind()) {
1799 case APValue::Indeterminate:
1811 mangleNumber(
V.getInt());
1817 mangleFloat(
V.getFloat());
1820 case APValue::LValue: {
1825 if (
V.isLValueOnePastTheEnd())
1829 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1831 if (
Base.isNull()) {
1837 mangleNumber(
V.getLValueOffset().getQuantity());
1838 }
else if (!
V.hasLValuePath()) {
1852 SmallVector<std::function<void()>, 2> EntryManglers;
1856 EntryTypes.push_back(
'C');
1857 EntryManglers.push_back([
this, I = E.getAsArrayIndex()] {
1862 ET = AT->getElementType();
1866 const Decl *D = E.getAsBaseOrMember().getPointer();
1867 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
1873 ET = getASTContext().getRecordType(cast<CXXRecordDecl>(D));
1879 EntryTypes.push_back(
'6');
1880 EntryManglers.push_back([
this, D] {
1881 mangleUnqualifiedName(cast<NamedDecl>(D));
1886 for (
auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
1892 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
1895 for (
const std::function<
void()> &Mangler : EntryManglers)
1904 case APValue::MemberPointer: {
1910 const ValueDecl *D =
V.getMemberPointerDecl();
1911 if (TAK == TplArgKind::ClassNTTP) {
1913 mangleMemberDataPointerInClassNTTP(RD, D);
1915 mangleMemberFunctionPointerInClassNTTP(RD,
1916 cast_or_null<CXXMethodDecl>(D));
1919 mangleMemberDataPointer(RD, D,
"");
1921 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D),
"");
1926 case APValue::Struct: {
1930 assert(RD &&
"unexpected type for record value");
1932 unsigned BaseIndex = 0;
1934 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
1936 if (!FD->isUnnamedBitField())
1937 mangleTemplateArgValue(FD->
getType(),
1938 V.getStructField(FD->getFieldIndex()), TAK,
1944 case APValue::Union:
1947 if (
const FieldDecl *FD =
V.getUnionField()) {
1948 mangleUnqualifiedName(FD);
1949 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
1954 case APValue::ComplexInt:
1959 mangleNumber(
V.getComplexIntReal());
1961 mangleNumber(
V.getComplexIntImag());
1965 case APValue::ComplexFloat:
1968 mangleFloat(
V.getComplexFloatReal());
1969 mangleFloat(
V.getComplexFloatImag());
1973 case APValue::Array: {
1975 QualType ElemT = getASTContext().getAsArrayType(
T)->getElementType();
1977 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
1978 const APValue &ElemV = I <
V.getArrayInitializedElts()
1979 ?
V.getArrayInitializedElt(I)
1980 :
V.getArrayFiller();
1981 mangleTemplateArgValue(ElemT, ElemV, TAK);
1988 case APValue::Vector: {
1996 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
1997 const APValue &ElemV =
V.getVectorElt(I);
1998 mangleTemplateArgValue(ElemT, ElemV, TAK);
2005 case APValue::AddrLabelDiff:
2006 case APValue::FixedPoint:
2016 void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2018 llvm::raw_svector_ostream Stream(TemplateMangling);
2019 MicrosoftCXXNameMangler Extra(Context, Stream);
2022 Extra.mangleSourceName(
"Protocol");
2023 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2025 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2028 void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType Type,
2032 llvm::raw_svector_ostream Stream(TemplateMangling);
2033 MicrosoftCXXNameMangler Extra(Context, Stream);
2037 case Qualifiers::OCL_None:
2038 case Qualifiers::OCL_ExplicitNone:
2040 case Qualifiers::OCL_Autoreleasing:
2041 Extra.mangleSourceName(
"Autoreleasing");
2043 case Qualifiers::OCL_Strong:
2044 Extra.mangleSourceName(
"Strong");
2046 case Qualifiers::OCL_Weak:
2047 Extra.mangleSourceName(
"Weak");
2050 Extra.manglePointerCVQualifiers(Quals);
2051 Extra.manglePointerExtQualifiers(Quals,
Type);
2054 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2057 void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *
T,
2061 llvm::raw_svector_ostream Stream(TemplateMangling);
2062 MicrosoftCXXNameMangler Extra(Context, Stream);
2065 Extra.mangleSourceName(
"KindOf");
2067 .stripObjCKindOfType(getASTContext())
2068 ->castAs<ObjCObjectType>(),
2071 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2074 void MicrosoftCXXNameMangler::mangleQualifiers(
Qualifiers Quals,
2132 if (HasConst && HasVolatile) {
2134 }
else if (HasVolatile) {
2136 }
else if (HasConst) {
2142 if (HasConst && HasVolatile) {
2144 }
else if (HasVolatile) {
2146 }
else if (HasConst) {
2157 MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2160 switch (RefQualifier) {
2174 void MicrosoftCXXNameMangler::manglePointerExtQualifiers(
Qualifiers Quals,
2177 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2190 void MicrosoftCXXNameMangler::manglePointerCVQualifiers(
Qualifiers Quals) {
2198 if (HasConst && HasVolatile) {
2200 }
else if (HasVolatile) {
2202 }
else if (HasConst) {
2209 void MicrosoftCXXNameMangler::mangleFunctionArgumentType(
QualType T,
2220 QualType OriginalType = DT->getOriginalType();
2223 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2224 OriginalType = getASTContext().getIncompleteArrayType(
2225 AT->getElementType(), AT->getSizeModifier(),
2226 AT->getIndexTypeCVRQualifiers());
2237 TypePtr =
T.getCanonicalType().getAsOpaquePtr();
2240 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);
2242 if (Found == FunArgBackReferences.end()) {
2243 size_t OutSizeBefore = Out.tell();
2245 mangleType(
T,
Range, QMM_Drop);
2250 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);
2251 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2252 size_t Size = FunArgBackReferences.size();
2253 FunArgBackReferences[TypePtr] =
Size;
2256 Out << Found->second;
2260 void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2261 const PassObjectSizeAttr *POSA) {
2262 int Type = POSA->getType();
2263 bool Dynamic = POSA->isDynamic();
2266 auto *TypePtr = (
const void *)&*
Iter;
2267 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);
2269 if (Found == FunArgBackReferences.end()) {
2271 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2272 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2275 if (FunArgBackReferences.size() < 10) {
2276 size_t Size = FunArgBackReferences.size();
2277 FunArgBackReferences[TypePtr] =
Size;
2280 Out << Found->second;
2284 void MicrosoftCXXNameMangler::mangleAddressSpaceType(
QualType T,
2302 llvm::raw_svector_ostream Stream(ASMangling);
2303 MicrosoftCXXNameMangler Extra(Context, Stream);
2309 Extra.mangleSourceName(
"_AS");
2310 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2314 llvm_unreachable(
"Not a language specific address space");
2315 case LangAS::opencl_global:
2316 Extra.mangleSourceName(
"_ASCLglobal");
2318 case LangAS::opencl_global_device:
2319 Extra.mangleSourceName(
"_ASCLdevice");
2321 case LangAS::opencl_global_host:
2322 Extra.mangleSourceName(
"_ASCLhost");
2324 case LangAS::opencl_local:
2325 Extra.mangleSourceName(
"_ASCLlocal");
2327 case LangAS::opencl_constant:
2328 Extra.mangleSourceName(
"_ASCLconstant");
2330 case LangAS::opencl_private:
2331 Extra.mangleSourceName(
"_ASCLprivate");
2333 case LangAS::opencl_generic:
2334 Extra.mangleSourceName(
"_ASCLgeneric");
2336 case LangAS::cuda_device:
2337 Extra.mangleSourceName(
"_ASCUdevice");
2339 case LangAS::sycl_global:
2340 Extra.mangleSourceName(
"_ASSYglobal");
2342 case LangAS::sycl_global_device:
2343 Extra.mangleSourceName(
"_ASSYdevice");
2345 case LangAS::sycl_global_host:
2346 Extra.mangleSourceName(
"_ASSYhost");
2348 case LangAS::sycl_local:
2349 Extra.mangleSourceName(
"_ASSYlocal");
2351 case LangAS::sycl_private:
2352 Extra.mangleSourceName(
"_ASSYprivate");
2354 case LangAS::cuda_constant:
2355 Extra.mangleSourceName(
"_ASCUconstant");
2357 case LangAS::cuda_shared:
2358 Extra.mangleSourceName(
"_ASCUshared");
2360 case LangAS::ptr32_sptr:
2361 case LangAS::ptr32_uptr:
2363 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2367 Extra.mangleType(
T,
Range, QMM_Escape);
2369 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2373 QualifierMangleMode QMM) {
2376 T =
T.getDesugaredType(getASTContext());
2379 if (
const ArrayType *AT = getASTContext().getAsArrayType(
T)) {
2382 if (QMM == QMM_Mangle)
2384 else if (QMM == QMM_Escape || QMM == QMM_Result)
2386 mangleArrayType(AT);
2401 mangleFunctionType(FT);
2404 mangleQualifiers(Quals,
false);
2407 if (!IsPointer && Quals) {
2409 mangleQualifiers(Quals,
false);
2417 if ((!IsPointer && Quals) || isa<TagType>(
T) || isArtificialTagType(
T)) {
2419 mangleQualifiers(Quals,
false);
2424 const Type *ty =
T.getTypePtr();
2427 #define ABSTRACT_TYPE(CLASS, PARENT)
2428 #define NON_CANONICAL_TYPE(CLASS, PARENT) \
2430 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2432 #define TYPE(CLASS, PARENT) \
2434 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2436 #include "clang/AST/TypeNodes.inc"
2437 #undef ABSTRACT_TYPE
2438 #undef NON_CANONICAL_TYPE
2472 switch (
T->getKind()) {
2473 case BuiltinType::Void:
2476 case BuiltinType::SChar:
2479 case BuiltinType::Char_U:
2480 case BuiltinType::Char_S:
2483 case BuiltinType::UChar:
2486 case BuiltinType::Short:
2489 case BuiltinType::UShort:
2492 case BuiltinType::Int:
2495 case BuiltinType::UInt:
2498 case BuiltinType::Long:
2501 case BuiltinType::ULong:
2507 case BuiltinType::Double:
2511 case BuiltinType::LongDouble:
2514 case BuiltinType::LongLong:
2517 case BuiltinType::ULongLong:
2520 case BuiltinType::Int128:
2523 case BuiltinType::UInt128:
2526 case BuiltinType::Bool:
2529 case BuiltinType::Char8:
2532 case BuiltinType::Char16:
2535 case BuiltinType::Char32:
2538 case BuiltinType::WChar_S:
2539 case BuiltinType::WChar_U:
2543 #define BUILTIN_TYPE(Id, SingletonId)
2544 #define PLACEHOLDER_TYPE(Id, SingletonId) \
2545 case BuiltinType::Id:
2546 #include "clang/AST/BuiltinTypes.def"
2547 case BuiltinType::Dependent:
2548 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2550 case BuiltinType::ObjCId:
2551 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2553 case BuiltinType::ObjCClass:
2554 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2556 case BuiltinType::ObjCSel:
2557 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2560 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2561 case BuiltinType::Id: \
2562 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2564 #include "clang/Basic/OpenCLImageTypes.def"
2565 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2566 case BuiltinType::Sampled##Id: \
2567 Out << "PAU__spirv_SampledImage__" #ImgType "_" #Suffix "@@"; \
2569 #define IMAGE_WRITE_TYPE(Type, Id, Ext)
2570 #define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
2571 #include "clang/Basic/OpenCLImageTypes.def"
2572 case BuiltinType::OCLSampler:
2574 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2576 case BuiltinType::OCLEvent:
2578 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2580 case BuiltinType::OCLClkEvent:
2582 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2584 case BuiltinType::OCLQueue:
2586 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2588 case BuiltinType::OCLReserveID:
2590 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2592 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2593 case BuiltinType::Id: \
2594 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2596 #include "clang/Basic/OpenCLExtensionTypes.def"
2598 case BuiltinType::NullPtr:
2602 case BuiltinType::Float16:
2603 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2606 case BuiltinType::Half:
2607 if (!getASTContext().getLangOpts().
HLSL)
2608 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2609 else if (getASTContext().getLangOpts().NativeHalfType)
2615 case BuiltinType::BFloat16:
2616 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2619 #define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2620 case BuiltinType::Id: \
2621 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2622 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2625 #include "clang/Basic/WebAssemblyReferenceTypes.def"
2626 #define SVE_TYPE(Name, Id, SingletonId) \
2627 case BuiltinType::Id:
2628 #include "clang/Basic/AArch64SVEACLETypes.def"
2629 #define PPC_VECTOR_TYPE(Name, Id, Size) \
2630 case BuiltinType::Id:
2631 #include "clang/Basic/PPCTypes.def"
2632 #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2633 #include "clang/Basic/RISCVVTypes.def"
2634 case BuiltinType::ShortAccum:
2635 case BuiltinType::Accum:
2636 case BuiltinType::LongAccum:
2637 case BuiltinType::UShortAccum:
2638 case BuiltinType::UAccum:
2639 case BuiltinType::ULongAccum:
2640 case BuiltinType::ShortFract:
2641 case BuiltinType::Fract:
2642 case BuiltinType::LongFract:
2643 case BuiltinType::UShortFract:
2644 case BuiltinType::UFract:
2645 case BuiltinType::ULongFract:
2646 case BuiltinType::SatShortAccum:
2647 case BuiltinType::SatAccum:
2648 case BuiltinType::SatLongAccum:
2649 case BuiltinType::SatUShortAccum:
2650 case BuiltinType::SatUAccum:
2651 case BuiltinType::SatULongAccum:
2652 case BuiltinType::SatShortFract:
2653 case BuiltinType::SatFract:
2654 case BuiltinType::SatLongFract:
2655 case BuiltinType::SatUShortFract:
2656 case BuiltinType::SatUFract:
2657 case BuiltinType::SatULongFract:
2658 case BuiltinType::Ibm128:
2659 case BuiltinType::Float128: {
2678 mangleFunctionType(
T,
nullptr,
true);
2681 mangleFunctionType(
T);
2687 mangleFunctionType(
T);
2690 void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *
T,
2692 bool ForceThisQuals,
2693 bool MangleExceptionSpec) {
2701 bool IsInLambda =
false;
2702 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
2704 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
2708 HasThisQuals =
true;
2709 if (isa<CXXDestructorDecl>(MD)) {
2711 }
else if (isa<CXXConstructorDecl>(MD)) {
2717 CC = getASTContext().getDefaultCallingConvention(
2726 manglePointerExtQualifiers(Quals,
QualType());
2728 mangleQualifiers(Quals,
false);
2731 mangleCallingConvention(CC);
2736 if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
2740 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
2749 if (IsCtorClosure) {
2759 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
2767 llvm_unreachable(
"unexpected constructor closure!");
2773 }
else if (IsInLambda && D && isa<CXXConversionDecl>(D)) {
2780 if (IsInLambda && isa<CXXConversionDecl>(D)) {
2784 mangleType(ResultType,
Range, QMM_Result);
2785 }
else if (
const auto *AT = dyn_cast_or_null<AutoType>(
2790 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2791 "shouldn't need to mangle __auto_type!");
2792 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
2794 }
else if (IsInLambda) {
2799 mangleType(ResultType,
Range, QMM_Result);
2815 for (
unsigned I = 0, E = Proto->
getNumParams(); I != E; ++I) {
2831 manglePassObjectSizeArg(
P);
2840 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
2841 getASTContext().getLangOpts().isCompatibleWithMSVC(
2842 LangOptions::MSVC2017_5))
2843 mangleThrowSpecification(Proto);
2848 void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
2873 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
2877 if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
2883 llvm_unreachable(
"Unsupported access specifier");
2912 void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC) {
2937 llvm_unreachable(
"Unsupported CC for mangling");
2940 case CC_C: Out <<
'A';
break;
2950 if (getASTContext().getLangOpts().RegCall4)
2961 if (!getASTContext().getLangOpts().SYCLIsNativeCPU)
2964 llvm_unreachable(
"Unsupported CC for mangling");
2968 void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *
T) {
2972 void MicrosoftCXXNameMangler::mangleThrowSpecification(
2988 "cannot mangle this unresolved dependent type yet");
2998 void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
3000 case TagTypeKind::Union:
3003 case TagTypeKind::Struct:
3004 case TagTypeKind::Interface:
3007 case TagTypeKind::Class:
3010 case TagTypeKind::Enum:
3017 mangleType(cast<TagType>(
T)->getDecl());
3021 mangleType(cast<TagType>(
T)->getDecl());
3023 void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3029 void MicrosoftCXXNameMangler::mangleArtificialTagType(
3033 mangleTagTypeKind(TK);
3036 mangleSourceName(UnqualifiedName);
3038 for (StringRef N : llvm::reverse(NestedNames))
3039 mangleSourceName(N);
3052 void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *
T) {
3055 manglePointerCVQualifiers(
T->getElementType().getQualifiers());
3060 llvm_unreachable(
"Should have been special cased");
3064 llvm_unreachable(
"Should have been special cased");
3068 llvm_unreachable(
"Should have been special cased");
3072 llvm_unreachable(
"Should have been special cased");
3074 void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *
T) {
3078 if (ElementTy->isConstantArrayType()) {
3080 getASTContext().getAsConstantArrayType(ElementTy);
3081 Dimensions.push_back(CAT->
getSize());
3083 }
else if (ElementTy->isIncompleteArrayType()) {
3085 getASTContext().getAsIncompleteArrayType(ElementTy);
3088 }
else if (ElementTy->isVariableArrayType()) {
3090 getASTContext().getAsVariableArrayType(ElementTy);
3093 }
else if (ElementTy->isDependentSizedArrayType()) {
3096 getASTContext().getAsDependentSizedArrayType(ElementTy);
3099 "cannot mangle this dependent-length array yet");
3109 mangleNumber(Dimensions.size());
3111 mangleNumber(Dimension.getLimitedValue());
3117 mangleArrayType(cast<ConstantArrayType>(
T));
3126 manglePointerCVQualifiers(Quals);
3127 manglePointerExtQualifiers(Quals, PointeeType);
3131 mangleFunctionType(FPT,
nullptr,
true);
3135 mangleType(PointeeType,
Range, QMM_Drop);
3143 "cannot mangle this template type parameter type yet");
3152 "cannot mangle this substituted parameter pack yet");
3163 manglePointerCVQualifiers(Quals);
3164 manglePointerExtQualifiers(Quals, PointeeType);
3170 mangleType(PointeeType,
Range);
3179 case Qualifiers::OCL_None:
3180 case Qualifiers::OCL_ExplicitNone:
3182 case Qualifiers::OCL_Autoreleasing:
3183 case Qualifiers::OCL_Strong:
3184 case Qualifiers::OCL_Weak:
3185 return mangleObjCLifetime(PointeeType, Quals,
Range);
3187 manglePointerCVQualifiers(Quals);
3188 manglePointerExtQualifiers(Quals, PointeeType);
3189 mangleType(PointeeType,
Range);
3200 manglePointerExtQualifiers(Quals, PointeeType);
3201 mangleType(PointeeType,
Range);
3212 manglePointerExtQualifiers(Quals, PointeeType);
3213 mangleType(PointeeType,
Range);
3218 QualType ElementType =
T->getElementType();
3221 llvm::raw_svector_ostream Stream(TemplateMangling);
3222 MicrosoftCXXNameMangler Extra(Context, Stream);
3224 Extra.mangleSourceName(
"_Complex");
3225 Extra.mangleType(ElementType,
Range, QMM_Escape);
3227 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3235 bool MicrosoftCXXNameMangler::isArtificialTagType(
QualType T)
const {
3236 const Type *ty =
T.getTypePtr();
3241 case Type::Vector: {
3255 assert((ET || BitIntTy) &&
3256 "vectors with non-builtin/_BitInt elements are unsupported");
3257 uint64_t Width = getASTContext().getTypeSize(
T);
3260 size_t OutSizeBefore = Out.tell();
3261 if (!isa<ExtVectorType>(
T)) {
3262 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
3263 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3264 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3265 }
else if (Width >= 128) {
3267 mangleArtificialTagType(TagTypeKind::Union,
3268 "__m" + llvm::utostr(Width));
3269 else if (ET->
getKind() == BuiltinType::LongLong)
3270 mangleArtificialTagType(TagTypeKind::Union,
3271 "__m" + llvm::utostr(Width) +
'i');
3272 else if (ET->
getKind() == BuiltinType::Double)
3273 mangleArtificialTagType(TagTypeKind::Struct,
3274 "__m" + llvm::utostr(Width) +
'd');
3279 bool IsBuiltin = Out.tell() != OutSizeBefore;
3286 llvm::raw_svector_ostream Stream(TemplateMangling);
3287 MicrosoftCXXNameMangler Extra(Context, Stream);
3289 Extra.mangleSourceName(
"__vector");
3290 Extra.mangleType(
QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3292 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumElements()));
3294 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3308 "cannot mangle this dependent-sized vector type yet");
3316 "cannot mangle this dependent-sized extended vector type yet");
3325 "Cannot mangle this matrix type yet");
3334 "Cannot mangle this dependent-sized matrix type yet");
3343 "cannot mangle this dependent address space type yet");
3350 mangleTagTypeKind(TagTypeKind::Struct);
3351 mangleName(
T->getDecl());
3356 if (
T->isKindOfType())
3357 return mangleObjCKindOfType(
T, Quals,
Range);
3359 if (
T->qual_empty() && !
T->isSpecialized())
3360 return mangleType(
T->getBaseType(),
Range, QMM_Drop);
3362 ArgBackRefMap OuterFunArgsContext;
3363 ArgBackRefMap OuterTemplateArgsContext;
3364 BackRefVec OuterTemplateContext;
3366 FunArgBackReferences.swap(OuterFunArgsContext);
3367 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3368 NameBackReferences.swap(OuterTemplateContext);
3370 mangleTagTypeKind(TagTypeKind::Struct);
3374 mangleSourceName(
"objc_object");
3375 else if (
T->isObjCClass())
3376 mangleSourceName(
"objc_class");
3378 mangleSourceName(
T->getInterface()->getName());
3380 for (
const auto &Q :
T->quals())
3381 mangleObjCProtocol(Q);
3383 if (
T->isSpecialized())
3384 for (
const auto &TA :
T->getTypeArgs())
3385 mangleType(TA,
Range, QMM_Drop);
3391 FunArgBackReferences.swap(OuterFunArgsContext);
3392 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3393 NameBackReferences.swap(OuterTemplateContext);
3399 manglePointerCVQualifiers(Quals);
3400 manglePointerExtQualifiers(Quals, PointeeType);
3409 llvm_unreachable(
"Cannot mangle injected class name type.");
3416 "cannot mangle this template specialization type yet");
3425 "cannot mangle this dependent name type yet");
3430 void MicrosoftCXXNameMangler::mangleType(
3435 "cannot mangle this dependent template specialization type yet");
3444 "cannot mangle this pack expansion yet");
3451 manglePointerCVQualifiers(Quals);
3452 mangleType(
T->getSelectedType(),
Range);
3459 "cannot mangle this typeof(type) yet");
3468 "cannot mangle this typeof(expression) yet");
3477 "cannot mangle this decltype() yet");
3486 "cannot mangle this unary transform type yet");
3493 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3497 "cannot mangle this 'auto' type yet");
3502 void MicrosoftCXXNameMangler::mangleType(
3504 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3508 "cannot mangle this deduced class template specialization type yet");
3518 llvm::raw_svector_ostream Stream(TemplateMangling);
3519 MicrosoftCXXNameMangler Extra(Context, Stream);
3521 Extra.mangleSourceName(
"_Atomic");
3522 Extra.mangleType(ValueType,
Range, QMM_Escape);
3524 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3529 QualType ElementType =
T->getElementType();
3532 llvm::raw_svector_ostream Stream(TemplateMangling);
3533 MicrosoftCXXNameMangler Extra(Context, Stream);
3535 Extra.mangleSourceName(
"ocl_pipe");
3536 Extra.mangleType(ElementType,
Range, QMM_Escape);
3537 Extra.mangleIntegerLiteral(llvm::APSInt::get(
T->isReadOnly()));
3539 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3542 void MicrosoftMangleContextImpl::mangleCXXName(
GlobalDecl GD,
3546 getASTContext().getSourceManager(),
3547 "Mangling declaration");
3549 msvc_hashing_ostream MHO(Out);
3551 if (
auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3553 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3554 return mangler.mangle(GD);
3557 if (
auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3559 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3560 return mangler.mangle(GD);
3563 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3564 return Mangler.mangle(GD);
3570 llvm::raw_svector_ostream Stream(TemplateMangling);
3571 MicrosoftCXXNameMangler Extra(Context, Stream);
3573 if (
T->isUnsigned())
3574 Extra.mangleSourceName(
"_UBitInt");
3576 Extra.mangleSourceName(
"_BitInt");
3577 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumBits()));
3579 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3616 MicrosoftCXXNameMangler &Mangler,
3623 llvm_unreachable(
"Unsupported access specifier");
3634 Out <<
'R' << AccessSpec;
3635 Mangler.mangleNumber(
3637 Mangler.mangleNumber(
3639 Mangler.mangleNumber(
3641 Mangler.mangleNumber(
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3644 Mangler.mangleNumber(
3646 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3651 llvm_unreachable(
"Unsupported access specifier");
3661 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3665 llvm_unreachable(
"Unsupported access specifier");
3678 void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
3681 msvc_hashing_ostream MHO(Out);
3682 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3683 Mangler.getStream() <<
'?';
3684 Mangler.mangleVirtualMemPtrThunk(MD, ML);
3687 void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
3690 msvc_hashing_ostream MHO(Out);
3691 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3692 Mangler.getStream() <<
'?';
3693 Mangler.mangleName(MD);
3702 assert(Thunk.
Method !=
nullptr &&
3703 "Thunk info should hold the overridee decl");
3706 Mangler.mangleFunctionType(
3710 void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
3717 msvc_hashing_ostream MHO(Out);
3718 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
3719 Mangler.getStream() <<
"??_E";
3725 void MicrosoftMangleContextImpl::mangleCXXVFTable(
3732 msvc_hashing_ostream MHO(Out);
3733 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3734 if (Derived->
hasAttr<DLLImportAttr>())
3735 Mangler.getStream() <<
"??_S";
3737 Mangler.getStream() <<
"??_7";
3738 Mangler.mangleName(Derived);
3739 Mangler.getStream() <<
"6B";
3741 Mangler.mangleName(RD);
3742 Mangler.getStream() <<
'@';
3745 void MicrosoftMangleContextImpl::mangleCXXVBTable(
3752 msvc_hashing_ostream MHO(Out);
3753 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3754 Mangler.getStream() <<
"??_8";
3755 Mangler.mangleName(Derived);
3756 Mangler.getStream() <<
"7B";
3758 Mangler.mangleName(RD);
3759 Mangler.getStream() <<
'@';
3762 void MicrosoftMangleContextImpl::mangleCXXRTTI(
QualType T, raw_ostream &Out) {
3763 msvc_hashing_ostream MHO(Out);
3764 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3765 Mangler.getStream() <<
"??_R0";
3766 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3767 Mangler.getStream() <<
"@8";
3770 void MicrosoftMangleContextImpl::mangleCXXRTTIName(
3771 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
3772 MicrosoftCXXNameMangler Mangler(*
this, Out);
3773 Mangler.getStream() <<
'.';
3774 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3777 void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
3779 msvc_hashing_ostream MHO(Out);
3780 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3781 Mangler.getStream() <<
"??_K";
3782 Mangler.mangleName(SrcRD);
3783 Mangler.getStream() <<
"$C";
3784 Mangler.mangleName(DstRD);
3787 void MicrosoftMangleContextImpl::mangleCXXThrowInfo(
QualType T,
bool IsConst,
3790 uint32_t NumEntries,
3792 msvc_hashing_ostream MHO(Out);
3793 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3794 Mangler.getStream() <<
"_TI";
3796 Mangler.getStream() <<
'C';
3798 Mangler.getStream() <<
'V';
3800 Mangler.getStream() <<
'U';
3801 Mangler.getStream() << NumEntries;
3802 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3805 void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
3806 QualType T, uint32_t NumEntries, raw_ostream &Out) {
3807 msvc_hashing_ostream MHO(Out);
3808 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3809 Mangler.getStream() <<
"_CTA";
3810 Mangler.getStream() << NumEntries;
3811 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3814 void MicrosoftMangleContextImpl::mangleCXXCatchableType(
3816 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
3818 MicrosoftCXXNameMangler Mangler(*
this, Out);
3819 Mangler.getStream() <<
"_CT";
3823 llvm::raw_svector_ostream Stream(RTTIMangling);
3824 msvc_hashing_ostream MHO(Stream);
3825 mangleCXXRTTI(
T, MHO);
3827 Mangler.getStream() << RTTIMangling;
3835 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
3836 LangOptions::MSVC2015) &&
3837 !getASTContext().getLangOpts().isCompatibleWithMSVC(
3838 LangOptions::MSVC2017_7);
3840 if (!OmitCopyCtor && CD) {
3841 llvm::raw_svector_ostream Stream(CopyCtorMangling);
3842 msvc_hashing_ostream MHO(Stream);
3845 Mangler.getStream() << CopyCtorMangling;
3847 Mangler.getStream() <<
Size;
3848 if (VBPtrOffset == -1) {
3850 Mangler.getStream() << NVOffset;
3853 Mangler.getStream() << NVOffset;
3854 Mangler.getStream() << VBPtrOffset;
3855 Mangler.getStream() << VBIndex;
3859 void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
3860 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
3861 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
3862 msvc_hashing_ostream MHO(Out);
3863 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3864 Mangler.getStream() <<
"??_R1";
3865 Mangler.mangleNumber(NVOffset);
3866 Mangler.mangleNumber(VBPtrOffset);
3867 Mangler.mangleNumber(VBTableOffset);
3868 Mangler.mangleNumber(Flags);
3869 Mangler.mangleName(Derived);
3870 Mangler.getStream() <<
"8";
3873 void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
3875 msvc_hashing_ostream MHO(Out);
3876 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3877 Mangler.getStream() <<
"??_R2";
3878 Mangler.mangleName(Derived);
3879 Mangler.getStream() <<
"8";
3882 void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
3884 msvc_hashing_ostream MHO(Out);
3885 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3886 Mangler.getStream() <<
"??_R3";
3887 Mangler.mangleName(Derived);
3888 Mangler.getStream() <<
"8";
3891 void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
3899 llvm::raw_svector_ostream Stream(VFTableMangling);
3900 mangleCXXVFTable(Derived, BasePath, Stream);
3902 if (VFTableMangling.starts_with(
"??@")) {
3903 assert(VFTableMangling.ends_with(
"@"));
3904 Out << VFTableMangling <<
"??_R4@";
3908 assert(VFTableMangling.starts_with(
"??_7") ||
3909 VFTableMangling.starts_with(
"??_S"));
3911 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
3914 void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
3915 GlobalDecl EnclosingDecl, raw_ostream &Out) {
3916 msvc_hashing_ostream MHO(Out);
3917 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3922 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
3923 Mangler.mangleName(EnclosingDecl);
3926 void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
3927 GlobalDecl EnclosingDecl, raw_ostream &Out) {
3928 msvc_hashing_ostream MHO(Out);
3929 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3934 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
3935 Mangler.mangleName(EnclosingDecl);
3938 void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
3939 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
3942 MicrosoftCXXNameMangler Mangler(*
this, Out);
3943 Mangler.getStream() <<
'?';
3944 Mangler.mangleType(
T.getCanonicalType(),
SourceRange());
3947 void MicrosoftMangleContextImpl::mangleReferenceTemporary(
3948 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
3949 msvc_hashing_ostream MHO(Out);
3950 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3952 Mangler.getStream() <<
"?";
3953 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
3954 Mangler.mangle(VD,
"");
3957 void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
3958 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
3959 msvc_hashing_ostream MHO(Out);
3960 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3962 Mangler.getStream() <<
"?";
3963 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
3964 Mangler.mangleNestedName(VD);
3965 Mangler.getStream() <<
"@4HA";
3968 void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
3980 msvc_hashing_ostream MHO(Out);
3981 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3985 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
3987 Mangler.getStream() <<
"?$S1@";
3989 unsigned ScopeDepth = 0;
3990 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
3994 Mangler.mangle(VD,
"");
3996 Mangler.mangleNestedName(VD);
3997 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
3999 Mangler.mangleNumber(ScopeDepth);
4002 void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *D,
4005 msvc_hashing_ostream MHO(Out);
4006 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4007 Mangler.getStream() <<
"??__" << CharCode;
4009 Mangler.getStream() <<
'?';
4010 Mangler.mangleName(D);
4011 Mangler.mangleVariableEncoding(D);
4012 Mangler.getStream() <<
"@@";
4014 Mangler.mangleName(D);
4018 Mangler.getStream() <<
"YAXXZ";
4021 void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *D,
4024 mangleInitFiniStub(D,
'E', Out);
4028 MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *D,
4031 mangleInitFiniStub(D,
'F', Out);
4034 void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4055 MicrosoftCXXNameMangler Mangler(*
this, Out);
4056 Mangler.getStream() <<
"??_C@_";
4064 unsigned StringLength =
4065 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4070 Mangler.getStream() <<
'1';
4072 Mangler.getStream() <<
'0';
4076 Mangler.mangleNumber(StringByteLength);
4078 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4080 if (Index / CharByteWidth >= SL->
getLength())
4081 return static_cast<char>(0);
4082 uint32_t CodeUnit = SL->
getCodeUnit(Index / CharByteWidth);
4083 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4084 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4087 auto GetBigEndianByte = [&SL](
unsigned Index) {
4089 if (Index / CharByteWidth >= SL->
getLength())
4090 return static_cast<char>(0);
4091 uint32_t CodeUnit = SL->
getCodeUnit(Index / CharByteWidth);
4092 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4093 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4098 for (
unsigned I = 0, E = StringByteLength; I != E; ++I)
4099 JC.update(GetLittleEndianByte(I));
4103 Mangler.mangleNumber(JC.getCRC());
4109 auto MangleByte = [&Mangler](
char Byte) {
4117 Mangler.getStream() << Byte;
4118 }
else if (
isLetter(Byte & 0x7f)) {
4119 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4121 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4122 ' ',
'\n',
'\t',
'\'',
'-'};
4123 const char *Pos = llvm::find(SpecialChars, Byte);
4124 if (Pos != std::end(SpecialChars)) {
4125 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4127 Mangler.getStream() <<
"?$";
4128 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4129 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4135 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4136 unsigned NumBytesToMangle =
std::min(MaxBytesToMangle, StringByteLength);
4137 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4139 MangleByte(GetBigEndianByte(I));
4141 MangleByte(GetLittleEndianByte(I));
4144 Mangler.getStream() <<
'@';
4150 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.
Defines the clang::FileManager interface and associated types.
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 GlobalDecl isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs)
static void mangleThunkThisAdjustment(AccessSpecifier AS, const ThisAdjustment &Adjustment, MicrosoftCXXNameMangler &Mangler, raw_ostream &Out)
Defines the SourceManager interface.
__DEVICE__ int min(int __a, int __b)
__DEVICE__ int max(int __a, int __b)
A non-discriminated union of a base, field, or array index.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const clang::PrintingPolicy & getPrintingPolicy() const
SourceManager & getSourceManager()
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
const LangOptions & getLangOpts() const
bool addressSpaceMapManglingFor(LangAS AS) 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...
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 ...
CXXRecordDecl * getMostRecentNonInjectedDecl()
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
AccessSpecifier getAccess() const
DeclContext * getDeclContext()
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
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.
SourceRange getBracketsRange() const
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.
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.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
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.
const ParmVarDecl * getParamDecl(unsigned i) const
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)
const Decl * getDecl() const
CXXDtorType getDtorType() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
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
A pointer to member type per C++ 8.3.3 - Pointers to members.
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
This represents a decl that may have a name.
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.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
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.
bool isExplicitObjectParameter() 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.
void * getAsOpaquePtr() const
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.
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.
bool hasUnaligned() const
bool hasAddressSpace() 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...
RecordDecl * getDecl() const
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 set of types for a template type parameter pack.
Represents the declaration of a 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.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
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.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
ArgKind getKind() const
Return the kind of stored template argument.
Expr * getAsExpr() const
Retrieve the template argument as an expression.
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() 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.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBlockPointerType() const
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
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.
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
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
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.
constexpr XRayInstrMask None
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
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)
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.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Diagnostic wrappers for TextAPI types for error reporting.
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.
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
struct clang::ThisAdjustment::VirtualAdjustment::@191 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...