31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/StringExtras.h"
33#include "llvm/Support/CRC.h"
34#include "llvm/Support/MD5.h"
35#include "llvm/Support/StringSaver.h"
36#include "llvm/Support/xxhash.h"
47 if (
auto *CD = dyn_cast<CXXConstructorDecl>(DC))
49 else if (
auto *DD = dyn_cast<CXXDestructorDecl>(DC))
56struct msvc_hashing_ostream :
public llvm::raw_svector_ostream {
60 msvc_hashing_ostream(raw_ostream &OS)
61 :
llvm::raw_svector_ostream(Buffer), OS(OS) {}
62 ~msvc_hashing_ostream()
override {
63 StringRef MangledName = str();
64 bool StartsWithEscape = MangledName.starts_with(
"\01");
66 MangledName = MangledName.drop_front(1);
67 if (MangledName.size() < 4096) {
73 llvm::MD5::MD5Result Hash;
74 Hasher.update(MangledName);
78 llvm::MD5::stringifyResult(Hash, HexString);
82 OS <<
"??@" << HexString <<
'@';
87getLambdaDefaultArgumentDeclContext(
const Decl *
D) {
88 if (
const auto *RD = dyn_cast<CXXRecordDecl>(
D))
90 if (
const auto *Parm =
91 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
92 return Parm->getDeclContext();
105 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(
D))
109 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(
D)) {
111 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
112 return ContextParam->getDeclContext();
116 if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||
117 isa<OMPDeclareMapperDecl>(DC)) {
118 return getEffectiveDeclContext(cast<Decl>(DC));
125 return getEffectiveDeclContext(cast<Decl>(DC));
129 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
132 const auto *FD = cast<FunctionDecl>(ND);
133 if (
const auto *FTD = FD->getPrimaryTemplate())
134 return FTD->getTemplatedDecl()->getCanonicalDecl();
136 return FD->getCanonicalDecl();
142 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
143 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
144 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
145 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
146 llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
147 llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
158 raw_ostream &Out)
override;
160 bool ElideOverrideInfo, raw_ostream &)
override;
162 const ThunkInfo &Thunk,
bool ElideOverrideInfo,
163 raw_ostream &)
override;
166 raw_ostream &Out)
override;
169 raw_ostream &Out)
override;
174 raw_ostream &Out)
override;
176 bool IsUnaligned, uint32_t NumEntries,
177 raw_ostream &Out)
override;
179 raw_ostream &Out)
override;
182 int32_t VBPtrOffset, uint32_t VBIndex,
183 raw_ostream &Out)
override;
186 bool NormalizeIntegers)
override;
188 uint32_t NVOffset, int32_t VBPtrOffset,
189 uint32_t VBTableOffset, uint32_t Flags,
190 raw_ostream &Out)
override;
192 raw_ostream &Out)
override;
194 raw_ostream &Out)
override;
198 raw_ostream &Out)
override;
200 bool NormalizeIntegers)
override;
202 raw_ostream &)
override;
205 raw_ostream &Out)
override;
208 raw_ostream &Out)
override;
210 raw_ostream &Out)
override;
212 raw_ostream &Out)
override;
214 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
215 const DeclContext *DC = getEffectiveDeclContext(ND);
221 if (
const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
222 if (RD->isLambda()) {
235 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
236 if (!
Tag->hasNameForLinkage() &&
237 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
243 unsigned &discriminator = Uniquifier[ND];
245 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
246 disc = discriminator + 1;
251 assert(Lambda->
isLambda() &&
"RD must be a lambda!");
252 std::string Name(
"<lambda_");
257 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
262 unsigned DefaultArgNo =
264 Name += llvm::utostr(DefaultArgNo);
268 if (LambdaManglingNumber)
269 LambdaId = LambdaManglingNumber;
271 LambdaId = getLambdaIdForDebugInfo(Lambda);
273 Name += llvm::utostr(LambdaId);
279 assert(RD->
isLambda() &&
"RD must be a lambda!");
282 "RD must not have a mangling number!");
283 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator,
bool>
284 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
285 return Result.first->second;
289 assert(RD->
isLambda() &&
"RD must be a lambda!");
292 "RD must not have a mangling number!");
294 return LambdaIds.lookup(RD);
299 StringRef getAnonymousNamespaceHash()
const {
300 return AnonymousNamespaceHash;
304 void mangleInitFiniStub(
const VarDecl *
D,
char CharCode, raw_ostream &Out);
309class MicrosoftCXXNameMangler {
310 MicrosoftMangleContextImpl &Context;
317 unsigned StructorType;
320 BackRefVec NameBackReferences;
322 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
323 ArgBackRefMap FunArgBackReferences;
324 ArgBackRefMap TemplateArgBackReferences;
326 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
327 TemplateArgStringMap TemplateArgStrings;
328 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
329 llvm::StringSaver TemplateArgStringStorage;
331 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
332 PassObjectSizeArgsSet PassObjectSizeArgs;
334 ASTContext &getASTContext()
const {
return Context.getASTContext(); }
336 const bool PointersAre64Bit;
343 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
344 enum class TplArgKind { ClassNTTP, StructuralValue };
346 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_)
347 : Context(
C), Out(Out_), Structor(nullptr), StructorType(-1),
348 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
349 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
352 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
354 : Context(
C), Out(Out_), Structor(getStructor(
D)), StructorType(
Type),
355 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
356 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
359 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
361 : Context(
C), Out(Out_), Structor(getStructor(
D)), StructorType(
Type),
362 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
363 PointersAre64Bit(
C.getASTContext().getTargetInfo().getPointerWidth(
366 raw_ostream &getStream()
const {
return Out; }
368 void mangle(
GlobalDecl GD, StringRef Prefix =
"?");
370 void mangleFunctionEncoding(
GlobalDecl GD,
bool ShouldMangle);
371 void mangleVariableEncoding(
const VarDecl *VD);
375 StringRef Prefix =
"$");
376 void mangleMemberDataPointerInClassNTTP(
const CXXRecordDecl *,
382 StringRef Prefix =
"$");
388 void mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD,
392 void mangleNumber(int64_t Number);
393 void mangleNumber(llvm::APSInt Number);
394 void mangleFloat(llvm::APFloat Number);
395 void mangleBits(llvm::APInt Number);
397 void mangleArtificialTagType(
TagTypeKind TK, StringRef UnqualifiedName,
401 QualifierMangleMode QMM = QMM_Mangle);
404 bool ForceThisQuals =
false,
405 bool MangleExceptionSpec =
true);
406 void mangleSourceName(StringRef Name);
409 void mangleAutoReturnType(
QualType T, QualifierMangleMode QMM);
412 bool isStructorDecl(
const NamedDecl *ND)
const {
413 return ND == Structor || getStructor(ND) == Structor;
418 return AddrSpace == LangAS::ptr64 ||
419 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||
420 AddrSpace == LangAS::ptr32_uptr));
424 mangleUnqualifiedName(GD, cast<NamedDecl>(GD.
getDecl())->getDeclName());
429 void mangleQualifiers(
Qualifiers Quals,
bool IsMember);
431 void manglePointerCVQualifiers(
Qualifiers Quals);
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);
488MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(
ASTContext &Context,
510 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
513 AnonymousNamespaceHash =
"0";
517bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *
D) {
521 if (FD->hasAttr<OverloadableAttr>())
533 if (FD->isMSVCRTEntryPoint())
547 if (!getASTContext().getLangOpts().
CPlusPlus)
550 const VarDecl *VD = dyn_cast<VarDecl>(
D);
551 if (VD && !isa<DecompositionDecl>(
D)) {
561 DC = getEffectiveParentContext(DC);
564 !isa<VarTemplateSpecializationDecl>(
D) &&
D->getIdentifier() !=
nullptr)
572MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
581 "cannot mangle this %0 %1 yet");
582 return Diags.
Report(loc, DiagID) << thing1 << thing2;
589 "cannot mangle this %0 yet");
590 return Diags.
Report(loc, DiagID) << thingy;
597 "cannot mangle this %0 yet");
598 return Diags.
Report(DiagID) << thingy;
601void MicrosoftCXXNameMangler::mangle(
GlobalDecl GD, StringRef Prefix) {
613 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
614 else if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
615 mangleVariableEncoding(VD);
616 else if (isa<MSGuidDecl>(
D))
619 Out <<
"3U__s_GUID@@B";
620 else if (isa<TemplateParamObjectDecl>(
D)) {
624 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
627void MicrosoftCXXNameMangler::mangleFunctionEncoding(
GlobalDecl GD,
652 mangleFunctionClass(FD);
654 mangleFunctionType(FT, FD,
false,
false);
660void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
691 mangleType(Ty, SR, QMM_Drop);
692 manglePointerExtQualifiers(
695 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
698 mangleName(MPT->getClass()->getAsCXXRecordDecl());
701 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
703 mangleDecayedArrayType(AT);
704 if (AT->getElementType()->isArrayType())
709 mangleType(Ty, SR, QMM_Drop);
714void MicrosoftCXXNameMangler::mangleMemberDataPointer(
730 FieldOffset = getASTContext().getFieldOffset(VD);
731 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
732 "cannot take address of bitfield");
733 FieldOffset /= getASTContext().getCharWidth();
737 if (IM == MSInheritanceModel::Virtual)
738 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
747 case MSInheritanceModel::Single: Code =
'0';
break;
748 case MSInheritanceModel::Multiple: Code =
'0';
break;
749 case MSInheritanceModel::Virtual: Code =
'F';
break;
750 case MSInheritanceModel::Unspecified: Code =
'G';
break;
756 getASTContext().getLangOpts().isCompatibleWithMSVC(
757 LangOptions::MSVC2019) &&
759 !TemplateArgType.
isNull()) {
761 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
766 mangleNumber(FieldOffset);
774 mangleNumber(VBTableOffset);
777void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
784 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
785 return mangleMemberDataPointer(RD, VD,
nullptr,
QualType(),
"");
793 mangleNestedName(VD);
795 mangleUnqualifiedName(VD);
799void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
817 case MSInheritanceModel::Single: Code =
'1';
break;
818 case MSInheritanceModel::Multiple: Code =
'H';
break;
819 case MSInheritanceModel::Virtual: Code =
'I';
break;
820 case MSInheritanceModel::Unspecified: Code =
'J';
break;
831 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
832 LangOptions::MSVC2019) &&
834 !TemplateArgType.
isNull()) {
836 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
842 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
845 mangleVirtualMemPtrThunk(MD, ML);
849 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
854 mangleFunctionEncoding(MD,
true);
857 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
858 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
861 if (IM == MSInheritanceModel::Single) {
862 Out << Prefix <<
"0A@";
865 if (IM == MSInheritanceModel::Unspecified)
867 Out << Prefix << Code;
871 mangleNumber(
static_cast<uint32_t>(NVOffset));
873 mangleNumber(VBPtrOffset);
875 mangleNumber(VBTableOffset);
878void MicrosoftCXXNameMangler::mangleFunctionPointer(
887 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
888 LangOptions::MSVC2019) &&
890 !TemplateArgType.
isNull()) {
892 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
897 mangleFunctionEncoding(FD,
true);
900void MicrosoftCXXNameMangler::mangleVarDecl(
const VarDecl *VD,
909 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
910 LangOptions::MSVC2019) &&
912 !TemplateArgType.
isNull()) {
914 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
919 mangleVariableEncoding(VD);
922void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
931 return mangleMemberFunctionPointer(RD, MD,
nullptr,
QualType(),
"");
940 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
943 mangleVirtualMemPtrThunk(MD, ML);
946 mangleFunctionEncoding(MD,
true);
950void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
953 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
954 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
960 mangleNumber(OffsetInVFTable);
966void MicrosoftCXXNameMangler::mangleName(
GlobalDecl GD) {
970 mangleUnqualifiedName(GD);
972 mangleNestedName(GD);
978void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
979 mangleNumber(llvm::APSInt(llvm::APInt(64, Number),
false));
982void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
987 unsigned Width = std::max(Number.getBitWidth(), 64U);
988 llvm::APInt
Value = Number.extend(Width);
996 if (
Value.isNegative()) {
1003void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
1004 using llvm::APFloat;
1006 switch (APFloat::SemanticsToEnum(Number.getSemantics())) {
1007 case APFloat::S_IEEEsingle: Out <<
'A';
break;
1008 case APFloat::S_IEEEdouble: Out <<
'B';
break;
1012 case APFloat::S_IEEEhalf: Out <<
'V';
break;
1013 case APFloat::S_BFloat: Out <<
'W';
break;
1014 case APFloat::S_x87DoubleExtended: Out <<
'X';
break;
1015 case APFloat::S_IEEEquad: Out <<
'Y';
break;
1016 case APFloat::S_PPCDoubleDouble: Out <<
'Z';
break;
1017 case APFloat::S_PPCDoubleDoubleLegacy:
1018 case APFloat::S_Float8E5M2:
1019 case APFloat::S_Float8E4M3:
1020 case APFloat::S_Float8E4M3FN:
1021 case APFloat::S_Float8E5M2FNUZ:
1022 case APFloat::S_Float8E4M3FNUZ:
1023 case APFloat::S_Float8E4M3B11FNUZ:
1024 case APFloat::S_Float8E3M4:
1025 case APFloat::S_FloatTF32:
1026 case APFloat::S_Float8E8M0FNU:
1027 case APFloat::S_Float6E3M2FN:
1028 case APFloat::S_Float6E2M3FN:
1029 case APFloat::S_Float4E2M1FN:
1030 llvm_unreachable(
"Tried to mangle unexpected APFloat semantics");
1033 mangleBits(Number.bitcastToAPInt());
1036void MicrosoftCXXNameMangler::mangleBits(llvm::APInt
Value) {
1047 EncodedNumberBuffer.push_back(
'A' + (
Value & 0xf).getZExtValue());
1048 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1049 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1058 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1067 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1068 TemplateArgs = &Spec->getTemplateArgs();
1069 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1074 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1075 TemplateArgs = &Spec->getTemplateArgs();
1076 return GD.
getWithDecl(Spec->getSpecializedTemplate());
1082void MicrosoftCXXNameMangler::mangleUnqualifiedName(
GlobalDecl GD,
1096 if (isa<FunctionTemplateDecl>(TD.getDecl())) {
1097 mangleTemplateInstantiationName(TD, *TemplateArgs);
1120 ArgBackRefMap::iterator
Found = TemplateArgBackReferences.find(ND);
1121 if (
Found == TemplateArgBackReferences.end()) {
1123 TemplateArgStringMap::iterator
Found = TemplateArgStrings.find(ND);
1124 if (
Found == TemplateArgStrings.end()) {
1127 llvm::raw_svector_ostream Stream(TemplateMangling);
1128 MicrosoftCXXNameMangler Extra(Context, Stream);
1129 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1132 mangleSourceName(TemplateMangling);
1136 BackRefVec::iterator StringFound =
1137 llvm::find(NameBackReferences, TemplateMangling);
1138 if (StringFound != NameBackReferences.end()) {
1139 TemplateArgBackReferences[ND] =
1140 StringFound - NameBackReferences.begin();
1142 TemplateArgStrings[ND] =
1143 TemplateArgStringStorage.save(TemplateMangling.str());
1146 Out <<
Found->second <<
'@';
1149 Out <<
Found->second;
1154 switch (Name.getNameKind()) {
1159 ((isa<FunctionDecl>(ND) && ND->
hasAttr<CUDAGlobalAttr>()) ||
1160 (isa<FunctionTemplateDecl>(ND) &&
1161 cast<FunctionTemplateDecl>(ND)
1162 ->getTemplatedDecl()
1163 ->hasAttr<CUDAGlobalAttr>())) &&
1167 (llvm::Twine(
"__device_stub__") + II->getName()).str());
1169 mangleSourceName(II->getName());
1174 assert(ND &&
"mangling empty name without declaration");
1176 if (
const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1177 if (NS->isAnonymousNamespace()) {
1178 Out <<
"?A0x" << Context.getAnonymousNamespaceHash() <<
'@';
1188 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1189 mangleSourceName(Name);
1193 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1196 assert(RD &&
"expected variable decl to have a record type");
1202 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1203 mangleSourceName(Name.str());
1207 if (
const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1210 SmallString<
sizeof(
"_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1211 llvm::raw_svector_ostream GUIDOS(GUID);
1212 Context.mangleMSGuidDecl(GD, GUIDOS);
1213 mangleSourceName(GUID);
1217 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1219 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1220 TPO->getValue(), TplArgKind::ClassNTTP);
1225 const TagDecl *TD = cast<TagDecl>(ND);
1228 "Typedef should not be in another decl context!");
1229 assert(
D->getDeclName().getAsIdentifierInfo() &&
1230 "Typedef was not named!");
1231 mangleSourceName(
D->getDeclName().getAsIdentifierInfo()->getName());
1236 if (
Record->isLambda()) {
1239 Decl *LambdaContextDecl =
Record->getLambdaContextDecl();
1240 unsigned LambdaManglingNumber =
Record->getLambdaManglingNumber();
1243 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1248 unsigned DefaultArgNo =
1250 Name += llvm::utostr(DefaultArgNo);
1254 if (LambdaManglingNumber)
1255 LambdaId = LambdaManglingNumber;
1257 LambdaId = Context.getLambdaId(
Record);
1259 Name += llvm::utostr(LambdaId);
1262 mangleSourceName(Name);
1266 if (LambdaManglingNumber && LambdaContextDecl) {
1267 if ((isa<VarDecl>(LambdaContextDecl) ||
1268 isa<FieldDecl>(LambdaContextDecl)) &&
1269 !isa<ParmVarDecl>(LambdaContextDecl)) {
1270 mangleUnqualifiedName(cast<NamedDecl>(LambdaContextDecl));
1282 Name +=
"<unnamed-type-";
1283 Name += DD->getName();
1289 Name +=
"<unnamed-type-";
1290 Name += TND->getName();
1291 }
else if (isa<EnumDecl>(TD) &&
1292 cast<EnumDecl>(TD)->enumerator_begin() !=
1293 cast<EnumDecl>(TD)->enumerator_end()) {
1295 auto *ED = cast<EnumDecl>(TD);
1296 Name +=
"<unnamed-enum-";
1297 Name += ED->enumerator_begin()->getName();
1300 Name +=
"<unnamed-type-$S";
1301 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1304 mangleSourceName(Name.str());
1315 mangleSourceName(Name.str());
1320 if (isStructorDecl(ND)) {
1334 if (isStructorDecl(ND))
1337 mangleCXXDtorType(
static_cast<CXXDtorType>(StructorType));
1351 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->
getLocation());
1356 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1361 llvm_unreachable(
"Can't mangle a deduction guide name!");
1364 llvm_unreachable(
"Can't mangle a using directive name!");
1370void MicrosoftCXXNameMangler::mangleNestedName(
GlobalDecl GD) {
1373 if (
const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1374 for (
unsigned I = 1, IE =
ID->getChainingSize(); I < IE; ++I)
1375 mangleSourceName(
"<unnamed-tag>");
1377 const DeclContext *DC = getEffectiveDeclContext(ND);
1379 if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
1381 if (Context.getNextDiscriminator(ND, Disc)) {
1388 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1390 [](StringRef Name,
const unsigned Discriminator,
1391 const unsigned ParameterDiscriminator) -> std::string {
1393 llvm::raw_string_ostream Stream(Buffer);
1396 Stream <<
'_' << Discriminator;
1397 if (ParameterDiscriminator)
1398 Stream <<
'_' << ParameterDiscriminator;
1402 unsigned Discriminator = BD->getBlockManglingNumber();
1404 Discriminator = Context.getBlockId(BD,
false);
1409 unsigned ParameterDiscriminator = 0;
1410 if (
const auto *MC = BD->getBlockManglingContextDecl())
1411 if (
const auto *
P = dyn_cast<ParmVarDecl>(MC))
1412 if (
const auto *F = dyn_cast<FunctionDecl>(
P->getDeclContext()))
1413 ParameterDiscriminator =
1414 F->getNumParams() -
P->getFunctionScopeIndex();
1416 DC = getEffectiveDeclContext(BD);
1419 mangleSourceName(Discriminate(
"_block_invoke", Discriminator,
1420 ParameterDiscriminator));
1425 if (
const auto *MC = BD->getBlockManglingContextDecl())
1426 if (!isa<ParmVarDecl>(MC))
1427 if (
const auto *ND = dyn_cast<NamedDecl>(MC))
1428 mangleUnqualifiedName(ND);
1432 if (
const auto *RD = dyn_cast<RecordDecl>(DC))
1441 if (PointersAre64Bit)
1444 mangleArtificialTagType(TagTypeKind::Struct,
1445 Discriminate(
"__block_literal", Discriminator,
1446 ParameterDiscriminator));
1451 if (isa<RecordDecl>(DC))
1454 }
else if (
const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
1455 mangleObjCMethodName(Method);
1456 }
else if (isa<NamedDecl>(DC)) {
1457 ND = cast<NamedDecl>(DC);
1458 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1459 mangle(getGlobalDeclAsDeclContext(FD),
"?");
1462 mangleUnqualifiedName(ND);
1465 if (
const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1475void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
1490 llvm_unreachable(
"not expecting a COMDAT");
1492 llvm_unreachable(
"Unsupported dtor type?");
1501 case OO_New: Out <<
"?2";
break;
1503 case OO_Delete: Out <<
"?3";
break;
1505 case OO_Equal: Out <<
"?4";
break;
1507 case OO_GreaterGreater: Out <<
"?5";
break;
1509 case OO_LessLess: Out <<
"?6";
break;
1511 case OO_Exclaim: Out <<
"?7";
break;
1513 case OO_EqualEqual: Out <<
"?8";
break;
1515 case OO_ExclaimEqual: Out <<
"?9";
break;
1517 case OO_Subscript: Out <<
"?A";
break;
1520 case OO_Arrow: Out <<
"?C";
break;
1522 case OO_Star: Out <<
"?D";
break;
1524 case OO_PlusPlus: Out <<
"?E";
break;
1526 case OO_MinusMinus: Out <<
"?F";
break;
1528 case OO_Minus: Out <<
"?G";
break;
1530 case OO_Plus: Out <<
"?H";
break;
1532 case OO_Amp: Out <<
"?I";
break;
1534 case OO_ArrowStar: Out <<
"?J";
break;
1536 case OO_Slash: Out <<
"?K";
break;
1538 case OO_Percent: Out <<
"?L";
break;
1540 case OO_Less: Out <<
"?M";
break;
1542 case OO_LessEqual: Out <<
"?N";
break;
1544 case OO_Greater: Out <<
"?O";
break;
1546 case OO_GreaterEqual: Out <<
"?P";
break;
1548 case OO_Comma: Out <<
"?Q";
break;
1550 case OO_Call: Out <<
"?R";
break;
1552 case OO_Tilde: Out <<
"?S";
break;
1554 case OO_Caret: Out <<
"?T";
break;
1556 case OO_Pipe: Out <<
"?U";
break;
1558 case OO_AmpAmp: Out <<
"?V";
break;
1560 case OO_PipePipe: Out <<
"?W";
break;
1562 case OO_StarEqual: Out <<
"?X";
break;
1564 case OO_PlusEqual: Out <<
"?Y";
break;
1566 case OO_MinusEqual: Out <<
"?Z";
break;
1568 case OO_SlashEqual: Out <<
"?_0";
break;
1570 case OO_PercentEqual: Out <<
"?_1";
break;
1572 case OO_GreaterGreaterEqual: Out <<
"?_2";
break;
1574 case OO_LessLessEqual: Out <<
"?_3";
break;
1576 case OO_AmpEqual: Out <<
"?_4";
break;
1578 case OO_PipeEqual: Out <<
"?_5";
break;
1580 case OO_CaretEqual: Out <<
"?_6";
break;
1609 case OO_Array_New: Out <<
"?_U";
break;
1611 case OO_Array_Delete: Out <<
"?_V";
break;
1613 case OO_Coawait: Out <<
"?__L";
break;
1615 case OO_Spaceship: Out <<
"?__M";
break;
1617 case OO_Conditional: {
1618 Error(
Loc,
"conditional operator");
1624 llvm_unreachable(
"Not an overloaded operator");
1628void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1630 BackRefVec::iterator
Found = llvm::find(NameBackReferences, Name);
1631 if (
Found == NameBackReferences.end()) {
1632 if (NameBackReferences.size() < 10)
1633 NameBackReferences.push_back(std::string(Name));
1636 Out << (
Found - NameBackReferences.begin());
1640void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1641 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1644void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1651 ArgBackRefMap OuterFunArgsContext;
1652 ArgBackRefMap OuterTemplateArgsContext;
1653 BackRefVec OuterTemplateContext;
1654 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1655 NameBackReferences.swap(OuterTemplateContext);
1656 FunArgBackReferences.swap(OuterFunArgsContext);
1657 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1658 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1660 mangleUnscopedTemplateName(GD);
1661 mangleTemplateArgs(cast<TemplateDecl>(GD.
getDecl()), TemplateArgs);
1664 NameBackReferences.swap(OuterTemplateContext);
1665 FunArgBackReferences.swap(OuterFunArgsContext);
1666 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1667 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1670void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(
GlobalDecl GD) {
1673 mangleUnqualifiedName(GD);
1676void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1687 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1688 LangOptions::MSVC2019) &&
1690 !TemplateArgType.
isNull()) {
1692 mangleType(TemplateArgType,
SourceRange(), QMM_Drop);
1697 mangleNumber(
Value);
1700void MicrosoftCXXNameMangler::mangleExpression(
1703 if (std::optional<llvm::APSInt>
Value =
1714void MicrosoftCXXNameMangler::mangleTemplateArgs(
1718 assert(TPL->
size() == TemplateArgs.
size() &&
1719 "size mismatch between args and parms!");
1721 for (
size_t i = 0; i < TemplateArgs.
size(); ++i) {
1729 mangleTemplateArg(TD, TA, TPL->
getParam(i));
1741 QualType BaseT =
V.getLValueBase().getType();
1742 if (!BaseT->
isArrayType() ||
V.getLValuePath().size() != 1 ||
1743 V.getLValuePath()[0].getAsArrayIndex() != 0)
1746 V.getLValueBase().dyn_cast<
const ValueDecl *>());
1749void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1789 llvm_unreachable(
"Can't mangle null template arguments!");
1791 llvm_unreachable(
"Can't mangle template expansion arguments!");
1799 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1800 mangleMemberDataPointer(cast<CXXRecordDecl>(ND->
getDeclContext())
1801 ->getMostRecentNonInjectedDecl(),
1802 cast<ValueDecl>(ND),
1803 cast<NonTypeTemplateParmDecl>(Parm),
1805 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1808 mangleMemberFunctionPointer(
1812 mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),
1817 auto *TPO = cast<TemplateParamObjectDecl>(ND);
1818 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1819 TPO->getValue(), TplArgKind::ClassNTTP);
1820 }
else if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1821 mangleVarDecl(VD, cast<NonTypeTemplateParmDecl>(Parm),
1831 cast<NonTypeTemplateParmDecl>(Parm),
T);
1837 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1838 if (MPT->isMemberFunctionPointerType() &&
1839 !isa<FunctionTemplateDecl>(TD)) {
1840 mangleMemberFunctionPointer(RD,
nullptr,
nullptr,
QualType());
1843 if (MPT->isMemberDataPointer()) {
1844 if (!isa<FunctionTemplateDecl>(TD)) {
1845 mangleMemberDataPointer(RD,
nullptr,
nullptr,
QualType());
1855 mangleIntegerLiteral(llvm::APSInt::get(-1),
1856 cast<NonTypeTemplateParmDecl>(Parm),
T);
1861 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1862 cast<NonTypeTemplateParmDecl>(Parm),
T);
1871 return mangleTemplateArg(
1875 if (cast<NonTypeTemplateParmDecl>(Parm)
1877 ->getContainedDeducedType()) {
1883 TplArgKind::StructuralValue,
1887 mangleExpression(TA.
getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
1891 if (TemplateArgs.empty()) {
1892 if (isa<TemplateTypeParmDecl>(Parm) ||
1893 isa<TemplateTemplateParmDecl>(Parm))
1897 LangOptions::MSVC2015)
1900 else if (isa<NonTypeTemplateParmDecl>(Parm))
1903 llvm_unreachable(
"unexpected template parameter decl!");
1906 mangleTemplateArg(TD, PA, Parm);
1913 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1915 }
else if (isa<TypeAliasDecl>(ND)) {
1919 llvm_unreachable(
"unexpected template template NamedDecl!");
1926void MicrosoftCXXNameMangler::mangleTemplateArgValue(
QualType T,
1929 bool WithScalarType) {
1930 switch (
V.getKind()) {
1944 mangleNumber(
V.getInt());
1950 mangleFloat(
V.getFloat());
1961 if (
V.isLValueOnePastTheEnd()) {
1970 if (!
V.hasLValuePath() ||
V.getLValuePath().empty()) {
1972 if (
Base.isNull()) {
1978 mangleNumber(
V.getLValueOffset().getQuantity());
1979 }
else if (!
V.hasLValuePath()) {
1981 Error(
"template argument (extension not comaptible with ms mangler)");
1987 Error(
"template argument (undeclared base)");
1995 SmallVector<std::function<void()>, 2> EntryManglers;
1999 EntryTypes.push_back(
'C');
2000 EntryManglers.push_back([
this, I =
E.getAsArrayIndex()] {
2005 ET = AT->getElementType();
2009 const Decl *
D =
E.getAsBaseOrMember().getPointer();
2010 if (
auto *FD = dyn_cast<FieldDecl>(
D)) {
2016 ET = getASTContext().getRecordType(cast<CXXRecordDecl>(
D));
2022 EntryTypes.push_back(
'6');
2023 EntryManglers.push_back([
this,
D] {
2024 mangleUnqualifiedName(cast<NamedDecl>(
D));
2029 for (
auto I = EntryTypes.rbegin(),
E = EntryTypes.rend(); I !=
E; ++I)
2034 Error(
"template argument (null value decl)");
2037 Out << (TAK == TplArgKind::ClassNTTP ?
'E' :
'1');
2040 for (
const std::function<
void()> &Mangler : EntryManglers)
2056 if (TAK == TplArgKind::ClassNTTP) {
2058 mangleMemberDataPointerInClassNTTP(RD,
D);
2060 mangleMemberFunctionPointerInClassNTTP(RD,
2061 cast_or_null<CXXMethodDecl>(
D));
2064 mangleMemberDataPointer(RD,
D,
nullptr,
QualType(),
"");
2066 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(
D),
nullptr,
2076 assert(RD &&
"unexpected type for record value");
2078 unsigned BaseIndex = 0;
2080 mangleTemplateArgValue(B.getType(),
V.getStructBase(BaseIndex++), TAK);
2082 if (!FD->isUnnamedBitField())
2083 mangleTemplateArgValue(FD->
getType(),
2084 V.getStructField(FD->getFieldIndex()), TAK,
2093 if (
const FieldDecl *FD =
V.getUnionField()) {
2094 mangleUnqualifiedName(FD);
2095 mangleTemplateArgValue(FD->
getType(),
V.getUnionValue(), TAK);
2105 mangleNumber(
V.getComplexIntReal());
2107 mangleNumber(
V.getComplexIntImag());
2114 mangleFloat(
V.getComplexFloatReal());
2115 mangleFloat(
V.getComplexFloatImag());
2121 QualType ElemT = getASTContext().getAsArrayType(
T)->getElementType();
2123 for (
unsigned I = 0, N =
V.getArraySize(); I != N; ++I) {
2124 const APValue &ElemV = I <
V.getArrayInitializedElts()
2125 ?
V.getArrayInitializedElt(I)
2126 :
V.getArrayFiller();
2127 mangleTemplateArgValue(ElemT, ElemV, TAK);
2142 for (
unsigned I = 0, N =
V.getVectorLength(); I != N; ++I) {
2143 const APValue &ElemV =
V.getVectorElt(I);
2144 mangleTemplateArgValue(ElemT, ElemV, TAK);
2152 Error(
"template argument (value type: address label diff)");
2157 Error(
"template argument (value type: fixed point)");
2163void MicrosoftCXXNameMangler::mangleObjCProtocol(
const ObjCProtocolDecl *PD) {
2165 llvm::raw_svector_ostream Stream(TemplateMangling);
2166 MicrosoftCXXNameMangler Extra(Context, Stream);
2169 Extra.mangleSourceName(
"Protocol");
2170 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->
getName());
2172 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2175void MicrosoftCXXNameMangler::mangleObjCLifetime(
const QualType Type,
2179 llvm::raw_svector_ostream Stream(TemplateMangling);
2180 MicrosoftCXXNameMangler Extra(Context, Stream);
2188 Extra.mangleSourceName(
"Autoreleasing");
2191 Extra.mangleSourceName(
"Strong");
2194 Extra.mangleSourceName(
"Weak");
2197 Extra.manglePointerCVQualifiers(Quals);
2198 Extra.manglePointerExtQualifiers(Quals,
Type);
2201 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2204void MicrosoftCXXNameMangler::mangleObjCKindOfType(
const ObjCObjectType *
T,
2208 llvm::raw_svector_ostream Stream(TemplateMangling);
2209 MicrosoftCXXNameMangler Extra(Context, Stream);
2212 Extra.mangleSourceName(
"KindOf");
2214 .stripObjCKindOfType(getASTContext())
2215 ->castAs<ObjCObjectType>(),
2218 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__ObjC"});
2221void MicrosoftCXXNameMangler::mangleQualifiers(
Qualifiers Quals,
2279 if (HasConst && HasVolatile) {
2281 }
else if (HasVolatile) {
2283 }
else if (HasConst) {
2289 if (HasConst && HasVolatile) {
2291 }
else if (HasVolatile) {
2293 }
else if (HasConst) {
2304MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
2307 switch (RefQualifier) {
2321void MicrosoftCXXNameMangler::manglePointerExtQualifiers(
Qualifiers Quals,
2324 bool is64Bit = PointeeType.
isNull() ? PointersAre64Bit :
2337void MicrosoftCXXNameMangler::manglePointerCVQualifiers(
Qualifiers Quals) {
2345 if (HasConst && HasVolatile) {
2347 }
else if (HasVolatile) {
2349 }
else if (HasConst) {
2356void MicrosoftCXXNameMangler::mangleFunctionArgumentType(
QualType T,
2367 QualType OriginalType = DT->getOriginalType();
2370 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
2371 OriginalType = getASTContext().getIncompleteArrayType(
2372 AT->getElementType(), AT->getSizeModifier(),
2373 AT->getIndexTypeCVRQualifiers());
2384 TypePtr =
T.getCanonicalType().getAsOpaquePtr();
2387 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2389 if (
Found == FunArgBackReferences.end()) {
2390 size_t OutSizeBefore = Out.tell();
2392 mangleType(
T,
Range, QMM_Drop);
2397 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);
2398 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2399 size_t Size = FunArgBackReferences.size();
2400 FunArgBackReferences[TypePtr] =
Size;
2403 Out <<
Found->second;
2407void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2408 const PassObjectSizeAttr *POSA) {
2409 int Type = POSA->getType();
2410 bool Dynamic = POSA->isDynamic();
2413 auto *TypePtr = (
const void *)&*
Iter;
2414 ArgBackRefMap::iterator
Found = FunArgBackReferences.find(TypePtr);
2416 if (
Found == FunArgBackReferences.end()) {
2418 Dynamic ?
"__pass_dynamic_object_size" :
"__pass_object_size";
2419 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(
Type),
2422 if (FunArgBackReferences.size() < 10) {
2423 size_t Size = FunArgBackReferences.size();
2424 FunArgBackReferences[TypePtr] =
Size;
2427 Out <<
Found->second;
2431void MicrosoftCXXNameMangler::mangleAddressSpaceType(
QualType T,
2449 llvm::raw_svector_ostream Stream(ASMangling);
2450 MicrosoftCXXNameMangler Extra(Context, Stream);
2456 Extra.mangleSourceName(
"_AS");
2457 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2461 llvm_unreachable(
"Not a language specific address space");
2462 case LangAS::opencl_global:
2463 Extra.mangleSourceName(
"_ASCLglobal");
2465 case LangAS::opencl_global_device:
2466 Extra.mangleSourceName(
"_ASCLdevice");
2468 case LangAS::opencl_global_host:
2469 Extra.mangleSourceName(
"_ASCLhost");
2471 case LangAS::opencl_local:
2472 Extra.mangleSourceName(
"_ASCLlocal");
2474 case LangAS::opencl_constant:
2475 Extra.mangleSourceName(
"_ASCLconstant");
2477 case LangAS::opencl_private:
2478 Extra.mangleSourceName(
"_ASCLprivate");
2480 case LangAS::opencl_generic:
2481 Extra.mangleSourceName(
"_ASCLgeneric");
2483 case LangAS::cuda_device:
2484 Extra.mangleSourceName(
"_ASCUdevice");
2486 case LangAS::cuda_constant:
2487 Extra.mangleSourceName(
"_ASCUconstant");
2489 case LangAS::cuda_shared:
2490 Extra.mangleSourceName(
"_ASCUshared");
2492 case LangAS::ptr32_sptr:
2493 case LangAS::ptr32_uptr:
2495 llvm_unreachable(
"don't mangle ptr address spaces with _AS");
2499 Extra.mangleType(
T,
Range, QMM_Escape);
2501 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {
"__clang"});
2504void MicrosoftCXXNameMangler::mangleAutoReturnType(
QualType T,
2505 QualifierMangleMode QMM) {
2506 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2507 LangOptions::MSVC2019) &&
2508 "Cannot mangle MSVC 2017 auto return types!");
2510 if (isa<AutoType>(
T)) {
2514 if (QMM == QMM_Result)
2516 if (QMM != QMM_Drop)
2517 mangleQualifiers(Quals,
false);
2518 Out << (AT->isDecltypeAuto() ?
"_T" :
"_P");
2522 T =
T.getDesugaredType(getASTContext());
2530 mangleQualifiers(Quals,
false);
2533 llvm_unreachable(
"QMM_Escape unexpected");
2536 const Type *ty =
T.getTypePtr();
2538 case Type::MemberPointer:
2539 mangleAutoReturnType(cast<MemberPointerType>(ty), Quals);
2542 mangleAutoReturnType(cast<PointerType>(ty), Quals);
2544 case Type::LValueReference:
2545 mangleAutoReturnType(cast<LValueReferenceType>(ty), Quals);
2547 case Type::RValueReference:
2548 mangleAutoReturnType(cast<RValueReferenceType>(ty), Quals);
2551 llvm_unreachable(
"Invalid type expected");
2556 QualifierMangleMode QMM) {
2559 T =
T.getDesugaredType(getASTContext());
2562 if (
const ArrayType *AT = getASTContext().getAsArrayType(
T)) {
2565 if (QMM == QMM_Mangle)
2567 else if (QMM == QMM_Escape || QMM == QMM_Result)
2569 mangleArrayType(AT);
2584 mangleFunctionType(FT);
2587 mangleQualifiers(Quals,
false);
2590 if (!IsPointer && Quals) {
2592 mangleQualifiers(Quals,
false);
2600 if ((!IsPointer && Quals) || isa<TagType>(
T) || isArtificialTagType(
T)) {
2602 mangleQualifiers(Quals,
false);
2607 const Type *ty =
T.getTypePtr();
2610#define ABSTRACT_TYPE(CLASS, PARENT)
2611#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2613 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2615#define TYPE(CLASS, PARENT) \
2617 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2619#include "clang/AST/TypeNodes.inc"
2621#undef NON_CANONICAL_TYPE
2655 switch (
T->getKind()) {
2656 case BuiltinType::Void:
2659 case BuiltinType::SChar:
2662 case BuiltinType::Char_U:
2663 case BuiltinType::Char_S:
2666 case BuiltinType::UChar:
2669 case BuiltinType::Short:
2672 case BuiltinType::UShort:
2675 case BuiltinType::Int:
2678 case BuiltinType::UInt:
2681 case BuiltinType::Long:
2684 case BuiltinType::ULong:
2687 case BuiltinType::Float:
2690 case BuiltinType::Double:
2694 case BuiltinType::LongDouble:
2697 case BuiltinType::LongLong:
2700 case BuiltinType::ULongLong:
2703 case BuiltinType::Int128:
2706 case BuiltinType::UInt128:
2709 case BuiltinType::Bool:
2712 case BuiltinType::Char8:
2715 case BuiltinType::Char16:
2718 case BuiltinType::Char32:
2721 case BuiltinType::WChar_S:
2722 case BuiltinType::WChar_U:
2726#define BUILTIN_TYPE(Id, SingletonId)
2727#define PLACEHOLDER_TYPE(Id, SingletonId) \
2728 case BuiltinType::Id:
2729#include "clang/AST/BuiltinTypes.def"
2730 case BuiltinType::Dependent:
2731 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
2733 case BuiltinType::ObjCId:
2734 mangleArtificialTagType(TagTypeKind::Struct,
"objc_object");
2736 case BuiltinType::ObjCClass:
2737 mangleArtificialTagType(TagTypeKind::Struct,
"objc_class");
2739 case BuiltinType::ObjCSel:
2740 mangleArtificialTagType(TagTypeKind::Struct,
"objc_selector");
2743#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2744 case BuiltinType::Id: \
2745 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2747#include "clang/Basic/OpenCLImageTypes.def"
2748 case BuiltinType::OCLSampler:
2750 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_sampler");
2752 case BuiltinType::OCLEvent:
2754 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_event");
2756 case BuiltinType::OCLClkEvent:
2758 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_clkevent");
2760 case BuiltinType::OCLQueue:
2762 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_queue");
2764 case BuiltinType::OCLReserveID:
2766 mangleArtificialTagType(TagTypeKind::Struct,
"ocl_reserveid");
2768#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2769 case BuiltinType::Id: \
2770 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2772#include "clang/Basic/OpenCLExtensionTypes.def"
2774 case BuiltinType::NullPtr:
2778 case BuiltinType::Float16:
2779 mangleArtificialTagType(TagTypeKind::Struct,
"_Float16", {
"__clang"});
2782 case BuiltinType::Half:
2783 if (!getASTContext().getLangOpts().
HLSL)
2784 mangleArtificialTagType(TagTypeKind::Struct,
"_Half", {
"__clang"});
2785 else if (getASTContext().getLangOpts().NativeHalfType)
2791 case BuiltinType::BFloat16:
2792 mangleArtificialTagType(TagTypeKind::Struct,
"__bf16", {
"__clang"});
2795#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2796 case BuiltinType::Id: \
2797 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2798 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2801#include "clang/Basic/WebAssemblyReferenceTypes.def"
2803#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2804 case BuiltinType::Id: \
2805 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2807#include "clang/Basic/HLSLIntangibleTypes.def"
2809#define SVE_TYPE(Name, Id, SingletonId) \
2810 case BuiltinType::Id:
2811#include "clang/Basic/AArch64SVEACLETypes.def"
2812#define PPC_VECTOR_TYPE(Name, Id, Size) \
2813 case BuiltinType::Id:
2814#include "clang/Basic/PPCTypes.def"
2815#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2816#include "clang/Basic/RISCVVTypes.def"
2817#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
2818#include "clang/Basic/AMDGPUTypes.def"
2819 case BuiltinType::ShortAccum:
2820 case BuiltinType::Accum:
2821 case BuiltinType::LongAccum:
2822 case BuiltinType::UShortAccum:
2823 case BuiltinType::UAccum:
2824 case BuiltinType::ULongAccum:
2825 case BuiltinType::ShortFract:
2826 case BuiltinType::Fract:
2827 case BuiltinType::LongFract:
2828 case BuiltinType::UShortFract:
2829 case BuiltinType::UFract:
2830 case BuiltinType::ULongFract:
2831 case BuiltinType::SatShortAccum:
2832 case BuiltinType::SatAccum:
2833 case BuiltinType::SatLongAccum:
2834 case BuiltinType::SatUShortAccum:
2835 case BuiltinType::SatUAccum:
2836 case BuiltinType::SatULongAccum:
2837 case BuiltinType::SatShortFract:
2838 case BuiltinType::SatFract:
2839 case BuiltinType::SatLongFract:
2840 case BuiltinType::SatUShortFract:
2841 case BuiltinType::SatUFract:
2842 case BuiltinType::SatULongFract:
2843 case BuiltinType::Ibm128:
2844 case BuiltinType::Float128: {
2861 mangleFunctionType(
T,
nullptr,
true);
2864 mangleFunctionType(
T);
2870 mangleFunctionType(
T);
2873void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *
T,
2875 bool ForceThisQuals,
2876 bool MangleExceptionSpec) {
2884 bool IsInLambda =
false;
2885 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
2887 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(
D)) {
2891 HasThisQuals =
true;
2892 if (isa<CXXDestructorDecl>(MD)) {
2894 }
else if (isa<CXXConstructorDecl>(MD)) {
2900 CC = getASTContext().getDefaultCallingConvention(
2909 manglePointerExtQualifiers(Quals,
QualType());
2911 mangleQualifiers(Quals,
false);
2914 mangleCallingConvention(CC,
Range);
2919 if (isa<CXXDestructorDecl>(
D) && isStructorDecl(
D)) {
2923 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
2932 if (IsCtorClosure) {
2942 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
2950 llvm_unreachable(
"unexpected constructor closure!");
2956 }
else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(
D)) {
2963 if (IsInLambda && isa<CXXConversionDecl>(
D)) {
2967 mangleType(ResultType,
Range, QMM_Result);
2968 }
else if (IsInLambda) {
2970 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2971 "shouldn't need to mangle __auto_type!");
2975 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
2981 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2982 "shouldn't need to mangle __auto_type!");
2988 auto UseClangMangling = [](
QualType ResultType) {
2990 while (isa<PointerType>(
T.getTypePtr())) {
2992 if (
T.getQualifiers().hasAddressSpace())
2998 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
2999 LangOptions::MSVC2019) &&
3000 !UseClangMangling(ResultType)) {
3001 if (
D && !
D->getPrimaryTemplate()) {
3004 if (
D &&
D->getPrimaryTemplate()) {
3006 ->getTemplatedDecl()
3012 mangleAutoReturnType(ResultType, QMM_Result);
3018 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
3024 mangleType(ResultType,
Range, QMM_Result);
3042 if (I == 0 &&
D &&
D->getParamDecl(I)->isExplicitObjectParameter())
3055 if (
const auto *
P =
D->getParamDecl(I)->
getAttr<PassObjectSizeAttr>())
3056 manglePassObjectSizeArg(
P);
3065 if (MangleExceptionSpec && getASTContext().getLangOpts().
CPlusPlus17 &&
3066 getASTContext().getLangOpts().isCompatibleWithMSVC(
3067 LangOptions::MSVC2017_5))
3068 mangleThrowSpecification(Proto);
3073void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
3098 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3102 if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
3108 llvm_unreachable(
"Unsupported access specifier");
3137void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC,
3200 if (getASTContext().getLangOpts().RegCall4)
3209void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *
T,
3214void MicrosoftCXXNameMangler::mangleThrowSpecification(
3236void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
3238 case TagTypeKind::Union:
3241 case TagTypeKind::Struct:
3242 case TagTypeKind::Interface:
3245 case TagTypeKind::Class:
3248 case TagTypeKind::Enum:
3255 mangleType(cast<TagType>(
T)->getDecl());
3259 mangleType(cast<TagType>(
T)->getDecl());
3261void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
3267void MicrosoftCXXNameMangler::mangleArtificialTagType(
3271 mangleTagTypeKind(TK);
3274 mangleSourceName(UnqualifiedName);
3276 for (StringRef N : llvm::reverse(NestedNames))
3277 mangleSourceName(N);
3290void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *
T) {
3293 manglePointerCVQualifiers(
T->getElementType().getQualifiers());
3298 llvm_unreachable(
"Should have been special cased");
3302 llvm_unreachable(
"Should have been special cased");
3306 llvm_unreachable(
"Should have been special cased");
3310 llvm_unreachable(
"Should have been special cased");
3312void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *
T) {
3316 if (ElementTy->isConstantArrayType()) {
3318 getASTContext().getAsConstantArrayType(ElementTy);
3319 Dimensions.push_back(CAT->
getSize());
3321 }
else if (ElementTy->isIncompleteArrayType()) {
3323 getASTContext().getAsIncompleteArrayType(ElementTy);
3324 Dimensions.push_back(llvm::APInt(32, 0));
3326 }
else if (ElementTy->isVariableArrayType()) {
3328 getASTContext().getAsVariableArrayType(ElementTy);
3329 Dimensions.push_back(llvm::APInt(32, 0));
3331 }
else if (ElementTy->isDependentSizedArrayType()) {
3334 getASTContext().getAsDependentSizedArrayType(ElementTy);
3344 mangleNumber(Dimensions.size());
3345 for (
const llvm::APInt &Dimension : Dimensions)
3346 mangleNumber(Dimension.getLimitedValue());
3352 mangleArrayType(cast<ConstantArrayType>(
T));
3361 manglePointerCVQualifiers(Quals);
3362 manglePointerExtQualifiers(Quals, PointeeType);
3366 mangleFunctionType(FPT,
nullptr,
true);
3370 mangleType(PointeeType,
Range, QMM_Drop);
3380 Name += llvm::utostr(
T->getDepth());
3382 Name += llvm::utostr(
T->getIndex());
3384 mangleSourceName(Name);
3398 manglePointerCVQualifiers(Quals);
3399 manglePointerExtQualifiers(Quals, PointeeType);
3405 mangleType(PointeeType,
Range);
3420 return mangleObjCLifetime(PointeeType, Quals,
Range);
3422 manglePointerCVQualifiers(Quals);
3423 manglePointerExtQualifiers(Quals, PointeeType);
3424 mangleType(PointeeType,
Range);
3435 manglePointerExtQualifiers(Quals, PointeeType);
3436 mangleType(PointeeType,
Range);
3447 manglePointerExtQualifiers(Quals, PointeeType);
3448 mangleType(PointeeType,
Range);
3453 QualType ElementType =
T->getElementType();
3456 llvm::raw_svector_ostream Stream(TemplateMangling);
3457 MicrosoftCXXNameMangler Extra(Context, Stream);
3459 Extra.mangleSourceName(
"_Complex");
3460 Extra.mangleType(ElementType,
Range, QMM_Escape);
3462 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3470bool MicrosoftCXXNameMangler::isArtificialTagType(
QualType T)
const {
3471 const Type *ty =
T.getTypePtr();
3476 case Type::Vector: {
3490 assert((ET || BitIntTy) &&
3491 "vectors with non-builtin/_BitInt elements are unsupported");
3492 uint64_t Width = getASTContext().getTypeSize(
T);
3495 size_t OutSizeBefore = Out.tell();
3496 if (!isa<ExtVectorType>(
T)) {
3497 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
3498 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
3499 mangleArtificialTagType(TagTypeKind::Union,
"__m64");
3500 }
else if (Width >= 128) {
3501 if (ET->
getKind() == BuiltinType::Float)
3502 mangleArtificialTagType(TagTypeKind::Union,
3503 "__m" + llvm::utostr(Width));
3504 else if (ET->
getKind() == BuiltinType::LongLong)
3505 mangleArtificialTagType(TagTypeKind::Union,
3506 "__m" + llvm::utostr(Width) +
'i');
3507 else if (ET->
getKind() == BuiltinType::Double)
3508 mangleArtificialTagType(TagTypeKind::Struct,
3509 "__m" + llvm::utostr(Width) +
'd');
3514 bool IsBuiltin = Out.tell() != OutSizeBefore;
3521 llvm::raw_svector_ostream Stream(TemplateMangling);
3522 MicrosoftCXXNameMangler Extra(Context, Stream);
3524 Extra.mangleSourceName(
"__vector");
3525 Extra.mangleType(
QualType(ET ?
static_cast<const Type *
>(ET) : BitIntTy, 0),
3527 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumElements()));
3529 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {
"__clang"});
3566 mangleTagTypeKind(TagTypeKind::Struct);
3567 mangleName(
T->getDecl());
3572 if (
T->isKindOfType())
3573 return mangleObjCKindOfType(
T, Quals,
Range);
3575 if (
T->qual_empty() && !
T->isSpecialized())
3576 return mangleType(
T->getBaseType(),
Range, QMM_Drop);
3578 ArgBackRefMap OuterFunArgsContext;
3579 ArgBackRefMap OuterTemplateArgsContext;
3580 BackRefVec OuterTemplateContext;
3582 FunArgBackReferences.swap(OuterFunArgsContext);
3583 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3584 NameBackReferences.swap(OuterTemplateContext);
3586 mangleTagTypeKind(TagTypeKind::Struct);
3590 mangleSourceName(
"objc_object");
3591 else if (
T->isObjCClass())
3592 mangleSourceName(
"objc_class");
3594 mangleSourceName(
T->getInterface()->getName());
3596 for (
const auto &Q :
T->quals())
3597 mangleObjCProtocol(Q);
3599 if (
T->isSpecialized())
3600 for (
const auto &TA :
T->getTypeArgs())
3601 mangleType(TA,
Range, QMM_Drop);
3607 FunArgBackReferences.swap(OuterFunArgsContext);
3608 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3609 NameBackReferences.swap(OuterTemplateContext);
3615 manglePointerCVQualifiers(Quals);
3616 manglePointerExtQualifiers(Quals, PointeeType);
3625 llvm_unreachable(
"Cannot mangle injected class name type.");
3638void MicrosoftCXXNameMangler::mangleType(
3651 manglePointerCVQualifiers(Quals);
3652 mangleType(
T->getSelectedType(),
Range);
3677 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3682void MicrosoftCXXNameMangler::mangleType(
3684 assert(
T->getDeducedType().isNull() &&
"expecting a dependent type!");
3695 llvm::raw_svector_ostream Stream(TemplateMangling);
3696 MicrosoftCXXNameMangler Extra(Context, Stream);
3698 Extra.mangleSourceName(
"_Atomic");
3699 Extra.mangleType(ValueType,
Range, QMM_Escape);
3701 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3706 QualType ElementType =
T->getElementType();
3709 llvm::raw_svector_ostream Stream(TemplateMangling);
3710 MicrosoftCXXNameMangler Extra(Context, Stream);
3712 Extra.mangleSourceName(
"ocl_pipe");
3713 Extra.mangleType(ElementType,
Range, QMM_Escape);
3714 Extra.mangleIntegerLiteral(llvm::APSInt::get(
T->isReadOnly()));
3716 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3719void MicrosoftMangleContextImpl::mangleCXXName(
GlobalDecl GD,
3723 getASTContext().getSourceManager(),
3724 "Mangling declaration");
3726 msvc_hashing_ostream MHO(Out);
3728 if (
auto *CD = dyn_cast<CXXConstructorDecl>(
D)) {
3730 MicrosoftCXXNameMangler mangler(*
this, MHO, CD,
Type);
3731 return mangler.mangle(GD);
3734 if (
auto *DD = dyn_cast<CXXDestructorDecl>(
D)) {
3736 MicrosoftCXXNameMangler mangler(*
this, MHO, DD,
Type);
3737 return mangler.mangle(GD);
3740 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3741 return Mangler.mangle(GD);
3747 llvm::raw_svector_ostream Stream(TemplateMangling);
3748 MicrosoftCXXNameMangler Extra(Context, Stream);
3750 if (
T->isUnsigned())
3751 Extra.mangleSourceName(
"_UBitInt");
3753 Extra.mangleSourceName(
"_BitInt");
3754 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(
T->getNumBits()));
3756 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {
"__clang"});
3766 llvm_unreachable(
"HLSL uses Itanium name mangling");
3795 MicrosoftCXXNameMangler &Mangler,
3802 llvm_unreachable(
"Unsupported access specifier");
3813 Out <<
'R' << AccessSpec;
3814 Mangler.mangleNumber(
3816 Mangler.mangleNumber(
3818 Mangler.mangleNumber(
3820 Mangler.mangleNumber(
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3823 Mangler.mangleNumber(
3825 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3830 llvm_unreachable(
"Unsupported access specifier");
3840 Mangler.mangleNumber(-
static_cast<uint32_t
>(Adjustment.
NonVirtual));
3844 llvm_unreachable(
"Unsupported access specifier");
3857void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
3860 msvc_hashing_ostream MHO(Out);
3861 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3862 Mangler.getStream() <<
'?';
3863 Mangler.mangleVirtualMemPtrThunk(MD, ML);
3866void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
3870 msvc_hashing_ostream MHO(Out);
3871 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3872 Mangler.getStream() <<
'?';
3873 Mangler.mangleName(MD);
3882 assert(Thunk.
Method !=
nullptr &&
3883 "Thunk info should hold the overridee decl");
3886 Mangler.mangleFunctionType(
3899 msvc_hashing_ostream MHO(Out);
3900 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD,
Type);
3901 Mangler.getStream() <<
"??_E";
3903 auto &Adjustment = Thunk.
This;
3908void MicrosoftMangleContextImpl::mangleCXXVFTable(
3915 msvc_hashing_ostream MHO(Out);
3916 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3917 if (Derived->
hasAttr<DLLImportAttr>())
3918 Mangler.getStream() <<
"??_S";
3920 Mangler.getStream() <<
"??_7";
3921 Mangler.mangleName(Derived);
3922 Mangler.getStream() <<
"6B";
3924 Mangler.mangleName(RD);
3925 Mangler.getStream() <<
'@';
3928void MicrosoftMangleContextImpl::mangleCXXVTable(
const CXXRecordDecl *Derived,
3931 mangleCXXVFTable(Derived, {}, Out);
3934void MicrosoftMangleContextImpl::mangleCXXVBTable(
3941 msvc_hashing_ostream MHO(Out);
3942 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3943 Mangler.getStream() <<
"??_8";
3944 Mangler.mangleName(Derived);
3945 Mangler.getStream() <<
"7B";
3947 Mangler.mangleName(RD);
3948 Mangler.getStream() <<
'@';
3951void MicrosoftMangleContextImpl::mangleCXXRTTI(
QualType T, raw_ostream &Out) {
3952 msvc_hashing_ostream MHO(Out);
3953 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3954 Mangler.getStream() <<
"??_R0";
3955 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3956 Mangler.getStream() <<
"@8";
3959void MicrosoftMangleContextImpl::mangleCXXRTTIName(
3960 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
3961 MicrosoftCXXNameMangler Mangler(*
this, Out);
3962 Mangler.getStream() <<
'.';
3963 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3966void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
3968 msvc_hashing_ostream MHO(Out);
3969 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3970 Mangler.getStream() <<
"??_K";
3971 Mangler.mangleName(SrcRD);
3972 Mangler.getStream() <<
"$C";
3973 Mangler.mangleName(DstRD);
3976void MicrosoftMangleContextImpl::mangleCXXThrowInfo(
QualType T,
bool IsConst,
3979 uint32_t NumEntries,
3981 msvc_hashing_ostream MHO(Out);
3982 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3983 Mangler.getStream() <<
"_TI";
3985 Mangler.getStream() <<
'C';
3987 Mangler.getStream() <<
'V';
3989 Mangler.getStream() <<
'U';
3990 Mangler.getStream() << NumEntries;
3991 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3994void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
3995 QualType T, uint32_t NumEntries, raw_ostream &Out) {
3996 msvc_hashing_ostream MHO(Out);
3997 MicrosoftCXXNameMangler Mangler(*
this, MHO);
3998 Mangler.getStream() <<
"_CTA";
3999 Mangler.getStream() << NumEntries;
4000 Mangler.mangleType(
T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4003void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4005 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
4007 MicrosoftCXXNameMangler Mangler(*
this, Out);
4008 Mangler.getStream() <<
"_CT";
4012 llvm::raw_svector_ostream Stream(RTTIMangling);
4013 msvc_hashing_ostream MHO(Stream);
4014 mangleCXXRTTI(
T, MHO);
4016 Mangler.getStream() << RTTIMangling;
4024 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4025 LangOptions::MSVC2015) &&
4026 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4027 LangOptions::MSVC2017_7);
4029 if (!OmitCopyCtor && CD) {
4030 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4031 msvc_hashing_ostream MHO(Stream);
4034 Mangler.getStream() << CopyCtorMangling;
4036 Mangler.getStream() <<
Size;
4037 if (VBPtrOffset == -1) {
4039 Mangler.getStream() << NVOffset;
4042 Mangler.getStream() << NVOffset;
4043 Mangler.getStream() << VBPtrOffset;
4044 Mangler.getStream() << VBIndex;
4048void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4049 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
4050 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
4051 msvc_hashing_ostream MHO(Out);
4052 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4053 Mangler.getStream() <<
"??_R1";
4054 Mangler.mangleNumber(NVOffset);
4055 Mangler.mangleNumber(VBPtrOffset);
4056 Mangler.mangleNumber(VBTableOffset);
4057 Mangler.mangleNumber(Flags);
4058 Mangler.mangleName(Derived);
4059 Mangler.getStream() <<
"8";
4062void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4064 msvc_hashing_ostream MHO(Out);
4065 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4066 Mangler.getStream() <<
"??_R2";
4067 Mangler.mangleName(Derived);
4068 Mangler.getStream() <<
"8";
4071void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4073 msvc_hashing_ostream MHO(Out);
4074 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4075 Mangler.getStream() <<
"??_R3";
4076 Mangler.mangleName(Derived);
4077 Mangler.getStream() <<
"8";
4080void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4088 llvm::raw_svector_ostream Stream(VFTableMangling);
4089 mangleCXXVFTable(Derived, BasePath, Stream);
4091 if (VFTableMangling.starts_with(
"??@")) {
4092 assert(VFTableMangling.ends_with(
"@"));
4093 Out << VFTableMangling <<
"??_R4@";
4097 assert(VFTableMangling.starts_with(
"??_7") ||
4098 VFTableMangling.starts_with(
"??_S"));
4100 Out <<
"??_R4" << VFTableMangling.str().drop_front(4);
4103void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4104 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4105 msvc_hashing_ostream MHO(Out);
4106 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4111 Mangler.getStream() <<
"?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
4112 Mangler.mangleName(EnclosingDecl);
4115void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4116 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4117 msvc_hashing_ostream MHO(Out);
4118 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4123 Mangler.getStream() <<
"?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
4124 Mangler.mangleName(EnclosingDecl);
4127void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4128 QualType T, raw_ostream &Out,
bool NormalizeIntegers =
false) {
4131 MicrosoftCXXNameMangler Mangler(*
this, Out);
4132 Mangler.getStream() <<
'?';
4133 Mangler.mangleType(
T.getCanonicalType(),
SourceRange());
4136void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4137 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
4138 msvc_hashing_ostream MHO(Out);
4139 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4141 Mangler.getStream() <<
"?";
4142 Mangler.mangleSourceName(
"$RT" + llvm::utostr(ManglingNumber));
4143 Mangler.mangle(VD,
"");
4146void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4147 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
4148 msvc_hashing_ostream MHO(Out);
4149 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4151 Mangler.getStream() <<
"?";
4152 Mangler.mangleSourceName(
"$TSS" + llvm::utostr(GuardNum));
4153 Mangler.mangleNestedName(VD);
4154 Mangler.getStream() <<
"@4HA";
4157void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
4169 msvc_hashing_ostream MHO(Out);
4170 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4174 Mangler.getStream() << (VD->
getTLSKind() ?
"??__J" :
"??_B");
4176 Mangler.getStream() <<
"?$S1@";
4178 unsigned ScopeDepth = 0;
4179 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4183 Mangler.mangle(VD,
"");
4185 Mangler.mangleNestedName(VD);
4186 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
4188 Mangler.mangleNumber(ScopeDepth);
4191void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *
D,
4194 msvc_hashing_ostream MHO(Out);
4195 MicrosoftCXXNameMangler Mangler(*
this, MHO);
4196 Mangler.getStream() <<
"??__" << CharCode;
4197 if (
D->isStaticDataMember()) {
4198 Mangler.getStream() <<
'?';
4199 Mangler.mangleName(
D);
4200 Mangler.mangleVariableEncoding(
D);
4201 Mangler.getStream() <<
"@@";
4203 Mangler.mangleName(
D);
4207 Mangler.getStream() <<
"YAXXZ";
4210void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *
D,
4213 mangleInitFiniStub(
D,
'E', Out);
4217MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *
D,
4220 mangleInitFiniStub(
D,
'F', Out);
4223void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
4244 MicrosoftCXXNameMangler Mangler(*
this, Out);
4245 Mangler.getStream() <<
"??_C@_";
4253 unsigned StringLength =
4254 getASTContext().getAsConstantArrayType(SL->
getType())->getZExtSize();
4259 Mangler.getStream() <<
'1';
4261 Mangler.getStream() <<
'0';
4265 Mangler.mangleNumber(StringByteLength);
4267 auto GetLittleEndianByte = [&SL](
unsigned Index) {
4269 if (Index / CharByteWidth >= SL->
getLength())
4270 return static_cast<char>(0);
4272 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4273 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4276 auto GetBigEndianByte = [&SL](
unsigned Index) {
4278 if (Index / CharByteWidth >= SL->
getLength())
4279 return static_cast<char>(0);
4281 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4282 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4287 for (
unsigned I = 0,
E = StringByteLength; I !=
E; ++I)
4288 JC.update(GetLittleEndianByte(I));
4292 Mangler.mangleNumber(JC.getCRC());
4298 auto MangleByte = [&Mangler](
char Byte) {
4306 Mangler.getStream() << Byte;
4307 }
else if (
isLetter(Byte & 0x7f)) {
4308 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
4310 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
4311 ' ',
'\n',
'\t',
'\'',
'-'};
4312 const char *Pos = llvm::find(SpecialChars, Byte);
4313 if (Pos != std::end(SpecialChars)) {
4314 Mangler.getStream() <<
'?' << (Pos - std::begin(SpecialChars));
4316 Mangler.getStream() <<
"?$";
4317 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
4318 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
4324 unsigned MaxBytesToMangle = SL->
isWide() ? 64U : 32U;
4325 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4326 for (
unsigned I = 0; I != NumBytesToMangle; ++I) {
4328 MangleByte(GetBigEndianByte(I));
4330 MangleByte(GetLittleEndianByte(I));
4333 Mangler.getStream() <<
'@';
4339 manglePointerCVQualifiers(Quals);
4340 manglePointerExtQualifiers(Quals, PointeeType);
4344 mangleFunctionType(FPT,
nullptr,
true);
4348 mangleAutoReturnType(PointeeType, QMM_Drop);
4352void MicrosoftCXXNameMangler::mangleAutoReturnType(
const PointerType *
T,
4356 "Unexpected address space mangling required");
4358 manglePointerCVQualifiers(Quals);
4359 manglePointerExtQualifiers(Quals, PointeeType);
4363 mangleFunctionType(FPT);
4365 mangleAutoReturnType(PointeeType, QMM_Mangle);
4374 manglePointerExtQualifiers(Quals, PointeeType);
4375 mangleAutoReturnType(PointeeType, QMM_Mangle);
4383 manglePointerExtQualifiers(Quals, PointeeType);
4384 mangleAutoReturnType(PointeeType, QMM_Mangle);
4390 return new MicrosoftMangleContextImpl(Context, Diags, IsAux);
Enums/classes describing ABI related information about constructors, destructors and thunks.
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
llvm::MachO::Record Record
static GlobalDecl isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs)
static ValueDecl * getAsArrayToPointerDecayedDecl(QualType T, const APValue &V)
If value V (with type T) represents a decayed pointer to the first element of an array,...
static void mangleThunkThisAdjustment(AccessSpecifier AS, const ThisAdjustment &Adjustment, MicrosoftCXXNameMangler &Mangler, raw_ostream &Out)
Defines the SourceManager interface.
A non-discriminated union of a base, field, or array index.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
unsigned getManglingNumber(const NamedDecl *ND, bool ForAuxTarget=false) const
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
const LangOptions & getLangOpts() const
bool addressSpaceMapManglingFor(LangAS AS) const
const clang::PrintingPolicy & getPrintingPolicy() const
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
unsigned getTargetAddressSpace(LangAS AS) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
A fixed int type of a specified bitwidth.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
This class is used for builtin types like 'int'.
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Represents a C++ struct/union/class.
Decl * getLambdaContextDecl() const
Retrieve the declaration that provides additional context for a lambda, when the normal declaration c...
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(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
Represents a type template specialization; the template must be a class template, a type alias templa...
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
The base class of the type hierarchy.
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::@193 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...