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,
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_Float8E3M4:
1019 case APFloat::S_FloatTF32:
1020 case APFloat::S_Float6E3M2FN:
1021 case APFloat::S_Float6E2M3FN:
1022 case APFloat::S_Float4E2M1FN:
1023 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
1026 mangleBits(Number.bitcastToAPInt());
1029void MicrosoftCXXNameMangler::mangleBits(llvm::APInt
Value) {
1040 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
1041 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1042 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1051 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1060 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1061 TemplateArgs = &Spec->getTemplateArgs();
1062 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1067 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1068 TemplateArgs = &Spec->getTemplateArgs();
1069 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1075void MicrosoftCXXNameMangler::mangleUnqualifiedName(
GlobalDecl GD,
1089 if (isa<FunctionTemplateDecl>(TD.getDecl())) {
1090 mangleTemplateInstantiationName(TD, *TemplateArgs);
1113 ArgBackRefMap::iterator
Found = TemplateArgBackReferences.find(ND);
1114 if (
Found == TemplateArgBackReferences.end()) {
1116 TemplateArgStringMap::iterator
Found = TemplateArgStrings.find(ND);
1117 if (
Found == TemplateArgStrings.end()) {
1120 llvm::raw_svector_ostream Stream(TemplateMangling);
1121 MicrosoftCXXNameMangler Extra(Context, Stream);
1122 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1125 mangleSourceName(TemplateMangling);
1129 BackRefVec::iterator StringFound =
1130 llvm::find(NameBackReferences, TemplateMangling);
1131 if (StringFound != NameBackReferences.end()) {
1132 TemplateArgBackReferences[ND] =
1133 StringFound - NameBackReferences.begin();
1135 TemplateArgStrings[ND] =
1136 TemplateArgStringStorage.save(TemplateMangling.str());
1139 Out <<
Found->second <<
'@';
1142 Out <<
Found->second;
1147 switch (Name.getNameKind()) {
1152 ((isa<FunctionDecl>(ND) && ND->
hasAttr<CUDAGlobalAttr>()) ||
1153 (isa<FunctionTemplateDecl>(ND) &&
1154 cast<FunctionTemplateDecl>(ND)
1155 ->getTemplatedDecl()
1156 ->hasAttr<CUDAGlobalAttr>())) &&
1160 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1162 mangleSourceName(II->getName());
1167 assert(ND &&
"mangling empty name without declaration");
1169 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1170 if (NS->isAnonymousNamespace()) {
1171 Out <<
"?A0x" << Context.getAnonymousNamespaceHash() <<
'@';
1181 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1182 mangleSourceName(Name);
1186 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1189 assert(RD &&
"expected variable decl to have a record type");
1195 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1196 mangleSourceName(Name.str());
1200 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1203 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1204 llvm::raw_svector_ostream GUIDOS(GUID);
1205 Context.mangleMSGuidDecl(GD, GUIDOS);
1206 mangleSourceName(GUID);
1210 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1212 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1213 TPO->getValue(), TplArgKind::ClassNTTP);
1218 const TagDecl *TD = cast<TagDecl>(ND);
1221 "Typedef should not be in another decl context!");
1222 assert(
D->getDeclName().getAsIdentifierInfo() &&
1223 "Typedef was not named!");
1224 mangleSourceName(
D->getDeclName().getAsIdentifierInfo()->getName());
1229 if (
Record->isLambda()) {
1232 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1233 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1236 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1241 unsigned DefaultArgNo =
1243 Name += llvm::utostr(DefaultArgNo);
1247 if (LambdaManglingNumber)
1248 LambdaId = LambdaManglingNumber;
1250 LambdaId = Context.getLambdaId(
Record);
1252 Name += llvm::utostr(LambdaId);
1255 mangleSourceName(Name);
1259 if (LambdaManglingNumber && LambdaContextDecl) {
1260 if ((isa<VarDecl>(LambdaContextDecl) ||
1261 isa<FieldDecl>(LambdaContextDecl)) &&
1262 !isa<ParmVarDecl>(LambdaContextDecl)) {
1263 mangleUnqualifiedName(cast<NamedDecl>(LambdaContextDecl));
1275 Name +=
"<unnamed-type-";
1276 Name += DD->getName();
1282 Name +=
"<unnamed-type-";
1283 Name += TND->getName();
1284 }
else if (isa<EnumDecl>(TD) &&
1285 cast<EnumDecl>(TD)->enumerator_begin() !=
1286 cast<EnumDecl>(TD)->enumerator_end()) {
1288 auto *ED = cast<EnumDecl>(TD);
1289 Name +=
"<unnamed-enum-";
1290 Name += ED->enumerator_begin()->getName();
1293 Name +=
"<unnamed-type-$S";
1294 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1297 mangleSourceName(Name.str());
1308 mangleSourceName(Name.str());
1313 if (isStructorDecl(ND)) {
1327 if (isStructorDecl(ND))
1330 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1344 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1349 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1354 llvm_unreachable(
"Can't mangle a deduction guide name!");
1357 llvm_unreachable(
"Can't mangle a using directive name!");
1363void MicrosoftCXXNameMangler::mangleNestedName(
GlobalDecl GD) {
1366 if (
const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1367 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1368 mangleSourceName(
"<unnamed-tag>");
1370 const DeclContext *DC = getEffectiveDeclContext(ND);
1372 if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
1374 if (Context.getNextDiscriminator(ND, Disc)) {
1381 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1383 [](StringRef Name,
const unsigned Discriminator,
1384 const unsigned ParameterDiscriminator) -> std::string {
1386 llvm::raw_string_ostream Stream(Buffer);
1389 Stream <<
'_' << Discriminator;
1390 if (ParameterDiscriminator)
1391 Stream <<
'_' << ParameterDiscriminator;
1392 return Stream.str();
1395 unsigned Discriminator = BD->getBlockManglingNumber();
1397 Discriminator = Context.getBlockId(BD,
false);
1402 unsigned ParameterDiscriminator = 0;
1403 if (
const auto *MC = BD->getBlockManglingContextDecl())
1404 if (
const auto *
P = dyn_cast<ParmVarDecl>(MC))
1405 if (
const auto *F = dyn_cast<FunctionDecl>(
P->getDeclContext()))
1406 ParameterDiscriminator =
1407 F->getNumParams() -
P->getFunctionScopeIndex();
1409 DC = getEffectiveDeclContext(BD);
1412 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1413 ParameterDiscriminator));
1418 if (
const auto *MC = BD->getBlockManglingContextDecl())
1419 if (!isa<ParmVarDecl>(MC))
1420 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1421 mangleUnqualifiedName(ND);
1425 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1434 if (PointersAre64Bit)
1437 mangleArtificialTagType(TagTypeKind::Struct,
1438 Discriminate(
"__block_literal", Discriminator,
1439 ParameterDiscriminator));
1444 if (isa<RecordDecl>(DC))
1447 }
else if (
const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
1448 mangleObjCMethodName(Method);
1449 }
else if (isa<NamedDecl>(DC)) {
1450 ND = cast<NamedDecl>(DC);
1451 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1452 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1455 mangleUnqualifiedName(ND);
1458 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1468void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1483 llvm_unreachable(
"not expecting a COMDAT");
1485 llvm_unreachable(
"Unsupported dtor type?");
1494 case OO_New: Out <<
"?2";
break;
1496 case OO_Delete: Out <<
"?3";
break;
1498 case OO_Equal: Out <<
"?4";
break;
1500 case OO_GreaterGreater: Out <<
"?5";
break;
1502 case OO_LessLess: Out <<
"?6";
break;
1504 case OO_Exclaim: Out <<
"?7";
break;
1506 case OO_EqualEqual: Out <<
"?8";
break;
1508 case OO_ExclaimEqual: Out <<
"?9";
break;
1510 case OO_Subscript: Out <<
"?A";
break;
1513 case OO_Arrow: Out <<
"?C";
break;
1515 case OO_Star: Out <<
"?D";
break;
1517 case OO_PlusPlus: Out <<
"?E";
break;
1519 case OO_MinusMinus: Out <<
"?F";
break;
1521 case OO_Minus: Out <<
"?G";
break;
1523 case OO_Plus: Out <<
"?H";
break;
1525 case OO_Amp: Out <<
"?I";
break;
1527 case OO_ArrowStar: Out <<
"?J";
break;
1529 case OO_Slash: Out <<
"?K";
break;
1531 case OO_Percent: Out <<
"?L";
break;
1533 case OO_Less: Out <<
"?M";
break;
1535 case OO_LessEqual: Out <<
"?N";
break;
1537 case OO_Greater: Out <<
"?O";
break;
1539 case OO_GreaterEqual: Out <<
"?P";
break;
1541 case OO_Comma: Out <<
"?Q";
break;
1543 case OO_Call: Out <<
"?R";
break;
1545 case OO_Tilde: Out <<
"?S";
break;
1547 case OO_Caret: Out <<
"?T";
break;
1549 case OO_Pipe: Out <<
"?U";
break;
1551 case OO_AmpAmp: Out <<
"?V";
break;
1553 case OO_PipePipe: Out <<
"?W";
break;
1555 case OO_StarEqual: Out <<
"?X";
break;
1557 case OO_PlusEqual: Out <<
"?Y";
break;
1559 case OO_MinusEqual: Out <<
"?Z";
break;
1561 case OO_SlashEqual: Out <<
"?_0";
break;
1563 case OO_PercentEqual: Out <<
"?_1";
break;
1565 case OO_GreaterGreaterEqual: Out <<
"?_2";
break;
1567 case OO_LessLessEqual: Out <<
"?_3";
break;
1569 case OO_AmpEqual: Out <<
"?_4";
break;
1571 case OO_PipeEqual: Out <<
"?_5";
break;
1573 case OO_CaretEqual: Out <<
"?_6";
break;
1602 case OO_Array_New: Out <<
"?_U";
break;
1604 case OO_Array_Delete: Out <<
"?_V";
break;
1606 case OO_Coawait: Out <<
"?__L";
break;
1608 case OO_Spaceship: Out <<
"?__M";
break;
1610 case OO_Conditional: {
1611 Error(
Loc,
"conditional operator");
1617 llvm_unreachable(
"Not an overloaded operator");
1621void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1623 BackRefVec::iterator
Found = llvm::find(NameBackReferences, Name);
1624 if (
Found == NameBackReferences.end()) {
1625 if (NameBackReferences.size() < 10)
1626 NameBackReferences.push_back(std::string(Name));
1629 Out << (
Found - NameBackReferences.begin());
1633void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1634 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1637void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1644 ArgBackRefMap OuterFunArgsContext;
1645 ArgBackRefMap OuterTemplateArgsContext;
1646 BackRefVec OuterTemplateContext;
1647 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1648 NameBackReferences.swap(OuterTemplateContext);
1649 FunArgBackReferences.swap(OuterFunArgsContext);
1650 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1651 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1653 mangleUnscopedTemplateName(GD);
1654 mangleTemplateArgs(cast<TemplateDecl>(GD.
getDecl()), TemplateArgs);
1657 NameBackReferences.swap(OuterTemplateContext);
1658 FunArgBackReferences.swap(OuterFunArgsContext);
1659 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1660 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1663void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(
GlobalDecl GD) {
1666 mangleUnqualifiedName(GD);
1669void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1680 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1681 LangOptions::MSVC2019) &&
1683 !TemplateArgType.
isNull()) {
1685 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
1690 mangleNumber(
Value);
1693void MicrosoftCXXNameMangler::mangleExpression(
1696 if (std::optional<llvm::APSInt>
Value =
1707void MicrosoftCXXNameMangler::mangleTemplateArgs(
1711 assert(TPL->
size() == TemplateArgs.
size() &&
1712 "size mismatch between args and parms!");
1714 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1722 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1734 QualType BaseT =
V.getLValueBase().getType();
1735 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1736 V.getLValuePath()[0].getAsArrayIndex() != 0)
1739 V.getLValueBase().dyn_cast<
const ValueDecl *>());
1742void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1782 llvm_unreachable(
"Can't mangle null template arguments!");
1784 llvm_unreachable(
"Can't mangle template expansion arguments!");
1792 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1793 mangleMemberDataPointer(cast<CXXRecordDecl>(ND->
getDeclContext())
1794 ->getMostRecentNonInjectedDecl(),
1795 cast<ValueDecl>(ND),
1796 cast<NonTypeTemplateParmDecl>(Parm),
1798 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1801 mangleMemberFunctionPointer(
1805 mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),
1810 auto *TPO = cast<TemplateParamObjectDecl>(ND);
1811 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1812 TPO->getValue(), TplArgKind::ClassNTTP);
1813 }
else if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1814 mangleVarDecl(VD, cast<NonTypeTemplateParmDecl>(Parm),
1824 cast<NonTypeTemplateParmDecl>(Parm),
T);
1830 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1831 if (MPT->isMemberFunctionPointerType() &&
1832 !isa<FunctionTemplateDecl>(TD)) {
1833 mangleMemberFunctionPointer(RD,
nullptr,
nullptr,
QualType());
1836 if (MPT->isMemberDataPointer()) {
1837 if (!isa<FunctionTemplateDecl>(TD)) {
1838 mangleMemberDataPointer(RD,
nullptr,
nullptr,
QualType());
1848 mangleIntegerLiteral(llvm::APSInt::get(-1),
1849 cast<NonTypeTemplateParmDecl>(Parm),
T);
1854 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1855 cast<NonTypeTemplateParmDecl>(Parm),
T);
1864 return mangleTemplateArg(
1868 if (cast<NonTypeTemplateParmDecl>(Parm)
1870 ->getContainedDeducedType()) {
1876 TplArgKind::StructuralValue,
1880 mangleExpression(TA.
getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
1884 if (TemplateArgs.empty()) {
1885 if (isa<TemplateTypeParmDecl>(Parm) ||
1886 isa<TemplateTemplateParmDecl>(Parm))
1890 LangOptions::MSVC2015)
1893 else if (isa<NonTypeTemplateParmDecl>(Parm))
1896 llvm_unreachable(
"unexpected template parameter decl!");
1899 mangleTemplateArg(TD, PA, Parm);
1906 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1908 }
else if (isa<TypeAliasDecl>(ND)) {
1912 llvm_unreachable(
"unexpected template template NamedDecl!");
1919void MicrosoftCXXNameMangler::mangleTemplateArgValue(
QualType T,
1922 bool WithScalarType) {
1923 switch (
V.getKind()) {
1937 mangleNumber(
V.getInt());
1943 mangleFloat(
V.getFloat());
1954 if (
V.isLValueOnePastTheEnd()) {
1963 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1965 if (
Base.isNull()) {
1971 mangleNumber(
V.getLValueOffset().getQuantity());
1972 }
else if (!
V.hasLValuePath()) {
1974 Error(
"template argument (extension not comaptible with ms mangler)");
1980 Error(
"template argument (undeclared base)");
1988 SmallVector<std::function<void()>, 2> EntryManglers;
1992 EntryTypes.push_back(
'C');
1993 EntryManglers.push_back([
this, I =
E.getAsArrayIndex()] {
1998 ET = AT->getElementType();
2002 const Decl *
D =
E.getAsBaseOrMember().getPointer();
2003 if (
auto *FD = dyn_cast<FieldDecl>(
D)) {
2009 ET = getASTContext().getRecordType(cast<CXXRecordDecl>(
D));
2015 EntryTypes.push_back(
'6');
2016 EntryManglers.push_back([
this,
D] {
2017 mangleUnqualifiedName(cast<NamedDecl>(
D));
2022 for (
auto I = EntryTypes.rbegin(),
E = EntryTypes.rend(); I !=
E; ++I)
2027 Error(
"template argument (null value decl)");
2030 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
2033 for (
const std::function<
void()> &Mangler : EntryManglers)
2049 if (TAK == TplArgKind::ClassNTTP) {
2051 mangleMemberDataPointerInClassNTTP(RD,
D);
2053 mangleMemberFunctionPointerInClassNTTP(RD,
2054 cast_or_null<CXXMethodDecl>(
D));
2057 mangleMemberDataPointer(RD,
D,
nullptr,
QualType(),
"");
2059 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(
D),
nullptr,
2069 assert(RD &&
"unexpected type for record value");
2071 unsigned BaseIndex = 0;
2073 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
2075 if (!FD->isUnnamedBitField())
2076 mangleTemplateArgValue(FD->
getType(),
2077 V.getStructField(FD->getFieldIndex()), TAK,
2086 if (
const FieldDecl *FD =
V.getUnionField()) {
2087 mangleUnqualifiedName(FD);
2088 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
2098 mangleNumber(
V.getComplexIntReal());
2100 mangleNumber(
V.getComplexIntImag());
2107 mangleFloat(
V.getComplexFloatReal());
2108 mangleFloat(
V.getComplexFloatImag());
2114 QualType ElemT = getASTContext().getAsArrayType(
T)->getElementType();
2116 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
2117 const APValue &ElemV = I <
V.getArrayInitializedElts()
2118 ?
V.getArrayInitializedElt(I)
2119 :
V.getArrayFiller();
2120 mangleTemplateArgValue(ElemT, ElemV, TAK);
2135 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
2136 const APValue &ElemV =
V.getVectorElt(I);
2137 mangleTemplateArgValue(ElemT, ElemV, TAK);
2145 Error(
"template argument (value type: address label diff)");
2150 Error(
"template argument (value type: fixed point)");
2156void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2158 llvm::raw_svector_ostream Stream(TemplateMangling);
2159 MicrosoftCXXNameMangler Extra(Context, Stream);
2162 Extra.mangleSourceName(
"Protocol");
2163 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2165 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2168void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType Type,
2172 llvm::raw_svector_ostream Stream(TemplateMangling);
2173 MicrosoftCXXNameMangler Extra(Context, Stream);
2181 Extra.mangleSourceName(
"Autoreleasing");
2184 Extra.mangleSourceName(
"Strong");
2187 Extra.mangleSourceName(
"Weak");
2190 Extra.manglePointerCVQualifiers(Quals);
2191 Extra.manglePointerExtQualifiers(Quals,
Type);
2194 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2197void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *
T,
2201 llvm::raw_svector_ostream Stream(TemplateMangling);
2202 MicrosoftCXXNameMangler Extra(Context, Stream);
2205 Extra.mangleSourceName(
"KindOf");
2207 .stripObjCKindOfType(getASTContext())
2208 ->castAs<ObjCObjectType>(),
2211 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2214void MicrosoftCXXNameMangler::mangleQualifiers(
Qualifiers Quals,
2272 if (HasConst && HasVolatile) {
2274 }
else if (HasVolatile) {
2276 }
else if (HasConst) {
2282 if (HasConst && HasVolatile) {
2284 }
else if (HasVolatile) {
2286 }
else if (HasConst) {
2297MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2300 switch (RefQualifier) {
2314void MicrosoftCXXNameMangler::manglePointerExtQualifiers(
Qualifiers Quals,
2317 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2330void MicrosoftCXXNameMangler::manglePointerCVQualifiers(
Qualifiers Quals) {
2338 if (HasConst && HasVolatile) {
2340 }
else if (HasVolatile) {
2342 }
else if (HasConst) {
2349void MicrosoftCXXNameMangler::mangleFunctionArgumentType(
QualType T,
2360 QualType OriginalType = DT->getOriginalType();
2363 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2364 OriginalType = getASTContext().getIncompleteArrayType(
2365 AT->getElementType(), AT->getSizeModifier(),
2366 AT->getIndexTypeCVRQualifiers());
2377 TypePtr =
T.getCanonicalType().getAsOpaquePtr();
2380 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2382 if (
Found == FunArgBackReferences.end()) {
2383 size_t OutSizeBefore = Out.tell();
2385 mangleType(
T,
Range, QMM_Drop);
2390 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);
2391 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2392 size_t Size = FunArgBackReferences.size();
2393 FunArgBackReferences[TypePtr] =
Size;
2396 Out <<
Found->second;
2400void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2401 const PassObjectSizeAttr *POSA) {
2402 int Type = POSA->getType();
2403 bool Dynamic = POSA->isDynamic();
2406 auto *TypePtr = (
const void *)&*
Iter;
2407 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2409 if (
Found == FunArgBackReferences.end()) {
2411 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2412 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2415 if (FunArgBackReferences.size() < 10) {
2416 size_t Size = FunArgBackReferences.size();
2417 FunArgBackReferences[TypePtr] =
Size;
2420 Out <<
Found->second;
2424void MicrosoftCXXNameMangler::mangleAddressSpaceType(
QualType T,
2442 llvm::raw_svector_ostream Stream(ASMangling);
2443 MicrosoftCXXNameMangler Extra(Context, Stream);
2449 Extra.mangleSourceName(
"_AS");
2450 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2454 llvm_unreachable(
"Not a language specific address space");
2455 case LangAS::opencl_global:
2456 Extra.mangleSourceName(
"_ASCLglobal");
2458 case LangAS::opencl_global_device:
2459 Extra.mangleSourceName(
"_ASCLdevice");
2461 case LangAS::opencl_global_host:
2462 Extra.mangleSourceName(
"_ASCLhost");
2464 case LangAS::opencl_local:
2465 Extra.mangleSourceName(
"_ASCLlocal");
2467 case LangAS::opencl_constant:
2468 Extra.mangleSourceName(
"_ASCLconstant");
2470 case LangAS::opencl_private:
2471 Extra.mangleSourceName(
"_ASCLprivate");
2473 case LangAS::opencl_generic:
2474 Extra.mangleSourceName(
"_ASCLgeneric");
2476 case LangAS::cuda_device:
2477 Extra.mangleSourceName(
"_ASCUdevice");
2479 case LangAS::cuda_constant:
2480 Extra.mangleSourceName(
"_ASCUconstant");
2482 case LangAS::cuda_shared:
2483 Extra.mangleSourceName(
"_ASCUshared");
2485 case LangAS::ptr32_sptr:
2486 case LangAS::ptr32_uptr:
2488 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2492 Extra.mangleType(
T,
Range, QMM_Escape);
2494 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2498 QualifierMangleMode QMM) {
2501 T =
T.getDesugaredType(getASTContext());
2504 if (
const ArrayType *AT = getASTContext().getAsArrayType(
T)) {
2507 if (QMM == QMM_Mangle)
2509 else if (QMM == QMM_Escape || QMM == QMM_Result)
2511 mangleArrayType(AT);
2526 mangleFunctionType(FT);
2529 mangleQualifiers(Quals,
false);
2532 if (!IsPointer && Quals) {
2534 mangleQualifiers(Quals,
false);
2542 if ((!IsPointer && Quals) || isa<TagType>(
T) || isArtificialTagType(
T)) {
2544 mangleQualifiers(Quals,
false);
2549 const Type *ty =
T.getTypePtr();
2552#define ABSTRACT_TYPE(CLASS, PARENT)
2553#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2555 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2557#define TYPE(CLASS, PARENT) \
2559 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2561#include "clang/AST/TypeNodes.inc"
2563#undef NON_CANONICAL_TYPE
2597 switch (
T->getKind()) {
2598 case BuiltinType::Void:
2601 case BuiltinType::SChar:
2604 case BuiltinType::Char_U:
2605 case BuiltinType::Char_S:
2608 case BuiltinType::UChar:
2611 case BuiltinType::Short:
2614 case BuiltinType::UShort:
2617 case BuiltinType::Int:
2620 case BuiltinType::UInt:
2623 case BuiltinType::Long:
2626 case BuiltinType::ULong:
2629 case BuiltinType::Float:
2632 case BuiltinType::Double:
2636 case BuiltinType::LongDouble:
2639 case BuiltinType::LongLong:
2642 case BuiltinType::ULongLong:
2645 case BuiltinType::Int128:
2648 case BuiltinType::UInt128:
2651 case BuiltinType::Bool:
2654 case BuiltinType::Char8:
2657 case BuiltinType::Char16:
2660 case BuiltinType::Char32:
2663 case BuiltinType::WChar_S:
2664 case BuiltinType::WChar_U:
2668#define BUILTIN_TYPE(Id, SingletonId)
2669#define PLACEHOLDER_TYPE(Id, SingletonId) \
2670 case BuiltinType::Id:
2671#include "clang/AST/BuiltinTypes.def"
2672 case BuiltinType::Dependent:
2673 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2675 case BuiltinType::ObjCId:
2676 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2678 case BuiltinType::ObjCClass:
2679 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2681 case BuiltinType::ObjCSel:
2682 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2685#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2686 case BuiltinType::Id: \
2687 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2689#include "clang/Basic/OpenCLImageTypes.def"
2690 case BuiltinType::OCLSampler:
2692 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2694 case BuiltinType::OCLEvent:
2696 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2698 case BuiltinType::OCLClkEvent:
2700 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2702 case BuiltinType::OCLQueue:
2704 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2706 case BuiltinType::OCLReserveID:
2708 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2710#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2711 case BuiltinType::Id: \
2712 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2714#include "clang/Basic/OpenCLExtensionTypes.def"
2716 case BuiltinType::NullPtr:
2720 case BuiltinType::Float16:
2721 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2724 case BuiltinType::Half:
2725 if (!getASTContext().getLangOpts().
HLSL)
2726 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2727 else if (getASTContext().getLangOpts().NativeHalfType)
2733 case BuiltinType::BFloat16:
2734 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2737#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2738 case BuiltinType::Id: \
2739 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2740 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2743#include "clang/Basic/WebAssemblyReferenceTypes.def"
2745#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2746 case BuiltinType::Id: \
2747 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2749#include "clang/Basic/HLSLIntangibleTypes.def"
2751#define SVE_TYPE(Name, Id, SingletonId) \
2752 case BuiltinType::Id:
2753#include "clang/Basic/AArch64SVEACLETypes.def"
2754#define PPC_VECTOR_TYPE(Name, Id, Size) \
2755 case BuiltinType::Id:
2756#include "clang/Basic/PPCTypes.def"
2757#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2758#include "clang/Basic/RISCVVTypes.def"
2759#define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2760#include "clang/Basic/AMDGPUTypes.def"
2761 case BuiltinType::ShortAccum:
2762 case BuiltinType::Accum:
2763 case BuiltinType::LongAccum:
2764 case BuiltinType::UShortAccum:
2765 case BuiltinType::UAccum:
2766 case BuiltinType::ULongAccum:
2767 case BuiltinType::ShortFract:
2768 case BuiltinType::Fract:
2769 case BuiltinType::LongFract:
2770 case BuiltinType::UShortFract:
2771 case BuiltinType::UFract:
2772 case BuiltinType::ULongFract:
2773 case BuiltinType::SatShortAccum:
2774 case BuiltinType::SatAccum:
2775 case BuiltinType::SatLongAccum:
2776 case BuiltinType::SatUShortAccum:
2777 case BuiltinType::SatUAccum:
2778 case BuiltinType::SatULongAccum:
2779 case BuiltinType::SatShortFract:
2780 case BuiltinType::SatFract:
2781 case BuiltinType::SatLongFract:
2782 case BuiltinType::SatUShortFract:
2783 case BuiltinType::SatUFract:
2784 case BuiltinType::SatULongFract:
2785 case BuiltinType::Ibm128:
2786 case BuiltinType::Float128: {
2803 mangleFunctionType(
T,
nullptr,
true);
2806 mangleFunctionType(
T);
2812 mangleFunctionType(
T);
2815void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *
T,
2817 bool ForceThisQuals,
2818 bool MangleExceptionSpec) {
2826 bool IsInLambda =
false;
2827 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
2829 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(
D)) {
2833 HasThisQuals =
true;
2834 if (isa<CXXDestructorDecl>(MD)) {
2836 }
else if (isa<CXXConstructorDecl>(MD)) {
2842 CC = getASTContext().getDefaultCallingConvention(
2851 manglePointerExtQualifiers(Quals,
QualType());
2853 mangleQualifiers(Quals,
false);
2856 mangleCallingConvention(CC,
Range);
2861 if (isa<CXXDestructorDecl>(
D) && isStructorDecl(
D)) {
2865 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
2874 if (IsCtorClosure) {
2884 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
2892 llvm_unreachable(
"unexpected constructor closure!");
2898 }
else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(
D)) {
2905 if (IsInLambda && isa<CXXConversionDecl>(
D)) {
2909 mangleType(ResultType,
Range, QMM_Result);
2910 }
else if (
const auto *AT = dyn_cast_or_null<AutoType>(
2915 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2916 "shouldn't need to mangle __auto_type!");
2917 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
2919 }
else if (IsInLambda) {
2924 mangleType(ResultType,
Range, QMM_Result);
2942 if (I == 0 &&
D &&
D->getParamDecl(I)->isExplicitObjectParameter())
2955 if (
const auto *
P =
D->getParamDecl(I)->
getAttr<PassObjectSizeAttr>())
2956 manglePassObjectSizeArg(
P);
2965 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
2966 getASTContext().getLangOpts().isCompatibleWithMSVC(
2967 LangOptions::MSVC2017_5))
2968 mangleThrowSpecification(Proto);
2973void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
2998 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3002 if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
3008 llvm_unreachable(
"Unsupported access specifier");
3037void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC,
3100 if (getASTContext().getLangOpts().RegCall4)
3109void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *
T,
3114void MicrosoftCXXNameMangler::mangleThrowSpecification(
3136void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
3138 case TagTypeKind::Union:
3141 case TagTypeKind::Struct:
3142 case TagTypeKind::Interface:
3145 case TagTypeKind::Class:
3148 case TagTypeKind::Enum:
3155 mangleType(cast<TagType>(
T)->getDecl());
3159 mangleType(cast<TagType>(
T)->getDecl());
3161void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3167void MicrosoftCXXNameMangler::mangleArtificialTagType(
3171 mangleTagTypeKind(TK);
3174 mangleSourceName(UnqualifiedName);
3176 for (StringRef N : llvm::reverse(NestedNames))
3177 mangleSourceName(N);
3190void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *
T) {
3193 manglePointerCVQualifiers(
T->getElementType().getQualifiers());
3198 llvm_unreachable(
"Should have been special cased");
3202 llvm_unreachable(
"Should have been special cased");
3206 llvm_unreachable(
"Should have been special cased");
3210 llvm_unreachable(
"Should have been special cased");
3212void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *
T) {
3216 if (ElementTy->isConstantArrayType()) {
3218 getASTContext().getAsConstantArrayType(ElementTy);
3219 Dimensions.push_back(CAT->
getSize());
3221 }
else if (ElementTy->isIncompleteArrayType()) {
3223 getASTContext().getAsIncompleteArrayType(ElementTy);
3224 Dimensions.push_back(llvm::APInt(32, 0));
3226 }
else if (ElementTy->isVariableArrayType()) {
3228 getASTContext().getAsVariableArrayType(ElementTy);
3229 Dimensions.push_back(llvm::APInt(32, 0));
3231 }
else if (ElementTy->isDependentSizedArrayType()) {
3234 getASTContext().getAsDependentSizedArrayType(ElementTy);
3244 mangleNumber(Dimensions.size());
3245 for (
const llvm::APInt &Dimension : Dimensions)
3246 mangleNumber(Dimension.getLimitedValue());
3252 mangleArrayType(cast<ConstantArrayType>(
T));
3261 manglePointerCVQualifiers(Quals);
3262 manglePointerExtQualifiers(Quals, PointeeType);
3266 mangleFunctionType(FPT,
nullptr,
true);
3270 mangleType(PointeeType,
Range, QMM_Drop);
3290 manglePointerCVQualifiers(Quals);
3291 manglePointerExtQualifiers(Quals, PointeeType);
3297 mangleType(PointeeType,
Range);
3312 return mangleObjCLifetime(PointeeType, Quals,
Range);
3314 manglePointerCVQualifiers(Quals);
3315 manglePointerExtQualifiers(Quals, PointeeType);
3316 mangleType(PointeeType,
Range);
3327 manglePointerExtQualifiers(Quals, PointeeType);
3328 mangleType(PointeeType,
Range);
3339 manglePointerExtQualifiers(Quals, PointeeType);
3340 mangleType(PointeeType,
Range);
3345 QualType ElementType =
T->getElementType();
3348 llvm::raw_svector_ostream Stream(TemplateMangling);
3349 MicrosoftCXXNameMangler Extra(Context, Stream);
3351 Extra.mangleSourceName(
"_Complex");
3352 Extra.mangleType(ElementType,
Range, QMM_Escape);
3354 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3362bool MicrosoftCXXNameMangler::isArtificialTagType(
QualType T)
const {
3363 const Type *ty =
T.getTypePtr();
3368 case Type::Vector: {
3382 assert((ET || BitIntTy) &&
3383 "vectors with non-builtin/_BitInt elements are unsupported");
3384 uint64_t Width = getASTContext().getTypeSize(
T);
3387 size_t OutSizeBefore = Out.tell();
3388 if (!isa<ExtVectorType>(
T)) {
3389 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
3390 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3391 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3392 }
else if (Width >= 128) {
3393 if (ET->
getKind() == BuiltinType::Float)
3394 mangleArtificialTagType(TagTypeKind::Union,
3395 "__m" + llvm::utostr(Width));
3396 else if (ET->
getKind() == BuiltinType::LongLong)
3397 mangleArtificialTagType(TagTypeKind::Union,
3398 "__m" + llvm::utostr(Width) +
'i');
3399 else if (ET->
getKind() == BuiltinType::Double)
3400 mangleArtificialTagType(TagTypeKind::Struct,
3401 "__m" + llvm::utostr(Width) +
'd');
3406 bool IsBuiltin = Out.tell() != OutSizeBefore;
3413 llvm::raw_svector_ostream Stream(TemplateMangling);
3414 MicrosoftCXXNameMangler Extra(Context, Stream);
3416 Extra.mangleSourceName(
"__vector");
3417 Extra.mangleType(
QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3419 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumElements()));
3421 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3458 mangleTagTypeKind(TagTypeKind::Struct);
3459 mangleName(
T->getDecl());
3464 if (
T->isKindOfType())
3465 return mangleObjCKindOfType(
T, Quals,
Range);
3467 if (
T->qual_empty() && !
T->isSpecialized())
3468 return mangleType(
T->getBaseType(),
Range, QMM_Drop);
3470 ArgBackRefMap OuterFunArgsContext;
3471 ArgBackRefMap OuterTemplateArgsContext;
3472 BackRefVec OuterTemplateContext;
3474 FunArgBackReferences.swap(OuterFunArgsContext);
3475 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3476 NameBackReferences.swap(OuterTemplateContext);
3478 mangleTagTypeKind(TagTypeKind::Struct);
3482 mangleSourceName(
"objc_object");
3483 else if (
T->isObjCClass())
3484 mangleSourceName(
"objc_class");
3486 mangleSourceName(
T->getInterface()->getName());
3488 for (
const auto &Q :
T->quals())
3489 mangleObjCProtocol(Q);
3491 if (
T->isSpecialized())
3492 for (
const auto &TA :
T->getTypeArgs())
3493 mangleType(TA,
Range, QMM_Drop);
3499 FunArgBackReferences.swap(OuterFunArgsContext);
3500 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3501 NameBackReferences.swap(OuterTemplateContext);
3507 manglePointerCVQualifiers(Quals);
3508 manglePointerExtQualifiers(Quals, PointeeType);
3517 llvm_unreachable(
"Cannot mangle injected class name type.");
3530void MicrosoftCXXNameMangler::mangleType(
3543 manglePointerCVQualifiers(Quals);
3544 mangleType(
T->getSelectedType(),
Range);
3569 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3574void MicrosoftCXXNameMangler::mangleType(
3576 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3587 llvm::raw_svector_ostream Stream(TemplateMangling);
3588 MicrosoftCXXNameMangler Extra(Context, Stream);
3590 Extra.mangleSourceName(
"_Atomic");
3591 Extra.mangleType(ValueType,
Range, QMM_Escape);
3593 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3598 QualType ElementType =
T->getElementType();
3601 llvm::raw_svector_ostream Stream(TemplateMangling);
3602 MicrosoftCXXNameMangler Extra(Context, Stream);
3604 Extra.mangleSourceName(
"ocl_pipe");
3605 Extra.mangleType(ElementType,
Range, QMM_Escape);
3606 Extra.mangleIntegerLiteral(llvm::APSInt::get(
T->isReadOnly()));
3608 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3611void MicrosoftMangleContextImpl::mangleCXXName(
GlobalDecl GD,
3615 getASTContext().getSourceManager(),
3616 "Mangling declaration");
3618 msvc_hashing_ostream MHO(Out);
3620 if (
auto *CD = dyn_cast<CXXConstructorDecl>(
D)) {
3622 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3623 return mangler.mangle(GD);
3626 if (
auto *DD = dyn_cast<CXXDestructorDecl>(
D)) {
3628 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3629 return mangler.mangle(GD);
3632 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3633 return Mangler.mangle(GD);
3639 llvm::raw_svector_ostream Stream(TemplateMangling);
3640 MicrosoftCXXNameMangler Extra(Context, Stream);
3642 if (
T->isUnsigned())
3643 Extra.mangleSourceName(
"_UBitInt");
3645 Extra.mangleSourceName(
"_BitInt");
3646 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumBits()));
3648 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3682 MicrosoftCXXNameMangler &Mangler,
3689 llvm_unreachable(
"Unsupported access specifier");
3700 Out <<
'R' << AccessSpec;
3701 Mangler.mangleNumber(
3703 Mangler.mangleNumber(
3705 Mangler.mangleNumber(
3707 Mangler.mangleNumber(
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3710 Mangler.mangleNumber(
3712 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3717 llvm_unreachable(
"Unsupported access specifier");
3727 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3731 llvm_unreachable(
"Unsupported access specifier");
3744void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
3747 msvc_hashing_ostream MHO(Out);
3748 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3749 Mangler.getStream() <<
'?';
3750 Mangler.mangleVirtualMemPtrThunk(MD, ML);
3753void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
3757 msvc_hashing_ostream MHO(Out);
3758 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3759 Mangler.getStream() <<
'?';
3760 Mangler.mangleName(MD);
3769 assert(Thunk.
Method !=
nullptr &&
3770 "Thunk info should hold the overridee decl");
3773 Mangler.mangleFunctionType(
3786 msvc_hashing_ostream MHO(Out);
3787 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
3788 Mangler.getStream() <<
"??_E";
3790 auto &Adjustment = Thunk.
This;
3795void MicrosoftMangleContextImpl::mangleCXXVFTable(
3802 msvc_hashing_ostream MHO(Out);
3803 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3804 if (Derived->
hasAttr<DLLImportAttr>())
3805 Mangler.getStream() <<
"??_S";
3807 Mangler.getStream() <<
"??_7";
3808 Mangler.mangleName(Derived);
3809 Mangler.getStream() <<
"6B";
3811 Mangler.mangleName(RD);
3812 Mangler.getStream() <<
'@';
3815void MicrosoftMangleContextImpl::mangleCXXVTable(
const CXXRecordDecl *Derived,
3818 mangleCXXVFTable(Derived, {}, Out);
3821void MicrosoftMangleContextImpl::mangleCXXVBTable(
3828 msvc_hashing_ostream MHO(Out);
3829 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3830 Mangler.getStream() <<
"??_8";
3831 Mangler.mangleName(Derived);
3832 Mangler.getStream() <<
"7B";
3834 Mangler.mangleName(RD);
3835 Mangler.getStream() <<
'@';
3838void MicrosoftMangleContextImpl::mangleCXXRTTI(
QualType T, raw_ostream &Out) {
3839 msvc_hashing_ostream MHO(Out);
3840 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3841 Mangler.getStream() <<
"??_R0";
3842 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3843 Mangler.getStream() <<
"@8";
3846void MicrosoftMangleContextImpl::mangleCXXRTTIName(
3847 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
3848 MicrosoftCXXNameMangler Mangler(*
this, Out);
3849 Mangler.getStream() <<
'.';
3850 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3853void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
3855 msvc_hashing_ostream MHO(Out);
3856 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3857 Mangler.getStream() <<
"??_K";
3858 Mangler.mangleName(SrcRD);
3859 Mangler.getStream() <<
"$C";
3860 Mangler.mangleName(DstRD);
3863void MicrosoftMangleContextImpl::mangleCXXThrowInfo(
QualType T,
bool IsConst,
3866 uint32_t NumEntries,
3868 msvc_hashing_ostream MHO(Out);
3869 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3870 Mangler.getStream() <<
"_TI";
3872 Mangler.getStream() <<
'C';
3874 Mangler.getStream() <<
'V';
3876 Mangler.getStream() <<
'U';
3877 Mangler.getStream() << NumEntries;
3878 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3881void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
3882 QualType T, uint32_t NumEntries, raw_ostream &Out) {
3883 msvc_hashing_ostream MHO(Out);
3884 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3885 Mangler.getStream() <<
"_CTA";
3886 Mangler.getStream() << NumEntries;
3887 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3890void MicrosoftMangleContextImpl::mangleCXXCatchableType(
3892 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
3894 MicrosoftCXXNameMangler Mangler(*
this, Out);
3895 Mangler.getStream() <<
"_CT";
3899 llvm::raw_svector_ostream Stream(RTTIMangling);
3900 msvc_hashing_ostream MHO(Stream);
3901 mangleCXXRTTI(
T, MHO);
3903 Mangler.getStream() << RTTIMangling;
3911 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
3912 LangOptions::MSVC2015) &&
3913 !getASTContext().getLangOpts().isCompatibleWithMSVC(
3914 LangOptions::MSVC2017_7);
3916 if (!OmitCopyCtor && CD) {
3917 llvm::raw_svector_ostream Stream(CopyCtorMangling);
3918 msvc_hashing_ostream MHO(Stream);
3921 Mangler.getStream() << CopyCtorMangling;
3923 Mangler.getStream() <<
Size;
3924 if (VBPtrOffset == -1) {
3926 Mangler.getStream() << NVOffset;
3929 Mangler.getStream() << NVOffset;
3930 Mangler.getStream() << VBPtrOffset;
3931 Mangler.getStream() << VBIndex;
3935void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
3936 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
3937 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
3938 msvc_hashing_ostream MHO(Out);
3939 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3940 Mangler.getStream() <<
"??_R1";
3941 Mangler.mangleNumber(NVOffset);
3942 Mangler.mangleNumber(VBPtrOffset);
3943 Mangler.mangleNumber(VBTableOffset);
3944 Mangler.mangleNumber(Flags);
3945 Mangler.mangleName(Derived);
3946 Mangler.getStream() <<
"8";
3949void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
3951 msvc_hashing_ostream MHO(Out);
3952 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3953 Mangler.getStream() <<
"??_R2";
3954 Mangler.mangleName(Derived);
3955 Mangler.getStream() <<
"8";
3958void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
3960 msvc_hashing_ostream MHO(Out);
3961 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3962 Mangler.getStream() <<
"??_R3";
3963 Mangler.mangleName(Derived);
3964 Mangler.getStream() <<
"8";
3967void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
3975 llvm::raw_svector_ostream Stream(VFTableMangling);
3976 mangleCXXVFTable(Derived, BasePath, Stream);
3978 if (VFTableMangling.starts_with(
"??@")) {
3979 assert(VFTableMangling.ends_with(
"@"));
3980 Out << VFTableMangling <<
"??_R4@";
3984 assert(VFTableMangling.starts_with(
"??_7") ||
3985 VFTableMangling.starts_with(
"??_S"));
3987 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
3990void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
3991 GlobalDecl EnclosingDecl, raw_ostream &Out) {
3992 msvc_hashing_ostream MHO(Out);
3993 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3998 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
3999 Mangler.mangleName(EnclosingDecl);
4002void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4003 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4004 msvc_hashing_ostream MHO(Out);
4005 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4010 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
4011 Mangler.mangleName(EnclosingDecl);
4014void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4015 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4018 MicrosoftCXXNameMangler Mangler(*
this, Out);
4019 Mangler.getStream() <<
'?';
4020 Mangler.mangleType(
T.getCanonicalType(),
SourceRange());
4023void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4024 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
4025 msvc_hashing_ostream MHO(Out);
4026 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4028 Mangler.getStream() <<
"?";
4029 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
4030 Mangler.mangle(VD,
"");
4033void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4034 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
4035 msvc_hashing_ostream MHO(Out);
4036 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4038 Mangler.getStream() <<
"?";
4039 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
4040 Mangler.mangleNestedName(VD);
4041 Mangler.getStream() <<
"@4HA";
4044void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
4056 msvc_hashing_ostream MHO(Out);
4057 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4061 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
4063 Mangler.getStream() <<
"?$S1@";
4065 unsigned ScopeDepth = 0;
4066 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4070 Mangler.mangle(VD,
"");
4072 Mangler.mangleNestedName(VD);
4073 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
4075 Mangler.mangleNumber(ScopeDepth);
4078void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *
D,
4081 msvc_hashing_ostream MHO(Out);
4082 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4083 Mangler.getStream() <<
"??__" << CharCode;
4084 if (
D->isStaticDataMember()) {
4085 Mangler.getStream() <<
'?';
4086 Mangler.mangleName(
D);
4087 Mangler.mangleVariableEncoding(
D);
4088 Mangler.getStream() <<
"@@";
4090 Mangler.mangleName(
D);
4094 Mangler.getStream() <<
"YAXXZ";
4097void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *
D,
4100 mangleInitFiniStub(
D,
'E', Out);
4104MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *
D,
4107 mangleInitFiniStub(
D,
'F', Out);
4110void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4131 MicrosoftCXXNameMangler Mangler(*
this, Out);
4132 Mangler.getStream() <<
"??_C@_";
4140 unsigned StringLength =
4141 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4146 Mangler.getStream() <<
'1';
4148 Mangler.getStream() <<
'0';
4152 Mangler.mangleNumber(StringByteLength);
4154 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4156 if (Index / CharByteWidth >= SL->
getLength())
4157 return static_cast<char>(0);
4159 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4160 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4163 auto GetBigEndianByte = [&SL](
unsigned Index) {
4165 if (Index / CharByteWidth >= SL->
getLength())
4166 return static_cast<char>(0);
4168 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4169 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4174 for (
unsigned I = 0,
E = StringByteLength; I !=
E; ++I)
4175 JC.update(GetLittleEndianByte(I));
4179 Mangler.mangleNumber(JC.getCRC());
4185 auto MangleByte = [&Mangler](
char Byte) {
4193 Mangler.getStream() << Byte;
4194 }
else if (
isLetter(Byte & 0x7f)) {
4195 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4197 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4198 ' ',
'\n',
'\t',
'\'',
'-'};
4199 const char *Pos = llvm::find(SpecialChars, Byte);
4200 if (Pos != std::end(SpecialChars)) {
4201 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4203 Mangler.getStream() <<
"?$";
4204 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4205 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4211 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4212 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4213 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4215 MangleByte(GetBigEndianByte(I));
4217 MangleByte(GetLittleEndianByte(I));
4220 Mangler.getStream() <<
'@';
4226 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::@192 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...