29 #include "llvm/ADT/StringExtras.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/JamCRC.h"
33 using namespace clang;
49 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
50 return ContextParam->getDeclContext();
54 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
56 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
57 return ContextParam->getDeclContext();
62 return getEffectiveDeclContext(CD);
68 return getEffectiveDeclContext(cast<Decl>(DC));
72 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
73 return FTD->getTemplatedDecl();
75 const auto *FD = cast<FunctionDecl>(ND);
76 if (
const auto *FTD = FD->getPrimaryTemplate())
77 return FTD->getTemplatedDecl();
82 static bool isLambda(
const NamedDecl *ND) {
93 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
94 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
95 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
96 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
97 llvm::DenseMap<const NamedDecl *, unsigned> SEHFilterIds;
98 llvm::DenseMap<const NamedDecl *, unsigned> SEHFinallyIds;
103 bool shouldMangleCXXName(
const NamedDecl *D)
override;
104 bool shouldMangleStringLiteral(
const StringLiteral *SL)
override;
105 void mangleCXXName(
const NamedDecl *D, raw_ostream &Out)
override;
107 raw_ostream &)
override;
109 raw_ostream &)
override;
112 raw_ostream &)
override;
115 raw_ostream &Out)
override;
118 raw_ostream &Out)
override;
119 void mangleCXXVirtualDisplacementMap(
const CXXRecordDecl *SrcRD,
121 raw_ostream &Out)
override;
122 void mangleCXXThrowInfo(
QualType T,
bool IsConst,
bool IsVolatile,
123 uint32_t NumEntries, raw_ostream &Out)
override;
124 void mangleCXXCatchableTypeArray(
QualType T, uint32_t NumEntries,
125 raw_ostream &Out)
override;
128 int32_t VBPtrOffset, uint32_t VBIndex,
129 raw_ostream &Out)
override;
130 void mangleCXXRTTI(
QualType T, raw_ostream &Out)
override;
131 void mangleCXXRTTIName(
QualType T, raw_ostream &Out)
override;
132 void mangleCXXRTTIBaseClassDescriptor(
const CXXRecordDecl *Derived,
133 uint32_t NVOffset, int32_t VBPtrOffset,
134 uint32_t VBTableOffset, uint32_t Flags,
135 raw_ostream &Out)
override;
136 void mangleCXXRTTIBaseClassArray(
const CXXRecordDecl *Derived,
137 raw_ostream &Out)
override;
138 void mangleCXXRTTIClassHierarchyDescriptor(
const CXXRecordDecl *Derived,
139 raw_ostream &Out)
override;
141 mangleCXXRTTICompleteObjectLocator(
const CXXRecordDecl *Derived,
143 raw_ostream &Out)
override;
144 void mangleTypeName(
QualType T, raw_ostream &)
override;
146 raw_ostream &)
override;
148 raw_ostream &)
override;
149 void mangleReferenceTemporary(
const VarDecl *,
unsigned ManglingNumber,
150 raw_ostream &)
override;
151 void mangleStaticGuardVariable(
const VarDecl *D, raw_ostream &Out)
override;
152 void mangleThreadSafeStaticGuardVariable(
const VarDecl *D,
unsigned GuardNum,
153 raw_ostream &Out)
override;
154 void mangleDynamicInitializer(
const VarDecl *D, raw_ostream &Out)
override;
155 void mangleDynamicAtExitDestructor(
const VarDecl *D,
156 raw_ostream &Out)
override;
157 void mangleSEHFilterExpression(
const NamedDecl *EnclosingDecl,
158 raw_ostream &Out)
override;
159 void mangleSEHFinallyBlock(
const NamedDecl *EnclosingDecl,
160 raw_ostream &Out)
override;
161 void mangleStringLiteral(
const StringLiteral *SL, raw_ostream &Out)
override;
162 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
167 const DeclContext *DC = getEffectiveDeclContext(ND);
173 disc = getASTContext().getManglingNumber(ND);
178 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
179 if (!Tag->hasNameForLinkage() &&
180 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
181 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))
186 unsigned &discriminator = Uniquifier[ND];
188 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
189 disc = discriminator + 1;
194 assert(RD->
isLambda() &&
"RD must be a lambda!");
197 "RD must not have a mangling number!");
199 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
200 return Result.first->second;
204 void mangleInitFiniStub(
const VarDecl *D, raw_ostream &Out,
char CharCode);
209 class MicrosoftCXXNameMangler {
210 MicrosoftMangleContextImpl &
Context;
220 BackRefVec NameBackReferences;
222 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
223 ArgBackRefMap TypeBackReferences;
225 typedef std::set<int> PassObjectSizeArgsSet;
226 PassObjectSizeArgsSet PassObjectSizeArgs;
232 const bool PointersAre64Bit;
235 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
237 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_)
239 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
242 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
245 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
248 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &
C, raw_ostream &Out_,
251 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
254 raw_ostream &getStream()
const {
return Out; }
256 void mangle(
const NamedDecl *D, StringRef Prefix =
"\01?");
258 void mangleFunctionEncoding(
const FunctionDecl *FD,
bool ShouldMangle);
259 void mangleVariableEncoding(
const VarDecl *VD);
263 void mangleVirtualMemPtrThunk(
266 void mangleNumber(int64_t Number);
268 void mangleArtificalTagType(
TagTypeKind TK, StringRef UnqualifiedName,
271 QualifierMangleMode QMM = QMM_Mangle);
274 bool ForceThisQuals =
false);
275 void mangleNestedName(
const NamedDecl *ND);
278 void mangleUnqualifiedName(
const NamedDecl *ND) {
282 void mangleSourceName(StringRef
Name);
285 void mangleQualifiers(
Qualifiers Quals,
bool IsMember);
287 void manglePointerCVQualifiers(
Qualifiers Quals);
290 void mangleUnscopedTemplateName(
const TemplateDecl *ND);
297 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
300 #define ABSTRACT_TYPE(CLASS, PARENT)
301 #define NON_CANONICAL_TYPE(CLASS, PARENT)
302 #define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
305 #include "clang/AST/TypeNodes.def"
307 #undef NON_CANONICAL_TYPE
310 void mangleType(
const TagDecl *TD);
311 void mangleDecayedArrayType(
const ArrayType *T);
312 void mangleArrayType(
const ArrayType *T);
316 void mangleIntegerLiteral(
const llvm::APSInt &Number,
bool IsBoolean);
317 void mangleExpression(
const Expr *
E);
327 bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *D) {
328 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
331 if (FD->hasAttr<OverloadableAttr>())
343 if (FD->isMSVCRTEntryPoint())
357 if (!getASTContext().getLangOpts().CPlusPlus)
360 if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
366 const DeclContext *DC = getEffectiveDeclContext(D);
370 DC = getEffectiveParentContext(DC);
373 !isa<VarTemplateSpecializationDecl>(D) &&
382 MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
386 void MicrosoftCXXNameMangler::mangle(
const NamedDecl *D, StringRef Prefix) {
397 mangleFunctionEncoding(FD,
Context.shouldMangleDeclName(FD));
398 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
399 mangleVariableEncoding(VD);
401 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
404 void MicrosoftCXXNameMangler::mangleFunctionEncoding(
const FunctionDecl *FD,
428 mangleFunctionClass(FD);
430 mangleFunctionType(FT, FD);
436 void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
467 mangleType(Ty, SR, QMM_Drop);
468 manglePointerExtQualifiers(
471 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
474 mangleName(MPT->getClass()->getAsCXXRecordDecl());
477 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
479 mangleDecayedArrayType(AT);
480 if (AT->getElementType()->isArrayType())
485 mangleType(Ty, SR, QMM_Drop);
490 void MicrosoftCXXNameMangler::mangleMemberDataPointer(
const CXXRecordDecl *RD,
497 int64_t VBTableOffset;
500 FieldOffset = getASTContext().getFieldOffset(VD);
501 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
502 "cannot take address of bitfield");
503 FieldOffset /= getASTContext().getCharWidth();
507 if (IM == MSInheritanceAttr::Keyword_virtual_inheritance)
508 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
517 case MSInheritanceAttr::Keyword_single_inheritance: Code =
'0';
break;
518 case MSInheritanceAttr::Keyword_multiple_inheritance: Code =
'0';
break;
519 case MSInheritanceAttr::Keyword_virtual_inheritance: Code =
'F';
break;
520 case MSInheritanceAttr::Keyword_unspecified_inheritance: Code =
'G';
break;
525 mangleNumber(FieldOffset);
530 if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
532 if (MSInheritanceAttr::hasVBTableOffsetField(IM))
533 mangleNumber(VBTableOffset);
537 MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
const CXXRecordDecl *RD,
548 case MSInheritanceAttr::Keyword_single_inheritance: Code =
'1';
break;
549 case MSInheritanceAttr::Keyword_multiple_inheritance: Code =
'H';
break;
550 case MSInheritanceAttr::Keyword_virtual_inheritance: Code =
'I';
break;
551 case MSInheritanceAttr::Keyword_unspecified_inheritance: Code =
'J';
break;
556 uint64_t NVOffset = 0;
557 uint64_t VBTableOffset = 0;
558 uint64_t VBPtrOffset = 0;
560 Out <<
'$' << Code <<
'?';
563 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
566 mangleVirtualMemPtrThunk(MD, ML);
567 NVOffset = ML.VFPtrOffset.getQuantity();
568 VBTableOffset = ML.VBTableIndex * 4;
570 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
575 mangleFunctionEncoding(MD,
true);
578 if (VBTableOffset == 0 &&
579 IM == MSInheritanceAttr::Keyword_virtual_inheritance)
580 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
583 if (IM == MSInheritanceAttr::Keyword_single_inheritance) {
587 if (IM == MSInheritanceAttr::Keyword_unspecified_inheritance)
592 if (MSInheritanceAttr::hasNVOffsetField(
true, IM))
593 mangleNumber(static_cast<uint32_t>(NVOffset));
594 if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
595 mangleNumber(VBPtrOffset);
596 if (MSInheritanceAttr::hasVBTableOffsetField(IM))
597 mangleNumber(VBTableOffset);
600 void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
604 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
605 getASTContext().getTargetInfo().getPointerWidth(0));
611 mangleNumber(OffsetInVFTable);
616 void MicrosoftCXXNameMangler::mangleName(
const NamedDecl *ND) {
620 mangleUnqualifiedName(ND);
622 mangleNestedName(ND);
628 void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
635 uint64_t
Value =
static_cast<uint64_t
>(Number);
643 else if (Value >= 1 && Value <= 10)
649 char EncodedNumberBuffer[
sizeof(uint64_t) * 2];
652 for (; Value != 0; Value >>= 4)
653 *I++ =
'A' + (Value & 0xf);
654 Out.write(I.base(), I - BufferRef.rbegin());
662 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
671 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
672 TemplateArgs = &Spec->getTemplateArgs();
673 return Spec->getSpecializedTemplate();
678 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
679 TemplateArgs = &Spec->getTemplateArgs();
680 return Spec->getSpecializedTemplate();
686 void MicrosoftCXXNameMangler::mangleUnqualifiedName(
const NamedDecl *ND,
699 if (isa<FunctionTemplateDecl>(TD)) {
700 mangleTemplateInstantiationName(TD, *TemplateArgs);
721 llvm::raw_svector_ostream Stream(TemplateMangling);
722 MicrosoftCXXNameMangler Extra(
Context, Stream);
723 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
725 mangleSourceName(TemplateMangling);
732 mangleSourceName(II->getName());
737 assert(ND &&
"mangling empty name without declaration");
740 if (NS->isAnonymousNamespace()) {
746 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
749 assert(RD &&
"expected variable decl to have a record type");
755 Name += llvm::utostr(
Context.getAnonymousStructId(RD) + 1);
756 mangleSourceName(Name.str());
761 const TagDecl *TD = cast<TagDecl>(ND);
764 "Typedef should not be in another decl context!");
766 "Typedef was not named!");
771 if (
const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
778 LambdaId =
Context.getLambdaId(Record);
780 Name += llvm::utostr(LambdaId);
783 mangleSourceName(Name);
793 Name += DD->getName();
799 Name += TND->getName();
803 Name += llvm::utostr(
Context.getAnonymousStructId(TD) + 1);
806 mangleSourceName(Name.str());
813 llvm_unreachable(
"Can't mangle Objective-C selector names here!");
816 if (Structor == getStructor(ND)) {
833 mangleCXXDtorType(static_cast<CXXDtorType>(
StructorType));
857 llvm_unreachable(
"Can't mangle a using directive name!");
861 void MicrosoftCXXNameMangler::mangleNestedName(
const NamedDecl *ND) {
864 const DeclContext *DC = getEffectiveDeclContext(ND);
867 if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
869 if (
Context.getNextDiscriminator(ND, Disc)) {
876 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
880 "cannot mangle a local inside this block yet");
881 Diags.
Report(BD->getLocation(), DiagID);
885 Out <<
"__block_invoke" <<
Context.getBlockId(BD,
false);
888 }
else if (
const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
889 mangleObjCMethodName(Method);
890 }
else if (isa<NamedDecl>(DC)) {
891 ND = cast<NamedDecl>(DC);
892 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
896 mangleUnqualifiedName(ND);
902 void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
917 llvm_unreachable(
"not expecting a COMDAT");
919 llvm_unreachable(
"Unsupported dtor type?");
928 case OO_New: Out <<
"?2";
break;
930 case OO_Delete: Out <<
"?3";
break;
932 case OO_Equal: Out <<
"?4";
break;
934 case OO_GreaterGreater: Out <<
"?5";
break;
936 case OO_LessLess: Out <<
"?6";
break;
938 case OO_Exclaim: Out <<
"?7";
break;
940 case OO_EqualEqual: Out <<
"?8";
break;
942 case OO_ExclaimEqual: Out <<
"?9";
break;
944 case OO_Subscript: Out <<
"?A";
break;
947 case OO_Arrow: Out <<
"?C";
break;
949 case OO_Star: Out <<
"?D";
break;
951 case OO_PlusPlus: Out <<
"?E";
break;
953 case OO_MinusMinus: Out <<
"?F";
break;
955 case OO_Minus: Out <<
"?G";
break;
957 case OO_Plus: Out <<
"?H";
break;
959 case OO_Amp: Out <<
"?I";
break;
961 case OO_ArrowStar: Out <<
"?J";
break;
963 case OO_Slash: Out <<
"?K";
break;
965 case OO_Percent: Out <<
"?L";
break;
967 case OO_Less: Out <<
"?M";
break;
969 case OO_LessEqual: Out <<
"?N";
break;
971 case OO_Greater: Out <<
"?O";
break;
973 case OO_GreaterEqual: Out <<
"?P";
break;
975 case OO_Comma: Out <<
"?Q";
break;
977 case OO_Call: Out <<
"?R";
break;
979 case OO_Tilde: Out <<
"?S";
break;
981 case OO_Caret: Out <<
"?T";
break;
983 case OO_Pipe: Out <<
"?U";
break;
985 case OO_AmpAmp: Out <<
"?V";
break;
987 case OO_PipePipe: Out <<
"?W";
break;
989 case OO_StarEqual: Out <<
"?X";
break;
991 case OO_PlusEqual: Out <<
"?Y";
break;
993 case OO_MinusEqual: Out <<
"?Z";
break;
995 case OO_SlashEqual: Out <<
"?_0";
break;
997 case OO_PercentEqual: Out <<
"?_1";
break;
999 case OO_GreaterGreaterEqual: Out <<
"?_2";
break;
1001 case OO_LessLessEqual: Out <<
"?_3";
break;
1003 case OO_AmpEqual: Out <<
"?_4";
break;
1005 case OO_PipeEqual: Out <<
"?_5";
break;
1007 case OO_CaretEqual: Out <<
"?_6";
break;
1036 case OO_Array_New: Out <<
"?_U";
break;
1038 case OO_Array_Delete: Out <<
"?_V";
break;
1040 case OO_Conditional: {
1043 "cannot mangle this conditional operator yet");
1044 Diags.
Report(Loc, DiagID);
1051 "cannot mangle this operator co_await yet");
1052 Diags.
Report(Loc, DiagID);
1058 llvm_unreachable(
"Not an overloaded operator");
1062 void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1065 std::find(NameBackReferences.begin(), NameBackReferences.end(),
Name);
1066 if (Found == NameBackReferences.end()) {
1067 if (NameBackReferences.size() < 10)
1068 NameBackReferences.push_back(Name);
1071 Out << (Found - NameBackReferences.begin());
1075 void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1076 Context.mangleObjCMethodName(MD, Out);
1079 void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1086 ArgBackRefMap OuterArgsContext;
1087 BackRefVec OuterTemplateContext;
1088 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1089 NameBackReferences.swap(OuterTemplateContext);
1090 TypeBackReferences.swap(OuterArgsContext);
1091 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1093 mangleUnscopedTemplateName(TD);
1094 mangleTemplateArgs(TD, TemplateArgs);
1097 NameBackReferences.swap(OuterTemplateContext);
1098 TypeBackReferences.swap(OuterArgsContext);
1099 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1103 MicrosoftCXXNameMangler::mangleUnscopedTemplateName(
const TemplateDecl *TD) {
1106 mangleUnqualifiedName(TD);
1109 void MicrosoftCXXNameMangler::mangleIntegerLiteral(
const llvm::APSInt &Value,
1114 if (IsBoolean && Value.getBoolValue())
1116 else if (Value.isSigned())
1117 mangleNumber(Value.getSExtValue());
1119 mangleNumber(Value.getZExtValue());
1122 void MicrosoftCXXNameMangler::mangleExpression(
const Expr *
E) {
1136 UE = dyn_cast<CXXUuidofExpr>(UO->getSubExpr());
1154 std::string Name =
"_GUID_" + Uuid.lower();
1155 std::replace(Name.begin(), Name.end(),
'-',
'_');
1157 mangleSourceName(Name);
1163 mangleArtificalTagType(
TTK_Struct,
"__s_GUID");
1174 << E->getSourceRange();
1177 void MicrosoftCXXNameMangler::mangleTemplateArgs(
1181 assert(TPL->
size() == TemplateArgs.
size() &&
1182 "size mismatch between args and parms!");
1186 mangleTemplateArg(TD, TA, TPL->
getParam(Idx++));
1189 void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1203 llvm_unreachable(
"Can't mangle null template arguments!");
1205 llvm_unreachable(
"Can't mangle template expansion arguments!");
1213 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1214 mangleMemberDataPointer(
1216 cast<ValueDecl>(ND));
1217 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1224 mangleFunctionEncoding(FD,
true);
1238 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1239 if (MPT->isMemberFunctionPointerType() &&
1240 !isa<FunctionTemplateDecl>(TD)) {
1241 mangleMemberFunctionPointer(RD,
nullptr);
1244 if (MPT->isMemberDataPointer()) {
1245 if (!isa<FunctionTemplateDecl>(TD)) {
1246 mangleMemberDataPointer(RD,
nullptr);
1256 mangleIntegerLiteral(llvm::APSInt::get(-1),
false);
1261 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
false);
1269 if (TemplateArgs.empty()) {
1270 if (isa<TemplateTypeParmDecl>(Parm) ||
1271 isa<TemplateTemplateParmDecl>(Parm))
1278 else if (isa<NonTypeTemplateParmDecl>(Parm))
1281 llvm_unreachable(
"unexpected template parameter decl!");
1284 mangleTemplateArg(TD, PA, Parm);
1291 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1293 }
else if (isa<TypeAliasDecl>(ND)) {
1297 llvm_unreachable(
"unexpected template template NamedDecl!");
1304 void MicrosoftCXXNameMangler::mangleQualifiers(
Qualifiers Quals,
1362 if (HasConst && HasVolatile) {
1364 }
else if (HasVolatile) {
1366 }
else if (HasConst) {
1372 if (HasConst && HasVolatile) {
1374 }
else if (HasVolatile) {
1376 }
else if (HasConst) {
1387 MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
1390 switch (RefQualifier) {
1404 void MicrosoftCXXNameMangler::manglePointerExtQualifiers(
Qualifiers Quals,
1407 if (PointersAre64Bit &&
1415 void MicrosoftCXXNameMangler::manglePointerCVQualifiers(
Qualifiers Quals) {
1423 if (HasConst && HasVolatile) {
1425 }
else if (HasVolatile) {
1427 }
else if (HasConst) {
1434 void MicrosoftCXXNameMangler::mangleArgumentType(
QualType T,
1445 QualType OriginalType = DT->getOriginalType();
1448 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
1449 OriginalType = getASTContext().getIncompleteArrayType(
1450 AT->getElementType(), AT->getSizeModifier(),
1451 AT->getIndexTypeCVRQualifiers());
1467 if (Found == TypeBackReferences.end()) {
1468 size_t OutSizeBefore = Out.tell();
1470 mangleType(T, Range, QMM_Drop);
1475 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);
1476 if (LongerThanOneChar && TypeBackReferences.size() < 10) {
1477 size_t Size = TypeBackReferences.size();
1478 TypeBackReferences[TypePtr] = Size;
1481 Out << Found->second;
1485 void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
1486 const PassObjectSizeAttr *POSA) {
1487 int Type = POSA->getType();
1489 auto Iter = PassObjectSizeArgs.insert(Type).first;
1490 auto *TypePtr = (
const void *)&*Iter;
1493 if (Found == TypeBackReferences.end()) {
1494 mangleArtificalTagType(
TTK_Enum,
"__pass_object_size" + llvm::utostr(Type),
1497 if (TypeBackReferences.size() < 10) {
1498 size_t Size = TypeBackReferences.size();
1499 TypeBackReferences[TypePtr] = Size;
1502 Out << Found->second;
1507 QualifierMangleMode QMM) {
1512 if (
const ArrayType *AT = getASTContext().getAsArrayType(T)) {
1515 if (QMM == QMM_Mangle)
1517 else if (QMM == QMM_Escape || QMM == QMM_Result)
1519 mangleArrayType(AT);
1530 if (
const FunctionType *FT = dyn_cast<FunctionType>(T)) {
1532 mangleFunctionType(FT);
1535 mangleQualifiers(Quals,
false);
1538 if (!IsPointer && Quals) {
1540 mangleQualifiers(Quals,
false);
1544 if ((!IsPointer && Quals) || isa<TagType>(T)) {
1546 mangleQualifiers(Quals,
false);
1554 #define ABSTRACT_TYPE(CLASS, PARENT)
1555 #define NON_CANONICAL_TYPE(CLASS, PARENT) \
1557 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
1559 #define TYPE(CLASS, PARENT) \
1561 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
1563 #include "clang/AST/TypeNodes.def"
1564 #undef ABSTRACT_TYPE
1565 #undef NON_CANONICAL_TYPE
1597 case BuiltinType::Void:
1600 case BuiltinType::SChar:
1603 case BuiltinType::Char_U:
1604 case BuiltinType::Char_S:
1607 case BuiltinType::UChar:
1610 case BuiltinType::Short:
1613 case BuiltinType::UShort:
1616 case BuiltinType::Int:
1619 case BuiltinType::UInt:
1622 case BuiltinType::Long:
1625 case BuiltinType::ULong:
1628 case BuiltinType::Float:
1631 case BuiltinType::Double:
1635 case BuiltinType::LongDouble:
1638 case BuiltinType::LongLong:
1641 case BuiltinType::ULongLong:
1644 case BuiltinType::Int128:
1647 case BuiltinType::UInt128:
1650 case BuiltinType::Bool:
1653 case BuiltinType::Char16:
1656 case BuiltinType::Char32:
1659 case BuiltinType::WChar_S:
1660 case BuiltinType::WChar_U:
1664 #define BUILTIN_TYPE(Id, SingletonId)
1665 #define PLACEHOLDER_TYPE(Id, SingletonId) \
1666 case BuiltinType::Id:
1667 #include "clang/AST/BuiltinTypes.def"
1668 case BuiltinType::Dependent:
1669 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
1671 case BuiltinType::ObjCId:
1673 mangleArtificalTagType(
TTK_Struct,
"objc_object");
1675 case BuiltinType::ObjCClass:
1677 mangleArtificalTagType(
TTK_Struct,
"objc_class");
1679 case BuiltinType::ObjCSel:
1681 mangleArtificalTagType(
TTK_Struct,
"objc_selector");
1684 case BuiltinType::OCLImage1d:
1686 mangleArtificalTagType(
TTK_Struct,
"ocl_image1d");
1688 case BuiltinType::OCLImage1dArray:
1690 mangleArtificalTagType(
TTK_Struct,
"ocl_image1darray");
1692 case BuiltinType::OCLImage1dBuffer:
1694 mangleArtificalTagType(
TTK_Struct,
"ocl_image1dbuffer");
1696 case BuiltinType::OCLImage2d:
1698 mangleArtificalTagType(
TTK_Struct,
"ocl_image2d");
1700 case BuiltinType::OCLImage2dArray:
1702 mangleArtificalTagType(
TTK_Struct,
"ocl_image2darray");
1704 case BuiltinType::OCLImage2dDepth:
1706 mangleArtificalTagType(
TTK_Struct,
"ocl_image2ddepth");
1708 case BuiltinType::OCLImage2dArrayDepth:
1710 mangleArtificalTagType(
TTK_Struct,
"ocl_image2darraydepth");
1712 case BuiltinType::OCLImage2dMSAA:
1714 mangleArtificalTagType(
TTK_Struct,
"ocl_image2dmsaa");
1716 case BuiltinType::OCLImage2dArrayMSAA:
1718 mangleArtificalTagType(
TTK_Struct,
"ocl_image2darraymsaa");
1720 case BuiltinType::OCLImage2dMSAADepth:
1722 mangleArtificalTagType(
TTK_Struct,
"ocl_image2dmsaadepth");
1724 case BuiltinType::OCLImage2dArrayMSAADepth:
1726 mangleArtificalTagType(
TTK_Struct,
"ocl_image2darraymsaadepth");
1728 case BuiltinType::OCLImage3d:
1730 mangleArtificalTagType(
TTK_Struct,
"ocl_image3d");
1732 case BuiltinType::OCLSampler:
1734 mangleArtificalTagType(
TTK_Struct,
"ocl_sampler");
1736 case BuiltinType::OCLEvent:
1738 mangleArtificalTagType(
TTK_Struct,
"ocl_event");
1740 case BuiltinType::OCLClkEvent:
1742 mangleArtificalTagType(
TTK_Struct,
"ocl_clkevent");
1744 case BuiltinType::OCLQueue:
1746 mangleArtificalTagType(
TTK_Struct,
"ocl_queue");
1748 case BuiltinType::OCLNDRange:
1750 mangleArtificalTagType(
TTK_Struct,
"ocl_ndrange");
1752 case BuiltinType::OCLReserveID:
1754 mangleArtificalTagType(
TTK_Struct,
"ocl_reserveid");
1757 case BuiltinType::NullPtr:
1761 case BuiltinType::Half: {
1780 mangleFunctionType(T,
nullptr,
true);
1783 mangleFunctionType(T);
1789 mangleFunctionType(T);
1792 void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *T,
1794 bool ForceThisQuals) {
1802 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
1804 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
1806 HasThisQuals =
true;
1807 if (isa<CXXDestructorDecl>(MD)) {
1809 }
else if (isa<CXXConstructorDecl>(MD)) {
1813 getStructor(MD) == Structor;
1815 CC = getASTContext().getDefaultCallingConvention(
1824 manglePointerExtQualifiers(Quals,
QualType());
1826 mangleQualifiers(Quals,
false);
1829 mangleCallingConvention(CC);
1834 if (isa<CXXDestructorDecl>(D) && D == Structor &&
1840 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
1843 if (IsCtorClosure) {
1853 mangleArgumentType(getASTContext().getLValueReferenceType(
1861 llvm_unreachable(
"unexpected constructor closure!");
1869 if (
const auto *AT =
1875 "shouldn't need to mangle __auto_type!");
1876 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
1881 mangleType(ResultType, Range, QMM_Result);
1909 manglePassObjectSizeArg(
P);
1918 mangleThrowSpecification(Proto);
1921 void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
1946 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
1949 llvm_unreachable(
"Unsupported access specifier");
1978 void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC) {
1998 llvm_unreachable(
"Unsupported CC for mangling");
2001 case CC_C: Out <<
'A';
break;
2009 void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *T) {
2012 void MicrosoftCXXNameMangler::mangleThrowSpecification(
2029 "cannot mangle this unresolved dependent type yet");
2039 void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
2058 mangleType(cast<TagType>(T)->getDecl());
2062 mangleType(cast<TagType>(T)->getDecl());
2064 void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
2068 void MicrosoftCXXNameMangler::mangleArtificalTagType(
2071 mangleTagTypeKind(TK);
2074 mangleSourceName(UnqualifiedName);
2076 for (
auto I = NestedNames.rbegin(), E = NestedNames.rend(); I !=
E; ++
I)
2077 mangleSourceName(*I);
2090 void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *T) {
2098 llvm_unreachable(
"Should have been special cased");
2102 llvm_unreachable(
"Should have been special cased");
2106 llvm_unreachable(
"Should have been special cased");
2110 llvm_unreachable(
"Should have been special cased");
2112 void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *T) {
2116 if (ElementTy->isConstantArrayType()) {
2118 getASTContext().getAsConstantArrayType(ElementTy);
2119 Dimensions.push_back(CAT->
getSize());
2121 }
else if (ElementTy->isIncompleteArrayType()) {
2123 getASTContext().getAsIncompleteArrayType(ElementTy);
2124 Dimensions.push_back(llvm::APInt(32, 0));
2126 }
else if (ElementTy->isVariableArrayType()) {
2128 getASTContext().getAsVariableArrayType(ElementTy);
2129 Dimensions.push_back(llvm::APInt(32, 0));
2131 }
else if (ElementTy->isDependentSizedArrayType()) {
2134 getASTContext().getAsDependentSizedArrayType(ElementTy);
2137 "cannot mangle this dependent-length array yet");
2147 mangleNumber(Dimensions.size());
2148 for (
const llvm::APInt &Dimension : Dimensions)
2149 mangleNumber(Dimension.getLimitedValue());
2159 manglePointerCVQualifiers(Quals);
2160 manglePointerExtQualifiers(Quals, PointeeType);
2164 mangleFunctionType(FPT,
nullptr,
true);
2168 mangleType(PointeeType, Range, QMM_Drop);
2176 "cannot mangle this template type parameter type yet");
2185 "cannot mangle this substituted parameter pack yet");
2196 manglePointerCVQualifiers(Quals);
2197 manglePointerExtQualifiers(Quals, PointeeType);
2198 mangleType(PointeeType, Range);
2203 manglePointerCVQualifiers(Quals);
2204 manglePointerExtQualifiers(Quals, PointeeType);
2207 mangleType(PointeeType, Range);
2218 manglePointerExtQualifiers(Quals, PointeeType);
2219 mangleType(PointeeType, Range);
2230 manglePointerExtQualifiers(Quals, PointeeType);
2231 mangleType(PointeeType, Range);
2239 llvm::raw_svector_ostream Stream(TemplateMangling);
2240 MicrosoftCXXNameMangler Extra(
Context, Stream);
2242 Extra.mangleSourceName(
"_Complex");
2243 Extra.mangleType(ElementType, Range, QMM_Escape);
2245 mangleArtificalTagType(
TTK_Struct, TemplateMangling, {
"__clang"});
2251 assert(ET &&
"vectors with non-builtin elements are unsupported");
2252 uint64_t Width = getASTContext().getTypeSize(T);
2255 size_t OutSizeBefore = Out.tell();
2256 llvm::Triple::ArchType AT =
2257 getASTContext().getTargetInfo().getTriple().getArch();
2258 if (AT == llvm::Triple::x86 || AT == llvm::Triple::x86_64) {
2259 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
2260 mangleArtificalTagType(
TTK_Union,
"__m64");
2261 }
else if (Width >= 128) {
2262 if (ET->
getKind() == BuiltinType::Float)
2263 mangleArtificalTagType(
TTK_Union,
"__m" + llvm::utostr(Width));
2264 else if (ET->
getKind() == BuiltinType::LongLong)
2265 mangleArtificalTagType(
TTK_Union,
"__m" + llvm::utostr(Width) +
'i');
2266 else if (ET->
getKind() == BuiltinType::Double)
2267 mangleArtificalTagType(
TTK_Struct,
"__m" + llvm::utostr(Width) +
'd');
2271 bool IsBuiltin = Out.tell() != OutSizeBefore;
2278 llvm::raw_svector_ostream Stream(TemplateMangling);
2279 MicrosoftCXXNameMangler Extra(
Context, Stream);
2281 Extra.mangleSourceName(
"__vector");
2282 Extra.mangleType(
QualType(ET, 0), Range, QMM_Escape);
2283 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->
getNumElements()),
2286 mangleArtificalTagType(
TTK_Union, TemplateMangling, {
"__clang"});
2290 void MicrosoftCXXNameMangler::mangleType(
const ExtVectorType *T,
2292 mangleType(static_cast<const VectorType *>(T), Quals, Range);
2298 "cannot mangle this dependent-sized extended vector type yet");
2320 manglePointerCVQualifiers(Quals);
2321 manglePointerExtQualifiers(Quals, PointeeType);
2330 llvm_unreachable(
"Cannot mangle injected class name type.");
2337 "cannot mangle this template specialization type yet");
2346 "cannot mangle this dependent name type yet");
2351 void MicrosoftCXXNameMangler::mangleType(
2356 "cannot mangle this dependent template specialization type yet");
2365 "cannot mangle this pack expansion yet");
2374 "cannot mangle this typeof(type) yet");
2383 "cannot mangle this typeof(expression) yet");
2392 "cannot mangle this decltype() yet");
2401 "cannot mangle this unary transform type yet");
2412 "cannot mangle this 'auto' type yet");
2413 Diags.Report(Range.
getBegin(), DiagID)
2422 llvm::raw_svector_ostream Stream(TemplateMangling);
2423 MicrosoftCXXNameMangler Extra(
Context, Stream);
2425 Extra.mangleSourceName(
"_Atomic");
2426 Extra.mangleType(ValueType, Range, QMM_Escape);
2428 mangleArtificalTagType(
TTK_Struct, TemplateMangling, {
"__clang"});
2435 "cannot mangle this OpenCL pipe type yet");
2440 void MicrosoftMangleContextImpl::mangleCXXName(
const NamedDecl *D,
2442 assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
2443 "Invalid mangleName() call, argument is not a variable or function!");
2444 assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
2445 "Invalid mangleName() call on 'structor decl!");
2448 getASTContext().getSourceManager(),
2449 "Mangling declaration");
2451 MicrosoftCXXNameMangler Mangler(*
this, Out);
2452 return Mangler.mangle(D);
2481 MicrosoftCXXNameMangler &Mangler,
2488 llvm_unreachable(
"Unsupported access specifier");
2499 Out <<
'R' << AccessSpec;
2500 Mangler.mangleNumber(
2502 Mangler.mangleNumber(
2504 Mangler.mangleNumber(
2506 Mangler.mangleNumber(static_cast<uint32_t>(Adjustment.
NonVirtual));
2509 Mangler.mangleNumber(
2511 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.
NonVirtual));
2516 llvm_unreachable(
"Unsupported access specifier");
2526 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.
NonVirtual));
2530 llvm_unreachable(
"Unsupported access specifier");
2544 MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
2547 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
2551 MicrosoftCXXNameMangler Mangler(*
this, Out);
2552 Mangler.getStream() <<
"\01?";
2553 Mangler.mangleVirtualMemPtrThunk(MD, ML);
2556 void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
2559 MicrosoftCXXNameMangler Mangler(*
this, Out);
2561 Mangler.mangleName(MD);
2564 assert(Thunk.
Method !=
nullptr &&
2565 "Thunk info should hold the overridee decl");
2568 Mangler.mangleFunctionType(
2572 void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
2579 MicrosoftCXXNameMangler Mangler(*
this, Out, DD, Type);
2586 void MicrosoftMangleContextImpl::mangleCXXVFTable(
2593 MicrosoftCXXNameMangler Mangler(*
this, Out);
2594 Mangler.getStream() <<
"\01??_7";
2595 Mangler.mangleName(Derived);
2596 Mangler.getStream() <<
"6B";
2598 Mangler.mangleName(RD);
2599 Mangler.getStream() <<
'@';
2602 void MicrosoftMangleContextImpl::mangleCXXVBTable(
2609 MicrosoftCXXNameMangler Mangler(*
this, Out);
2610 Mangler.getStream() <<
"\01??_8";
2611 Mangler.mangleName(Derived);
2612 Mangler.getStream() <<
"7B";
2614 Mangler.mangleName(RD);
2615 Mangler.getStream() <<
'@';
2618 void MicrosoftMangleContextImpl::mangleCXXRTTI(
QualType T, raw_ostream &Out) {
2619 MicrosoftCXXNameMangler Mangler(*
this, Out);
2620 Mangler.getStream() <<
"\01??_R0";
2621 Mangler.mangleType(T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
2622 Mangler.getStream() <<
"@8";
2625 void MicrosoftMangleContextImpl::mangleCXXRTTIName(
QualType T,
2627 MicrosoftCXXNameMangler Mangler(*
this, Out);
2628 Mangler.getStream() <<
'.';
2629 Mangler.mangleType(T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
2632 void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
2634 MicrosoftCXXNameMangler Mangler(*
this, Out);
2635 Mangler.getStream() <<
"\01??_K";
2636 Mangler.mangleName(SrcRD);
2637 Mangler.getStream() <<
"$C";
2638 Mangler.mangleName(DstRD);
2641 void MicrosoftMangleContextImpl::mangleCXXThrowInfo(
QualType T,
2644 uint32_t NumEntries,
2646 MicrosoftCXXNameMangler Mangler(*
this, Out);
2647 Mangler.getStream() <<
"_TI";
2649 Mangler.getStream() <<
'C';
2651 Mangler.getStream() <<
'V';
2652 Mangler.getStream() << NumEntries;
2653 Mangler.mangleType(T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
2656 void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
2657 QualType T, uint32_t NumEntries, raw_ostream &Out) {
2658 MicrosoftCXXNameMangler Mangler(*
this, Out);
2659 Mangler.getStream() <<
"_CTA";
2660 Mangler.getStream() << NumEntries;
2661 Mangler.mangleType(T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
2664 void MicrosoftMangleContextImpl::mangleCXXCatchableType(
2666 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
2668 MicrosoftCXXNameMangler Mangler(*
this, Out);
2669 Mangler.getStream() <<
"_CT";
2673 llvm::raw_svector_ostream Stream(RTTIMangling);
2674 mangleCXXRTTI(T, Stream);
2676 Mangler.getStream() << RTTIMangling.substr(1);
2683 llvm::raw_svector_ostream Stream(CopyCtorMangling);
2684 mangleCXXCtor(CD, CT, Stream);
2686 Mangler.getStream() << CopyCtorMangling.substr(1);
2688 Mangler.getStream() << Size;
2689 if (VBPtrOffset == -1) {
2691 Mangler.getStream() << NVOffset;
2694 Mangler.getStream() << NVOffset;
2695 Mangler.getStream() << VBPtrOffset;
2696 Mangler.getStream() << VBIndex;
2700 void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
2701 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
2702 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
2703 MicrosoftCXXNameMangler Mangler(*
this, Out);
2704 Mangler.getStream() <<
"\01??_R1";
2705 Mangler.mangleNumber(NVOffset);
2706 Mangler.mangleNumber(VBPtrOffset);
2707 Mangler.mangleNumber(VBTableOffset);
2708 Mangler.mangleNumber(Flags);
2709 Mangler.mangleName(Derived);
2710 Mangler.getStream() <<
"8";
2713 void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
2715 MicrosoftCXXNameMangler Mangler(*
this, Out);
2716 Mangler.getStream() <<
"\01??_R2";
2717 Mangler.mangleName(Derived);
2718 Mangler.getStream() <<
"8";
2721 void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
2723 MicrosoftCXXNameMangler Mangler(*
this, Out);
2724 Mangler.getStream() <<
"\01??_R3";
2725 Mangler.mangleName(Derived);
2726 Mangler.getStream() <<
"8";
2729 void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
2736 MicrosoftCXXNameMangler Mangler(*
this, Out);
2737 Mangler.getStream() <<
"\01??_R4";
2738 Mangler.mangleName(Derived);
2739 Mangler.getStream() <<
"6B";
2741 Mangler.mangleName(RD);
2742 Mangler.getStream() <<
'@';
2745 void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
2746 const NamedDecl *EnclosingDecl, raw_ostream &Out) {
2747 MicrosoftCXXNameMangler Mangler(*
this, Out);
2752 Mangler.getStream() <<
"\01?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
2753 Mangler.mangleName(EnclosingDecl);
2756 void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
2757 const NamedDecl *EnclosingDecl, raw_ostream &Out) {
2758 MicrosoftCXXNameMangler Mangler(*
this, Out);
2763 Mangler.getStream() <<
"\01?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
2764 Mangler.mangleName(EnclosingDecl);
2767 void MicrosoftMangleContextImpl::mangleTypeName(
QualType T, raw_ostream &Out) {
2770 MicrosoftCXXNameMangler Mangler(*
this, Out);
2771 Mangler.getStream() <<
'?';
2778 MicrosoftCXXNameMangler mangler(*
this, Out, D, Type);
2785 MicrosoftCXXNameMangler mangler(*
this, Out, D, Type);
2789 void MicrosoftMangleContextImpl::mangleReferenceTemporary(
2790 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
2791 MicrosoftCXXNameMangler Mangler(*
this, Out);
2793 Mangler.getStream() <<
"\01?$RT" << ManglingNumber <<
'@';
2794 Mangler.mangle(VD,
"");
2797 void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
2798 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
2799 MicrosoftCXXNameMangler Mangler(*
this, Out);
2801 Mangler.getStream() <<
"\01?$TSS" << GuardNum <<
'@';
2802 Mangler.mangleNestedName(VD);
2805 void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
2817 MicrosoftCXXNameMangler Mangler(*
this, Out);
2821 Mangler.getStream() << (VD->
getTLSKind() ?
"\01??__J" :
"\01??_B");
2823 Mangler.getStream() <<
"\01?$S1@";
2825 unsigned ScopeDepth = 0;
2826 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
2830 Mangler.mangle(VD,
"");
2832 Mangler.mangleNestedName(VD);
2833 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
2835 Mangler.mangleNumber(ScopeDepth);
2838 void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *D,
2841 MicrosoftCXXNameMangler Mangler(*
this, Out);
2842 Mangler.getStream() <<
"\01??__" << CharCode;
2843 Mangler.mangleName(D);
2845 Mangler.mangleVariableEncoding(D);
2846 Mangler.getStream() <<
'@';
2850 Mangler.getStream() <<
"YAXXZ";
2853 void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *D,
2856 mangleInitFiniStub(D, Out,
'E');
2860 MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *D,
2863 mangleInitFiniStub(D, Out,
'F');
2866 void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
2887 MicrosoftCXXNameMangler Mangler(*
this, Out);
2888 Mangler.getStream() <<
"\01??_C@_";
2892 Mangler.getStream() <<
'1';
2894 Mangler.getStream() <<
'0';
2903 auto GetLittleEndianByte = [&Mangler, &SL](
unsigned Index) {
2905 uint32_t CodeUnit = SL->
getCodeUnit(Index / CharByteWidth);
2906 unsigned OffsetInCodeUnit = Index % CharByteWidth;
2907 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
2910 auto GetBigEndianByte = [&Mangler, &SL](
unsigned Index) {
2912 uint32_t CodeUnit = SL->
getCodeUnit(Index / CharByteWidth);
2913 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
2914 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
2920 JC.update(GetLittleEndianByte(I));
2930 Mangler.mangleNumber(JC.getCRC());
2936 auto MangleByte = [&Mangler](
char Byte) {
2944 Mangler.getStream() << Byte;
2945 }
else if (
isLetter(Byte & 0x7f)) {
2946 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
2948 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
2949 ' ',
'\n',
'\t',
'\'',
'-'};
2952 if (Pos !=
std::end(SpecialChars)) {
2953 Mangler.getStream() <<
'?' << (Pos -
std::begin(SpecialChars));
2955 Mangler.getStream() <<
"?$";
2956 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
2957 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
2963 unsigned NumCharsToMangle = std::min(32U, SL->
getLength());
2967 MangleByte(GetBigEndianByte(I));
2969 MangleByte(GetLittleEndianByte(I));
2972 if (NumCharsToMangle < 32)
2977 Mangler.getStream() <<
'@';
2982 return new MicrosoftMangleContextImpl(Context, Diags);
unsigned getNumElements() const
Defines the clang::ASTContext interface.
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
PointerType - C99 6.7.5.1 - Pointer Declarators.
Represents the dependent type named by a dependently-scoped typename using declaration, e.g.
A (possibly-)qualified type.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
bool isMemberPointerType() const
__auto_type (GNU extension)
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
static MicrosoftMangleContext * create(ASTContext &Context, DiagnosticsEngine &Diags)
MSInheritanceAttr::Spelling getMSInheritanceModel() const
Returns the inheritance model used for this record.
StringRef getUuidAsStringRef(ASTContext &Context) const
FunctionType - C99 6.7.5.3 - Function Declarators.
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
IdentifierInfo * getCXXLiteralIdentifier() const
getCXXLiteralIdentifier - If this name is the name of a literal operator, retrieve the identifier ass...
Represents a qualified type name for which the type name is dependent.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
The template argument is an expression, and we've not resolved it to one of the other forms yet...
Decl - This represents one declaration (or definition), e.g.
static LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type...
Defines the C++ template declaration subclasses.
Represents a C++11 auto or C++14 decltype(auto) type.
TemplateSpecializationType(TemplateName T, const TemplateArgument *Args, unsigned NumArgs, QualType Canon, QualType Aliased)
QualType getPointeeType() const
IdentifierInfo * getAsIdentifierInfo() const
getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in this declaration name, or NULL if this declaration name isn't a simple identifier.
The base class of the type hierarchy.
bool hasLinkage() const
Determine whether this declaration has linkage.
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, unsigned NumArgs, const TemplateArgument *Args, QualType Canon)
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
The template argument is a declaration that was provided for a pointer, reference, or pointer to member non-type template parameter.
NamespaceDecl - Represent a C++ namespace.
NamedDecl * getParam(unsigned Idx)
bool isBooleanType() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
bool isBlockPointerType() const
Represents a C++ constructor within a class.
Default closure variant of a ctor.
const llvm::APInt & getSize() const
void * getAsOpaquePtr() const
VarDecl - An instance of this class is created to represent a variable declaration or definition...
TLSKind getTLSKind() const
Represents an empty template argument, e.g., one that has not been deduced.
AccessSpecifier getAccess() const
struct clang::ThisAdjustment::VirtualAdjustment::@114 Microsoft
CallingConv getCallConv() const
A this pointer adjustment.
The "__interface" keyword.
Represents a variable template specialization, which refers to a variable template with a given set o...
ObjCMethodDecl - Represents an instance or class method declaration.
const CXXMethodDecl * Method
Holds a pointer to the overridden method this thunk is for, if needed by the ABI to distinguish diffe...
Stores a list of template parameters for a TemplateDecl and its derived classes.
ParmVarDecl - Represents a parameter to a function.
Defines the clang::Expr interface and subclasses for C++ expressions.
The collection of all-type qualifiers we support.
unsigned getNumParams() const
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
bool isExternC() const
Determines whether this function is a function with external, C linkage.
One of these records is kept for each identifier that is lexed.
Represents a class template specialization, which refers to a class template with a given set of temp...
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Represents a class type in Objective C.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
bool isReferenceType() const
bool isAnyPointerType() const
bool isTranslationUnit() const
unsigned size() const
Retrieve the number of template arguments in this template argument list.
TagKind getTagKind() const
Represents the result of substituting a set of types for a template type parameter pack...
The this pointer adjustment as well as an optional return adjustment for a thunk. ...
uint32_t getCodeUnit(size_t i) const
An rvalue reference type, per C++11 [dcl.ref].
unsigned getLambdaManglingNumber() const
If this is the closure type of a lambda expression, retrieve the number to be used for name mangling ...
An lvalue ref-qualifier was provided (&).
const LangOptions & getLangOpts() const
unsigned getLength() const
CharUnits - This is an opaque type for sizes expressed in character units.
QualType getBaseType() const
Gets the base type of this object type.
QualType getReturnType() const
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
Concrete class used by the front-end to report problems and issues.
Represents a typeof (or typeof) expression (a GCC extension).
Enums/classes describing ABI related information about constructors, destructors and thunks...
TypeClass getTypeClass() const
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
This represents the body of a CapturedStmt, and serves as its DeclContext.
detail::InMemoryDirectory::const_iterator I
Represents an extended vector type where either the type or size is dependent.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments...
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
CXXRecordDecl * getMostRecentDecl()
QualType getParamType(unsigned i) const
Represents a prototype with parameter type info, e.g.
Expr * IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY
IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the value (including ptr->int ...
Represents a ValueDecl that came out of a declarator.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
NameKind getNameKind() const
getNameKind - Determine what kind of name this is.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Represents an array type in C++ whose size is a value-dependent expression.
CXXDtorType
C++ destructor types.
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
QualType getPointeeType() const
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Represents a C++ destructor within a class.
const ParmVarDecl * getParamDecl(unsigned i) const
ArgKind getKind() const
Return the kind of stored template argument.
DeclContext * getDeclContext()
Represents the type decltype(expr) (C++11).
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool isFunctionOrMethod() const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isExternallyVisible() const
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
Represents a GCC generic vector type.
An lvalue reference type, per C++11 [dcl.ref].
DeclarationName getDeclName() const
getDeclName - 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.
QualType getElementType() const
static const TemplateDecl * isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs)
The result type of a method or function.
The COMDAT used for dtors.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
TypedefNameDecl * getTypedefNameForAnonDecl() const
GlobalDecl - represents a global declaration.
const clang::PrintingPolicy & getPrintingPolicy() const
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
SourceRange getBracketsRange() const
Encodes a location in the source.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
const TemplateArgument * iterator
QualType getElementType() const
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Represents typeof(type), a GCC extension.
Interfaces are the core concept in Objective-C for object oriented design.
OverloadedOperatorKind getCXXOverloadedOperator() const
getCXXOverloadedOperator - If this name is the name of an overloadable operator in C++ (e...
TagDecl - Represents the declaration of a struct/union/class/enum.
LanguageLinkage
Describes the different kinds of language linkage (C++ [dcl.link]) that an entity may have...
QualType withConst() const
Represents a static or instance method of a struct/union/class.
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
No ref-qualifier was provided.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
unsigned getCharByteWidth() const
RefQualifierKind
The kind of C++11 ref-qualifier associated with a function type.
SourceLocation getBegin() const
const T * castAs() const
Member-template castAs<specific type>.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
An rvalue ref-qualifier was provided (&&).
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
Represents a pointer type decayed from an array or function type.
CXXCtorType
C++ constructor types.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
The injected class name of a C++ class template or class template partial specialization.
QualType getPointeeType() const
Represents a pack expansion of types.
static void mangleThunkThisAdjustment(const CXXMethodDecl *MD, const ThisAdjustment &Adjustment, MicrosoftCXXNameMangler &Mangler, raw_ostream &Out)
Expr * getSizeExpr() const
Base class for declarations which introduce a typedef-name.
Represents a template argument.
QualType getAsType() const
Retrieve the type for a type template argument.
TagTypeKind
The kind of a tag type.
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
ThisAdjustment This
The this pointer adjustment.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
unsigned getByteLength() const
The base class of all kinds of template declarations (e.g., class, function, etc.).
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
The template argument is a pack expansion of a template name that was provided for a template templat...
DeclarationName - The name of a declaration.
detail::InMemoryDirectory::const_iterator E
A pointer to member type per C++ 8.3.3 - Pointers to members.
bool isLambda() const
Determine whether this class describes a lambda function object.
union clang::ThisAdjustment::VirtualAdjustment Virtual
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Represents a pointer to an Objective C object.
Not an overloaded operator.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Complex values, per C99 6.2.5p11.
const T * getAs() const
Member-template getAs<specific type>'.
unsigned getTypeQuals() const
QualType getCanonicalType() const
QualType getIntegralType() const
Retrieve the type of the integral value.
bool isFunctionType() const
ExtVectorType - Extended vector type.
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
ReturnAdjustment Return
The return adjustment.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
The template argument is a type.
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
The template argument is actually a parameter pack.
bool isStaticDataMember() const
Determines whether this is a static data member.
QualType getPointeeType() const
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
A template argument list.
static LLVM_READONLY bool isIdentifierBody(unsigned char c, bool AllowDollar=false)
Returns true if this is a body character of a C identifier, which is [a-zA-Z0-9_].
const Type * getClass() const
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Represents a C++ struct/union/class.
The template argument is a template name that was provided for a template template parameter...
Represents a C array with an unspecified size.
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
This class is used for builtin types like 'int'.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
QualType getParamTypeForDecl() const
Copying closure variant of a ctor.
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
uint64_t Index
Method's index in the vftable.
static Qualifiers fromCVRMask(unsigned CVR)
QualType getElementType() const
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
NamedDecl - This represents a decl with a name.
StringRef getName(const PrintingPolicy &Policy) const
Represents a C array with a specified size that is not an integer-constant-expression.
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...
Represents the canonical version of C arrays with a specified constant size.
const MethodVFTableLocation & getMethodVFTableLocation(GlobalDecl GD)
PrettyStackTraceDecl - If a crash occurs, indicate that it happened when doing something to a specifi...
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isPointerType() const
QualType getDeducedType() const
Get the type deduced for this auto type, or null if it's either not been deduced or was deduced to a ...