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 raw_ostream &)
override;
165 raw_ostream &)
override;
168 raw_ostream &Out)
override;
171 raw_ostream &Out)
override;
174 raw_ostream &Out)
override;
176 bool IsUnaligned, uint32_t NumEntries,
177 raw_ostream &Out)
override;
179 raw_ostream &Out)
override;
182 int32_t VBPtrOffset, uint32_t VBIndex,
183 raw_ostream &Out)
override;
186 bool NormalizeIntegers)
override;
188 uint32_t NVOffset, int32_t VBPtrOffset,
189 uint32_t VBTableOffset, uint32_t Flags,
190 raw_ostream &Out)
override;
192 raw_ostream &Out)
override;
194 raw_ostream &Out)
override;
198 raw_ostream &Out)
override;
200 bool NormalizeIntegers)
override;
202 raw_ostream &)
override;
205 raw_ostream &Out)
override;
208 raw_ostream &Out)
override;
210 raw_ostream &Out)
override;
212 raw_ostream &Out)
override;
214 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
215 const DeclContext *DC = getEffectiveDeclContext(ND);
221 if (
const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
222 if (RD->isLambda()) {
235 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
236 if (!Tag->hasNameForLinkage() &&
237 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
243 unsigned &discriminator = Uniquifier[ND];
245 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
246 disc = discriminator + 1;
251 assert(Lambda->
isLambda() &&
"RD must be a lambda!");
252 std::string Name(
"<lambda_");
257 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
262 unsigned DefaultArgNo =
264 Name += llvm::utostr(DefaultArgNo);
268 if (LambdaManglingNumber)
269 LambdaId = LambdaManglingNumber;
271 LambdaId = getLambdaIdForDebugInfo(Lambda);
273 Name += llvm::utostr(LambdaId);
279 assert(RD->
isLambda() &&
"RD must be a lambda!");
282 "RD must not have a mangling number!");
283 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator,
bool>
284 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
285 return Result.first->second;
289 assert(RD->
isLambda() &&
"RD must be a lambda!");
292 "RD must not have a mangling number!");
294 return LambdaIds.lookup(RD);
299 StringRef getAnonymousNamespaceHash()
const {
300 return AnonymousNamespaceHash;
304 void mangleInitFiniStub(
const VarDecl *D,
char CharCode, raw_ostream &Out);
309class MicrosoftCXXNameMangler {
310 MicrosoftMangleContextImpl &Context;
317 unsigned StructorType;
320 BackRefVec NameBackReferences;
322 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
323 ArgBackRefMap FunArgBackReferences;
324 ArgBackRefMap TemplateArgBackReferences;
326 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
327 TemplateArgStringMap TemplateArgStrings;
328 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
329 llvm::StringSaver TemplateArgStringStorage;
331 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
332 PassObjectSizeArgsSet PassObjectSizeArgs;
334 ASTContext &getASTContext()
const {
return Context.getASTContext(); }
336 const bool PointersAre64Bit;
339 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
340 enum class TplArgKind { ClassNTTP, StructuralValue };
342 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_)
343 : Context(
C), Out(Out_), Structor(nullptr), StructorType(-1),
344 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
345 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
348 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
350 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
351 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
352 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
355 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
357 : Context(
C), Out(Out_), Structor(getStructor(D)), StructorType(
Type),
358 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
359 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
362 raw_ostream &getStream()
const {
return Out; }
364 void mangle(
GlobalDecl GD, StringRef Prefix =
"?");
366 void mangleFunctionEncoding(
GlobalDecl GD,
bool ShouldMangle);
367 void mangleVariableEncoding(
const VarDecl *VD);
369 StringRef Prefix =
"$");
370 void mangleMemberDataPointerInClassNTTP(
const CXXRecordDecl *,
374 StringRef Prefix =
"$");
375 void mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD,
379 void mangleNumber(int64_t Number);
380 void mangleNumber(llvm::APSInt Number);
381 void mangleFloat(llvm::APFloat Number);
382 void mangleBits(llvm::APInt Number);
384 void mangleArtificialTagType(
TagTypeKind TK, StringRef UnqualifiedName,
388 QualifierMangleMode QMM = QMM_Mangle);
391 bool ForceThisQuals =
false,
392 bool MangleExceptionSpec =
true);
393 void mangleSourceName(StringRef Name);
397 bool isStructorDecl(
const NamedDecl *ND)
const {
398 return ND == Structor || getStructor(ND) == Structor;
403 return AddrSpace == LangAS::ptr64 ||
404 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||
405 AddrSpace == LangAS::ptr32_uptr));
409 mangleUnqualifiedName(GD, cast<NamedDecl>(GD.
getDecl())->getDeclName());
414 void mangleQualifiers(
Qualifiers Quals,
bool IsMember);
416 void manglePointerCVQualifiers(
Qualifiers Quals);
419 void mangleUnscopedTemplateName(
GlobalDecl GD);
421 mangleTemplateInstantiationName(
GlobalDecl GD,
426 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
428 bool isArtificialTagType(
QualType T)
const;
431#define ABSTRACT_TYPE(CLASS, PARENT)
432#define NON_CANONICAL_TYPE(CLASS, PARENT)
433#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
436#include "clang/AST/TypeNodes.inc"
438#undef NON_CANONICAL_TYPE
441 void mangleType(
const TagDecl *TD);
442 void mangleDecayedArrayType(
const ArrayType *
T);
447 void mangleIntegerLiteral(
const llvm::APSInt &Number,
458 bool WithScalarType =
false);
468MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(
ASTContext &Context,
489 uint32_t TruncatedHash = uint32_t(xxh3_64bits(FE->getName()));
490 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
493 AnonymousNamespaceHash =
"0";
497bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *D) {
498 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
501 if (FD->hasAttr<OverloadableAttr>())
513 if (FD->isMSVCRTEntryPoint())
527 if (!getASTContext().getLangOpts().
CPlusPlus)
530 const VarDecl *VD = dyn_cast<VarDecl>(D);
531 if (VD && !isa<DecompositionDecl>(D)) {
537 const DeclContext *DC = getEffectiveDeclContext(D);
541 DC = getEffectiveParentContext(DC);
544 !isa<VarTemplateSpecializationDecl>(D) && D->
getIdentifier() !=
nullptr)
552MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
556void MicrosoftCXXNameMangler::mangle(
GlobalDecl GD, StringRef Prefix) {
568 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
569 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
570 mangleVariableEncoding(VD);
571 else if (isa<MSGuidDecl>(D))
574 Out <<
"3U__s_GUID@@B";
575 else if (isa<TemplateParamObjectDecl>(D)) {
579 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
582void MicrosoftCXXNameMangler::mangleFunctionEncoding(
GlobalDecl GD,
607 mangleFunctionClass(FD);
609 mangleFunctionType(FT, FD,
false,
false);
615void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
646 mangleType(Ty, SR, QMM_Drop);
647 manglePointerExtQualifiers(
650 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
653 mangleName(MPT->getClass()->getAsCXXRecordDecl());
656 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
658 mangleDecayedArrayType(AT);
659 if (AT->getElementType()->isArrayType())
664 mangleType(Ty, SR, QMM_Drop);
669void MicrosoftCXXNameMangler::mangleMemberDataPointer(
const CXXRecordDecl *RD,
680 FieldOffset = getASTContext().getFieldOffset(VD);
681 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
682 "cannot take address of bitfield");
683 FieldOffset /= getASTContext().getCharWidth();
687 if (IM == MSInheritanceModel::Virtual)
688 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
697 case MSInheritanceModel::Single: Code =
'0';
break;
698 case MSInheritanceModel::Multiple: Code =
'0';
break;
699 case MSInheritanceModel::Virtual: Code =
'F';
break;
700 case MSInheritanceModel::Unspecified: Code =
'G';
break;
703 Out << Prefix << Code;
705 mangleNumber(FieldOffset);
713 mangleNumber(VBTableOffset);
716void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
723 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
724 return mangleMemberDataPointer(RD, VD,
"");
732 mangleNestedName(VD);
734 mangleUnqualifiedName(VD);
739MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
const CXXRecordDecl *RD,
751 case MSInheritanceModel::Single: Code =
'1';
break;
752 case MSInheritanceModel::Multiple: Code =
'H';
break;
753 case MSInheritanceModel::Virtual: Code =
'I';
break;
754 case MSInheritanceModel::Unspecified: Code =
'J';
break;
763 Out << Prefix << Code <<
'?';
766 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
769 mangleVirtualMemPtrThunk(MD, ML);
773 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
778 mangleFunctionEncoding(MD,
true);
781 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
782 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
785 if (IM == MSInheritanceModel::Single) {
786 Out << Prefix <<
"0A@";
789 if (IM == MSInheritanceModel::Unspecified)
791 Out << Prefix << Code;
795 mangleNumber(
static_cast<uint32_t
>(NVOffset));
797 mangleNumber(VBPtrOffset);
799 mangleNumber(VBTableOffset);
802void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
811 return mangleMemberFunctionPointer(RD, MD,
"");
820 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
823 mangleVirtualMemPtrThunk(MD, ML);
826 mangleFunctionEncoding(MD,
true);
830void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
833 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
834 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
840 mangleNumber(OffsetInVFTable);
845void MicrosoftCXXNameMangler::mangleName(
GlobalDecl GD) {
849 mangleUnqualifiedName(GD);
851 mangleNestedName(GD);
857void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
858 mangleNumber(llvm::APSInt(llvm::APInt(64, Number),
false));
861void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
866 unsigned Width = std::max(Number.getBitWidth(), 64U);
867 llvm::APInt
Value = Number.extend(Width);
875 if (
Value.isNegative()) {
882void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
885 switch (APFloat::SemanticsToEnum(Number.getSemantics())) {
886 case APFloat::S_IEEEsingle: Out <<
'A';
break;
887 case APFloat::S_IEEEdouble: Out <<
'B';
break;
891 case APFloat::S_IEEEhalf: Out <<
'V';
break;
892 case APFloat::S_BFloat: Out <<
'W';
break;
893 case APFloat::S_x87DoubleExtended: Out <<
'X';
break;
894 case APFloat::S_IEEEquad: Out <<
'Y';
break;
895 case APFloat::S_PPCDoubleDouble: Out <<
'Z';
break;
896 case APFloat::S_Float8E5M2:
897 case APFloat::S_Float8E4M3FN:
898 case APFloat::S_Float8E5M2FNUZ:
899 case APFloat::S_Float8E4M3FNUZ:
900 case APFloat::S_Float8E4M3B11FNUZ:
901 case APFloat::S_FloatTF32:
902 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
905 mangleBits(Number.bitcastToAPInt());
908void MicrosoftCXXNameMangler::mangleBits(llvm::APInt
Value) {
919 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
920 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
921 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
930 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
939 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
940 TemplateArgs = &Spec->getTemplateArgs();
941 return GD.
getWithDecl(Spec->getSpecializedTemplate());
946 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
947 TemplateArgs = &Spec->getTemplateArgs();
948 return GD.
getWithDecl(Spec->getSpecializedTemplate());
954void MicrosoftCXXNameMangler::mangleUnqualifiedName(
GlobalDecl GD,
968 if (isa<FunctionTemplateDecl>(TD.getDecl())) {
969 mangleTemplateInstantiationName(TD, *TemplateArgs);
992 ArgBackRefMap::iterator Found = TemplateArgBackReferences.find(ND);
993 if (Found == TemplateArgBackReferences.end()) {
995 TemplateArgStringMap::iterator Found = TemplateArgStrings.find(ND);
996 if (Found == TemplateArgStrings.end()) {
999 llvm::raw_svector_ostream Stream(TemplateMangling);
1000 MicrosoftCXXNameMangler Extra(Context, Stream);
1001 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1004 mangleSourceName(TemplateMangling);
1008 BackRefVec::iterator StringFound =
1009 llvm::find(NameBackReferences, TemplateMangling);
1010 if (StringFound != NameBackReferences.end()) {
1011 TemplateArgBackReferences[ND] =
1012 StringFound - NameBackReferences.begin();
1014 TemplateArgStrings[ND] =
1015 TemplateArgStringStorage.save(TemplateMangling.str());
1018 Out << Found->second <<
'@';
1021 Out << Found->second;
1026 switch (Name.getNameKind()) {
1031 ((isa<FunctionDecl>(ND) && ND->
hasAttr<CUDAGlobalAttr>()) ||
1032 (isa<FunctionTemplateDecl>(ND) &&
1033 cast<FunctionTemplateDecl>(ND)
1034 ->getTemplatedDecl()
1035 ->hasAttr<CUDAGlobalAttr>())) &&
1039 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1041 mangleSourceName(II->getName());
1046 assert(ND &&
"mangling empty name without declaration");
1048 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1049 if (NS->isAnonymousNamespace()) {
1050 Out <<
"?A0x" << Context.getAnonymousNamespaceHash() <<
'@';
1060 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1061 mangleSourceName(Name);
1065 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1068 assert(RD &&
"expected variable decl to have a record type");
1074 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1075 mangleSourceName(Name.str());
1079 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1082 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1083 llvm::raw_svector_ostream GUIDOS(GUID);
1084 Context.mangleMSGuidDecl(GD, GUIDOS);
1085 mangleSourceName(GUID);
1089 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1091 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1092 TPO->getValue(), TplArgKind::ClassNTTP);
1097 const TagDecl *TD = cast<TagDecl>(ND);
1100 "Typedef should not be in another decl context!");
1102 "Typedef was not named!");
1108 if (
Record->isLambda()) {
1111 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1112 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1115 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1120 unsigned DefaultArgNo =
1122 Name += llvm::utostr(DefaultArgNo);
1126 if (LambdaManglingNumber)
1127 LambdaId = LambdaManglingNumber;
1129 LambdaId = Context.getLambdaId(
Record);
1131 Name += llvm::utostr(LambdaId);
1134 mangleSourceName(Name);
1138 if (LambdaManglingNumber && LambdaContextDecl) {
1139 if ((isa<VarDecl>(LambdaContextDecl) ||
1140 isa<FieldDecl>(LambdaContextDecl)) &&
1141 !isa<ParmVarDecl>(LambdaContextDecl)) {
1142 mangleUnqualifiedName(cast<NamedDecl>(LambdaContextDecl));
1154 Name +=
"<unnamed-type-";
1155 Name += DD->getName();
1161 Name +=
"<unnamed-type-";
1162 Name += TND->getName();
1163 }
else if (isa<EnumDecl>(TD) &&
1164 cast<EnumDecl>(TD)->enumerator_begin() !=
1165 cast<EnumDecl>(TD)->enumerator_end()) {
1167 auto *ED = cast<EnumDecl>(TD);
1168 Name +=
"<unnamed-enum-";
1169 Name += ED->enumerator_begin()->getName();
1172 Name +=
"<unnamed-type-$S";
1173 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1176 mangleSourceName(Name.str());
1187 mangleSourceName(Name.str());
1192 if (isStructorDecl(ND)) {
1206 if (isStructorDecl(ND))
1209 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1223 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1228 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1233 llvm_unreachable(
"Can't mangle a deduction guide name!");
1236 llvm_unreachable(
"Can't mangle a using directive name!");
1242void MicrosoftCXXNameMangler::mangleNestedName(
GlobalDecl GD) {
1245 if (
const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1246 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1247 mangleSourceName(
"<unnamed-tag>");
1249 const DeclContext *DC = getEffectiveDeclContext(ND);
1251 if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
1253 if (Context.getNextDiscriminator(ND, Disc)) {
1260 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1262 [](StringRef Name,
const unsigned Discriminator,
1263 const unsigned ParameterDiscriminator) -> std::string {
1265 llvm::raw_string_ostream Stream(Buffer);
1268 Stream <<
'_' << Discriminator;
1269 if (ParameterDiscriminator)
1270 Stream <<
'_' << ParameterDiscriminator;
1271 return Stream.str();
1274 unsigned Discriminator = BD->getBlockManglingNumber();
1276 Discriminator = Context.getBlockId(BD,
false);
1281 unsigned ParameterDiscriminator = 0;
1282 if (
const auto *MC = BD->getBlockManglingContextDecl())
1283 if (
const auto *
P = dyn_cast<ParmVarDecl>(MC))
1284 if (
const auto *F = dyn_cast<FunctionDecl>(
P->getDeclContext()))
1285 ParameterDiscriminator =
1286 F->getNumParams() -
P->getFunctionScopeIndex();
1288 DC = getEffectiveDeclContext(BD);
1291 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1292 ParameterDiscriminator));
1297 if (
const auto *MC = BD->getBlockManglingContextDecl())
1298 if (!isa<ParmVarDecl>(MC))
1299 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1300 mangleUnqualifiedName(ND);
1304 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1313 if (PointersAre64Bit)
1316 mangleArtificialTagType(TagTypeKind::Struct,
1317 Discriminate(
"__block_literal", Discriminator,
1318 ParameterDiscriminator));
1323 if (isa<RecordDecl>(DC))
1326 }
else if (
const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
1327 mangleObjCMethodName(Method);
1328 }
else if (isa<NamedDecl>(DC)) {
1329 ND = cast<NamedDecl>(DC);
1330 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1331 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1334 mangleUnqualifiedName(ND);
1337 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1347void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1362 llvm_unreachable(
"not expecting a COMDAT");
1364 llvm_unreachable(
"Unsupported dtor type?");
1373 case OO_New: Out <<
"?2";
break;
1375 case OO_Delete: Out <<
"?3";
break;
1377 case OO_Equal: Out <<
"?4";
break;
1379 case OO_GreaterGreater: Out <<
"?5";
break;
1381 case OO_LessLess: Out <<
"?6";
break;
1383 case OO_Exclaim: Out <<
"?7";
break;
1385 case OO_EqualEqual: Out <<
"?8";
break;
1387 case OO_ExclaimEqual: Out <<
"?9";
break;
1389 case OO_Subscript: Out <<
"?A";
break;
1392 case OO_Arrow: Out <<
"?C";
break;
1394 case OO_Star: Out <<
"?D";
break;
1396 case OO_PlusPlus: Out <<
"?E";
break;
1398 case OO_MinusMinus: Out <<
"?F";
break;
1400 case OO_Minus: Out <<
"?G";
break;
1402 case OO_Plus: Out <<
"?H";
break;
1404 case OO_Amp: Out <<
"?I";
break;
1406 case OO_ArrowStar: Out <<
"?J";
break;
1408 case OO_Slash: Out <<
"?K";
break;
1410 case OO_Percent: Out <<
"?L";
break;
1412 case OO_Less: Out <<
"?M";
break;
1414 case OO_LessEqual: Out <<
"?N";
break;
1416 case OO_Greater: Out <<
"?O";
break;
1418 case OO_GreaterEqual: Out <<
"?P";
break;
1420 case OO_Comma: Out <<
"?Q";
break;
1422 case OO_Call: Out <<
"?R";
break;
1424 case OO_Tilde: Out <<
"?S";
break;
1426 case OO_Caret: Out <<
"?T";
break;
1428 case OO_Pipe: Out <<
"?U";
break;
1430 case OO_AmpAmp: Out <<
"?V";
break;
1432 case OO_PipePipe: Out <<
"?W";
break;
1434 case OO_StarEqual: Out <<
"?X";
break;
1436 case OO_PlusEqual: Out <<
"?Y";
break;
1438 case OO_MinusEqual: Out <<
"?Z";
break;
1440 case OO_SlashEqual: Out <<
"?_0";
break;
1442 case OO_PercentEqual: Out <<
"?_1";
break;
1444 case OO_GreaterGreaterEqual: Out <<
"?_2";
break;
1446 case OO_LessLessEqual: Out <<
"?_3";
break;
1448 case OO_AmpEqual: Out <<
"?_4";
break;
1450 case OO_PipeEqual: Out <<
"?_5";
break;
1452 case OO_CaretEqual: Out <<
"?_6";
break;
1481 case OO_Array_New: Out <<
"?_U";
break;
1483 case OO_Array_Delete: Out <<
"?_V";
break;
1485 case OO_Coawait: Out <<
"?__L";
break;
1487 case OO_Spaceship: Out <<
"?__M";
break;
1489 case OO_Conditional: {
1492 "cannot mangle this conditional operator yet");
1493 Diags.
Report(Loc, DiagID);
1499 llvm_unreachable(
"Not an overloaded operator");
1503void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1505 BackRefVec::iterator Found = llvm::find(NameBackReferences, Name);
1506 if (Found == NameBackReferences.end()) {
1507 if (NameBackReferences.size() < 10)
1508 NameBackReferences.push_back(std::string(Name));
1511 Out << (Found - NameBackReferences.begin());
1515void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1516 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1519void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1526 ArgBackRefMap OuterFunArgsContext;
1527 ArgBackRefMap OuterTemplateArgsContext;
1528 BackRefVec OuterTemplateContext;
1529 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1530 NameBackReferences.swap(OuterTemplateContext);
1531 FunArgBackReferences.swap(OuterFunArgsContext);
1532 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1533 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1535 mangleUnscopedTemplateName(GD);
1536 mangleTemplateArgs(cast<TemplateDecl>(GD.
getDecl()), TemplateArgs);
1539 NameBackReferences.swap(OuterTemplateContext);
1540 FunArgBackReferences.swap(OuterFunArgsContext);
1541 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1542 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1545void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(
GlobalDecl GD) {
1548 mangleUnqualifiedName(GD);
1551void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1559 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1560 LangOptions::MSVC2019) &&
1562 !TemplateArgType.
isNull()) {
1564 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
1569 mangleNumber(
Value);
1572void MicrosoftCXXNameMangler::mangleExpression(
1575 if (std::optional<llvm::APSInt>
Value =
1589void MicrosoftCXXNameMangler::mangleTemplateArgs(
1593 assert(TPL->
size() == TemplateArgs.
size() &&
1594 "size mismatch between args and parms!");
1596 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1604 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1616 QualType BaseT =
V.getLValueBase().getType();
1617 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1618 V.getLValuePath()[0].getAsArrayIndex() != 0)
1621 V.getLValueBase().dyn_cast<
const ValueDecl *>());
1624void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1661 llvm_unreachable(
"Can't mangle null template arguments!");
1663 llvm_unreachable(
"Can't mangle template expansion arguments!");
1671 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1672 mangleMemberDataPointer(cast<CXXRecordDecl>(ND->
getDeclContext())
1673 ->getMostRecentNonInjectedDecl(),
1674 cast<ValueDecl>(ND));
1675 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1678 mangleMemberFunctionPointer(
1683 mangleFunctionEncoding(FD,
true);
1687 auto *TPO = cast<TemplateParamObjectDecl>(ND);
1688 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1689 TPO->getValue(), TplArgKind::ClassNTTP);
1698 cast<NonTypeTemplateParmDecl>(Parm),
T);
1704 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1705 if (MPT->isMemberFunctionPointerType() &&
1706 !isa<FunctionTemplateDecl>(TD)) {
1707 mangleMemberFunctionPointer(RD,
nullptr);
1710 if (MPT->isMemberDataPointer()) {
1711 if (!isa<FunctionTemplateDecl>(TD)) {
1712 mangleMemberDataPointer(RD,
nullptr);
1722 mangleIntegerLiteral(llvm::APSInt::get(-1),
1723 cast<NonTypeTemplateParmDecl>(Parm),
T);
1728 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1729 cast<NonTypeTemplateParmDecl>(Parm),
T);
1738 return mangleTemplateArg(
1742 if (cast<NonTypeTemplateParmDecl>(Parm)
1744 ->getContainedDeducedType()) {
1750 TplArgKind::StructuralValue,
1754 mangleExpression(TA.
getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
1758 if (TemplateArgs.empty()) {
1759 if (isa<TemplateTypeParmDecl>(Parm) ||
1760 isa<TemplateTemplateParmDecl>(Parm))
1764 LangOptions::MSVC2015)
1767 else if (isa<NonTypeTemplateParmDecl>(Parm))
1770 llvm_unreachable(
"unexpected template parameter decl!");
1773 mangleTemplateArg(TD, PA, Parm);
1780 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1782 }
else if (isa<TypeAliasDecl>(ND)) {
1786 llvm_unreachable(
"unexpected template template NamedDecl!");
1793void MicrosoftCXXNameMangler::mangleTemplateArgValue(
QualType T,
1796 bool WithScalarType) {
1797 switch (
V.getKind()) {
1811 mangleNumber(
V.getInt());
1817 mangleFloat(
V.getFloat());
1825 if (
V.isLValueOnePastTheEnd())
1829 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1831 if (
Base.isNull()) {
1837 mangleNumber(
V.getLValueOffset().getQuantity());
1838 }
else if (!
V.hasLValuePath()) {
1852 SmallVector<std::function<void()>, 2> EntryManglers;
1856 EntryTypes.push_back(
'C');
1857 EntryManglers.push_back([
this, I = E.getAsArrayIndex()] {
1862 ET = AT->getElementType();
1866 const Decl *D = E.getAsBaseOrMember().getPointer();
1867 if (
auto *FD = dyn_cast<FieldDecl>(D)) {
1873 ET = getASTContext().getRecordType(cast<CXXRecordDecl>(D));
1879 EntryTypes.push_back(
'6');
1880 EntryManglers.push_back([
this, D] {
1881 mangleUnqualifiedName(cast<NamedDecl>(D));
1886 for (
auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
1892 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
1895 for (
const std::function<
void()> &Mangler : EntryManglers)
1910 const ValueDecl *D =
V.getMemberPointerDecl();
1911 if (TAK == TplArgKind::ClassNTTP) {
1913 mangleMemberDataPointerInClassNTTP(RD, D);
1915 mangleMemberFunctionPointerInClassNTTP(RD,
1916 cast_or_null<CXXMethodDecl>(D));
1919 mangleMemberDataPointer(RD, D,
"");
1921 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D),
"");
1930 assert(RD &&
"unexpected type for record value");
1932 unsigned BaseIndex = 0;
1934 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
1936 if (!FD->isUnnamedBitField())
1937 mangleTemplateArgValue(FD->
getType(),
1938 V.getStructField(FD->getFieldIndex()), TAK,
1947 if (
const FieldDecl *FD =
V.getUnionField()) {
1948 mangleUnqualifiedName(FD);
1949 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
1959 mangleNumber(
V.getComplexIntReal());
1961 mangleNumber(
V.getComplexIntImag());
1968 mangleFloat(
V.getComplexFloatReal());
1969 mangleFloat(
V.getComplexFloatImag());
1975 QualType ElemT = getASTContext().getAsArrayType(
T)->getElementType();
1977 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
1978 const APValue &ElemV = I <
V.getArrayInitializedElts()
1979 ?
V.getArrayInitializedElt(I)
1980 :
V.getArrayFiller();
1981 mangleTemplateArgValue(ElemT, ElemV, TAK);
1996 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
1997 const APValue &ElemV =
V.getVectorElt(I);
1998 mangleTemplateArgValue(ElemT, ElemV, TAK);
2016void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2018 llvm::raw_svector_ostream Stream(TemplateMangling);
2019 MicrosoftCXXNameMangler Extra(Context, Stream);
2022 Extra.mangleSourceName(
"Protocol");
2023 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2025 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2028void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType Type,
2032 llvm::raw_svector_ostream Stream(TemplateMangling);
2033 MicrosoftCXXNameMangler Extra(Context, Stream);
2041 Extra.mangleSourceName(
"Autoreleasing");
2044 Extra.mangleSourceName(
"Strong");
2047 Extra.mangleSourceName(
"Weak");
2050 Extra.manglePointerCVQualifiers(Quals);
2051 Extra.manglePointerExtQualifiers(Quals,
Type);
2052 Extra.mangleType(
Type, Range);
2054 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2057void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *
T,
2061 llvm::raw_svector_ostream Stream(TemplateMangling);
2062 MicrosoftCXXNameMangler Extra(Context, Stream);
2065 Extra.mangleSourceName(
"KindOf");
2067 .stripObjCKindOfType(getASTContext())
2068 ->castAs<ObjCObjectType>(),
2071 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2074void MicrosoftCXXNameMangler::mangleQualifiers(
Qualifiers Quals,
2132 if (HasConst && HasVolatile) {
2134 }
else if (HasVolatile) {
2136 }
else if (HasConst) {
2142 if (HasConst && HasVolatile) {
2144 }
else if (HasVolatile) {
2146 }
else if (HasConst) {
2157MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2160 switch (RefQualifier) {
2174void MicrosoftCXXNameMangler::manglePointerExtQualifiers(
Qualifiers Quals,
2177 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2190void MicrosoftCXXNameMangler::manglePointerCVQualifiers(
Qualifiers Quals) {
2198 if (HasConst && HasVolatile) {
2200 }
else if (HasVolatile) {
2202 }
else if (HasConst) {
2209void MicrosoftCXXNameMangler::mangleFunctionArgumentType(
QualType T,
2220 QualType OriginalType = DT->getOriginalType();
2223 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2224 OriginalType = getASTContext().getIncompleteArrayType(
2225 AT->getElementType(), AT->getSizeModifier(),
2226 AT->getIndexTypeCVRQualifiers());
2237 TypePtr =
T.getCanonicalType().getAsOpaquePtr();
2240 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);
2242 if (Found == FunArgBackReferences.end()) {
2243 size_t OutSizeBefore = Out.tell();
2245 mangleType(
T, Range, QMM_Drop);
2250 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);
2251 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2252 size_t Size = FunArgBackReferences.size();
2253 FunArgBackReferences[TypePtr] =
Size;
2256 Out << Found->second;
2260void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2261 const PassObjectSizeAttr *POSA) {
2262 int Type = POSA->getType();
2263 bool Dynamic = POSA->isDynamic();
2266 auto *TypePtr = (
const void *)&*
Iter;
2267 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);
2269 if (Found == FunArgBackReferences.end()) {
2271 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2272 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2275 if (FunArgBackReferences.size() < 10) {
2276 size_t Size = FunArgBackReferences.size();
2277 FunArgBackReferences[TypePtr] =
Size;
2280 Out << Found->second;
2284void MicrosoftCXXNameMangler::mangleAddressSpaceType(
QualType T,
2302 llvm::raw_svector_ostream Stream(ASMangling);
2303 MicrosoftCXXNameMangler Extra(Context, Stream);
2309 Extra.mangleSourceName(
"_AS");
2310 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2314 llvm_unreachable(
"Not a language specific address space");
2315 case LangAS::opencl_global:
2316 Extra.mangleSourceName(
"_ASCLglobal");
2318 case LangAS::opencl_global_device:
2319 Extra.mangleSourceName(
"_ASCLdevice");
2321 case LangAS::opencl_global_host:
2322 Extra.mangleSourceName(
"_ASCLhost");
2324 case LangAS::opencl_local:
2325 Extra.mangleSourceName(
"_ASCLlocal");
2327 case LangAS::opencl_constant:
2328 Extra.mangleSourceName(
"_ASCLconstant");
2330 case LangAS::opencl_private:
2331 Extra.mangleSourceName(
"_ASCLprivate");
2333 case LangAS::opencl_generic:
2334 Extra.mangleSourceName(
"_ASCLgeneric");
2336 case LangAS::cuda_device:
2337 Extra.mangleSourceName(
"_ASCUdevice");
2339 case LangAS::cuda_constant:
2340 Extra.mangleSourceName(
"_ASCUconstant");
2342 case LangAS::cuda_shared:
2343 Extra.mangleSourceName(
"_ASCUshared");
2345 case LangAS::ptr32_sptr:
2346 case LangAS::ptr32_uptr:
2348 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2352 Extra.mangleType(
T, Range, QMM_Escape);
2354 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2358 QualifierMangleMode QMM) {
2361 T =
T.getDesugaredType(getASTContext());
2364 if (
const ArrayType *AT = getASTContext().getAsArrayType(
T)) {
2367 if (QMM == QMM_Mangle)
2369 else if (QMM == QMM_Escape || QMM == QMM_Result)
2371 mangleArrayType(AT);
2386 mangleFunctionType(FT);
2389 mangleQualifiers(Quals,
false);
2392 if (!IsPointer && Quals) {
2394 mangleQualifiers(Quals,
false);
2402 if ((!IsPointer && Quals) || isa<TagType>(
T) || isArtificialTagType(
T)) {
2404 mangleQualifiers(Quals,
false);
2409 const Type *ty =
T.getTypePtr();
2412#define ABSTRACT_TYPE(CLASS, PARENT)
2413#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2415 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2417#define TYPE(CLASS, PARENT) \
2419 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2421#include "clang/AST/TypeNodes.inc"
2423#undef NON_CANONICAL_TYPE
2457 switch (
T->getKind()) {
2458 case BuiltinType::Void:
2461 case BuiltinType::SChar:
2464 case BuiltinType::Char_U:
2465 case BuiltinType::Char_S:
2468 case BuiltinType::UChar:
2471 case BuiltinType::Short:
2474 case BuiltinType::UShort:
2477 case BuiltinType::Int:
2480 case BuiltinType::UInt:
2483 case BuiltinType::Long:
2486 case BuiltinType::ULong:
2489 case BuiltinType::Float:
2492 case BuiltinType::Double:
2496 case BuiltinType::LongDouble:
2499 case BuiltinType::LongLong:
2502 case BuiltinType::ULongLong:
2505 case BuiltinType::Int128:
2508 case BuiltinType::UInt128:
2511 case BuiltinType::Bool:
2514 case BuiltinType::Char8:
2517 case BuiltinType::Char16:
2520 case BuiltinType::Char32:
2523 case BuiltinType::WChar_S:
2524 case BuiltinType::WChar_U:
2528#define BUILTIN_TYPE(Id, SingletonId)
2529#define PLACEHOLDER_TYPE(Id, SingletonId) \
2530 case BuiltinType::Id:
2531#include "clang/AST/BuiltinTypes.def"
2532 case BuiltinType::Dependent:
2533 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2535 case BuiltinType::ObjCId:
2536 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2538 case BuiltinType::ObjCClass:
2539 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2541 case BuiltinType::ObjCSel:
2542 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2545#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2546 case BuiltinType::Id: \
2547 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2549#include "clang/Basic/OpenCLImageTypes.def"
2550 case BuiltinType::OCLSampler:
2552 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2554 case BuiltinType::OCLEvent:
2556 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2558 case BuiltinType::OCLClkEvent:
2560 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2562 case BuiltinType::OCLQueue:
2564 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2566 case BuiltinType::OCLReserveID:
2568 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2570#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2571 case BuiltinType::Id: \
2572 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2574#include "clang/Basic/OpenCLExtensionTypes.def"
2576 case BuiltinType::NullPtr:
2580 case BuiltinType::Float16:
2581 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2584 case BuiltinType::Half:
2585 if (!getASTContext().getLangOpts().
HLSL)
2586 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2587 else if (getASTContext().getLangOpts().NativeHalfType)
2593 case BuiltinType::BFloat16:
2594 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2597#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2598 case BuiltinType::Id: \
2599 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2600 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2603#include "clang/Basic/WebAssemblyReferenceTypes.def"
2604#define SVE_TYPE(Name, Id, SingletonId) \
2605 case BuiltinType::Id:
2606#include "clang/Basic/AArch64SVEACLETypes.def"
2607#define PPC_VECTOR_TYPE(Name, Id, Size) \
2608 case BuiltinType::Id:
2609#include "clang/Basic/PPCTypes.def"
2610#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2611#include "clang/Basic/RISCVVTypes.def"
2612 case BuiltinType::ShortAccum:
2613 case BuiltinType::Accum:
2614 case BuiltinType::LongAccum:
2615 case BuiltinType::UShortAccum:
2616 case BuiltinType::UAccum:
2617 case BuiltinType::ULongAccum:
2618 case BuiltinType::ShortFract:
2619 case BuiltinType::Fract:
2620 case BuiltinType::LongFract:
2621 case BuiltinType::UShortFract:
2622 case BuiltinType::UFract:
2623 case BuiltinType::ULongFract:
2624 case BuiltinType::SatShortAccum:
2625 case BuiltinType::SatAccum:
2626 case BuiltinType::SatLongAccum:
2627 case BuiltinType::SatUShortAccum:
2628 case BuiltinType::SatUAccum:
2629 case BuiltinType::SatULongAccum:
2630 case BuiltinType::SatShortFract:
2631 case BuiltinType::SatFract:
2632 case BuiltinType::SatLongFract:
2633 case BuiltinType::SatUShortFract:
2634 case BuiltinType::SatUFract:
2635 case BuiltinType::SatULongFract:
2636 case BuiltinType::Ibm128:
2637 case BuiltinType::Float128: {
2656 mangleFunctionType(
T,
nullptr,
true);
2659 mangleFunctionType(
T);
2665 mangleFunctionType(
T);
2668void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *
T,
2670 bool ForceThisQuals,
2671 bool MangleExceptionSpec) {
2679 bool IsInLambda =
false;
2680 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
2682 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
2686 HasThisQuals =
true;
2687 if (isa<CXXDestructorDecl>(MD)) {
2689 }
else if (isa<CXXConstructorDecl>(MD)) {
2695 CC = getASTContext().getDefaultCallingConvention(
2704 manglePointerExtQualifiers(Quals,
QualType());
2706 mangleQualifiers(Quals,
false);
2709 mangleCallingConvention(CC);
2714 if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
2718 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
2727 if (IsCtorClosure) {
2737 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
2745 llvm_unreachable(
"unexpected constructor closure!");
2751 }
else if (IsInLambda && D && isa<CXXConversionDecl>(D)) {
2758 if (IsInLambda && isa<CXXConversionDecl>(D)) {
2762 mangleType(ResultType, Range, QMM_Result);
2763 }
else if (
const auto *AT = dyn_cast_or_null<AutoType>(
2768 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2769 "shouldn't need to mangle __auto_type!");
2770 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
2772 }
else if (IsInLambda) {
2777 mangleType(ResultType, Range, QMM_Result);
2793 for (
unsigned I = 0, E = Proto->
getNumParams(); I != E; ++I) {
2798 mangleFunctionArgumentType(Proto->
getParamType(I), Range);
2809 manglePassObjectSizeArg(
P);
2818 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
2819 getASTContext().getLangOpts().isCompatibleWithMSVC(
2820 LangOptions::MSVC2017_5))
2821 mangleThrowSpecification(Proto);
2826void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
2851 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
2855 if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
2861 llvm_unreachable(
"Unsupported access specifier");
2890void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC) {
2915 llvm_unreachable(
"Unsupported CC for mangling");
2918 case CC_C: Out <<
'A';
break;
2928 if (getASTContext().getLangOpts().RegCall4)
2935void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *
T) {
2939void MicrosoftCXXNameMangler::mangleThrowSpecification(
2955 "cannot mangle this unresolved dependent type yet");
2965void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
2967 case TagTypeKind::Union:
2970 case TagTypeKind::Struct:
2971 case TagTypeKind::Interface:
2974 case TagTypeKind::Class:
2977 case TagTypeKind::Enum:
2984 mangleType(cast<TagType>(
T)->getDecl());
2988 mangleType(cast<TagType>(
T)->getDecl());
2990void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
2996void MicrosoftCXXNameMangler::mangleArtificialTagType(
3000 mangleTagTypeKind(TK);
3003 mangleSourceName(UnqualifiedName);
3005 for (StringRef N : llvm::reverse(NestedNames))
3006 mangleSourceName(N);
3019void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *
T) {
3022 manglePointerCVQualifiers(
T->getElementType().getQualifiers());
3027 llvm_unreachable(
"Should have been special cased");
3031 llvm_unreachable(
"Should have been special cased");
3035 llvm_unreachable(
"Should have been special cased");
3039 llvm_unreachable(
"Should have been special cased");
3041void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *
T) {
3045 if (ElementTy->isConstantArrayType()) {
3047 getASTContext().getAsConstantArrayType(ElementTy);
3048 Dimensions.push_back(CAT->
getSize());
3050 }
else if (ElementTy->isIncompleteArrayType()) {
3052 getASTContext().getAsIncompleteArrayType(ElementTy);
3053 Dimensions.push_back(llvm::APInt(32, 0));
3055 }
else if (ElementTy->isVariableArrayType()) {
3057 getASTContext().getAsVariableArrayType(ElementTy);
3058 Dimensions.push_back(llvm::APInt(32, 0));
3060 }
else if (ElementTy->isDependentSizedArrayType()) {
3063 getASTContext().getAsDependentSizedArrayType(ElementTy);
3066 "cannot mangle this dependent-length array yet");
3076 mangleNumber(Dimensions.size());
3077 for (
const llvm::APInt &Dimension : Dimensions)
3078 mangleNumber(Dimension.getLimitedValue());
3084 mangleArrayType(cast<ConstantArrayType>(
T));
3093 manglePointerCVQualifiers(Quals);
3094 manglePointerExtQualifiers(Quals, PointeeType);
3098 mangleFunctionType(FPT,
nullptr,
true);
3102 mangleType(PointeeType, Range, QMM_Drop);
3110 "cannot mangle this template type parameter type yet");
3119 "cannot mangle this substituted parameter pack yet");
3130 manglePointerCVQualifiers(Quals);
3131 manglePointerExtQualifiers(Quals, PointeeType);
3137 mangleType(PointeeType, Range);
3139 mangleAddressSpaceType(PointeeType, PointeeType.
getQualifiers(), Range);
3152 return mangleObjCLifetime(PointeeType, Quals, Range);
3154 manglePointerCVQualifiers(Quals);
3155 manglePointerExtQualifiers(Quals, PointeeType);
3156 mangleType(PointeeType, Range);
3167 manglePointerExtQualifiers(Quals, PointeeType);
3168 mangleType(PointeeType, Range);
3179 manglePointerExtQualifiers(Quals, PointeeType);
3180 mangleType(PointeeType, Range);
3185 QualType ElementType =
T->getElementType();
3188 llvm::raw_svector_ostream Stream(TemplateMangling);
3189 MicrosoftCXXNameMangler Extra(Context, Stream);
3191 Extra.mangleSourceName(
"_Complex");
3192 Extra.mangleType(ElementType, Range, QMM_Escape);
3194 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3202bool MicrosoftCXXNameMangler::isArtificialTagType(
QualType T)
const {
3203 const Type *ty =
T.getTypePtr();
3208 case Type::Vector: {
3222 assert((ET || BitIntTy) &&
3223 "vectors with non-builtin/_BitInt elements are unsupported");
3224 uint64_t Width = getASTContext().getTypeSize(
T);
3227 size_t OutSizeBefore = Out.tell();
3228 if (!isa<ExtVectorType>(
T)) {
3229 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
3230 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3231 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3232 }
else if (Width >= 128) {
3233 if (ET->
getKind() == BuiltinType::Float)
3234 mangleArtificialTagType(TagTypeKind::Union,
3235 "__m" + llvm::utostr(Width));
3236 else if (ET->
getKind() == BuiltinType::LongLong)
3237 mangleArtificialTagType(TagTypeKind::Union,
3238 "__m" + llvm::utostr(Width) +
'i');
3239 else if (ET->
getKind() == BuiltinType::Double)
3240 mangleArtificialTagType(TagTypeKind::Struct,
3241 "__m" + llvm::utostr(Width) +
'd');
3246 bool IsBuiltin = Out.tell() != OutSizeBefore;
3253 llvm::raw_svector_ostream Stream(TemplateMangling);
3254 MicrosoftCXXNameMangler Extra(Context, Stream);
3256 Extra.mangleSourceName(
"__vector");
3257 Extra.mangleType(
QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3259 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumElements()));
3261 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3267 mangleType(
static_cast<const VectorType *
>(
T), Quals, Range);
3275 "cannot mangle this dependent-sized vector type yet");
3283 "cannot mangle this dependent-sized extended vector type yet");
3292 "Cannot mangle this matrix type yet");
3301 "Cannot mangle this dependent-sized matrix type yet");
3310 "cannot mangle this dependent address space type yet");
3317 mangleTagTypeKind(TagTypeKind::Struct);
3318 mangleName(
T->getDecl());
3323 if (
T->isKindOfType())
3324 return mangleObjCKindOfType(
T, Quals, Range);
3326 if (
T->qual_empty() && !
T->isSpecialized())
3327 return mangleType(
T->getBaseType(), Range, QMM_Drop);
3329 ArgBackRefMap OuterFunArgsContext;
3330 ArgBackRefMap OuterTemplateArgsContext;
3331 BackRefVec OuterTemplateContext;
3333 FunArgBackReferences.swap(OuterFunArgsContext);
3334 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3335 NameBackReferences.swap(OuterTemplateContext);
3337 mangleTagTypeKind(TagTypeKind::Struct);
3341 mangleSourceName(
"objc_object");
3342 else if (
T->isObjCClass())
3343 mangleSourceName(
"objc_class");
3345 mangleSourceName(
T->getInterface()->getName());
3347 for (
const auto &Q :
T->quals())
3348 mangleObjCProtocol(Q);
3350 if (
T->isSpecialized())
3351 for (
const auto &TA :
T->getTypeArgs())
3352 mangleType(TA, Range, QMM_Drop);
3358 FunArgBackReferences.swap(OuterFunArgsContext);
3359 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3360 NameBackReferences.swap(OuterTemplateContext);
3366 manglePointerCVQualifiers(Quals);
3367 manglePointerExtQualifiers(Quals, PointeeType);
3376 llvm_unreachable(
"Cannot mangle injected class name type.");
3383 "cannot mangle this template specialization type yet");
3392 "cannot mangle this dependent name type yet");
3397void MicrosoftCXXNameMangler::mangleType(
3402 "cannot mangle this dependent template specialization type yet");
3411 "cannot mangle this pack expansion yet");
3418 manglePointerCVQualifiers(Quals);
3419 mangleType(
T->getSelectedType(), Range);
3426 "cannot mangle this typeof(type) yet");
3435 "cannot mangle this typeof(expression) yet");
3444 "cannot mangle this decltype() yet");
3453 "cannot mangle this unary transform type yet");
3460 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3464 "cannot mangle this 'auto' type yet");
3469void MicrosoftCXXNameMangler::mangleType(
3471 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3475 "cannot mangle this deduced class template specialization type yet");
3485 llvm::raw_svector_ostream Stream(TemplateMangling);
3486 MicrosoftCXXNameMangler Extra(Context, Stream);
3488 Extra.mangleSourceName(
"_Atomic");
3489 Extra.mangleType(ValueType, Range, QMM_Escape);
3491 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3496 QualType ElementType =
T->getElementType();
3499 llvm::raw_svector_ostream Stream(TemplateMangling);
3500 MicrosoftCXXNameMangler Extra(Context, Stream);
3502 Extra.mangleSourceName(
"ocl_pipe");
3503 Extra.mangleType(ElementType, Range, QMM_Escape);
3504 Extra.mangleIntegerLiteral(llvm::APSInt::get(
T->isReadOnly()));
3506 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3509void MicrosoftMangleContextImpl::mangleCXXName(
GlobalDecl GD,
3513 getASTContext().getSourceManager(),
3514 "Mangling declaration");
3516 msvc_hashing_ostream MHO(Out);
3518 if (
auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3520 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3521 return mangler.mangle(GD);
3524 if (
auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3526 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3527 return mangler.mangle(GD);
3530 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3531 return Mangler.mangle(GD);
3537 llvm::raw_svector_ostream Stream(TemplateMangling);
3538 MicrosoftCXXNameMangler Extra(Context, Stream);
3540 if (
T->isUnsigned())
3541 Extra.mangleSourceName(
"_UBitInt");
3543 Extra.mangleSourceName(
"_BitInt");
3544 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumBits()));
3546 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3583 MicrosoftCXXNameMangler &Mangler,
3590 llvm_unreachable(
"Unsupported access specifier");
3601 Out <<
'R' << AccessSpec;
3602 Mangler.mangleNumber(
3604 Mangler.mangleNumber(
3606 Mangler.mangleNumber(
3608 Mangler.mangleNumber(
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3611 Mangler.mangleNumber(
3613 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3618 llvm_unreachable(
"Unsupported access specifier");
3628 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3632 llvm_unreachable(
"Unsupported access specifier");
3645void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
3648 msvc_hashing_ostream MHO(Out);
3649 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3650 Mangler.getStream() <<
'?';
3651 Mangler.mangleVirtualMemPtrThunk(MD, ML);
3654void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
3657 msvc_hashing_ostream MHO(Out);
3658 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3659 Mangler.getStream() <<
'?';
3660 Mangler.mangleName(MD);
3669 assert(Thunk.
Method !=
nullptr &&
3670 "Thunk info should hold the overridee decl");
3673 Mangler.mangleFunctionType(
3677void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
3684 msvc_hashing_ostream MHO(Out);
3685 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
3686 Mangler.getStream() <<
"??_E";
3692void MicrosoftMangleContextImpl::mangleCXXVFTable(
3699 msvc_hashing_ostream MHO(Out);
3700 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3701 if (Derived->
hasAttr<DLLImportAttr>())
3702 Mangler.getStream() <<
"??_S";
3704 Mangler.getStream() <<
"??_7";
3705 Mangler.mangleName(Derived);
3706 Mangler.getStream() <<
"6B";
3708 Mangler.mangleName(RD);
3709 Mangler.getStream() <<
'@';
3712void MicrosoftMangleContextImpl::mangleCXXVBTable(
3719 msvc_hashing_ostream MHO(Out);
3720 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3721 Mangler.getStream() <<
"??_8";
3722 Mangler.mangleName(Derived);
3723 Mangler.getStream() <<
"7B";
3725 Mangler.mangleName(RD);
3726 Mangler.getStream() <<
'@';
3729void MicrosoftMangleContextImpl::mangleCXXRTTI(
QualType T, raw_ostream &Out) {
3730 msvc_hashing_ostream MHO(Out);
3731 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3732 Mangler.getStream() <<
"??_R0";
3733 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3734 Mangler.getStream() <<
"@8";
3737void MicrosoftMangleContextImpl::mangleCXXRTTIName(
3738 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
3739 MicrosoftCXXNameMangler Mangler(*
this, Out);
3740 Mangler.getStream() <<
'.';
3741 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3744void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
3746 msvc_hashing_ostream MHO(Out);
3747 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3748 Mangler.getStream() <<
"??_K";
3749 Mangler.mangleName(SrcRD);
3750 Mangler.getStream() <<
"$C";
3751 Mangler.mangleName(DstRD);
3754void MicrosoftMangleContextImpl::mangleCXXThrowInfo(
QualType T,
bool IsConst,
3757 uint32_t NumEntries,
3759 msvc_hashing_ostream MHO(Out);
3760 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3761 Mangler.getStream() <<
"_TI";
3763 Mangler.getStream() <<
'C';
3765 Mangler.getStream() <<
'V';
3767 Mangler.getStream() <<
'U';
3768 Mangler.getStream() << NumEntries;
3769 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3772void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
3773 QualType T, uint32_t NumEntries, raw_ostream &Out) {
3774 msvc_hashing_ostream MHO(Out);
3775 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3776 Mangler.getStream() <<
"_CTA";
3777 Mangler.getStream() << NumEntries;
3778 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3781void MicrosoftMangleContextImpl::mangleCXXCatchableType(
3783 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
3785 MicrosoftCXXNameMangler Mangler(*
this, Out);
3786 Mangler.getStream() <<
"_CT";
3790 llvm::raw_svector_ostream Stream(RTTIMangling);
3791 msvc_hashing_ostream MHO(Stream);
3792 mangleCXXRTTI(
T, MHO);
3794 Mangler.getStream() << RTTIMangling;
3802 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
3803 LangOptions::MSVC2015) &&
3804 !getASTContext().getLangOpts().isCompatibleWithMSVC(
3805 LangOptions::MSVC2017_7);
3807 if (!OmitCopyCtor && CD) {
3808 llvm::raw_svector_ostream Stream(CopyCtorMangling);
3809 msvc_hashing_ostream MHO(Stream);
3812 Mangler.getStream() << CopyCtorMangling;
3814 Mangler.getStream() <<
Size;
3815 if (VBPtrOffset == -1) {
3817 Mangler.getStream() << NVOffset;
3820 Mangler.getStream() << NVOffset;
3821 Mangler.getStream() << VBPtrOffset;
3822 Mangler.getStream() << VBIndex;
3826void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
3827 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
3828 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
3829 msvc_hashing_ostream MHO(Out);
3830 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3831 Mangler.getStream() <<
"??_R1";
3832 Mangler.mangleNumber(NVOffset);
3833 Mangler.mangleNumber(VBPtrOffset);
3834 Mangler.mangleNumber(VBTableOffset);
3835 Mangler.mangleNumber(Flags);
3836 Mangler.mangleName(Derived);
3837 Mangler.getStream() <<
"8";
3840void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
3842 msvc_hashing_ostream MHO(Out);
3843 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3844 Mangler.getStream() <<
"??_R2";
3845 Mangler.mangleName(Derived);
3846 Mangler.getStream() <<
"8";
3849void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
3851 msvc_hashing_ostream MHO(Out);
3852 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3853 Mangler.getStream() <<
"??_R3";
3854 Mangler.mangleName(Derived);
3855 Mangler.getStream() <<
"8";
3858void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
3866 llvm::raw_svector_ostream Stream(VFTableMangling);
3867 mangleCXXVFTable(Derived, BasePath, Stream);
3869 if (VFTableMangling.starts_with(
"??@")) {
3870 assert(VFTableMangling.ends_with(
"@"));
3871 Out << VFTableMangling <<
"??_R4@";
3875 assert(VFTableMangling.starts_with(
"??_7") ||
3876 VFTableMangling.starts_with(
"??_S"));
3878 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
3881void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
3882 GlobalDecl EnclosingDecl, raw_ostream &Out) {
3883 msvc_hashing_ostream MHO(Out);
3884 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3889 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
3890 Mangler.mangleName(EnclosingDecl);
3893void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
3894 GlobalDecl EnclosingDecl, raw_ostream &Out) {
3895 msvc_hashing_ostream MHO(Out);
3896 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3901 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
3902 Mangler.mangleName(EnclosingDecl);
3905void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
3906 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
3909 MicrosoftCXXNameMangler Mangler(*
this, Out);
3910 Mangler.getStream() <<
'?';
3911 Mangler.mangleType(
T.getCanonicalType(),
SourceRange());
3914void MicrosoftMangleContextImpl::mangleReferenceTemporary(
3915 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
3916 msvc_hashing_ostream MHO(Out);
3917 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3919 Mangler.getStream() <<
"?";
3920 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
3921 Mangler.mangle(VD,
"");
3924void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
3925 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
3926 msvc_hashing_ostream MHO(Out);
3927 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3929 Mangler.getStream() <<
"?";
3930 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
3931 Mangler.mangleNestedName(VD);
3932 Mangler.getStream() <<
"@4HA";
3935void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
3947 msvc_hashing_ostream MHO(Out);
3948 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3952 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
3954 Mangler.getStream() <<
"?$S1@";
3956 unsigned ScopeDepth = 0;
3957 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
3961 Mangler.mangle(VD,
"");
3963 Mangler.mangleNestedName(VD);
3964 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
3966 Mangler.mangleNumber(ScopeDepth);
3969void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *D,
3972 msvc_hashing_ostream MHO(Out);
3973 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3974 Mangler.getStream() <<
"??__" << CharCode;
3976 Mangler.getStream() <<
'?';
3977 Mangler.mangleName(D);
3978 Mangler.mangleVariableEncoding(D);
3979 Mangler.getStream() <<
"@@";
3981 Mangler.mangleName(D);
3985 Mangler.getStream() <<
"YAXXZ";
3988void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *D,
3991 mangleInitFiniStub(D,
'E', Out);
3995MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *D,
3998 mangleInitFiniStub(D,
'F', Out);
4001void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4022 MicrosoftCXXNameMangler Mangler(*
this, Out);
4023 Mangler.getStream() <<
"??_C@_";
4031 unsigned StringLength =
4032 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4037 Mangler.getStream() <<
'1';
4039 Mangler.getStream() <<
'0';
4043 Mangler.mangleNumber(StringByteLength);
4045 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4047 if (Index / CharByteWidth >= SL->
getLength())
4048 return static_cast<char>(0);
4049 uint32_t CodeUnit = SL->
getCodeUnit(Index / CharByteWidth);
4050 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4051 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4054 auto GetBigEndianByte = [&SL](
unsigned Index) {
4056 if (Index / CharByteWidth >= SL->
getLength())
4057 return static_cast<char>(0);
4058 uint32_t CodeUnit = SL->
getCodeUnit(Index / CharByteWidth);
4059 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4060 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4065 for (
unsigned I = 0, E = StringByteLength; I != E; ++I)
4066 JC.update(GetLittleEndianByte(I));
4070 Mangler.mangleNumber(JC.getCRC());
4076 auto MangleByte = [&Mangler](
char Byte) {
4084 Mangler.getStream() << Byte;
4085 }
else if (
isLetter(Byte & 0x7f)) {
4086 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4088 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4089 ' ',
'\n',
'\t',
'\'',
'-'};
4090 const char *Pos = llvm::find(SpecialChars, Byte);
4091 if (Pos != std::end(SpecialChars)) {
4092 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4094 Mangler.getStream() <<
"?$";
4095 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4096 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4102 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4103 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4104 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4106 MangleByte(GetBigEndianByte(I));
4108 MangleByte(GetLittleEndianByte(I));
4111 Mangler.getStream() <<
'@';
4117 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
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
@ 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.
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.
const ParmVarDecl * getParamDecl(unsigned i) const
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isExternC() const
Determines whether this function is a function with external, C linkage.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Represents a 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.
StringRef getName() const
Return the actual identifier string.
Represents a C array with an unspecified size.
The injected class name of a C++ class template or class template partial specialization.
An lvalue reference type, per C++11 [dcl.ref].
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
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 mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThisAdjustment &ThisAdjustment, 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 mangleSEHFinallyBlock(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &)=0
virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, 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.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
bool isExternallyVisible() const
Represent a C++ namespace.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Interfaces are the core concept in Objective-C for object oriented design.
ObjCMethodDecl - Represents an instance or class method declaration.
Represents a pointer to an Objective C object.
Represents a class type in Objective C.
Represents an Objective-C protocol declaration.
Represents a pack expansion of types.
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
PrettyStackTraceDecl - If a crash occurs, indicate that it happened when doing something to a specifi...
A (possibly-)qualified type.
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.
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.
struct clang::ThisAdjustment::VirtualAdjustment::@189 Microsoft
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...