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"
49 if (
auto *CD = dyn_cast<CXXConstructorDecl>(DC))
51 else if (
auto *DD = dyn_cast<CXXDestructorDecl>(DC))
58struct msvc_hashing_ostream :
public llvm::raw_svector_ostream {
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 <<
'@';
89getLambdaDefaultArgumentDeclContext(
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;
160 raw_ostream &Out)
override;
162 bool ElideOverrideInfo, raw_ostream &)
override;
164 const ThunkInfo &Thunk,
bool ElideOverrideInfo,
165 raw_ostream &)
override;
168 raw_ostream &Out)
override;
171 raw_ostream &Out)
override;
176 raw_ostream &Out)
override;
178 bool IsUnaligned, uint32_t NumEntries,
179 raw_ostream &Out)
override;
181 raw_ostream &Out)
override;
184 int32_t VBPtrOffset, uint32_t VBIndex,
185 raw_ostream &Out)
override;
188 bool NormalizeIntegers)
override;
190 uint32_t NVOffset, int32_t VBPtrOffset,
191 uint32_t VBTableOffset, uint32_t Flags,
192 raw_ostream &Out)
override;
194 raw_ostream &Out)
override;
196 raw_ostream &Out)
override;
200 raw_ostream &Out)
override;
202 bool NormalizeIntegers)
override;
204 raw_ostream &)
override;
207 raw_ostream &Out)
override;
210 raw_ostream &Out)
override;
212 raw_ostream &Out)
override;
214 raw_ostream &Out)
override;
216 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
217 const DeclContext *DC = getEffectiveDeclContext(ND);
223 if (
const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
224 if (RD->isLambda()) {
237 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
238 if (!
Tag->hasNameForLinkage() &&
239 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
245 unsigned &discriminator = Uniquifier[ND];
247 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
248 disc = discriminator + 1;
253 assert(Lambda->
isLambda() &&
"RD must be a lambda!");
254 std::string Name(
"<lambda_");
259 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
264 unsigned DefaultArgNo =
266 Name += llvm::utostr(DefaultArgNo);
270 if (LambdaManglingNumber)
271 LambdaId = LambdaManglingNumber;
273 LambdaId = getLambdaIdForDebugInfo(Lambda);
275 Name += llvm::utostr(LambdaId);
281 assert(RD->
isLambda() &&
"RD must be a lambda!");
284 "RD must not have a mangling number!");
285 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator,
bool>
286 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
287 return Result.first->second;
291 assert(RD->
isLambda() &&
"RD must be a lambda!");
294 "RD must not have a mangling number!");
296 return LambdaIds.lookup(RD);
301 StringRef getAnonymousNamespaceHash()
const {
302 return AnonymousNamespaceHash;
306 void mangleInitFiniStub(
const VarDecl *
D,
char CharCode, raw_ostream &Out);
311class MicrosoftCXXNameMangler {
312 MicrosoftMangleContextImpl &Context;
319 unsigned StructorType;
322 BackRefVec NameBackReferences;
324 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
325 ArgBackRefMap FunArgBackReferences;
326 ArgBackRefMap TemplateArgBackReferences;
328 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
329 TemplateArgStringMap TemplateArgStrings;
330 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
331 llvm::StringSaver TemplateArgStringStorage;
333 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
334 PassObjectSizeArgsSet PassObjectSizeArgs;
336 ASTContext &getASTContext()
const {
return Context.getASTContext(); }
338 const bool PointersAre64Bit;
345 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
346 enum class TplArgKind { ClassNTTP, StructuralValue };
348 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_)
349 : Context(
C), Out(Out_), Structor(nullptr), StructorType(-1),
350 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
351 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
354 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
356 : Context(
C), Out(Out_), Structor(getStructor(
D)), StructorType(
Type),
357 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
358 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
361 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
363 : Context(
C), Out(Out_), Structor(getStructor(
D)), StructorType(
Type),
364 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
365 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
368 raw_ostream &getStream()
const {
return Out; }
370 void mangle(
GlobalDecl GD, StringRef Prefix =
"?");
372 void mangleFunctionEncoding(
GlobalDecl GD,
bool ShouldMangle);
373 void mangleVariableEncoding(
const VarDecl *VD);
377 StringRef Prefix =
"$");
378 void mangleMemberDataPointerInClassNTTP(
const CXXRecordDecl *,
384 StringRef Prefix =
"$");
390 void mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD,
394 void mangleNumber(int64_t Number);
395 void mangleNumber(llvm::APSInt Number);
396 void mangleFloat(llvm::APFloat Number);
397 void mangleBits(llvm::APInt Number);
399 void mangleArtificialTagType(
TagTypeKind TK, StringRef UnqualifiedName,
403 QualifierMangleMode QMM = QMM_Mangle);
406 bool ForceThisQuals =
false,
407 bool MangleExceptionSpec =
true);
408 void mangleSourceName(StringRef Name);
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);
434 void mangleUnscopedTemplateName(
GlobalDecl GD);
436 mangleTemplateInstantiationName(
GlobalDecl GD,
441 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
443 bool isArtificialTagType(
QualType T)
const;
446#define ABSTRACT_TYPE(CLASS, PARENT)
447#define NON_CANONICAL_TYPE(CLASS, PARENT)
448#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
451#include "clang/AST/TypeNodes.inc"
453#undef NON_CANONICAL_TYPE
456 void mangleType(
const TagDecl *TD);
457 void mangleDecayedArrayType(
const ArrayType *
T);
462 void mangleIntegerLiteral(
const llvm::APSInt &Number,
473 bool WithScalarType =
false);
483MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(
ASTContext &Context,
504 uint32_t TruncatedHash = uint32_t(xxh3_64bits(FE->getName()));
505 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
508 AnonymousNamespaceHash =
"0";
512bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *
D) {
516 if (FD->hasAttr<OverloadableAttr>())
528 if (FD->isMSVCRTEntryPoint())
542 if (!getASTContext().getLangOpts().
CPlusPlus)
545 const VarDecl *VD = dyn_cast<VarDecl>(
D);
546 if (VD && !isa<DecompositionDecl>(
D)) {
556 DC = getEffectiveParentContext(DC);
559 !isa<VarTemplateSpecializationDecl>(
D) &&
D->getIdentifier() !=
nullptr)
567MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
576 "cannot mangle this %0 %1 yet");
577 return Diags.
Report(loc, DiagID) << thing1 << thing2;
584 "cannot mangle this %0 yet");
585 return Diags.
Report(loc, DiagID) << thingy;
592 "cannot mangle this %0 yet");
593 return Diags.
Report(DiagID) << thingy;
596void MicrosoftCXXNameMangler::mangle(
GlobalDecl GD, StringRef Prefix) {
608 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
609 else if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
610 mangleVariableEncoding(VD);
611 else if (isa<MSGuidDecl>(
D))
614 Out <<
"3U__s_GUID@@B";
615 else if (isa<TemplateParamObjectDecl>(
D)) {
619 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
622void MicrosoftCXXNameMangler::mangleFunctionEncoding(
GlobalDecl GD,
647 mangleFunctionClass(FD);
649 mangleFunctionType(FT, FD,
false,
false);
655void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
686 mangleType(Ty, SR, QMM_Drop);
687 manglePointerExtQualifiers(
690 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
693 mangleName(MPT->getClass()->getAsCXXRecordDecl());
696 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
698 mangleDecayedArrayType(AT);
699 if (AT->getElementType()->isArrayType())
704 mangleType(Ty, SR, QMM_Drop);
709void MicrosoftCXXNameMangler::mangleMemberDataPointer(
725 FieldOffset = getASTContext().getFieldOffset(VD);
726 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
727 "cannot take address of bitfield");
728 FieldOffset /= getASTContext().getCharWidth();
732 if (IM == MSInheritanceModel::Virtual)
733 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
742 case MSInheritanceModel::Single: Code =
'0';
break;
743 case MSInheritanceModel::Multiple: Code =
'0';
break;
744 case MSInheritanceModel::Virtual: Code =
'F';
break;
745 case MSInheritanceModel::Unspecified: Code =
'G';
break;
751 getASTContext().getLangOpts().isCompatibleWithMSVC(
752 LangOptions::MSVC2019) &&
754 !TemplateArgType.
isNull()) {
756 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
761 mangleNumber(FieldOffset);
769 mangleNumber(VBTableOffset);
772void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
779 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
780 return mangleMemberDataPointer(RD, VD,
nullptr,
QualType(),
"");
788 mangleNestedName(VD);
790 mangleUnqualifiedName(VD);
794void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
812 case MSInheritanceModel::Single: Code =
'1';
break;
813 case MSInheritanceModel::Multiple: Code =
'H';
break;
814 case MSInheritanceModel::Virtual: Code =
'I';
break;
815 case MSInheritanceModel::Unspecified: Code =
'J';
break;
826 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
827 LangOptions::MSVC2019) &&
829 !TemplateArgType.
isNull()) {
831 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
837 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
840 mangleVirtualMemPtrThunk(MD, ML);
844 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
849 mangleFunctionEncoding(MD,
true);
852 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
853 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
856 if (IM == MSInheritanceModel::Single) {
857 Out << Prefix <<
"0A@";
860 if (IM == MSInheritanceModel::Unspecified)
862 Out << Prefix << Code;
866 mangleNumber(
static_cast<uint32_t
>(NVOffset));
868 mangleNumber(VBPtrOffset);
870 mangleNumber(VBTableOffset);
873void MicrosoftCXXNameMangler::mangleFunctionPointer(
882 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
883 LangOptions::MSVC2019) &&
885 !TemplateArgType.
isNull()) {
887 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
892 mangleFunctionEncoding(FD,
true);
895void MicrosoftCXXNameMangler::mangleVarDecl(
const VarDecl *VD,
904 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
905 LangOptions::MSVC2019) &&
907 !TemplateArgType.
isNull()) {
909 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
914 mangleVariableEncoding(VD);
917void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
926 return mangleMemberFunctionPointer(RD, MD,
nullptr,
QualType(),
"");
935 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
938 mangleVirtualMemPtrThunk(MD, ML);
941 mangleFunctionEncoding(MD,
true);
945void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
948 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
949 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
955 mangleNumber(OffsetInVFTable);
961void MicrosoftCXXNameMangler::mangleName(
GlobalDecl GD) {
965 mangleUnqualifiedName(GD);
967 mangleNestedName(GD);
973void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
974 mangleNumber(llvm::APSInt(llvm::APInt(64, Number),
false));
977void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
982 unsigned Width = std::max(Number.getBitWidth(), 64U);
983 llvm::APInt
Value = Number.extend(Width);
991 if (
Value.isNegative()) {
998void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
1001 switch (APFloat::SemanticsToEnum(Number.getSemantics())) {
1002 case APFloat::S_IEEEsingle: Out <<
'A';
break;
1003 case APFloat::S_IEEEdouble: Out <<
'B';
break;
1007 case APFloat::S_IEEEhalf: Out <<
'V';
break;
1008 case APFloat::S_BFloat: Out <<
'W';
break;
1009 case APFloat::S_x87DoubleExtended: Out <<
'X';
break;
1010 case APFloat::S_IEEEquad: Out <<
'Y';
break;
1011 case APFloat::S_PPCDoubleDouble: Out <<
'Z';
break;
1012 case APFloat::S_Float8E5M2:
1013 case APFloat::S_Float8E4M3:
1014 case APFloat::S_Float8E4M3FN:
1015 case APFloat::S_Float8E5M2FNUZ:
1016 case APFloat::S_Float8E4M3FNUZ:
1017 case APFloat::S_Float8E4M3B11FNUZ:
1018 case APFloat::S_FloatTF32:
1019 case APFloat::S_Float6E3M2FN:
1020 case APFloat::S_Float6E2M3FN:
1021 case APFloat::S_Float4E2M1FN:
1022 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
1025 mangleBits(Number.bitcastToAPInt());
1028void MicrosoftCXXNameMangler::mangleBits(llvm::APInt
Value) {
1039 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
1040 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1041 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1050 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1059 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1060 TemplateArgs = &Spec->getTemplateArgs();
1061 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1066 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1067 TemplateArgs = &Spec->getTemplateArgs();
1068 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1074void MicrosoftCXXNameMangler::mangleUnqualifiedName(
GlobalDecl GD,
1088 if (isa<FunctionTemplateDecl>(TD.getDecl())) {
1089 mangleTemplateInstantiationName(TD, *TemplateArgs);
1112 ArgBackRefMap::iterator
Found = TemplateArgBackReferences.find(ND);
1113 if (
Found == TemplateArgBackReferences.end()) {
1115 TemplateArgStringMap::iterator
Found = TemplateArgStrings.find(ND);
1116 if (
Found == TemplateArgStrings.end()) {
1119 llvm::raw_svector_ostream Stream(TemplateMangling);
1120 MicrosoftCXXNameMangler Extra(Context, Stream);
1121 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1124 mangleSourceName(TemplateMangling);
1128 BackRefVec::iterator StringFound =
1129 llvm::find(NameBackReferences, TemplateMangling);
1130 if (StringFound != NameBackReferences.end()) {
1131 TemplateArgBackReferences[ND] =
1132 StringFound - NameBackReferences.begin();
1134 TemplateArgStrings[ND] =
1135 TemplateArgStringStorage.save(TemplateMangling.str());
1138 Out <<
Found->second <<
'@';
1141 Out <<
Found->second;
1146 switch (Name.getNameKind()) {
1151 ((isa<FunctionDecl>(ND) && ND->
hasAttr<CUDAGlobalAttr>()) ||
1152 (isa<FunctionTemplateDecl>(ND) &&
1153 cast<FunctionTemplateDecl>(ND)
1154 ->getTemplatedDecl()
1155 ->hasAttr<CUDAGlobalAttr>())) &&
1159 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1161 mangleSourceName(II->getName());
1166 assert(ND &&
"mangling empty name without declaration");
1168 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1169 if (NS->isAnonymousNamespace()) {
1170 Out <<
"?A0x" << Context.getAnonymousNamespaceHash() <<
'@';
1180 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1181 mangleSourceName(Name);
1185 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1188 assert(RD &&
"expected variable decl to have a record type");
1194 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1195 mangleSourceName(Name.str());
1199 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1202 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1203 llvm::raw_svector_ostream GUIDOS(GUID);
1204 Context.mangleMSGuidDecl(GD, GUIDOS);
1205 mangleSourceName(GUID);
1209 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1211 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1212 TPO->getValue(), TplArgKind::ClassNTTP);
1217 const TagDecl *TD = cast<TagDecl>(ND);
1220 "Typedef should not be in another decl context!");
1221 assert(
D->getDeclName().getAsIdentifierInfo() &&
1222 "Typedef was not named!");
1223 mangleSourceName(
D->getDeclName().getAsIdentifierInfo()->getName());
1228 if (
Record->isLambda()) {
1231 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1232 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1235 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1240 unsigned DefaultArgNo =
1242 Name += llvm::utostr(DefaultArgNo);
1246 if (LambdaManglingNumber)
1247 LambdaId = LambdaManglingNumber;
1249 LambdaId = Context.getLambdaId(
Record);
1251 Name += llvm::utostr(LambdaId);
1254 mangleSourceName(Name);
1258 if (LambdaManglingNumber && LambdaContextDecl) {
1259 if ((isa<VarDecl>(LambdaContextDecl) ||
1260 isa<FieldDecl>(LambdaContextDecl)) &&
1261 !isa<ParmVarDecl>(LambdaContextDecl)) {
1262 mangleUnqualifiedName(cast<NamedDecl>(LambdaContextDecl));
1274 Name +=
"<unnamed-type-";
1275 Name += DD->getName();
1281 Name +=
"<unnamed-type-";
1282 Name += TND->getName();
1283 }
else if (isa<EnumDecl>(TD) &&
1284 cast<EnumDecl>(TD)->enumerator_begin() !=
1285 cast<EnumDecl>(TD)->enumerator_end()) {
1287 auto *ED = cast<EnumDecl>(TD);
1288 Name +=
"<unnamed-enum-";
1289 Name += ED->enumerator_begin()->getName();
1292 Name +=
"<unnamed-type-$S";
1293 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1296 mangleSourceName(Name.str());
1307 mangleSourceName(Name.str());
1312 if (isStructorDecl(ND)) {
1326 if (isStructorDecl(ND))
1329 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1343 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1348 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1353 llvm_unreachable(
"Can't mangle a deduction guide name!");
1356 llvm_unreachable(
"Can't mangle a using directive name!");
1362void MicrosoftCXXNameMangler::mangleNestedName(
GlobalDecl GD) {
1365 if (
const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1366 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1367 mangleSourceName(
"<unnamed-tag>");
1369 const DeclContext *DC = getEffectiveDeclContext(ND);
1371 if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
1373 if (Context.getNextDiscriminator(ND, Disc)) {
1380 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1382 [](StringRef Name,
const unsigned Discriminator,
1383 const unsigned ParameterDiscriminator) -> std::string {
1385 llvm::raw_string_ostream Stream(Buffer);
1388 Stream <<
'_' << Discriminator;
1389 if (ParameterDiscriminator)
1390 Stream <<
'_' << ParameterDiscriminator;
1391 return Stream.str();
1394 unsigned Discriminator = BD->getBlockManglingNumber();
1396 Discriminator = Context.getBlockId(BD,
false);
1401 unsigned ParameterDiscriminator = 0;
1402 if (
const auto *MC = BD->getBlockManglingContextDecl())
1403 if (
const auto *
P = dyn_cast<ParmVarDecl>(MC))
1404 if (
const auto *F = dyn_cast<FunctionDecl>(
P->getDeclContext()))
1405 ParameterDiscriminator =
1406 F->getNumParams() -
P->getFunctionScopeIndex();
1408 DC = getEffectiveDeclContext(BD);
1411 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1412 ParameterDiscriminator));
1417 if (
const auto *MC = BD->getBlockManglingContextDecl())
1418 if (!isa<ParmVarDecl>(MC))
1419 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1420 mangleUnqualifiedName(ND);
1424 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1433 if (PointersAre64Bit)
1436 mangleArtificialTagType(TagTypeKind::Struct,
1437 Discriminate(
"__block_literal", Discriminator,
1438 ParameterDiscriminator));
1443 if (isa<RecordDecl>(DC))
1446 }
else if (
const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
1447 mangleObjCMethodName(Method);
1448 }
else if (isa<NamedDecl>(DC)) {
1449 ND = cast<NamedDecl>(DC);
1450 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1451 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1454 mangleUnqualifiedName(ND);
1457 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1467void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1482 llvm_unreachable(
"not expecting a COMDAT");
1484 llvm_unreachable(
"Unsupported dtor type?");
1493 case OO_New: Out <<
"?2";
break;
1495 case OO_Delete: Out <<
"?3";
break;
1497 case OO_Equal: Out <<
"?4";
break;
1499 case OO_GreaterGreater: Out <<
"?5";
break;
1501 case OO_LessLess: Out <<
"?6";
break;
1503 case OO_Exclaim: Out <<
"?7";
break;
1505 case OO_EqualEqual: Out <<
"?8";
break;
1507 case OO_ExclaimEqual: Out <<
"?9";
break;
1509 case OO_Subscript: Out <<
"?A";
break;
1512 case OO_Arrow: Out <<
"?C";
break;
1514 case OO_Star: Out <<
"?D";
break;
1516 case OO_PlusPlus: Out <<
"?E";
break;
1518 case OO_MinusMinus: Out <<
"?F";
break;
1520 case OO_Minus: Out <<
"?G";
break;
1522 case OO_Plus: Out <<
"?H";
break;
1524 case OO_Amp: Out <<
"?I";
break;
1526 case OO_ArrowStar: Out <<
"?J";
break;
1528 case OO_Slash: Out <<
"?K";
break;
1530 case OO_Percent: Out <<
"?L";
break;
1532 case OO_Less: Out <<
"?M";
break;
1534 case OO_LessEqual: Out <<
"?N";
break;
1536 case OO_Greater: Out <<
"?O";
break;
1538 case OO_GreaterEqual: Out <<
"?P";
break;
1540 case OO_Comma: Out <<
"?Q";
break;
1542 case OO_Call: Out <<
"?R";
break;
1544 case OO_Tilde: Out <<
"?S";
break;
1546 case OO_Caret: Out <<
"?T";
break;
1548 case OO_Pipe: Out <<
"?U";
break;
1550 case OO_AmpAmp: Out <<
"?V";
break;
1552 case OO_PipePipe: Out <<
"?W";
break;
1554 case OO_StarEqual: Out <<
"?X";
break;
1556 case OO_PlusEqual: Out <<
"?Y";
break;
1558 case OO_MinusEqual: Out <<
"?Z";
break;
1560 case OO_SlashEqual: Out <<
"?_0";
break;
1562 case OO_PercentEqual: Out <<
"?_1";
break;
1564 case OO_GreaterGreaterEqual: Out <<
"?_2";
break;
1566 case OO_LessLessEqual: Out <<
"?_3";
break;
1568 case OO_AmpEqual: Out <<
"?_4";
break;
1570 case OO_PipeEqual: Out <<
"?_5";
break;
1572 case OO_CaretEqual: Out <<
"?_6";
break;
1601 case OO_Array_New: Out <<
"?_U";
break;
1603 case OO_Array_Delete: Out <<
"?_V";
break;
1605 case OO_Coawait: Out <<
"?__L";
break;
1607 case OO_Spaceship: Out <<
"?__M";
break;
1609 case OO_Conditional: {
1610 Error(
Loc,
"conditional operator");
1616 llvm_unreachable(
"Not an overloaded operator");
1620void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1622 BackRefVec::iterator
Found = llvm::find(NameBackReferences, Name);
1623 if (
Found == NameBackReferences.end()) {
1624 if (NameBackReferences.size() < 10)
1625 NameBackReferences.push_back(std::string(Name));
1628 Out << (
Found - NameBackReferences.begin());
1632void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1633 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1636void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1643 ArgBackRefMap OuterFunArgsContext;
1644 ArgBackRefMap OuterTemplateArgsContext;
1645 BackRefVec OuterTemplateContext;
1646 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1647 NameBackReferences.swap(OuterTemplateContext);
1648 FunArgBackReferences.swap(OuterFunArgsContext);
1649 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1650 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1652 mangleUnscopedTemplateName(GD);
1653 mangleTemplateArgs(cast<TemplateDecl>(GD.
getDecl()), TemplateArgs);
1656 NameBackReferences.swap(OuterTemplateContext);
1657 FunArgBackReferences.swap(OuterFunArgsContext);
1658 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1659 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1662void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(
GlobalDecl GD) {
1665 mangleUnqualifiedName(GD);
1668void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1679 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1680 LangOptions::MSVC2019) &&
1682 !TemplateArgType.
isNull()) {
1684 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
1689 mangleNumber(
Value);
1692void MicrosoftCXXNameMangler::mangleExpression(
1695 if (std::optional<llvm::APSInt>
Value =
1706void MicrosoftCXXNameMangler::mangleTemplateArgs(
1710 assert(TPL->
size() == TemplateArgs.
size() &&
1711 "size mismatch between args and parms!");
1713 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1721 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1733 QualType BaseT =
V.getLValueBase().getType();
1734 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1735 V.getLValuePath()[0].getAsArrayIndex() != 0)
1738 V.getLValueBase().dyn_cast<
const ValueDecl *>());
1741void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1781 llvm_unreachable(
"Can't mangle null template arguments!");
1783 llvm_unreachable(
"Can't mangle template expansion arguments!");
1791 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1792 mangleMemberDataPointer(cast<CXXRecordDecl>(ND->
getDeclContext())
1793 ->getMostRecentNonInjectedDecl(),
1794 cast<ValueDecl>(ND),
1795 cast<NonTypeTemplateParmDecl>(Parm),
1797 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1800 mangleMemberFunctionPointer(
1804 mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),
1809 auto *TPO = cast<TemplateParamObjectDecl>(ND);
1810 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1811 TPO->getValue(), TplArgKind::ClassNTTP);
1812 }
else if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1813 mangleVarDecl(VD, cast<NonTypeTemplateParmDecl>(Parm),
1823 cast<NonTypeTemplateParmDecl>(Parm),
T);
1829 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1830 if (MPT->isMemberFunctionPointerType() &&
1831 !isa<FunctionTemplateDecl>(TD)) {
1832 mangleMemberFunctionPointer(RD,
nullptr,
nullptr,
QualType());
1835 if (MPT->isMemberDataPointer()) {
1836 if (!isa<FunctionTemplateDecl>(TD)) {
1837 mangleMemberDataPointer(RD,
nullptr,
nullptr,
QualType());
1847 mangleIntegerLiteral(llvm::APSInt::get(-1),
1848 cast<NonTypeTemplateParmDecl>(Parm),
T);
1853 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1854 cast<NonTypeTemplateParmDecl>(Parm),
T);
1863 return mangleTemplateArg(
1867 if (cast<NonTypeTemplateParmDecl>(Parm)
1869 ->getContainedDeducedType()) {
1875 TplArgKind::StructuralValue,
1879 mangleExpression(TA.
getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
1883 if (TemplateArgs.empty()) {
1884 if (isa<TemplateTypeParmDecl>(Parm) ||
1885 isa<TemplateTemplateParmDecl>(Parm))
1889 LangOptions::MSVC2015)
1892 else if (isa<NonTypeTemplateParmDecl>(Parm))
1895 llvm_unreachable(
"unexpected template parameter decl!");
1898 mangleTemplateArg(TD, PA, Parm);
1905 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1907 }
else if (isa<TypeAliasDecl>(ND)) {
1911 llvm_unreachable(
"unexpected template template NamedDecl!");
1918void MicrosoftCXXNameMangler::mangleTemplateArgValue(
QualType T,
1921 bool WithScalarType) {
1922 switch (
V.getKind()) {
1936 mangleNumber(
V.getInt());
1942 mangleFloat(
V.getFloat());
1953 if (
V.isLValueOnePastTheEnd()) {
1962 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1964 if (
Base.isNull()) {
1970 mangleNumber(
V.getLValueOffset().getQuantity());
1971 }
else if (!
V.hasLValuePath()) {
1973 Error(
"template argument (extension not comaptible with ms mangler)");
1979 Error(
"template argument (undeclared base)");
1987 SmallVector<std::function<void()>, 2> EntryManglers;
1991 EntryTypes.push_back(
'C');
1992 EntryManglers.push_back([
this, I =
E.getAsArrayIndex()] {
1997 ET = AT->getElementType();
2001 const Decl *
D =
E.getAsBaseOrMember().getPointer();
2002 if (
auto *FD = dyn_cast<FieldDecl>(
D)) {
2008 ET = getASTContext().getRecordType(cast<CXXRecordDecl>(
D));
2014 EntryTypes.push_back(
'6');
2015 EntryManglers.push_back([
this,
D] {
2016 mangleUnqualifiedName(cast<NamedDecl>(
D));
2021 for (
auto I = EntryTypes.rbegin(),
E = EntryTypes.rend(); I !=
E; ++I)
2026 Error(
"template argument (null value decl)");
2029 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
2032 for (
const std::function<
void()> &Mangler : EntryManglers)
2048 if (TAK == TplArgKind::ClassNTTP) {
2050 mangleMemberDataPointerInClassNTTP(RD,
D);
2052 mangleMemberFunctionPointerInClassNTTP(RD,
2053 cast_or_null<CXXMethodDecl>(
D));
2056 mangleMemberDataPointer(RD,
D,
nullptr,
QualType(),
"");
2058 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(
D),
nullptr,
2068 assert(RD &&
"unexpected type for record value");
2070 unsigned BaseIndex = 0;
2072 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
2074 if (!FD->isUnnamedBitField())
2075 mangleTemplateArgValue(FD->
getType(),
2076 V.getStructField(FD->getFieldIndex()), TAK,
2085 if (
const FieldDecl *FD =
V.getUnionField()) {
2086 mangleUnqualifiedName(FD);
2087 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
2097 mangleNumber(
V.getComplexIntReal());
2099 mangleNumber(
V.getComplexIntImag());
2106 mangleFloat(
V.getComplexFloatReal());
2107 mangleFloat(
V.getComplexFloatImag());
2113 QualType ElemT = getASTContext().getAsArrayType(
T)->getElementType();
2115 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
2116 const APValue &ElemV = I <
V.getArrayInitializedElts()
2117 ?
V.getArrayInitializedElt(I)
2118 :
V.getArrayFiller();
2119 mangleTemplateArgValue(ElemT, ElemV, TAK);
2134 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
2135 const APValue &ElemV =
V.getVectorElt(I);
2136 mangleTemplateArgValue(ElemT, ElemV, TAK);
2144 Error(
"template argument (value type: address label diff)");
2149 Error(
"template argument (value type: fixed point)");
2155void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2157 llvm::raw_svector_ostream Stream(TemplateMangling);
2158 MicrosoftCXXNameMangler Extra(Context, Stream);
2161 Extra.mangleSourceName(
"Protocol");
2162 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2164 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2167void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType Type,
2171 llvm::raw_svector_ostream Stream(TemplateMangling);
2172 MicrosoftCXXNameMangler Extra(Context, Stream);
2180 Extra.mangleSourceName(
"Autoreleasing");
2183 Extra.mangleSourceName(
"Strong");
2186 Extra.mangleSourceName(
"Weak");
2189 Extra.manglePointerCVQualifiers(Quals);
2190 Extra.manglePointerExtQualifiers(Quals,
Type);
2193 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2196void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *
T,
2200 llvm::raw_svector_ostream Stream(TemplateMangling);
2201 MicrosoftCXXNameMangler Extra(Context, Stream);
2204 Extra.mangleSourceName(
"KindOf");
2206 .stripObjCKindOfType(getASTContext())
2207 ->castAs<ObjCObjectType>(),
2210 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2213void MicrosoftCXXNameMangler::mangleQualifiers(
Qualifiers Quals,
2271 if (HasConst && HasVolatile) {
2273 }
else if (HasVolatile) {
2275 }
else if (HasConst) {
2281 if (HasConst && HasVolatile) {
2283 }
else if (HasVolatile) {
2285 }
else if (HasConst) {
2296MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2299 switch (RefQualifier) {
2313void MicrosoftCXXNameMangler::manglePointerExtQualifiers(
Qualifiers Quals,
2316 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2329void MicrosoftCXXNameMangler::manglePointerCVQualifiers(
Qualifiers Quals) {
2337 if (HasConst && HasVolatile) {
2339 }
else if (HasVolatile) {
2341 }
else if (HasConst) {
2348void MicrosoftCXXNameMangler::mangleFunctionArgumentType(
QualType T,
2359 QualType OriginalType = DT->getOriginalType();
2362 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2363 OriginalType = getASTContext().getIncompleteArrayType(
2364 AT->getElementType(), AT->getSizeModifier(),
2365 AT->getIndexTypeCVRQualifiers());
2376 TypePtr =
T.getCanonicalType().getAsOpaquePtr();
2379 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2381 if (
Found == FunArgBackReferences.end()) {
2382 size_t OutSizeBefore = Out.tell();
2384 mangleType(
T,
Range, QMM_Drop);
2389 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);
2390 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2391 size_t Size = FunArgBackReferences.size();
2392 FunArgBackReferences[TypePtr] =
Size;
2395 Out <<
Found->second;
2399void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2400 const PassObjectSizeAttr *POSA) {
2401 int Type = POSA->getType();
2402 bool Dynamic = POSA->isDynamic();
2405 auto *TypePtr = (
const void *)&*
Iter;
2406 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2408 if (
Found == FunArgBackReferences.end()) {
2410 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2411 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2414 if (FunArgBackReferences.size() < 10) {
2415 size_t Size = FunArgBackReferences.size();
2416 FunArgBackReferences[TypePtr] =
Size;
2419 Out <<
Found->second;
2423void MicrosoftCXXNameMangler::mangleAddressSpaceType(
QualType T,
2441 llvm::raw_svector_ostream Stream(ASMangling);
2442 MicrosoftCXXNameMangler Extra(Context, Stream);
2448 Extra.mangleSourceName(
"_AS");
2449 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2453 llvm_unreachable(
"Not a language specific address space");
2454 case LangAS::opencl_global:
2455 Extra.mangleSourceName(
"_ASCLglobal");
2457 case LangAS::opencl_global_device:
2458 Extra.mangleSourceName(
"_ASCLdevice");
2460 case LangAS::opencl_global_host:
2461 Extra.mangleSourceName(
"_ASCLhost");
2463 case LangAS::opencl_local:
2464 Extra.mangleSourceName(
"_ASCLlocal");
2466 case LangAS::opencl_constant:
2467 Extra.mangleSourceName(
"_ASCLconstant");
2469 case LangAS::opencl_private:
2470 Extra.mangleSourceName(
"_ASCLprivate");
2472 case LangAS::opencl_generic:
2473 Extra.mangleSourceName(
"_ASCLgeneric");
2475 case LangAS::cuda_device:
2476 Extra.mangleSourceName(
"_ASCUdevice");
2478 case LangAS::cuda_constant:
2479 Extra.mangleSourceName(
"_ASCUconstant");
2481 case LangAS::cuda_shared:
2482 Extra.mangleSourceName(
"_ASCUshared");
2484 case LangAS::ptr32_sptr:
2485 case LangAS::ptr32_uptr:
2487 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2491 Extra.mangleType(
T,
Range, QMM_Escape);
2493 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2497 QualifierMangleMode QMM) {
2500 T =
T.getDesugaredType(getASTContext());
2503 if (
const ArrayType *AT = getASTContext().getAsArrayType(
T)) {
2506 if (QMM == QMM_Mangle)
2508 else if (QMM == QMM_Escape || QMM == QMM_Result)
2510 mangleArrayType(AT);
2525 mangleFunctionType(FT);
2528 mangleQualifiers(Quals,
false);
2531 if (!IsPointer && Quals) {
2533 mangleQualifiers(Quals,
false);
2541 if ((!IsPointer && Quals) || isa<TagType>(
T) || isArtificialTagType(
T)) {
2543 mangleQualifiers(Quals,
false);
2548 const Type *ty =
T.getTypePtr();
2551#define ABSTRACT_TYPE(CLASS, PARENT)
2552#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2554 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2556#define TYPE(CLASS, PARENT) \
2558 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2560#include "clang/AST/TypeNodes.inc"
2562#undef NON_CANONICAL_TYPE
2596 switch (
T->getKind()) {
2597 case BuiltinType::Void:
2600 case BuiltinType::SChar:
2603 case BuiltinType::Char_U:
2604 case BuiltinType::Char_S:
2607 case BuiltinType::UChar:
2610 case BuiltinType::Short:
2613 case BuiltinType::UShort:
2616 case BuiltinType::Int:
2619 case BuiltinType::UInt:
2622 case BuiltinType::Long:
2625 case BuiltinType::ULong:
2628 case BuiltinType::Float:
2631 case BuiltinType::Double:
2635 case BuiltinType::LongDouble:
2638 case BuiltinType::LongLong:
2641 case BuiltinType::ULongLong:
2644 case BuiltinType::Int128:
2647 case BuiltinType::UInt128:
2650 case BuiltinType::Bool:
2653 case BuiltinType::Char8:
2656 case BuiltinType::Char16:
2659 case BuiltinType::Char32:
2662 case BuiltinType::WChar_S:
2663 case BuiltinType::WChar_U:
2667#define BUILTIN_TYPE(Id, SingletonId)
2668#define PLACEHOLDER_TYPE(Id, SingletonId) \
2669 case BuiltinType::Id:
2670#include "clang/AST/BuiltinTypes.def"
2671 case BuiltinType::Dependent:
2672 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2674 case BuiltinType::ObjCId:
2675 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2677 case BuiltinType::ObjCClass:
2678 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2680 case BuiltinType::ObjCSel:
2681 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2684#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2685 case BuiltinType::Id: \
2686 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2688#include "clang/Basic/OpenCLImageTypes.def"
2689 case BuiltinType::OCLSampler:
2691 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2693 case BuiltinType::OCLEvent:
2695 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2697 case BuiltinType::OCLClkEvent:
2699 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2701 case BuiltinType::OCLQueue:
2703 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2705 case BuiltinType::OCLReserveID:
2707 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2709#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2710 case BuiltinType::Id: \
2711 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2713#include "clang/Basic/OpenCLExtensionTypes.def"
2715 case BuiltinType::NullPtr:
2719 case BuiltinType::Float16:
2720 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2723 case BuiltinType::Half:
2724 if (!getASTContext().getLangOpts().
HLSL)
2725 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2726 else if (getASTContext().getLangOpts().NativeHalfType)
2732 case BuiltinType::BFloat16:
2733 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2736#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2737 case BuiltinType::Id: \
2738 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2739 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2742#include "clang/Basic/WebAssemblyReferenceTypes.def"
2743#define SVE_TYPE(Name, Id, SingletonId) \
2744 case BuiltinType::Id:
2745#include "clang/Basic/AArch64SVEACLETypes.def"
2746#define PPC_VECTOR_TYPE(Name, Id, Size) \
2747 case BuiltinType::Id:
2748#include "clang/Basic/PPCTypes.def"
2749#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2750#include "clang/Basic/RISCVVTypes.def"
2751#define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2752#include "clang/Basic/AMDGPUTypes.def"
2753 case BuiltinType::ShortAccum:
2754 case BuiltinType::Accum:
2755 case BuiltinType::LongAccum:
2756 case BuiltinType::UShortAccum:
2757 case BuiltinType::UAccum:
2758 case BuiltinType::ULongAccum:
2759 case BuiltinType::ShortFract:
2760 case BuiltinType::Fract:
2761 case BuiltinType::LongFract:
2762 case BuiltinType::UShortFract:
2763 case BuiltinType::UFract:
2764 case BuiltinType::ULongFract:
2765 case BuiltinType::SatShortAccum:
2766 case BuiltinType::SatAccum:
2767 case BuiltinType::SatLongAccum:
2768 case BuiltinType::SatUShortAccum:
2769 case BuiltinType::SatUAccum:
2770 case BuiltinType::SatULongAccum:
2771 case BuiltinType::SatShortFract:
2772 case BuiltinType::SatFract:
2773 case BuiltinType::SatLongFract:
2774 case BuiltinType::SatUShortFract:
2775 case BuiltinType::SatUFract:
2776 case BuiltinType::SatULongFract:
2777 case BuiltinType::Ibm128:
2778 case BuiltinType::Float128: {
2795 mangleFunctionType(
T,
nullptr,
true);
2798 mangleFunctionType(
T);
2804 mangleFunctionType(
T);
2807void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *
T,
2809 bool ForceThisQuals,
2810 bool MangleExceptionSpec) {
2818 bool IsInLambda =
false;
2819 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
2821 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(
D)) {
2825 HasThisQuals =
true;
2826 if (isa<CXXDestructorDecl>(MD)) {
2828 }
else if (isa<CXXConstructorDecl>(MD)) {
2834 CC = getASTContext().getDefaultCallingConvention(
2843 manglePointerExtQualifiers(Quals,
QualType());
2845 mangleQualifiers(Quals,
false);
2848 mangleCallingConvention(CC,
Range);
2853 if (isa<CXXDestructorDecl>(
D) && isStructorDecl(
D)) {
2857 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
2866 if (IsCtorClosure) {
2876 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
2884 llvm_unreachable(
"unexpected constructor closure!");
2890 }
else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(
D)) {
2897 if (IsInLambda && isa<CXXConversionDecl>(
D)) {
2901 mangleType(ResultType,
Range, QMM_Result);
2902 }
else if (
const auto *AT = dyn_cast_or_null<AutoType>(
2907 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2908 "shouldn't need to mangle __auto_type!");
2909 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
2911 }
else if (IsInLambda) {
2916 mangleType(ResultType,
Range, QMM_Result);
2934 if (I == 0 &&
D &&
D->getParamDecl(I)->isExplicitObjectParameter())
2947 if (
const auto *
P =
D->getParamDecl(I)->
getAttr<PassObjectSizeAttr>())
2948 manglePassObjectSizeArg(
P);
2957 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
2958 getASTContext().getLangOpts().isCompatibleWithMSVC(
2959 LangOptions::MSVC2017_5))
2960 mangleThrowSpecification(Proto);
2965void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
2990 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
2994 if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
3000 llvm_unreachable(
"Unsupported access specifier");
3029void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC,
3092 if (getASTContext().getLangOpts().RegCall4)
3101void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *
T,
3106void MicrosoftCXXNameMangler::mangleThrowSpecification(
3128void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
3130 case TagTypeKind::Union:
3133 case TagTypeKind::Struct:
3134 case TagTypeKind::Interface:
3137 case TagTypeKind::Class:
3140 case TagTypeKind::Enum:
3147 mangleType(cast<TagType>(
T)->getDecl());
3151 mangleType(cast<TagType>(
T)->getDecl());
3153void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3159void MicrosoftCXXNameMangler::mangleArtificialTagType(
3163 mangleTagTypeKind(TK);
3166 mangleSourceName(UnqualifiedName);
3168 for (StringRef N : llvm::reverse(NestedNames))
3169 mangleSourceName(N);
3182void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *
T) {
3185 manglePointerCVQualifiers(
T->getElementType().getQualifiers());
3190 llvm_unreachable(
"Should have been special cased");
3194 llvm_unreachable(
"Should have been special cased");
3198 llvm_unreachable(
"Should have been special cased");
3202 llvm_unreachable(
"Should have been special cased");
3204void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *
T) {
3208 if (ElementTy->isConstantArrayType()) {
3210 getASTContext().getAsConstantArrayType(ElementTy);
3211 Dimensions.push_back(CAT->
getSize());
3213 }
else if (ElementTy->isIncompleteArrayType()) {
3215 getASTContext().getAsIncompleteArrayType(ElementTy);
3216 Dimensions.push_back(llvm::APInt(32, 0));
3218 }
else if (ElementTy->isVariableArrayType()) {
3220 getASTContext().getAsVariableArrayType(ElementTy);
3221 Dimensions.push_back(llvm::APInt(32, 0));
3223 }
else if (ElementTy->isDependentSizedArrayType()) {
3226 getASTContext().getAsDependentSizedArrayType(ElementTy);
3236 mangleNumber(Dimensions.size());
3237 for (
const llvm::APInt &Dimension : Dimensions)
3238 mangleNumber(Dimension.getLimitedValue());
3244 mangleArrayType(cast<ConstantArrayType>(
T));
3253 manglePointerCVQualifiers(Quals);
3254 manglePointerExtQualifiers(Quals, PointeeType);
3258 mangleFunctionType(FPT,
nullptr,
true);
3262 mangleType(PointeeType,
Range, QMM_Drop);
3282 manglePointerCVQualifiers(Quals);
3283 manglePointerExtQualifiers(Quals, PointeeType);
3289 mangleType(PointeeType,
Range);
3304 return mangleObjCLifetime(PointeeType, Quals,
Range);
3306 manglePointerCVQualifiers(Quals);
3307 manglePointerExtQualifiers(Quals, PointeeType);
3308 mangleType(PointeeType,
Range);
3319 manglePointerExtQualifiers(Quals, PointeeType);
3320 mangleType(PointeeType,
Range);
3331 manglePointerExtQualifiers(Quals, PointeeType);
3332 mangleType(PointeeType,
Range);
3337 QualType ElementType =
T->getElementType();
3340 llvm::raw_svector_ostream Stream(TemplateMangling);
3341 MicrosoftCXXNameMangler Extra(Context, Stream);
3343 Extra.mangleSourceName(
"_Complex");
3344 Extra.mangleType(ElementType,
Range, QMM_Escape);
3346 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3354bool MicrosoftCXXNameMangler::isArtificialTagType(
QualType T)
const {
3355 const Type *ty =
T.getTypePtr();
3360 case Type::Vector: {
3374 assert((ET || BitIntTy) &&
3375 "vectors with non-builtin/_BitInt elements are unsupported");
3376 uint64_t Width = getASTContext().getTypeSize(
T);
3379 size_t OutSizeBefore = Out.tell();
3380 if (!isa<ExtVectorType>(
T)) {
3381 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
3382 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3383 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3384 }
else if (Width >= 128) {
3385 if (ET->
getKind() == BuiltinType::Float)
3386 mangleArtificialTagType(TagTypeKind::Union,
3387 "__m" + llvm::utostr(Width));
3388 else if (ET->
getKind() == BuiltinType::LongLong)
3389 mangleArtificialTagType(TagTypeKind::Union,
3390 "__m" + llvm::utostr(Width) +
'i');
3391 else if (ET->
getKind() == BuiltinType::Double)
3392 mangleArtificialTagType(TagTypeKind::Struct,
3393 "__m" + llvm::utostr(Width) +
'd');
3398 bool IsBuiltin = Out.tell() != OutSizeBefore;
3405 llvm::raw_svector_ostream Stream(TemplateMangling);
3406 MicrosoftCXXNameMangler Extra(Context, Stream);
3408 Extra.mangleSourceName(
"__vector");
3409 Extra.mangleType(
QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3411 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumElements()));
3413 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3450 mangleTagTypeKind(TagTypeKind::Struct);
3451 mangleName(
T->getDecl());
3456 if (
T->isKindOfType())
3457 return mangleObjCKindOfType(
T, Quals,
Range);
3459 if (
T->qual_empty() && !
T->isSpecialized())
3460 return mangleType(
T->getBaseType(),
Range, QMM_Drop);
3462 ArgBackRefMap OuterFunArgsContext;
3463 ArgBackRefMap OuterTemplateArgsContext;
3464 BackRefVec OuterTemplateContext;
3466 FunArgBackReferences.swap(OuterFunArgsContext);
3467 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3468 NameBackReferences.swap(OuterTemplateContext);
3470 mangleTagTypeKind(TagTypeKind::Struct);
3474 mangleSourceName(
"objc_object");
3475 else if (
T->isObjCClass())
3476 mangleSourceName(
"objc_class");
3478 mangleSourceName(
T->getInterface()->getName());
3480 for (
const auto &Q :
T->quals())
3481 mangleObjCProtocol(Q);
3483 if (
T->isSpecialized())
3484 for (
const auto &TA :
T->getTypeArgs())
3485 mangleType(TA,
Range, QMM_Drop);
3491 FunArgBackReferences.swap(OuterFunArgsContext);
3492 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3493 NameBackReferences.swap(OuterTemplateContext);
3499 manglePointerCVQualifiers(Quals);
3500 manglePointerExtQualifiers(Quals, PointeeType);
3509 llvm_unreachable(
"Cannot mangle injected class name type.");
3522void MicrosoftCXXNameMangler::mangleType(
3535 manglePointerCVQualifiers(Quals);
3536 mangleType(
T->getSelectedType(),
Range);
3561 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3566void MicrosoftCXXNameMangler::mangleType(
3568 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3579 llvm::raw_svector_ostream Stream(TemplateMangling);
3580 MicrosoftCXXNameMangler Extra(Context, Stream);
3582 Extra.mangleSourceName(
"_Atomic");
3583 Extra.mangleType(ValueType,
Range, QMM_Escape);
3585 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3590 QualType ElementType =
T->getElementType();
3593 llvm::raw_svector_ostream Stream(TemplateMangling);
3594 MicrosoftCXXNameMangler Extra(Context, Stream);
3596 Extra.mangleSourceName(
"ocl_pipe");
3597 Extra.mangleType(ElementType,
Range, QMM_Escape);
3598 Extra.mangleIntegerLiteral(llvm::APSInt::get(
T->isReadOnly()));
3600 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3603void MicrosoftMangleContextImpl::mangleCXXName(
GlobalDecl GD,
3607 getASTContext().getSourceManager(),
3608 "Mangling declaration");
3610 msvc_hashing_ostream MHO(Out);
3612 if (
auto *CD = dyn_cast<CXXConstructorDecl>(
D)) {
3614 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3615 return mangler.mangle(GD);
3618 if (
auto *DD = dyn_cast<CXXDestructorDecl>(
D)) {
3620 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3621 return mangler.mangle(GD);
3624 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3625 return Mangler.mangle(GD);
3631 llvm::raw_svector_ostream Stream(TemplateMangling);
3632 MicrosoftCXXNameMangler Extra(Context, Stream);
3634 if (
T->isUnsigned())
3635 Extra.mangleSourceName(
"_UBitInt");
3637 Extra.mangleSourceName(
"_BitInt");
3638 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumBits()));
3640 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3674 MicrosoftCXXNameMangler &Mangler,
3681 llvm_unreachable(
"Unsupported access specifier");
3692 Out <<
'R' << AccessSpec;
3693 Mangler.mangleNumber(
3695 Mangler.mangleNumber(
3697 Mangler.mangleNumber(
3699 Mangler.mangleNumber(
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3702 Mangler.mangleNumber(
3704 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3709 llvm_unreachable(
"Unsupported access specifier");
3719 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3723 llvm_unreachable(
"Unsupported access specifier");
3736void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
3739 msvc_hashing_ostream MHO(Out);
3740 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3741 Mangler.getStream() <<
'?';
3742 Mangler.mangleVirtualMemPtrThunk(MD, ML);
3745void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
3749 msvc_hashing_ostream MHO(Out);
3750 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3751 Mangler.getStream() <<
'?';
3752 Mangler.mangleName(MD);
3761 assert(Thunk.
Method !=
nullptr &&
3762 "Thunk info should hold the overridee decl");
3765 Mangler.mangleFunctionType(
3778 msvc_hashing_ostream MHO(Out);
3779 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
3780 Mangler.getStream() <<
"??_E";
3782 auto &Adjustment = Thunk.
This;
3787void MicrosoftMangleContextImpl::mangleCXXVFTable(
3794 msvc_hashing_ostream MHO(Out);
3795 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3796 if (Derived->
hasAttr<DLLImportAttr>())
3797 Mangler.getStream() <<
"??_S";
3799 Mangler.getStream() <<
"??_7";
3800 Mangler.mangleName(Derived);
3801 Mangler.getStream() <<
"6B";
3803 Mangler.mangleName(RD);
3804 Mangler.getStream() <<
'@';
3807void MicrosoftMangleContextImpl::mangleCXXVTable(
const CXXRecordDecl *Derived,
3810 mangleCXXVFTable(Derived, {}, Out);
3813void MicrosoftMangleContextImpl::mangleCXXVBTable(
3820 msvc_hashing_ostream MHO(Out);
3821 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3822 Mangler.getStream() <<
"??_8";
3823 Mangler.mangleName(Derived);
3824 Mangler.getStream() <<
"7B";
3826 Mangler.mangleName(RD);
3827 Mangler.getStream() <<
'@';
3830void MicrosoftMangleContextImpl::mangleCXXRTTI(
QualType T, raw_ostream &Out) {
3831 msvc_hashing_ostream MHO(Out);
3832 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3833 Mangler.getStream() <<
"??_R0";
3834 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3835 Mangler.getStream() <<
"@8";
3838void MicrosoftMangleContextImpl::mangleCXXRTTIName(
3839 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
3840 MicrosoftCXXNameMangler Mangler(*
this, Out);
3841 Mangler.getStream() <<
'.';
3842 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3845void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
3847 msvc_hashing_ostream MHO(Out);
3848 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3849 Mangler.getStream() <<
"??_K";
3850 Mangler.mangleName(SrcRD);
3851 Mangler.getStream() <<
"$C";
3852 Mangler.mangleName(DstRD);
3855void MicrosoftMangleContextImpl::mangleCXXThrowInfo(
QualType T,
bool IsConst,
3858 uint32_t NumEntries,
3860 msvc_hashing_ostream MHO(Out);
3861 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3862 Mangler.getStream() <<
"_TI";
3864 Mangler.getStream() <<
'C';
3866 Mangler.getStream() <<
'V';
3868 Mangler.getStream() <<
'U';
3869 Mangler.getStream() << NumEntries;
3870 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3873void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
3874 QualType T, uint32_t NumEntries, raw_ostream &Out) {
3875 msvc_hashing_ostream MHO(Out);
3876 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3877 Mangler.getStream() <<
"_CTA";
3878 Mangler.getStream() << NumEntries;
3879 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3882void MicrosoftMangleContextImpl::mangleCXXCatchableType(
3884 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
3886 MicrosoftCXXNameMangler Mangler(*
this, Out);
3887 Mangler.getStream() <<
"_CT";
3891 llvm::raw_svector_ostream Stream(RTTIMangling);
3892 msvc_hashing_ostream MHO(Stream);
3893 mangleCXXRTTI(
T, MHO);
3895 Mangler.getStream() << RTTIMangling;
3903 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
3904 LangOptions::MSVC2015) &&
3905 !getASTContext().getLangOpts().isCompatibleWithMSVC(
3906 LangOptions::MSVC2017_7);
3908 if (!OmitCopyCtor && CD) {
3909 llvm::raw_svector_ostream Stream(CopyCtorMangling);
3910 msvc_hashing_ostream MHO(Stream);
3913 Mangler.getStream() << CopyCtorMangling;
3915 Mangler.getStream() <<
Size;
3916 if (VBPtrOffset == -1) {
3918 Mangler.getStream() << NVOffset;
3921 Mangler.getStream() << NVOffset;
3922 Mangler.getStream() << VBPtrOffset;
3923 Mangler.getStream() << VBIndex;
3927void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
3928 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
3929 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
3930 msvc_hashing_ostream MHO(Out);
3931 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3932 Mangler.getStream() <<
"??_R1";
3933 Mangler.mangleNumber(NVOffset);
3934 Mangler.mangleNumber(VBPtrOffset);
3935 Mangler.mangleNumber(VBTableOffset);
3936 Mangler.mangleNumber(Flags);
3937 Mangler.mangleName(Derived);
3938 Mangler.getStream() <<
"8";
3941void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
3943 msvc_hashing_ostream MHO(Out);
3944 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3945 Mangler.getStream() <<
"??_R2";
3946 Mangler.mangleName(Derived);
3947 Mangler.getStream() <<
"8";
3950void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
3952 msvc_hashing_ostream MHO(Out);
3953 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3954 Mangler.getStream() <<
"??_R3";
3955 Mangler.mangleName(Derived);
3956 Mangler.getStream() <<
"8";
3959void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
3967 llvm::raw_svector_ostream Stream(VFTableMangling);
3968 mangleCXXVFTable(Derived, BasePath, Stream);
3970 if (VFTableMangling.starts_with(
"??@")) {
3971 assert(VFTableMangling.ends_with(
"@"));
3972 Out << VFTableMangling <<
"??_R4@";
3976 assert(VFTableMangling.starts_with(
"??_7") ||
3977 VFTableMangling.starts_with(
"??_S"));
3979 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
3982void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
3983 GlobalDecl EnclosingDecl, raw_ostream &Out) {
3984 msvc_hashing_ostream MHO(Out);
3985 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3990 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
3991 Mangler.mangleName(EnclosingDecl);
3994void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
3995 GlobalDecl EnclosingDecl, raw_ostream &Out) {
3996 msvc_hashing_ostream MHO(Out);
3997 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4002 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
4003 Mangler.mangleName(EnclosingDecl);
4006void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4007 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4010 MicrosoftCXXNameMangler Mangler(*
this, Out);
4011 Mangler.getStream() <<
'?';
4012 Mangler.mangleType(
T.getCanonicalType(),
SourceRange());
4015void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4016 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
4017 msvc_hashing_ostream MHO(Out);
4018 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4020 Mangler.getStream() <<
"?";
4021 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
4022 Mangler.mangle(VD,
"");
4025void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4026 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
4027 msvc_hashing_ostream MHO(Out);
4028 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4030 Mangler.getStream() <<
"?";
4031 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
4032 Mangler.mangleNestedName(VD);
4033 Mangler.getStream() <<
"@4HA";
4036void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
4048 msvc_hashing_ostream MHO(Out);
4049 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4053 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
4055 Mangler.getStream() <<
"?$S1@";
4057 unsigned ScopeDepth = 0;
4058 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4062 Mangler.mangle(VD,
"");
4064 Mangler.mangleNestedName(VD);
4065 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
4067 Mangler.mangleNumber(ScopeDepth);
4070void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *
D,
4073 msvc_hashing_ostream MHO(Out);
4074 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4075 Mangler.getStream() <<
"??__" << CharCode;
4076 if (
D->isStaticDataMember()) {
4077 Mangler.getStream() <<
'?';
4078 Mangler.mangleName(
D);
4079 Mangler.mangleVariableEncoding(
D);
4080 Mangler.getStream() <<
"@@";
4082 Mangler.mangleName(
D);
4086 Mangler.getStream() <<
"YAXXZ";
4089void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *
D,
4092 mangleInitFiniStub(
D,
'E', Out);
4096MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *
D,
4099 mangleInitFiniStub(
D,
'F', Out);
4102void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4123 MicrosoftCXXNameMangler Mangler(*
this, Out);
4124 Mangler.getStream() <<
"??_C@_";
4132 unsigned StringLength =
4133 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4138 Mangler.getStream() <<
'1';
4140 Mangler.getStream() <<
'0';
4144 Mangler.mangleNumber(StringByteLength);
4146 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4148 if (Index / CharByteWidth >= SL->
getLength())
4149 return static_cast<char>(0);
4150 uint32_t CodeUnit = SL->
getCodeUnit(Index / CharByteWidth);
4151 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4152 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4155 auto GetBigEndianByte = [&SL](
unsigned Index) {
4157 if (Index / CharByteWidth >= SL->
getLength())
4158 return static_cast<char>(0);
4159 uint32_t CodeUnit = SL->
getCodeUnit(Index / CharByteWidth);
4160 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4161 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4166 for (
unsigned I = 0,
E = StringByteLength; I !=
E; ++I)
4167 JC.update(GetLittleEndianByte(I));
4171 Mangler.mangleNumber(JC.getCRC());
4177 auto MangleByte = [&Mangler](
char Byte) {
4185 Mangler.getStream() << Byte;
4186 }
else if (
isLetter(Byte & 0x7f)) {
4187 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4189 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4190 ' ',
'\n',
'\t',
'\'',
'-'};
4191 const char *Pos = llvm::find(SpecialChars, Byte);
4192 if (Pos != std::end(SpecialChars)) {
4193 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4195 Mangler.getStream() <<
"?$";
4196 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4197 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4203 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4204 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4205 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4207 MangleByte(GetBigEndianByte(I));
4209 MangleByte(GetLittleEndianByte(I));
4212 Mangler.getStream() <<
'@';
4218 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 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...
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
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.
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.
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.
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.
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
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.
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
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.
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() 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
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
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.
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::@194 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...