30 #include "llvm/ADT/StringExtras.h"
31 #include "llvm/Support/JamCRC.h"
32 #include "llvm/Support/MD5.h"
33 #include "llvm/Support/MathExtras.h"
35 using namespace clang;
39 struct msvc_hashing_ostream :
public llvm::raw_svector_ostream {
43 msvc_hashing_ostream(raw_ostream &OS)
44 : llvm::raw_svector_ostream(
Buffer), OS(OS) {}
45 ~msvc_hashing_ostream()
override {
46 StringRef MangledName = str();
47 bool StartsWithEscape = MangledName.startswith(
"\01");
49 MangledName = MangledName.drop_front(1);
50 if (MangledName.size() <= 4096) {
56 llvm::MD5::MD5Result Hash;
57 Hasher.update(MangledName);
61 llvm::MD5::stringifyResult(Hash, HexString);
65 OS <<
"??@" << HexString <<
'@';
81 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
82 return ContextParam->getDeclContext();
86 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
88 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
89 return ContextParam->getDeclContext();
93 if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC)) {
94 return getEffectiveDeclContext(cast<Decl>(DC));
101 return getEffectiveDeclContext(cast<Decl>(DC));
105 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
106 return FTD->getTemplatedDecl();
108 const auto *FD = cast<FunctionDecl>(ND);
109 if (
const auto *FTD = FD->getPrimaryTemplate())
110 return FTD->getTemplatedDecl();
115 static bool isLambda(
const NamedDecl *ND) {
126 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
127 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
128 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
129 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
130 llvm::DenseMap<const NamedDecl *, unsigned> SEHFilterIds;
131 llvm::DenseMap<const NamedDecl *, unsigned> SEHFinallyIds;
136 bool shouldMangleCXXName(
const NamedDecl *D)
override;
137 bool shouldMangleStringLiteral(
const StringLiteral *SL)
override;
138 void mangleCXXName(
const NamedDecl *D, raw_ostream &Out)
override;
140 raw_ostream &)
override;
142 raw_ostream &)
override;
145 raw_ostream &)
override;
148 raw_ostream &Out)
override;
151 raw_ostream &Out)
override;
152 void mangleCXXVirtualDisplacementMap(
const CXXRecordDecl *SrcRD,
154 raw_ostream &Out)
override;
155 void mangleCXXThrowInfo(
QualType T,
bool IsConst,
bool IsVolatile,
156 bool IsUnaligned, uint32_t NumEntries,
157 raw_ostream &Out)
override;
158 void mangleCXXCatchableTypeArray(
QualType T, uint32_t NumEntries,
159 raw_ostream &Out)
override;
162 int32_t VBPtrOffset, uint32_t VBIndex,
163 raw_ostream &Out)
override;
164 void mangleCXXRTTI(
QualType T, raw_ostream &Out)
override;
165 void mangleCXXRTTIName(
QualType T, raw_ostream &Out)
override;
166 void mangleCXXRTTIBaseClassDescriptor(
const CXXRecordDecl *Derived,
167 uint32_t NVOffset, int32_t VBPtrOffset,
168 uint32_t VBTableOffset, uint32_t Flags,
169 raw_ostream &Out)
override;
170 void mangleCXXRTTIBaseClassArray(
const CXXRecordDecl *Derived,
171 raw_ostream &Out)
override;
172 void mangleCXXRTTIClassHierarchyDescriptor(
const CXXRecordDecl *Derived,
173 raw_ostream &Out)
override;
175 mangleCXXRTTICompleteObjectLocator(
const CXXRecordDecl *Derived,
177 raw_ostream &Out)
override;
178 void mangleTypeName(
QualType T, raw_ostream &)
override;
180 raw_ostream &)
override;
182 raw_ostream &)
override;
183 void mangleReferenceTemporary(
const VarDecl *,
unsigned ManglingNumber,
184 raw_ostream &)
override;
185 void mangleStaticGuardVariable(
const VarDecl *D, raw_ostream &Out)
override;
186 void mangleThreadSafeStaticGuardVariable(
const VarDecl *D,
unsigned GuardNum,
187 raw_ostream &Out)
override;
188 void mangleDynamicInitializer(
const VarDecl *D, raw_ostream &Out)
override;
189 void mangleDynamicAtExitDestructor(
const VarDecl *D,
190 raw_ostream &Out)
override;
191 void mangleSEHFilterExpression(
const NamedDecl *EnclosingDecl,
192 raw_ostream &Out)
override;
193 void mangleSEHFinallyBlock(
const NamedDecl *EnclosingDecl,
194 raw_ostream &Out)
override;
195 void mangleStringLiteral(
const StringLiteral *SL, raw_ostream &Out)
override;
196 bool getNextDiscriminator(
const NamedDecl *ND,
unsigned &disc) {
197 const DeclContext *DC = getEffectiveDeclContext(ND);
210 disc = getASTContext().getManglingNumber(ND);
215 if (
const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
216 if (!Tag->hasNameForLinkage() &&
217 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
218 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))
223 unsigned &discriminator = Uniquifier[ND];
225 discriminator = ++Discriminator[std::make_pair(DC, ND->
getIdentifier())];
226 disc = discriminator + 1;
231 assert(RD->
isLambda() &&
"RD must be a lambda!");
234 "RD must not have a mangling number!");
236 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
237 return Result.first->second;
241 void mangleInitFiniStub(
const VarDecl *D,
char CharCode, raw_ostream &Out);
246 class MicrosoftCXXNameMangler {
247 MicrosoftMangleContextImpl &
Context;
257 BackRefVec NameBackReferences;
259 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
260 ArgBackRefMap TypeBackReferences;
262 typedef std::set<int> PassObjectSizeArgsSet;
263 PassObjectSizeArgsSet PassObjectSizeArgs;
269 const bool PointersAre64Bit;
272 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
274 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
276 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
279 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
282 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
285 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
288 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
291 raw_ostream &getStream()
const {
return Out; }
293 void mangle(
const NamedDecl *D, StringRef Prefix =
"\01?");
295 void mangleFunctionEncoding(
const FunctionDecl *FD,
bool ShouldMangle);
296 void mangleVariableEncoding(
const VarDecl *VD);
300 void mangleVirtualMemPtrThunk(
303 void mangleNumber(int64_t Number);
305 void mangleArtificalTagType(
TagTypeKind TK, StringRef UnqualifiedName,
308 QualifierMangleMode QMM = QMM_Mangle);
311 bool ForceThisQuals =
false);
312 void mangleNestedName(
const NamedDecl *ND);
315 void mangleUnqualifiedName(
const NamedDecl *ND) {
319 void mangleSourceName(StringRef
Name);
322 void mangleQualifiers(
Qualifiers Quals,
bool IsMember);
324 void manglePointerCVQualifiers(
Qualifiers Quals);
327 void mangleUnscopedTemplateName(
const TemplateDecl *ND);
334 void manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA);
337 #define ABSTRACT_TYPE(CLASS, PARENT)
338 #define NON_CANONICAL_TYPE(CLASS, PARENT)
339 #define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
342 #include "clang/AST/TypeNodes.def"
344 #undef NON_CANONICAL_TYPE
347 void mangleType(
const TagDecl *TD);
348 void mangleDecayedArrayType(
const ArrayType *T);
349 void mangleArrayType(
const ArrayType *T);
353 void mangleIntegerLiteral(
const llvm::APSInt &Number,
bool IsBoolean);
354 void mangleExpression(
const Expr *
E);
364 bool MicrosoftMangleContextImpl::shouldMangleCXXName(
const NamedDecl *D) {
365 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
368 if (FD->hasAttr<OverloadableAttr>())
380 if (FD->isMSVCRTEntryPoint())
394 if (!getASTContext().getLangOpts().CPlusPlus)
397 if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
403 const DeclContext *DC = getEffectiveDeclContext(D);
407 DC = getEffectiveParentContext(DC);
410 !isa<VarTemplateSpecializationDecl>(D) &&
419 MicrosoftMangleContextImpl::shouldMangleStringLiteral(
const StringLiteral *SL) {
423 void MicrosoftCXXNameMangler::mangle(
const NamedDecl *D, StringRef Prefix) {
434 mangleFunctionEncoding(FD,
Context.shouldMangleDeclName(FD));
435 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
436 mangleVariableEncoding(VD);
438 llvm_unreachable(
"Tried to mangle unexpected NamedDecl!");
441 void MicrosoftCXXNameMangler::mangleFunctionEncoding(
const FunctionDecl *FD,
462 if (FD->
isExternC() && FD->hasAttr<OverloadableAttr>())
465 mangleFunctionClass(FD);
467 mangleFunctionType(FT, FD);
473 void MicrosoftCXXNameMangler::mangleVariableEncoding(
const VarDecl *VD) {
484 switch (VD->getAccess()) {
504 mangleType(Ty, SR, QMM_Drop);
505 manglePointerExtQualifiers(
508 mangleQualifiers(MPT->getPointeeType().getQualifiers(),
true);
511 mangleName(MPT->getClass()->getAsCXXRecordDecl());
514 }
else if (
const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
516 mangleDecayedArrayType(AT);
517 if (AT->getElementType()->isArrayType())
522 mangleType(Ty, SR, QMM_Drop);
527 void MicrosoftCXXNameMangler::mangleMemberDataPointer(
const CXXRecordDecl *RD,
534 int64_t VBTableOffset;
537 FieldOffset = getASTContext().getFieldOffset(VD);
538 assert(FieldOffset % getASTContext().
getCharWidth() == 0 &&
539 "cannot take address of bitfield");
540 FieldOffset /= getASTContext().getCharWidth();
544 if (IM == MSInheritanceAttr::Keyword_virtual_inheritance)
545 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
554 case MSInheritanceAttr::Keyword_single_inheritance: Code =
'0';
break;
555 case MSInheritanceAttr::Keyword_multiple_inheritance: Code =
'0';
break;
556 case MSInheritanceAttr::Keyword_virtual_inheritance: Code =
'F';
break;
557 case MSInheritanceAttr::Keyword_unspecified_inheritance: Code =
'G';
break;
562 mangleNumber(FieldOffset);
567 if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
569 if (MSInheritanceAttr::hasVBTableOffsetField(IM))
570 mangleNumber(VBTableOffset);
574 MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
const CXXRecordDecl *RD,
585 case MSInheritanceAttr::Keyword_single_inheritance: Code =
'1';
break;
586 case MSInheritanceAttr::Keyword_multiple_inheritance: Code =
'H';
break;
587 case MSInheritanceAttr::Keyword_virtual_inheritance: Code =
'I';
break;
588 case MSInheritanceAttr::Keyword_unspecified_inheritance: Code =
'J';
break;
593 uint64_t NVOffset = 0;
594 uint64_t VBTableOffset = 0;
595 uint64_t VBPtrOffset = 0;
597 Out <<
'$' << Code <<
'?';
600 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
603 mangleVirtualMemPtrThunk(MD, ML);
604 NVOffset = ML.VFPtrOffset.getQuantity();
605 VBTableOffset = ML.VBTableIndex * 4;
607 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
612 mangleFunctionEncoding(MD,
true);
615 if (VBTableOffset == 0 &&
616 IM == MSInheritanceAttr::Keyword_virtual_inheritance)
617 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
620 if (IM == MSInheritanceAttr::Keyword_single_inheritance) {
624 if (IM == MSInheritanceAttr::Keyword_unspecified_inheritance)
629 if (MSInheritanceAttr::hasNVOffsetField(
true, IM))
630 mangleNumber(static_cast<uint32_t>(NVOffset));
631 if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
632 mangleNumber(VBPtrOffset);
633 if (MSInheritanceAttr::hasVBTableOffsetField(IM))
634 mangleNumber(VBTableOffset);
637 void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
641 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
642 getASTContext().getTargetInfo().getPointerWidth(0));
648 mangleNumber(OffsetInVFTable);
653 void MicrosoftCXXNameMangler::mangleName(
const NamedDecl *ND) {
657 mangleUnqualifiedName(ND);
659 mangleNestedName(ND);
665 void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
672 uint64_t
Value =
static_cast<uint64_t
>(Number);
680 else if (Value >= 1 && Value <= 10)
686 char EncodedNumberBuffer[
sizeof(uint64_t) * 2];
689 for (; Value != 0; Value >>= 4)
690 *I++ =
'A' + (Value & 0xf);
691 Out.write(I.base(), I - BufferRef.rbegin());
699 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
708 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
709 TemplateArgs = &Spec->getTemplateArgs();
710 return Spec->getSpecializedTemplate();
715 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
716 TemplateArgs = &Spec->getTemplateArgs();
717 return Spec->getSpecializedTemplate();
723 void MicrosoftCXXNameMangler::mangleUnqualifiedName(
const NamedDecl *ND,
736 if (isa<FunctionTemplateDecl>(TD)) {
737 mangleTemplateInstantiationName(TD, *TemplateArgs);
758 llvm::raw_svector_ostream Stream(TemplateMangling);
759 MicrosoftCXXNameMangler Extra(
Context, Stream);
760 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
762 mangleSourceName(TemplateMangling);
769 mangleSourceName(II->getName());
774 assert(ND &&
"mangling empty name without declaration");
777 if (NS->isAnonymousNamespace()) {
783 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
786 assert(RD &&
"expected variable decl to have a record type");
792 Name += llvm::utostr(
Context.getAnonymousStructId(RD) + 1);
793 mangleSourceName(Name.str());
798 const TagDecl *TD = cast<TagDecl>(ND);
800 assert(TD->getDeclContext() == D->getDeclContext() &&
801 "Typedef should not be in another decl context!");
803 "Typedef was not named!");
808 if (
const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
815 LambdaId =
Context.getLambdaId(Record);
817 Name += llvm::utostr(LambdaId);
820 mangleSourceName(Name);
830 Name += DD->getName();
836 Name += TND->getName();
840 Name += llvm::utostr(
Context.getAnonymousStructId(TD) + 1);
843 mangleSourceName(Name.str());
850 llvm_unreachable(
"Can't mangle Objective-C selector names here!");
853 if (Structor == getStructor(ND)) {
870 mangleCXXDtorType(static_cast<CXXDtorType>(
StructorType));
894 llvm_unreachable(
"Can't mangle a using directive name!");
898 void MicrosoftCXXNameMangler::mangleNestedName(
const NamedDecl *ND) {
901 const DeclContext *DC = getEffectiveDeclContext(ND);
904 if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
906 if (
Context.getNextDiscriminator(ND, Disc)) {
913 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
917 "cannot mangle a local inside this block yet");
918 Diags.
Report(BD->getLocation(), DiagID);
922 Out <<
"__block_invoke" <<
Context.getBlockId(BD,
false);
925 }
else if (
const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
926 mangleObjCMethodName(Method);
927 }
else if (isa<NamedDecl>(DC)) {
928 ND = cast<NamedDecl>(DC);
929 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
933 mangleUnqualifiedName(ND);
939 void MicrosoftCXXNameMangler::mangleCXXDtorType(
CXXDtorType T) {
954 llvm_unreachable(
"not expecting a COMDAT");
956 llvm_unreachable(
"Unsupported dtor type?");
965 case OO_New: Out <<
"?2";
break;
967 case OO_Delete: Out <<
"?3";
break;
969 case OO_Equal: Out <<
"?4";
break;
971 case OO_GreaterGreater: Out <<
"?5";
break;
973 case OO_LessLess: Out <<
"?6";
break;
975 case OO_Exclaim: Out <<
"?7";
break;
977 case OO_EqualEqual: Out <<
"?8";
break;
979 case OO_ExclaimEqual: Out <<
"?9";
break;
981 case OO_Subscript: Out <<
"?A";
break;
984 case OO_Arrow: Out <<
"?C";
break;
986 case OO_Star: Out <<
"?D";
break;
988 case OO_PlusPlus: Out <<
"?E";
break;
990 case OO_MinusMinus: Out <<
"?F";
break;
992 case OO_Minus: Out <<
"?G";
break;
994 case OO_Plus: Out <<
"?H";
break;
996 case OO_Amp: Out <<
"?I";
break;
998 case OO_ArrowStar: Out <<
"?J";
break;
1000 case OO_Slash: Out <<
"?K";
break;
1002 case OO_Percent: Out <<
"?L";
break;
1004 case OO_Less: Out <<
"?M";
break;
1006 case OO_LessEqual: Out <<
"?N";
break;
1008 case OO_Greater: Out <<
"?O";
break;
1010 case OO_GreaterEqual: Out <<
"?P";
break;
1012 case OO_Comma: Out <<
"?Q";
break;
1014 case OO_Call: Out <<
"?R";
break;
1016 case OO_Tilde: Out <<
"?S";
break;
1018 case OO_Caret: Out <<
"?T";
break;
1020 case OO_Pipe: Out <<
"?U";
break;
1022 case OO_AmpAmp: Out <<
"?V";
break;
1024 case OO_PipePipe: Out <<
"?W";
break;
1026 case OO_StarEqual: Out <<
"?X";
break;
1028 case OO_PlusEqual: Out <<
"?Y";
break;
1030 case OO_MinusEqual: Out <<
"?Z";
break;
1032 case OO_SlashEqual: Out <<
"?_0";
break;
1034 case OO_PercentEqual: Out <<
"?_1";
break;
1036 case OO_GreaterGreaterEqual: Out <<
"?_2";
break;
1038 case OO_LessLessEqual: Out <<
"?_3";
break;
1040 case OO_AmpEqual: Out <<
"?_4";
break;
1042 case OO_PipeEqual: Out <<
"?_5";
break;
1044 case OO_CaretEqual: Out <<
"?_6";
break;
1073 case OO_Array_New: Out <<
"?_U";
break;
1075 case OO_Array_Delete: Out <<
"?_V";
break;
1077 case OO_Conditional: {
1080 "cannot mangle this conditional operator yet");
1081 Diags.
Report(Loc, DiagID);
1088 "cannot mangle this operator co_await yet");
1089 Diags.
Report(Loc, DiagID);
1095 llvm_unreachable(
"Not an overloaded operator");
1099 void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1102 std::find(NameBackReferences.begin(), NameBackReferences.end(),
Name);
1103 if (Found == NameBackReferences.end()) {
1104 if (NameBackReferences.size() < 10)
1105 NameBackReferences.push_back(Name);
1108 Out << (Found - NameBackReferences.begin());
1112 void MicrosoftCXXNameMangler::mangleObjCMethodName(
const ObjCMethodDecl *MD) {
1113 Context.mangleObjCMethodName(MD, Out);
1116 void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1123 ArgBackRefMap OuterArgsContext;
1124 BackRefVec OuterTemplateContext;
1125 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1126 NameBackReferences.swap(OuterTemplateContext);
1127 TypeBackReferences.swap(OuterArgsContext);
1128 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1130 mangleUnscopedTemplateName(TD);
1131 mangleTemplateArgs(TD, TemplateArgs);
1134 NameBackReferences.swap(OuterTemplateContext);
1135 TypeBackReferences.swap(OuterArgsContext);
1136 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1140 MicrosoftCXXNameMangler::mangleUnscopedTemplateName(
const TemplateDecl *TD) {
1143 mangleUnqualifiedName(TD);
1146 void MicrosoftCXXNameMangler::mangleIntegerLiteral(
const llvm::APSInt &Value,
1151 if (IsBoolean && Value.getBoolValue())
1153 else if (Value.isSigned())
1154 mangleNumber(Value.getSExtValue());
1156 mangleNumber(Value.getZExtValue());
1159 void MicrosoftCXXNameMangler::mangleExpression(
const Expr *
E) {
1172 if (UO->getOpcode() == UO_AddrOf)
1173 UE = dyn_cast<CXXUuidofExpr>(UO->getSubExpr());
1191 std::string Name =
"_GUID_" + Uuid.lower();
1192 std::replace(Name.begin(), Name.end(),
'-',
'_');
1194 mangleSourceName(Name);
1200 mangleArtificalTagType(
TTK_Struct,
"__s_GUID");
1211 << E->getSourceRange();
1214 void MicrosoftCXXNameMangler::mangleTemplateArgs(
1218 assert(TPL->
size() == TemplateArgs.
size() &&
1219 "size mismatch between args and parms!");
1223 mangleTemplateArg(TD, TA, TPL->
getParam(Idx++));
1226 void MicrosoftCXXNameMangler::mangleTemplateArg(
const TemplateDecl *TD,
1240 llvm_unreachable(
"Can't mangle null template arguments!");
1242 llvm_unreachable(
"Can't mangle template expansion arguments!");
1250 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1251 mangleMemberDataPointer(
1252 cast<CXXRecordDecl>(ND->getDeclContext())->getMostRecentDecl(),
1253 cast<ValueDecl>(ND));
1254 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1261 mangleFunctionEncoding(FD,
true);
1275 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1276 if (MPT->isMemberFunctionPointerType() &&
1277 !isa<FunctionTemplateDecl>(TD)) {
1278 mangleMemberFunctionPointer(RD,
nullptr);
1281 if (MPT->isMemberDataPointer()) {
1282 if (!isa<FunctionTemplateDecl>(TD)) {
1283 mangleMemberDataPointer(RD,
nullptr);
1293 mangleIntegerLiteral(llvm::APSInt::get(-1),
false);
1298 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
false);
1306 if (TemplateArgs.empty()) {
1307 if (isa<TemplateTypeParmDecl>(Parm) ||
1308 isa<TemplateTemplateParmDecl>(Parm))
1315 else if (isa<NonTypeTemplateParmDecl>(Parm))
1318 llvm_unreachable(
"unexpected template parameter decl!");
1321 mangleTemplateArg(TD, PA, Parm);
1328 if (
const auto *TD = dyn_cast<TagDecl>(ND)) {
1330 }
else if (isa<TypeAliasDecl>(ND)) {
1334 llvm_unreachable(
"unexpected template template NamedDecl!");
1341 void MicrosoftCXXNameMangler::mangleQualifiers(
Qualifiers Quals,
1399 if (HasConst && HasVolatile) {
1401 }
else if (HasVolatile) {
1403 }
else if (HasConst) {
1409 if (HasConst && HasVolatile) {
1411 }
else if (HasVolatile) {
1413 }
else if (HasConst) {
1424 MicrosoftCXXNameMangler::mangleRefQualifier(
RefQualifierKind RefQualifier) {
1427 switch (RefQualifier) {
1441 void MicrosoftCXXNameMangler::manglePointerExtQualifiers(
Qualifiers Quals,
1444 if (PointersAre64Bit &&
1456 void MicrosoftCXXNameMangler::manglePointerCVQualifiers(
Qualifiers Quals) {
1464 if (HasConst && HasVolatile) {
1466 }
else if (HasVolatile) {
1468 }
else if (HasConst) {
1475 void MicrosoftCXXNameMangler::mangleArgumentType(
QualType T,
1486 QualType OriginalType = DT->getOriginalType();
1489 if (
const auto *AT = getASTContext().getAsArrayType(OriginalType))
1490 OriginalType = getASTContext().getIncompleteArrayType(
1491 AT->getElementType(), AT->getSizeModifier(),
1492 AT->getIndexTypeCVRQualifiers());
1508 if (Found == TypeBackReferences.end()) {
1509 size_t OutSizeBefore = Out.tell();
1511 mangleType(T, Range, QMM_Drop);
1516 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);
1517 if (LongerThanOneChar && TypeBackReferences.size() < 10) {
1518 size_t Size = TypeBackReferences.size();
1519 TypeBackReferences[TypePtr] = Size;
1522 Out << Found->second;
1526 void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
1527 const PassObjectSizeAttr *POSA) {
1528 int Type = POSA->getType();
1530 auto Iter = PassObjectSizeArgs.insert(Type).first;
1531 auto *TypePtr = (
const void *)&*Iter;
1534 if (Found == TypeBackReferences.end()) {
1535 mangleArtificalTagType(
TTK_Enum,
"__pass_object_size" + llvm::utostr(Type),
1538 if (TypeBackReferences.size() < 10) {
1539 size_t Size = TypeBackReferences.size();
1540 TypeBackReferences[TypePtr] = Size;
1543 Out << Found->second;
1548 QualifierMangleMode QMM) {
1553 if (
const ArrayType *AT = getASTContext().getAsArrayType(T)) {
1556 if (QMM == QMM_Mangle)
1558 else if (QMM == QMM_Escape || QMM == QMM_Result)
1560 mangleArrayType(AT);
1571 if (
const FunctionType *FT = dyn_cast<FunctionType>(T)) {
1573 mangleFunctionType(FT);
1576 mangleQualifiers(Quals,
false);
1579 if (!IsPointer && Quals) {
1581 mangleQualifiers(Quals,
false);
1587 if ((!IsPointer && Quals) || isa<TagType>(T)) {
1589 mangleQualifiers(Quals,
false);
1597 #define ABSTRACT_TYPE(CLASS, PARENT)
1598 #define NON_CANONICAL_TYPE(CLASS, PARENT) \
1600 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
1602 #define TYPE(CLASS, PARENT) \
1604 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
1606 #include "clang/AST/TypeNodes.def"
1607 #undef ABSTRACT_TYPE
1608 #undef NON_CANONICAL_TYPE
1640 case BuiltinType::Void:
1643 case BuiltinType::SChar:
1646 case BuiltinType::Char_U:
1647 case BuiltinType::Char_S:
1650 case BuiltinType::UChar:
1653 case BuiltinType::Short:
1656 case BuiltinType::UShort:
1659 case BuiltinType::Int:
1662 case BuiltinType::UInt:
1665 case BuiltinType::Long:
1668 case BuiltinType::ULong:
1671 case BuiltinType::Float:
1674 case BuiltinType::Double:
1678 case BuiltinType::LongDouble:
1681 case BuiltinType::LongLong:
1684 case BuiltinType::ULongLong:
1687 case BuiltinType::Int128:
1690 case BuiltinType::UInt128:
1693 case BuiltinType::Bool:
1696 case BuiltinType::Char16:
1699 case BuiltinType::Char32:
1702 case BuiltinType::WChar_S:
1703 case BuiltinType::WChar_U:
1707 #define BUILTIN_TYPE(Id, SingletonId)
1708 #define PLACEHOLDER_TYPE(Id, SingletonId) \
1709 case BuiltinType::Id:
1710 #include "clang/AST/BuiltinTypes.def"
1711 case BuiltinType::Dependent:
1712 llvm_unreachable(
"placeholder types shouldn't get to name mangling");
1714 case BuiltinType::ObjCId:
1716 mangleArtificalTagType(
TTK_Struct,
"objc_object");
1718 case BuiltinType::ObjCClass:
1720 mangleArtificalTagType(
TTK_Struct,
"objc_class");
1722 case BuiltinType::ObjCSel:
1724 mangleArtificalTagType(
TTK_Struct,
"objc_selector");
1727 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
1728 case BuiltinType::Id: \
1729 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
1731 #include "clang/Basic/OpenCLImageTypes.def"
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::Float128:
1762 case BuiltinType::Half: {
1781 mangleFunctionType(T,
nullptr,
true);
1784 mangleFunctionType(T);
1790 mangleFunctionType(T);
1793 void MicrosoftCXXNameMangler::mangleFunctionType(
const FunctionType *T,
1795 bool ForceThisQuals) {
1803 bool IsInLambda =
false;
1804 bool IsStructor =
false, HasThisQuals = ForceThisQuals, IsCtorClosure =
false;
1806 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
1810 HasThisQuals =
true;
1811 if (isa<CXXDestructorDecl>(MD)) {
1813 }
else if (isa<CXXConstructorDecl>(MD)) {
1817 getStructor(MD) == Structor;
1819 CC = getASTContext().getDefaultCallingConvention(
1828 manglePointerExtQualifiers(Quals,
QualType());
1830 mangleQualifiers(Quals,
false);
1833 mangleCallingConvention(CC);
1838 if (isa<CXXDestructorDecl>(D) && D == Structor &&
1844 Out << (PointersAre64Bit ?
"PEAXI@Z" :
"PAXI@Z");
1847 if (IsCtorClosure) {
1857 mangleArgumentType(getASTContext().getLValueReferenceType(
1865 llvm_unreachable(
"unexpected constructor closure!");
1873 if (
const auto *AT =
1879 "shouldn't need to mangle __auto_type!");
1880 mangleSourceName(AT->isDecltypeAuto() ?
"<decltype-auto>" :
"<auto>");
1882 }
else if (IsInLambda) {
1887 mangleType(ResultType, Range, QMM_Result);
1914 if (
const auto *
P = D->
getParamDecl(I)->getAttr<PassObjectSizeAttr>())
1915 manglePassObjectSizeArg(
P);
1924 mangleThrowSpecification(Proto);
1927 void MicrosoftCXXNameMangler::mangleFunctionClass(
const FunctionDecl *FD) {
1952 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
1953 switch (MD->getAccess()) {
1955 llvm_unreachable(
"Unsupported access specifier");
1984 void MicrosoftCXXNameMangler::mangleCallingConvention(
CallingConv CC) {
2004 llvm_unreachable(
"Unsupported CC for mangling");
2007 case CC_C: Out <<
'A';
break;
2015 void MicrosoftCXXNameMangler::mangleCallingConvention(
const FunctionType *T) {
2018 void MicrosoftCXXNameMangler::mangleThrowSpecification(
2035 "cannot mangle this unresolved dependent type yet");
2045 void MicrosoftCXXNameMangler::mangleTagTypeKind(
TagTypeKind TTK) {
2064 mangleType(cast<TagType>(T)->getDecl());
2068 mangleType(cast<TagType>(T)->getDecl());
2070 void MicrosoftCXXNameMangler::mangleType(
const TagDecl *TD) {
2074 void MicrosoftCXXNameMangler::mangleArtificalTagType(
2077 mangleTagTypeKind(TK);
2080 mangleSourceName(UnqualifiedName);
2082 for (
auto I = NestedNames.rbegin(), E = NestedNames.rend(); I !=
E; ++
I)
2083 mangleSourceName(*I);
2096 void MicrosoftCXXNameMangler::mangleDecayedArrayType(
const ArrayType *T) {
2104 llvm_unreachable(
"Should have been special cased");
2108 llvm_unreachable(
"Should have been special cased");
2112 llvm_unreachable(
"Should have been special cased");
2116 llvm_unreachable(
"Should have been special cased");
2118 void MicrosoftCXXNameMangler::mangleArrayType(
const ArrayType *T) {
2122 if (ElementTy->isConstantArrayType()) {
2124 getASTContext().getAsConstantArrayType(ElementTy);
2125 Dimensions.push_back(CAT->
getSize());
2127 }
else if (ElementTy->isIncompleteArrayType()) {
2129 getASTContext().getAsIncompleteArrayType(ElementTy);
2130 Dimensions.push_back(llvm::APInt(32, 0));
2132 }
else if (ElementTy->isVariableArrayType()) {
2134 getASTContext().getAsVariableArrayType(ElementTy);
2135 Dimensions.push_back(llvm::APInt(32, 0));
2137 }
else if (ElementTy->isDependentSizedArrayType()) {
2140 getASTContext().getAsDependentSizedArrayType(ElementTy);
2143 "cannot mangle this dependent-length array yet");
2153 mangleNumber(Dimensions.size());
2154 for (
const llvm::APInt &Dimension : Dimensions)
2155 mangleNumber(Dimension.getLimitedValue());
2165 manglePointerCVQualifiers(Quals);
2166 manglePointerExtQualifiers(Quals, PointeeType);
2170 mangleFunctionType(FPT,
nullptr,
true);
2174 mangleType(PointeeType, Range, QMM_Drop);
2182 "cannot mangle this template type parameter type yet");
2191 "cannot mangle this substituted parameter pack yet");
2202 manglePointerCVQualifiers(Quals);
2203 manglePointerExtQualifiers(Quals, PointeeType);
2204 mangleType(PointeeType, Range);
2209 manglePointerCVQualifiers(Quals);
2210 manglePointerExtQualifiers(Quals, PointeeType);
2213 mangleType(PointeeType, Range);
2224 manglePointerExtQualifiers(Quals, PointeeType);
2225 mangleType(PointeeType, Range);
2236 manglePointerExtQualifiers(Quals, PointeeType);
2237 mangleType(PointeeType, Range);
2245 llvm::raw_svector_ostream Stream(TemplateMangling);
2246 MicrosoftCXXNameMangler Extra(
Context, Stream);
2248 Extra.mangleSourceName(
"_Complex");
2249 Extra.mangleType(ElementType, Range, QMM_Escape);
2251 mangleArtificalTagType(
TTK_Struct, TemplateMangling, {
"__clang"});
2257 assert(ET &&
"vectors with non-builtin elements are unsupported");
2258 uint64_t Width = getASTContext().getTypeSize(T);
2261 size_t OutSizeBefore = Out.tell();
2262 llvm::Triple::ArchType AT =
2263 getASTContext().getTargetInfo().getTriple().getArch();
2264 if (AT == llvm::Triple::x86 || AT == llvm::Triple::x86_64) {
2265 if (Width == 64 && ET->
getKind() == BuiltinType::LongLong) {
2266 mangleArtificalTagType(
TTK_Union,
"__m64");
2267 }
else if (Width >= 128) {
2268 if (ET->
getKind() == BuiltinType::Float)
2269 mangleArtificalTagType(
TTK_Union,
"__m" + llvm::utostr(Width));
2270 else if (ET->
getKind() == BuiltinType::LongLong)
2271 mangleArtificalTagType(
TTK_Union,
"__m" + llvm::utostr(Width) +
'i');
2272 else if (ET->
getKind() == BuiltinType::Double)
2273 mangleArtificalTagType(
TTK_Struct,
"__m" + llvm::utostr(Width) +
'd');
2277 bool IsBuiltin = Out.tell() != OutSizeBefore;
2284 llvm::raw_svector_ostream Stream(TemplateMangling);
2285 MicrosoftCXXNameMangler Extra(
Context, Stream);
2287 Extra.mangleSourceName(
"__vector");
2288 Extra.mangleType(
QualType(ET, 0), Range, QMM_Escape);
2289 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->
getNumElements()),
2292 mangleArtificalTagType(
TTK_Union, TemplateMangling, {
"__clang"});
2296 void MicrosoftCXXNameMangler::mangleType(
const ExtVectorType *T,
2298 mangleType(static_cast<const VectorType *>(T), Quals, Range);
2304 "cannot mangle this dependent-sized extended vector type yet");
2326 manglePointerCVQualifiers(Quals);
2327 manglePointerExtQualifiers(Quals, PointeeType);
2336 llvm_unreachable(
"Cannot mangle injected class name type.");
2343 "cannot mangle this template specialization type yet");
2352 "cannot mangle this dependent name type yet");
2357 void MicrosoftCXXNameMangler::mangleType(
2362 "cannot mangle this dependent template specialization type yet");
2371 "cannot mangle this pack expansion yet");
2380 "cannot mangle this typeof(type) yet");
2389 "cannot mangle this typeof(expression) yet");
2398 "cannot mangle this decltype() yet");
2407 "cannot mangle this unary transform type yet");
2418 "cannot mangle this 'auto' type yet");
2419 Diags.Report(Range.
getBegin(), DiagID)
2428 llvm::raw_svector_ostream Stream(TemplateMangling);
2429 MicrosoftCXXNameMangler Extra(
Context, Stream);
2431 Extra.mangleSourceName(
"_Atomic");
2432 Extra.mangleType(ValueType, Range, QMM_Escape);
2434 mangleArtificalTagType(
TTK_Struct, TemplateMangling, {
"__clang"});
2441 "cannot mangle this OpenCL pipe type yet");
2446 void MicrosoftMangleContextImpl::mangleCXXName(
const NamedDecl *D,
2448 assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
2449 "Invalid mangleName() call, argument is not a variable or function!");
2450 assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
2451 "Invalid mangleName() call on 'structor decl!");
2454 getASTContext().getSourceManager(),
2455 "Mangling declaration");
2457 msvc_hashing_ostream MHO(Out);
2458 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2459 return Mangler.mangle(D);
2488 MicrosoftCXXNameMangler &Mangler,
2493 switch (MD->getAccess()) {
2495 llvm_unreachable(
"Unsupported access specifier");
2506 Out <<
'R' << AccessSpec;
2507 Mangler.mangleNumber(
2509 Mangler.mangleNumber(
2511 Mangler.mangleNumber(
2513 Mangler.mangleNumber(static_cast<uint32_t>(Adjustment.
NonVirtual));
2516 Mangler.mangleNumber(
2518 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.
NonVirtual));
2521 switch (MD->getAccess()) {
2523 llvm_unreachable(
"Unsupported access specifier");
2533 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.
NonVirtual));
2535 switch (MD->getAccess()) {
2537 llvm_unreachable(
"Unsupported access specifier");
2551 MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
const CXXMethodDecl *MD,
2554 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
2558 msvc_hashing_ostream MHO(Out);
2559 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2560 Mangler.getStream() <<
"\01?";
2561 Mangler.mangleVirtualMemPtrThunk(MD, ML);
2564 void MicrosoftMangleContextImpl::mangleThunk(
const CXXMethodDecl *MD,
2567 msvc_hashing_ostream MHO(Out);
2568 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2569 Mangler.getStream() <<
"\01?";
2570 Mangler.mangleName(MD);
2573 assert(Thunk.
Method !=
nullptr &&
2574 "Thunk info should hold the overridee decl");
2577 Mangler.mangleFunctionType(
2581 void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
2588 msvc_hashing_ostream MHO(Out);
2589 MicrosoftCXXNameMangler Mangler(*
this, MHO, DD, Type);
2590 Mangler.getStream() <<
"\01??_E";
2596 void MicrosoftMangleContextImpl::mangleCXXVFTable(
2603 msvc_hashing_ostream MHO(Out);
2604 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2605 if (Derived->hasAttr<DLLImportAttr>())
2606 Mangler.getStream() <<
"\01??_S";
2608 Mangler.getStream() <<
"\01??_7";
2609 Mangler.mangleName(Derived);
2610 Mangler.getStream() <<
"6B";
2612 Mangler.mangleName(RD);
2613 Mangler.getStream() <<
'@';
2616 void MicrosoftMangleContextImpl::mangleCXXVBTable(
2623 msvc_hashing_ostream MHO(Out);
2624 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2625 Mangler.getStream() <<
"\01??_8";
2626 Mangler.mangleName(Derived);
2627 Mangler.getStream() <<
"7B";
2629 Mangler.mangleName(RD);
2630 Mangler.getStream() <<
'@';
2633 void MicrosoftMangleContextImpl::mangleCXXRTTI(
QualType T, raw_ostream &Out) {
2634 msvc_hashing_ostream MHO(Out);
2635 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2636 Mangler.getStream() <<
"\01??_R0";
2637 Mangler.mangleType(T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
2638 Mangler.getStream() <<
"@8";
2641 void MicrosoftMangleContextImpl::mangleCXXRTTIName(
QualType T,
2643 MicrosoftCXXNameMangler Mangler(*
this, Out);
2644 Mangler.getStream() <<
'.';
2645 Mangler.mangleType(T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
2648 void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
2650 msvc_hashing_ostream MHO(Out);
2651 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2652 Mangler.getStream() <<
"\01??_K";
2653 Mangler.mangleName(SrcRD);
2654 Mangler.getStream() <<
"$C";
2655 Mangler.mangleName(DstRD);
2658 void MicrosoftMangleContextImpl::mangleCXXThrowInfo(
QualType T,
bool IsConst,
2661 uint32_t NumEntries,
2663 msvc_hashing_ostream MHO(Out);
2664 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2665 Mangler.getStream() <<
"_TI";
2667 Mangler.getStream() <<
'C';
2669 Mangler.getStream() <<
'V';
2671 Mangler.getStream() <<
'U';
2672 Mangler.getStream() << NumEntries;
2673 Mangler.mangleType(T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
2676 void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
2677 QualType T, uint32_t NumEntries, raw_ostream &Out) {
2678 msvc_hashing_ostream MHO(Out);
2679 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2680 Mangler.getStream() <<
"_CTA";
2681 Mangler.getStream() << NumEntries;
2682 Mangler.mangleType(T,
SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
2685 void MicrosoftMangleContextImpl::mangleCXXCatchableType(
2687 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
2689 MicrosoftCXXNameMangler Mangler(*
this, Out);
2690 Mangler.getStream() <<
"_CT";
2694 llvm::raw_svector_ostream Stream(RTTIMangling);
2695 msvc_hashing_ostream MHO(Stream);
2696 mangleCXXRTTI(T, MHO);
2698 Mangler.getStream() << RTTIMangling.substr(1);
2703 if (!getASTContext().getLangOpts().isCompatibleWithMSVC(
2706 llvm::raw_svector_ostream Stream(CopyCtorMangling);
2707 msvc_hashing_ostream MHO(Stream);
2708 mangleCXXCtor(CD, CT, MHO);
2710 Mangler.getStream() << CopyCtorMangling.substr(1);
2712 Mangler.getStream() << Size;
2713 if (VBPtrOffset == -1) {
2715 Mangler.getStream() << NVOffset;
2718 Mangler.getStream() << NVOffset;
2719 Mangler.getStream() << VBPtrOffset;
2720 Mangler.getStream() << VBIndex;
2724 void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
2725 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
2726 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
2727 msvc_hashing_ostream MHO(Out);
2728 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2729 Mangler.getStream() <<
"\01??_R1";
2730 Mangler.mangleNumber(NVOffset);
2731 Mangler.mangleNumber(VBPtrOffset);
2732 Mangler.mangleNumber(VBTableOffset);
2733 Mangler.mangleNumber(Flags);
2734 Mangler.mangleName(Derived);
2735 Mangler.getStream() <<
"8";
2738 void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
2740 msvc_hashing_ostream MHO(Out);
2741 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2742 Mangler.getStream() <<
"\01??_R2";
2743 Mangler.mangleName(Derived);
2744 Mangler.getStream() <<
"8";
2747 void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
2749 msvc_hashing_ostream MHO(Out);
2750 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2751 Mangler.getStream() <<
"\01??_R3";
2752 Mangler.mangleName(Derived);
2753 Mangler.getStream() <<
"8";
2756 void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
2764 llvm::raw_svector_ostream Stream(VFTableMangling);
2765 mangleCXXVFTable(Derived, BasePath, Stream);
2767 if (VFTableMangling.startswith(
"\01??@")) {
2768 assert(VFTableMangling.endswith(
"@"));
2769 Out << VFTableMangling <<
"??_R4@";
2773 assert(VFTableMangling.startswith(
"\01??_7") ||
2774 VFTableMangling.startswith(
"\01??_S"));
2776 Out <<
"\01??_R4" << StringRef(VFTableMangling).drop_front(5);
2779 void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
2780 const NamedDecl *EnclosingDecl, raw_ostream &Out) {
2781 msvc_hashing_ostream MHO(Out);
2782 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2787 Mangler.getStream() <<
"\01?filt$" << SEHFilterIds[EnclosingDecl]++ <<
"@0@";
2788 Mangler.mangleName(EnclosingDecl);
2791 void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
2792 const NamedDecl *EnclosingDecl, raw_ostream &Out) {
2793 msvc_hashing_ostream MHO(Out);
2794 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2799 Mangler.getStream() <<
"\01?fin$" << SEHFinallyIds[EnclosingDecl]++ <<
"@0@";
2800 Mangler.mangleName(EnclosingDecl);
2803 void MicrosoftMangleContextImpl::mangleTypeName(
QualType T, raw_ostream &Out) {
2806 MicrosoftCXXNameMangler Mangler(*
this, Out);
2807 Mangler.getStream() <<
'?';
2814 msvc_hashing_ostream MHO(Out);
2815 MicrosoftCXXNameMangler mangler(*
this, MHO, D, Type);
2822 msvc_hashing_ostream MHO(Out);
2823 MicrosoftCXXNameMangler mangler(*
this, MHO, D, Type);
2827 void MicrosoftMangleContextImpl::mangleReferenceTemporary(
2828 const VarDecl *VD,
unsigned ManglingNumber, raw_ostream &Out) {
2829 msvc_hashing_ostream MHO(Out);
2830 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2832 Mangler.getStream() <<
"\01?$RT" << ManglingNumber <<
'@';
2833 Mangler.mangle(VD,
"");
2836 void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
2837 const VarDecl *VD,
unsigned GuardNum, raw_ostream &Out) {
2838 msvc_hashing_ostream MHO(Out);
2839 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2841 Mangler.getStream() <<
"\01?$TSS" << GuardNum <<
'@';
2842 Mangler.mangleNestedName(VD);
2843 Mangler.getStream() <<
"@4HA";
2846 void MicrosoftMangleContextImpl::mangleStaticGuardVariable(
const VarDecl *VD,
2858 msvc_hashing_ostream MHO(Out);
2859 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2863 Mangler.getStream() << (VD->
getTLSKind() ?
"\01??__J" :
"\01??_B");
2865 Mangler.getStream() <<
"\01?$S1@";
2867 unsigned ScopeDepth = 0;
2868 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
2872 Mangler.mangle(VD,
"");
2874 Mangler.mangleNestedName(VD);
2875 Mangler.getStream() << (Visible ?
"@5" :
"@4IA");
2877 Mangler.mangleNumber(ScopeDepth);
2880 void MicrosoftMangleContextImpl::mangleInitFiniStub(
const VarDecl *D,
2883 msvc_hashing_ostream MHO(Out);
2884 MicrosoftCXXNameMangler Mangler(*
this, MHO);
2885 Mangler.getStream() <<
"\01??__" << CharCode;
2886 Mangler.mangleName(D);
2888 Mangler.mangleVariableEncoding(D);
2889 Mangler.getStream() <<
'@';
2893 Mangler.getStream() <<
"YAXXZ";
2896 void MicrosoftMangleContextImpl::mangleDynamicInitializer(
const VarDecl *D,
2899 mangleInitFiniStub(D,
'E', Out);
2903 MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(
const VarDecl *D,
2906 mangleInitFiniStub(D,
'F', Out);
2909 void MicrosoftMangleContextImpl::mangleStringLiteral(
const StringLiteral *SL,
2930 MicrosoftCXXNameMangler Mangler(*
this, Out);
2931 Mangler.getStream() <<
"\01??_C@_";
2935 Mangler.getStream() <<
'1';
2937 Mangler.getStream() <<
'0';
2946 auto GetLittleEndianByte = [&Mangler, &SL](
unsigned Index) {
2948 uint32_t CodeUnit = SL->
getCodeUnit(Index / CharByteWidth);
2949 unsigned OffsetInCodeUnit = Index % CharByteWidth;
2950 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
2953 auto GetBigEndianByte = [&Mangler, &SL](
unsigned Index) {
2955 uint32_t CodeUnit = SL->
getCodeUnit(Index / CharByteWidth);
2956 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
2957 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
2963 JC.update(GetLittleEndianByte(I));
2973 Mangler.mangleNumber(JC.getCRC());
2979 auto MangleByte = [&Mangler](
char Byte) {
2987 Mangler.getStream() << Byte;
2988 }
else if (
isLetter(Byte & 0x7f)) {
2989 Mangler.getStream() <<
'?' <<
static_cast<char>(Byte & 0x7f);
2991 const char SpecialChars[] = {
',',
'/',
'\\',
':',
'.',
2992 ' ',
'\n',
'\t',
'\'',
'-'};
2995 if (Pos !=
std::end(SpecialChars)) {
2996 Mangler.getStream() <<
'?' << (Pos -
std::begin(SpecialChars));
2998 Mangler.getStream() <<
"?$";
2999 Mangler.getStream() <<
static_cast<char>(
'A' + ((Byte >> 4) & 0xf));
3000 Mangler.getStream() <<
static_cast<char>(
'A' + (Byte & 0xf));
3010 MangleByte(GetBigEndianByte(I));
3012 MangleByte(GetLittleEndianByte(I));
3015 if (NumCharsToMangle < 32)
3020 Mangler.getStream() <<
'@';
3025 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...
static Qualifiers fromCVRUMask(unsigned CVRU)
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.
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...
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.
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.
std::unique_ptr< llvm::MemoryBuffer > Buffer
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, ArrayRef< TemplateArgument > Args, QualType Canon)
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.
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.
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.
bool hasUnaligned() const
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.
Represents the type decltype(expr) (C++11).
char __ovld __cnfn min(char x, char y)
Returns y if y < x, otherwise it returns x.
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.
StringRef getUuidStr() const
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.
This file defines OpenMP nodes for declarative directives.
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
struct clang::ThisAdjustment::VirtualAdjustment::@113 Microsoft
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)
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
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
uint64_t Index
Method's index in the vftable.
QualType getElementType() const
A trivial tuple used to represent a source range.
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...
TemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon, QualType Aliased)
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 ...