clang 24.0.0git
MicrosoftMangle.cpp
Go to the documentation of this file.
1//===--- MicrosoftMangle.cpp - Microsoft Visual C++ Name Mangling ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This provides C++ name mangling targeting the Microsoft Visual C++ ABI.
10//
11//===----------------------------------------------------------------------===//
12
14#include "clang/AST/Attr.h"
16#include "clang/AST/CharUnits.h"
17#include "clang/AST/Decl.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/DeclObjC.h"
22#include "clang/AST/Expr.h"
23#include "clang/AST/ExprCXX.h"
25#include "clang/AST/Mangle.h"
27#include "clang/Basic/ABI.h"
33#include "llvm/ADT/SmallVector.h"
34#include "llvm/ADT/StringExtras.h"
35#include "llvm/Support/CRC.h"
36#include "llvm/Support/MD5.h"
37#include "llvm/Support/StringSaver.h"
38#include "llvm/Support/xxhash.h"
39#include <functional>
40#include <optional>
41
42using namespace clang;
43
44namespace {
45
46// Get GlobalDecl of DeclContext of local entities.
47static GlobalDecl getGlobalDeclAsDeclContext(const DeclContext *DC) {
48 GlobalDecl GD;
49 if (auto *CD = dyn_cast<CXXConstructorDecl>(DC))
50 GD = GlobalDecl(CD, Ctor_Complete);
51 else if (auto *DD = dyn_cast<CXXDestructorDecl>(DC))
52 GD = GlobalDecl(DD, Dtor_Complete);
53 else
55 return GD;
56}
57
58struct msvc_hashing_ostream : public llvm::raw_svector_ostream {
59 raw_ostream &OS;
60 size_t Threshold;
61 llvm::SmallString<64> Buffer;
62
63 msvc_hashing_ostream(raw_ostream &OS, size_t Threshold = 4096)
64 : llvm::raw_svector_ostream(Buffer), OS(OS), Threshold(Threshold) {}
65 ~msvc_hashing_ostream() override {
66 StringRef MangledName = str();
67 bool StartsWithEscape = MangledName.starts_with("\01");
68 if (StartsWithEscape)
69 MangledName = MangledName.drop_front(1);
70 if (MangledName.size() < Threshold) {
71 OS << str();
72 return;
73 }
74
75 llvm::MD5 Hasher;
76 llvm::MD5::MD5Result Hash;
77 Hasher.update(MangledName);
78 Hasher.final(Hash);
79
80 SmallString<32> HexString;
81 llvm::MD5::stringifyResult(Hash, HexString);
82
83 if (StartsWithEscape)
84 OS << '\01';
85 OS << "??@" << HexString << '@';
86 }
87};
88
89static const DeclContext *
90getLambdaDefaultArgumentDeclContext(const Decl *D) {
91 if (const auto *RD = dyn_cast<CXXRecordDecl>(D))
92 if (RD->isLambda())
93 if (const auto *Parm =
94 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
95 return Parm->getDeclContext();
96 return nullptr;
97}
98
99/// Retrieve the declaration context that should be used when mangling
100/// the given declaration.
101static const DeclContext *getEffectiveDeclContext(const Decl *D) {
102 // The ABI assumes that lambda closure types that occur within
103 // default arguments live in the context of the function. However, due to
104 // the way in which Clang parses and creates function declarations, this is
105 // not the case: the lambda closure type ends up living in the context
106 // where the function itself resides, because the function declaration itself
107 // had not yet been created. Fix the context here.
108 if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))
109 return LDADC;
110
111 // Perform the same check for block literals.
112 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
113 if (ParmVarDecl *ContextParam =
114 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
115 return ContextParam->getDeclContext();
116 }
117
118 const DeclContext *DC = D->getDeclContext();
121 return getEffectiveDeclContext(cast<Decl>(DC));
122 }
123
124 return DC->getRedeclContext();
125}
126
127static const FunctionDecl *getStructor(const NamedDecl *ND) {
128 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
129 return FTD->getTemplatedDecl()->getCanonicalDecl();
130
131 const auto *FD = cast<FunctionDecl>(ND);
132 if (const auto *FTD = FD->getPrimaryTemplate())
133 return FTD->getTemplatedDecl()->getCanonicalDecl();
134
135 return FD->getCanonicalDecl();
136}
137
138/// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
139/// Microsoft Visual C++ ABI.
140class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
141 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
142 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
143 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
144 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
145 llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;
146 llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;
147 SmallString<16> AnonymousNamespaceHash;
148
149public:
150 MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags,
151 bool IsAux = false);
152 bool shouldMangleCXXName(const NamedDecl *D) override;
153 bool shouldMangleStringLiteral(const StringLiteral *SL) override;
154 void mangleCXXName(GlobalDecl GD, raw_ostream &Out) override;
155 void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
156 const MethodVFTableLocation &ML,
157 raw_ostream &Out) override;
158 void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk,
159 bool ElideOverrideInfo, raw_ostream &) override;
160 void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
161 const ThunkInfo &Thunk, bool ElideOverrideInfo,
162 raw_ostream &) override;
163 void mangleCXXVFTable(const CXXRecordDecl *Derived,
164 ArrayRef<const CXXRecordDecl *> BasePath,
165 raw_ostream &Out) override;
166 void mangleCXXVBTable(const CXXRecordDecl *Derived,
167 ArrayRef<const CXXRecordDecl *> BasePath,
168 raw_ostream &Out) override;
169
170 void mangleCXXVTable(const CXXRecordDecl *, raw_ostream &) override;
171 void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
172 const CXXRecordDecl *DstRD,
173 raw_ostream &Out) override;
174 void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
175 bool IsUnaligned, uint32_t NumEntries,
176 raw_ostream &Out) override;
177 void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
178 raw_ostream &Out) override;
179 void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
180 CXXCtorType CT, uint32_t Size, uint32_t NVOffset,
181 int32_t VBPtrOffset, uint32_t VBIndex,
182 raw_ostream &Out) override;
183 void mangleCXXRTTI(QualType T, raw_ostream &Out) override;
184 void mangleCXXRTTIName(QualType T, raw_ostream &Out,
185 bool NormalizeIntegers) override;
186 void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived,
187 uint32_t NVOffset, int32_t VBPtrOffset,
188 uint32_t VBTableOffset, uint32_t Flags,
189 raw_ostream &Out) override;
190 void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
191 raw_ostream &Out) override;
192 void mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
193 raw_ostream &Out) override;
194 void
195 mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
196 ArrayRef<const CXXRecordDecl *> BasePath,
197 raw_ostream &Out) override;
198 void mangleCanonicalTypeName(QualType T, raw_ostream &,
199 bool NormalizeIntegers) override;
200 void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber,
201 raw_ostream &) override;
202 void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override;
203 void mangleThreadSafeStaticGuardVariable(const VarDecl *D, unsigned GuardNum,
204 raw_ostream &Out) override;
205 void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
206 void mangleDynamicAtExitDestructor(const VarDecl *D,
207 raw_ostream &Out) override;
208 void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
209 raw_ostream &Out) override;
210 void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
211 raw_ostream &Out) override;
212 void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override;
213 bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
214 const DeclContext *DC = getEffectiveDeclContext(ND);
215 if (!DC->isFunctionOrMethod())
216 return false;
217
218 // Lambda closure types are already numbered, give out a phony number so
219 // that they demangle nicely.
220 if (const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
221 if (RD->isLambda()) {
222 disc = 1;
223 return true;
224 }
225 }
226
227 // Use the canonical number for externally visible decls.
228 if (ND->isExternallyVisible()) {
229 disc = getASTContext().getManglingNumber(ND, isAux());
230 return true;
231 }
232
233 // Anonymous tags are already numbered.
234 if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
235 if (!Tag->hasNameForLinkage() &&
236 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&
237 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))
238 return false;
239 }
240
241 // Make up a reasonable number for internal decls.
242 unsigned &discriminator = Uniquifier[ND];
243 if (!discriminator)
244 discriminator = ++Discriminator[std::make_pair(DC, ND->getIdentifier())];
245 disc = discriminator + 1;
246 return true;
247 }
248
249 std::string getLambdaString(const CXXRecordDecl *Lambda) override {
250 assert(Lambda->isLambda() && "RD must be a lambda!");
251 std::string Name("<lambda_");
252
253 Decl *LambdaContextDecl = Lambda->getLambdaContextDecl();
254 unsigned LambdaManglingNumber = Lambda->getLambdaManglingNumber();
255 unsigned LambdaId;
256 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
257 const FunctionDecl *Func =
258 Parm ? dyn_cast<FunctionDecl>(Parm->getDeclContext()) : nullptr;
259
260 if (Func) {
261 unsigned DefaultArgNo =
262 Func->getNumParams() - Parm->getFunctionScopeIndex();
263 Name += llvm::utostr(DefaultArgNo);
264 Name += "_";
265 }
266
267 if (LambdaManglingNumber)
268 LambdaId = LambdaManglingNumber;
269 else
270 LambdaId = getLambdaIdForDebugInfo(Lambda);
271
272 Name += llvm::utostr(LambdaId);
273 Name += ">";
274 return Name;
275 }
276
277 unsigned getLambdaId(const CXXRecordDecl *RD) {
278 assert(RD->isLambda() && "RD must be a lambda!");
279 assert(!RD->isExternallyVisible() && "RD must not be visible!");
280 assert(RD->getLambdaManglingNumber() == 0 &&
281 "RD must not have a mangling number!");
282 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator, bool>
283 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
284 return Result.first->second;
285 }
286
287 unsigned getLambdaIdForDebugInfo(const CXXRecordDecl *RD) {
288 assert(RD->isLambda() && "RD must be a lambda!");
289 assert(!RD->isExternallyVisible() && "RD must not be visible!");
290 assert(RD->getLambdaManglingNumber() == 0 &&
291 "RD must not have a mangling number!");
292 // The lambda should exist, but return 0 in case it doesn't.
293 return LambdaIds.lookup(RD);
294 }
295
296 /// Return a character sequence that is (somewhat) unique to the TU suitable
297 /// for mangling anonymous namespaces.
298 StringRef getAnonymousNamespaceHash() const {
299 return AnonymousNamespaceHash;
300 }
301
302private:
303 void mangleInitFiniStub(const VarDecl *D, char CharCode, raw_ostream &Out);
304};
305
306/// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
307/// Microsoft Visual C++ ABI.
308class MicrosoftCXXNameMangler {
309 MicrosoftMangleContextImpl &Context;
310 raw_ostream &Out;
311
312 /// The "structor" is the top-level declaration being mangled, if
313 /// that's not a template specialization; otherwise it's the pattern
314 /// for that specialization.
315 const NamedDecl *Structor;
316 unsigned StructorType;
317
318 typedef llvm::SmallVector<std::string, 10> BackRefVec;
319 BackRefVec NameBackReferences;
320
321 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
322 ArgBackRefMap FunArgBackReferences;
323 ArgBackRefMap TemplateArgBackReferences;
324
325 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;
326 TemplateArgStringMap TemplateArgStrings;
327 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;
328 llvm::StringSaver TemplateArgStringStorage;
329
330 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
331 PassObjectSizeArgsSet PassObjectSizeArgs;
332
333 ASTContext &getASTContext() const { return Context.getASTContext(); }
334
335 const bool PointersAre64Bit;
336
337 DiagnosticBuilder Error(SourceLocation, StringRef, StringRef);
338 DiagnosticBuilder Error(SourceLocation, StringRef);
339 DiagnosticBuilder Error(StringRef);
340
341public:
342 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
343 enum class TplArgKind { ClassNTTP, StructuralValue };
344
345 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
346 : Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
347 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
348 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
349 LangAS::Default) == 64) {}
350
351 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
352 const CXXConstructorDecl *D, CXXCtorType Type)
353 : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
354 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
355 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
356 LangAS::Default) == 64) {}
357
358 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
359 const CXXDestructorDecl *D, CXXDtorType Type)
360 : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
361 TemplateArgStringStorage(TemplateArgStringStorageAlloc),
362 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
363 LangAS::Default) == 64) {}
364
365 raw_ostream &getStream() const { return Out; }
366
367 void mangle(GlobalDecl GD, StringRef Prefix = "?");
368 void mangleName(GlobalDecl GD);
369 void mangleFunctionEncoding(GlobalDecl GD, bool ShouldMangle);
370 void mangleVariableEncoding(const VarDecl *VD);
371 void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD,
372 const NonTypeTemplateParmDecl *PD,
373 QualType TemplateArgType,
374 StringRef Prefix = "$");
375 void mangleMemberDataPointerInClassNTTP(const CXXRecordDecl *,
376 const ValueDecl *);
377 void mangleMemberFunctionPointer(const CXXRecordDecl *RD,
378 const CXXMethodDecl *MD,
379 const NonTypeTemplateParmDecl *PD,
380 QualType TemplateArgType,
381 StringRef Prefix = "$");
382 void mangleFunctionPointer(const FunctionDecl *FD,
383 const NonTypeTemplateParmDecl *PD,
384 QualType TemplateArgType);
385 void mangleVarDecl(const VarDecl *VD, const NonTypeTemplateParmDecl *PD,
386 QualType TemplateArgType);
387 void mangleMemberFunctionPointerInClassNTTP(const CXXRecordDecl *RD,
388 const CXXMethodDecl *MD);
389 void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
390 const MethodVFTableLocation &ML);
391 void mangleNumber(int64_t Number);
392 void mangleNumber(llvm::APSInt Number);
393 void mangleFloat(llvm::APFloat Number);
394 void mangleBits(llvm::APInt Number);
395 void mangleTagTypeKind(TagTypeKind TK);
396 void mangleArtificialTagType(TagTypeKind TK, StringRef UnqualifiedName,
397 ArrayRef<StringRef> NestedNames = {});
398 void mangleAddressSpaceType(QualType T, Qualifiers Quals, SourceRange Range);
399 void mangleType(QualType T, SourceRange Range,
400 QualifierMangleMode QMM = QMM_Mangle);
401 void mangleFunctionType(const FunctionType *T,
402 const FunctionDecl *D = nullptr,
403 bool ForceThisQuals = false,
404 bool MangleExceptionSpec = true);
405 void mangleSourceName(StringRef Name);
406 void mangleNestedName(GlobalDecl GD);
407
408 void mangleAutoReturnType(QualType T, QualifierMangleMode QMM);
409
410private:
411 bool isStructorDecl(const NamedDecl *ND) const {
412 return ND == Structor || getStructor(ND) == Structor;
413 }
414
415 bool is64BitPointer(Qualifiers Quals) const {
416 LangAS AddrSpace = Quals.getAddressSpace();
417 return AddrSpace == LangAS::ptr64 ||
418 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||
419 AddrSpace == LangAS::ptr32_uptr));
420 }
421
422 void mangleUnqualifiedName(GlobalDecl GD) {
423 mangleUnqualifiedName(GD, cast<NamedDecl>(GD.getDecl())->getDeclName());
424 }
425 void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name);
426 void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc);
427 void mangleCXXDtorType(CXXDtorType T);
428 void mangleQualifiers(Qualifiers Quals, bool IsMember);
429 void mangleRefQualifier(RefQualifierKind RefQualifier);
430 void manglePointerCVQualifiers(Qualifiers Quals);
431 void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType);
432 void manglePointerAuthQualifier(Qualifiers Quals);
433
434 void mangleUnscopedTemplateName(GlobalDecl GD);
435 void
436 mangleTemplateInstantiationName(GlobalDecl GD,
437 const TemplateArgumentList &TemplateArgs);
438 void mangleObjCMethodName(const ObjCMethodDecl *MD);
439
440 void mangleFunctionArgumentType(QualType T, SourceRange Range);
441 void manglePassObjectSizeArg(const PassObjectSizeAttr *POSA);
442
443 bool isArtificialTagType(QualType T) const;
444
445 // Declare manglers for every type class.
446#define ABSTRACT_TYPE(CLASS, PARENT)
447#define NON_CANONICAL_TYPE(CLASS, PARENT)
448#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
449 Qualifiers Quals, \
450 SourceRange Range);
451#include "clang/AST/TypeNodes.inc"
452#undef ABSTRACT_TYPE
453#undef NON_CANONICAL_TYPE
454#undef TYPE
455
456 void mangleType(const TagDecl *TD);
457 void mangleDecayedArrayType(const ArrayType *T);
458 void mangleArrayType(const ArrayType *T);
459 void mangleFunctionClass(const FunctionDecl *FD);
460 void mangleCallingConvention(CallingConv CC, SourceRange Range);
461 void mangleCallingConvention(const FunctionType *T, SourceRange Range);
462 void mangleIntegerLiteral(const llvm::APSInt &Number,
463 const NonTypeTemplateParmDecl *PD = nullptr,
464 QualType TemplateArgType = QualType());
465 void mangleExpression(const Expr *E, const NonTypeTemplateParmDecl *PD);
466 void mangleThrowSpecification(const FunctionProtoType *T);
467
468 void mangleTemplateArgs(const TemplateDecl *TD,
469 const TemplateArgumentList &TemplateArgs);
470 void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA,
471 const NamedDecl *Parm);
472 void mangleTemplateArgValue(QualType T, const APValue &V, TplArgKind,
473 bool WithScalarType = false);
474
475 void mangleObjCProtocol(const ObjCProtocolDecl *PD);
476 void mangleObjCLifetime(const QualType T, Qualifiers Quals,
477 SourceRange Range);
478 void mangleObjCKindOfType(const ObjCObjectType *T, Qualifiers Quals,
479 SourceRange Range);
480
481 void mangleAutoReturnType(const MemberPointerType *T, Qualifiers Quals);
482 void mangleAutoReturnType(const PointerType *T, Qualifiers Quals);
483 void mangleAutoReturnType(const LValueReferenceType *T, Qualifiers Quals);
484 void mangleAutoReturnType(const RValueReferenceType *T, Qualifiers Quals);
485};
486}
487
488MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(ASTContext &Context,
489 DiagnosticsEngine &Diags,
490 bool IsAux)
491 : MicrosoftMangleContext(Context, Diags, IsAux) {
492 // To mangle anonymous namespaces, hash the path to the main source file. The
493 // path should be whatever (probably relative) path was passed on the command
494 // line. The goal is for the compiler to produce the same output regardless of
495 // working directory, so use the uncanonicalized relative path.
496 //
497 // It's important to make the mangled names unique because, when CodeView
498 // debug info is in use, the debugger uses mangled type names to distinguish
499 // between otherwise identically named types in anonymous namespaces.
500 //
501 // These symbols are always internal, so there is no need for the hash to
502 // match what MSVC produces. For the same reason, clang is free to change the
503 // hash at any time without breaking compatibility with old versions of clang.
504 // The generated names are intended to look similar to what MSVC generates,
505 // which are something like "?A0x01234567@".
506 SourceManager &SM = Context.getSourceManager();
508 SmallString<256> Path(FE->getName());
509 // Do a path substitution from the MacroPrefixMap if needed.
510 clang::Preprocessor::processPathForFileMacro(Path, Context.getLangOpts(),
511 Context.getTargetInfo());
512
513 // Truncate the hash so we get 8 characters of hexadecimal.
514 uint32_t TruncatedHash = uint32_t(xxh3_64bits(Path));
515 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
516 } else {
517 // If we don't have a path to the main file, we'll just use 0.
518 AnonymousNamespaceHash = "0";
519 }
520}
521
522bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
523 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
524 LanguageLinkage L = FD->getLanguageLinkage();
525 // Overloadable functions need mangling.
526 if (FD->hasAttr<OverloadableAttr>())
527 return true;
528
529 // The ABI expects that we would never mangle "typical" user-defined entry
530 // points regardless of visibility or freestanding-ness.
531 //
532 // N.B. This is distinct from asking about "main". "main" has a lot of
533 // special rules associated with it in the standard while these
534 // user-defined entry points are outside of the purview of the standard.
535 // For example, there can be only one definition for "main" in a standards
536 // compliant program; however nothing forbids the existence of wmain and
537 // WinMain in the same translation unit.
538 if (FD->isMSVCRTEntryPoint())
539 return false;
540
541 // C++ functions and those whose names are not a simple identifier need
542 // mangling.
543 if (!FD->getDeclName().isIdentifier() || L == CXXLanguageLinkage)
544 return true;
545
546 // C functions are not mangled.
547 if (L == CLanguageLinkage)
548 return false;
549 }
550
551 // Otherwise, no mangling is done outside C++ mode.
552 if (!getASTContext().getLangOpts().CPlusPlus)
553 return false;
554
555 const VarDecl *VD = dyn_cast<VarDecl>(D);
556 if (VD && !isa<DecompositionDecl>(D)) {
557 // C variables are not mangled.
558 if (VD->isExternC())
559 return false;
560
561 // Variables at global scope with internal linkage are not mangled.
562 const DeclContext *DC = getEffectiveDeclContext(D);
563 if (DC->isTranslationUnit() && D->getFormalLinkage() == Linkage::Internal &&
565 return false;
566 }
567
568 return true;
569}
570
571bool
572MicrosoftMangleContextImpl::shouldMangleStringLiteral(const StringLiteral *SL) {
573 return true;
574}
575
576DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
577 StringRef thing1,
578 StringRef thing2) {
579 DiagnosticsEngine &Diags = Context.getDiags();
580 return Diags.Report(loc, diag::err_ms_mangle_unsupported_with_detail)
581 << thing1 << thing2;
582}
583
584DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,
585 StringRef thingy) {
586 DiagnosticsEngine &Diags = Context.getDiags();
587 return Diags.Report(loc, diag::err_ms_mangle_unsupported) << thingy;
588}
589
590DiagnosticBuilder MicrosoftCXXNameMangler::Error(StringRef thingy) {
591 DiagnosticsEngine &Diags = Context.getDiags();
592 // extra placeholders are ignored quietly when not used
593 return Diags.Report(diag::err_ms_mangle_unsupported) << thingy;
594}
595
596void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) {
597 const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
598 // MSVC doesn't mangle C++ names the same way it mangles extern "C" names.
599 // Therefore it's really important that we don't decorate the
600 // name with leading underscores or leading/trailing at signs. So, by
601 // default, we emit an asm marker at the start so we get the name right.
602 // Callers can override this with a custom prefix.
603
604 // <mangled-name> ::= ? <name> <type-encoding>
605 Out << Prefix;
606 mangleName(GD);
607 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
608 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));
609 else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
610 mangleVariableEncoding(VD);
611 else if (isa<MSGuidDecl>(D))
612 // MSVC appears to mangle GUIDs as if they were variables of type
613 // 'const struct __s_GUID'.
614 Out << "3U__s_GUID@@B";
615 else if (isa<TemplateParamObjectDecl>(D)) {
616 // Template parameter objects don't get a <type-encoding>; their type is
617 // specified as part of their value.
618 } else
619 llvm_unreachable("Tried to mangle unexpected NamedDecl!");
620}
621
622void MicrosoftCXXNameMangler::mangleFunctionEncoding(GlobalDecl GD,
623 bool ShouldMangle) {
624 const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
625 // <type-encoding> ::= <function-class> <function-type>
626
627 // Since MSVC operates on the type as written and not the canonical type, it
628 // actually matters which decl we have here. MSVC appears to choose the
629 // first, since it is most likely to be the declaration in a header file.
630 FD = FD->getFirstDecl();
631
632 // We should never ever see a FunctionNoProtoType at this point.
633 // We don't even know how to mangle their types anyway :).
634 const FunctionProtoType *FT = FD->getType()->castAs<FunctionProtoType>();
635
636 // extern "C" functions can hold entities that must be mangled.
637 // As it stands, these functions still need to get expressed in the full
638 // external name. They have their class and type omitted, replaced with '9'.
639 if (ShouldMangle) {
640 // We would like to mangle all extern "C" functions using this additional
641 // component but this would break compatibility with MSVC's behavior.
642 // Instead, do this when we know that compatibility isn't important (in
643 // other words, when it is an overloaded extern "C" function).
644 if (FD->isExternC() && FD->hasAttr<OverloadableAttr>())
645 Out << "$$J0";
646
647 mangleFunctionClass(FD);
648
649 mangleFunctionType(FT, FD, false, false);
650 } else {
651 Out << '9';
652 }
653}
654
655void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
656 // <type-encoding> ::= <storage-class> <variable-type>
657 // <storage-class> ::= 0 # private static member
658 // ::= 1 # protected static member
659 // ::= 2 # public static member
660 // ::= 3 # global
661 // ::= 4 # static local
662
663 // The first character in the encoding (after the name) is the storage class.
664 if (VD->isStaticDataMember()) {
665 // If it's a static member, it also encodes the access level.
666 switch (VD->getAccess()) {
667 default:
668 case AS_private: Out << '0'; break;
669 case AS_protected: Out << '1'; break;
670 case AS_public: Out << '2'; break;
671 }
672 }
673 else if (!VD->isStaticLocal())
674 Out << '3';
675 else
676 Out << '4';
677 // Now mangle the type.
678 // <variable-type> ::= <type> <cvr-qualifiers>
679 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
680 // Pointers and references are odd. The type of 'int * const foo;' gets
681 // mangled as 'QAHA' instead of 'PAHB', for example.
682 SourceRange SR = VD->getSourceRange();
683 QualType Ty = VD->getType();
684 if (Ty->isPointerType() || Ty->isReferenceType() ||
685 Ty->isMemberPointerType()) {
686 mangleType(Ty, SR, QMM_Drop);
687 manglePointerExtQualifiers(
688 Ty.getDesugaredType(getASTContext()).getLocalQualifiers(), QualType());
689 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()) {
690 mangleQualifiers(MPT->getPointeeType().getQualifiers(), true);
691 // Member pointers are suffixed with a back reference to the member
692 // pointer's class name.
693 mangleName(MPT->getMostRecentCXXRecordDecl());
694 } else
695 mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
696 } else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
697 // Global arrays are funny, too.
698 mangleDecayedArrayType(AT);
699 if (AT->getElementType()->isArrayType())
700 Out << 'A';
701 else
702 mangleQualifiers(Ty.getQualifiers(), false);
703 } else {
704 mangleType(Ty, SR, QMM_Drop);
705 mangleQualifiers(Ty.getQualifiers(), false);
706 }
707}
708
709void MicrosoftCXXNameMangler::mangleMemberDataPointer(
710 const CXXRecordDecl *RD, const ValueDecl *VD,
711 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
712 StringRef Prefix) {
713 // <member-data-pointer> ::= <integer-literal>
714 // ::= $F <number> <number>
715 // ::= $G <number> <number> <number>
716 //
717 // <auto-nttp> ::= $ M <type> <integer-literal>
718 // <auto-nttp> ::= $ M <type> F <name> <number>
719 // <auto-nttp> ::= $ M <type> G <name> <number> <number>
720
721 int64_t FieldOffset;
722 int64_t VBTableOffset;
724 if (VD) {
725 FieldOffset = getASTContext().getFieldOffset(VD);
726 assert(FieldOffset % getASTContext().getCharWidth() == 0 &&
727 "cannot take address of bitfield");
728 FieldOffset /= getASTContext().getCharWidth();
729
730 VBTableOffset = 0;
731
732 if (IM == MSInheritanceModel::Virtual)
733 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
734 } else {
735 FieldOffset = RD->nullFieldOffsetIsZero() ? 0 : -1;
736
737 VBTableOffset = -1;
738 }
739
740 char Code = '\0';
741 switch (IM) {
742 case MSInheritanceModel::Single: Code = '0'; break;
743 case MSInheritanceModel::Multiple: Code = '0'; break;
744 case MSInheritanceModel::Virtual: Code = 'F'; break;
745 case MSInheritanceModel::Unspecified: Code = 'G'; break;
746 }
747
748 Out << Prefix;
749
750 if (VD &&
751 getASTContext().getLangOpts().isCompatibleWithMSVC(
752 LangOptions::MSVC2019) &&
753 PD && PD->getType()->getTypeClass() == Type::Auto &&
754 !TemplateArgType.isNull()) {
755 Out << "M";
756 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
757 }
758
759 Out << Code;
760
761 mangleNumber(FieldOffset);
762
763 // The C++ standard doesn't allow base-to-derived member pointer conversions
764 // in template parameter contexts, so the vbptr offset of data member pointers
765 // is always zero.
767 mangleNumber(0);
769 mangleNumber(VBTableOffset);
770}
771
772void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(
773 const CXXRecordDecl *RD, const ValueDecl *VD) {
775 // <nttp-class-member-data-pointer> ::= <member-data-pointer>
776 // ::= N
777 // ::= 8 <postfix> @ <unqualified-name> @
778
779 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)
780 return mangleMemberDataPointer(RD, VD, nullptr, QualType(), "");
781
782 if (!VD) {
783 Out << 'N';
784 return;
785 }
786
787 Out << '8';
788 mangleNestedName(VD);
789 Out << '@';
790 mangleUnqualifiedName(VD);
791 Out << '@';
792}
793
794void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(
795 const CXXRecordDecl *RD, const CXXMethodDecl *MD,
796 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,
797 StringRef Prefix) {
798 // <member-function-pointer> ::= $1? <name>
799 // ::= $H? <name> <number>
800 // ::= $I? <name> <number> <number>
801 // ::= $J? <name> <number> <number> <number>
802 //
803 // <auto-nttp> ::= $ M <type> 1? <name>
804 // <auto-nttp> ::= $ M <type> H? <name> <number>
805 // <auto-nttp> ::= $ M <type> I? <name> <number> <number>
806 // <auto-nttp> ::= $ M <type> J? <name> <number> <number> <number>
807
809
810 char Code = '\0';
811 switch (IM) {
812 case MSInheritanceModel::Single: Code = '1'; break;
813 case MSInheritanceModel::Multiple: Code = 'H'; break;
814 case MSInheritanceModel::Virtual: Code = 'I'; break;
815 case MSInheritanceModel::Unspecified: Code = 'J'; break;
816 }
817
818 // If non-virtual, mangle the name. If virtual, mangle as a virtual memptr
819 // thunk.
820 uint64_t NVOffset = 0;
821 uint64_t VBTableOffset = 0;
822 uint64_t VBPtrOffset = 0;
823 if (MD) {
824 Out << Prefix;
825
826 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
827 LangOptions::MSVC2019) &&
828 PD && PD->getType()->getTypeClass() == Type::Auto &&
829 !TemplateArgType.isNull()) {
830 Out << "M";
831 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
832 }
833
834 Out << Code << '?';
835 if (MD->isVirtual()) {
836 MicrosoftVTableContext *VTContext =
837 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
838 MethodVFTableLocation ML =
839 VTContext->getMethodVFTableLocation(GlobalDecl(MD));
840 mangleVirtualMemPtrThunk(MD, ML);
841 NVOffset = ML.VFPtrOffset.getQuantity();
842 VBTableOffset = ML.VBTableIndex * 4;
843 if (ML.VBase) {
844 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
845 VBPtrOffset = Layout.getVBPtrOffset().getQuantity();
846 }
847 } else {
848 mangleName(MD);
849 mangleFunctionEncoding(MD, /*ShouldMangle=*/true);
850 }
851
852 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)
853 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
854 } else {
855 // Null single inheritance member functions are encoded as a simple nullptr.
856 if (IM == MSInheritanceModel::Single) {
857 Out << Prefix << "0A@";
858 return;
859 }
860 if (IM == MSInheritanceModel::Unspecified)
861 VBTableOffset = -1;
862 Out << Prefix << Code;
863 }
864
865 if (inheritanceModelHasNVOffsetField(/*IsMemberFunction=*/true, IM))
866 mangleNumber(static_cast<uint32_t>(NVOffset));
868 mangleNumber(VBPtrOffset);
870 mangleNumber(VBTableOffset);
871}
872
873void MicrosoftCXXNameMangler::mangleFunctionPointer(
874 const FunctionDecl *FD, const NonTypeTemplateParmDecl *PD,
875 QualType TemplateArgType) {
876 // <func-ptr> ::= $1? <mangled-name>
877 // <func-ptr> ::= <auto-nttp>
878 //
879 // <auto-nttp> ::= $ M <type> 1? <mangled-name>
880 Out << '$';
881
882 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
883 LangOptions::MSVC2019) &&
884 PD && PD->getType()->getTypeClass() == Type::Auto &&
885 !TemplateArgType.isNull()) {
886 Out << "M";
887 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
888 }
889
890 Out << "1?";
891 mangleName(FD);
892 mangleFunctionEncoding(FD, /*ShouldMangle=*/true);
893}
894
895void MicrosoftCXXNameMangler::mangleVarDecl(const VarDecl *VD,
896 const NonTypeTemplateParmDecl *PD,
897 QualType TemplateArgType) {
898 // <var-ptr> ::= $1? <mangled-name>
899 // <var-ptr> ::= <auto-nttp>
900 //
901 // <auto-nttp> ::= $ M <type> 1? <mangled-name>
902 Out << '$';
903
904 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
905 LangOptions::MSVC2019) &&
906 PD && PD->getType()->getTypeClass() == Type::Auto &&
907 !TemplateArgType.isNull()) {
908 Out << "M";
909 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
910 }
911
912 Out << "1?";
913 mangleName(VD);
914 mangleVariableEncoding(VD);
915}
916
917void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
918 const CXXRecordDecl *RD, const CXXMethodDecl *MD) {
919 // <nttp-class-member-function-pointer> ::= <member-function-pointer>
920 // ::= N
921 // ::= E? <virtual-mem-ptr-thunk>
922 // ::= E? <mangled-name> <type-encoding>
923
924 if (!MD) {
925 if (RD->getMSInheritanceModel() != MSInheritanceModel::Single)
926 return mangleMemberFunctionPointer(RD, MD, nullptr, QualType(), "");
927
928 Out << 'N';
929 return;
930 }
931
932 Out << "E?";
933 if (MD->isVirtual()) {
934 MicrosoftVTableContext *VTContext =
935 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
936 MethodVFTableLocation ML =
937 VTContext->getMethodVFTableLocation(GlobalDecl(MD));
938 mangleVirtualMemPtrThunk(MD, ML);
939 } else {
940 mangleName(MD);
941 mangleFunctionEncoding(MD, /*ShouldMangle=*/true);
942 }
943}
944
945void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
946 const CXXMethodDecl *MD, const MethodVFTableLocation &ML) {
947 // Get the vftable offset.
948 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
949 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));
950 uint64_t OffsetInVFTable = ML.Index * PointerWidth.getQuantity();
951
952 Out << "?_9";
953 mangleName(MD->getParent());
954 Out << "$B";
955 mangleNumber(OffsetInVFTable);
956 Out << 'A';
957 mangleCallingConvention(MD->getType()->castAs<FunctionProtoType>(),
958 MD->getSourceRange());
959}
960
961void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {
962 // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
963
964 // Always start with the unqualified name.
965 mangleUnqualifiedName(GD);
966
967 mangleNestedName(GD);
968
969 // Terminate the whole name with an '@'.
970 Out << '@';
971}
972
973void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
974 mangleNumber(llvm::APSInt(llvm::APInt(64, Number), /*IsUnsigned*/false));
975}
976
977void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {
978 // MSVC never mangles any integer wider than 64 bits. In general it appears
979 // to convert every integer to signed 64 bit before mangling (including
980 // unsigned 64 bit values). Do the same, but preserve bits beyond the bottom
981 // 64.
982 unsigned Width = std::max(Number.getBitWidth(), 64U);
983 llvm::APInt Value = Number.extend(Width);
984
985 // <non-negative integer> ::= A@ # when Number == 0
986 // ::= <decimal digit> # when 1 <= Number <= 10
987 // ::= <hex digit>+ @ # when Number >= 10
988 //
989 // <number> ::= [?] <non-negative integer>
990
991 if (Value.isNegative()) {
992 Value = -Value;
993 Out << '?';
994 }
995 mangleBits(Value);
996}
997
998void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
999 using llvm::APFloat;
1000
1001 switch (APFloat::SemanticsToEnum(Number.getSemantics())) {
1002 case APFloat::S_IEEEsingle: Out << 'A'; break;
1003 case APFloat::S_IEEEdouble: Out << 'B'; break;
1004
1005 // The following are all Clang extensions. We try to pick manglings that are
1006 // unlikely to conflict with MSVC's scheme.
1007 case APFloat::S_IEEEhalf: Out << 'V'; break;
1008 case APFloat::S_BFloat: Out << 'W'; break;
1009 case APFloat::S_x87DoubleExtended: Out << 'X'; break;
1010 case APFloat::S_IEEEquad: Out << 'Y'; break;
1011 case APFloat::S_PPCDoubleDouble: Out << 'Z'; break;
1012 case APFloat::S_PPCDoubleDoubleLegacy:
1013 case APFloat::S_Float8E5M2:
1014 case APFloat::S_Float8E4M3:
1015 case APFloat::S_Float8E4M3FN:
1016 case APFloat::S_Float8E5M2FNUZ:
1017 case APFloat::S_Float8E4M3FNUZ:
1018 case APFloat::S_Float8E4M3B11FNUZ:
1019 case APFloat::S_Float8E3M4:
1020 case APFloat::S_FloatTF32:
1021 case APFloat::S_Float8E8M0FNU:
1022 case APFloat::S_Float8E5M3FNU:
1023 case APFloat::S_Float6E3M2FN:
1024 case APFloat::S_Float6E2M3FN:
1025 case APFloat::S_Float4E2M1FN:
1026 llvm_unreachable("Tried to mangle unexpected APFloat semantics");
1027 }
1028
1029 mangleBits(Number.bitcastToAPInt());
1030}
1031
1032void MicrosoftCXXNameMangler::mangleBits(llvm::APInt Value) {
1033 if (Value == 0)
1034 Out << "A@";
1035 else if (Value.uge(1) && Value.ule(10))
1036 Out << (Value - 1);
1037 else {
1038 // Numbers that are not encoded as decimal digits are represented as nibbles
1039 // in the range of ASCII characters 'A' to 'P'.
1040 // The number 0x123450 would be encoded as 'BCDEFA'
1041 llvm::SmallString<32> EncodedNumberBuffer;
1042 for (; Value != 0; Value.lshrInPlace(4))
1043 EncodedNumberBuffer.push_back('A' + (Value & 0xf).getZExtValue());
1044 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1045 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1046 Out << '@';
1047 }
1048}
1049
1051 const TemplateArgumentList *&TemplateArgs) {
1052 const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
1053 // Check if we have a function template.
1054 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1055 if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {
1056 TemplateArgs = FD->getTemplateSpecializationArgs();
1057 return GD.getWithDecl(TD);
1058 }
1059 }
1060
1061 // Check if we have a class template.
1062 if (const ClassTemplateSpecializationDecl *Spec =
1063 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1064 TemplateArgs = &Spec->getTemplateArgs();
1065 return GD.getWithDecl(Spec->getSpecializedTemplate());
1066 }
1067
1068 // Check if we have a variable template.
1069 if (const VarTemplateSpecializationDecl *Spec =
1070 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1071 TemplateArgs = &Spec->getTemplateArgs();
1072 return GD.getWithDecl(Spec->getSpecializedTemplate());
1073 }
1074
1075 return GlobalDecl();
1076}
1077
1078void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
1079 DeclarationName Name) {
1080 const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
1081 // <unqualified-name> ::= <operator-name>
1082 // ::= <ctor-dtor-name>
1083 // ::= <source-name>
1084 // ::= <template-name>
1085
1086 // Check if we have a template.
1087 const TemplateArgumentList *TemplateArgs = nullptr;
1088 if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) {
1089 // Function templates aren't considered for name back referencing. This
1090 // makes sense since function templates aren't likely to occur multiple
1091 // times in a symbol.
1092 if (isa<FunctionTemplateDecl>(TD.getDecl())) {
1093 mangleTemplateInstantiationName(TD, *TemplateArgs);
1094 Out << '@';
1095 return;
1096 }
1097
1098 // Here comes the tricky thing: if we need to mangle something like
1099 // void foo(A::X<Y>, B::X<Y>),
1100 // the X<Y> part is aliased. However, if you need to mangle
1101 // void foo(A::X<A::Y>, A::X<B::Y>),
1102 // the A::X<> part is not aliased.
1103 // That is, from the mangler's perspective we have a structure like this:
1104 // namespace[s] -> type[ -> template-parameters]
1105 // but from the Clang perspective we have
1106 // type [ -> template-parameters]
1107 // \-> namespace[s]
1108 // What we do is we create a new mangler, mangle the same type (without
1109 // a namespace suffix) to a string using the extra mangler and then use
1110 // the mangled type name as a key to check the mangling of different types
1111 // for aliasing.
1112
1113 // It's important to key cache reads off ND, not TD -- the same TD can
1114 // be used with different TemplateArgs, but ND uniquely identifies
1115 // TD / TemplateArg pairs.
1116 ArgBackRefMap::iterator Found = TemplateArgBackReferences.find(ND);
1117 if (Found == TemplateArgBackReferences.end()) {
1118
1119 TemplateArgStringMap::iterator Found = TemplateArgStrings.find(ND);
1120 if (Found == TemplateArgStrings.end()) {
1121 // Mangle full template name into temporary buffer.
1122 llvm::SmallString<64> TemplateMangling;
1123 llvm::raw_svector_ostream Stream(TemplateMangling);
1124 MicrosoftCXXNameMangler Extra(Context, Stream);
1125 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1126
1127 // Use the string backref vector to possibly get a back reference.
1128 mangleSourceName(TemplateMangling);
1129
1130 // Memoize back reference for this type if one exist, else memoize
1131 // the mangling itself.
1132 BackRefVec::iterator StringFound =
1133 llvm::find(NameBackReferences, TemplateMangling);
1134 if (StringFound != NameBackReferences.end()) {
1135 TemplateArgBackReferences[ND] =
1136 StringFound - NameBackReferences.begin();
1137 } else {
1138 TemplateArgStrings[ND] =
1139 TemplateArgStringStorage.save(TemplateMangling.str());
1140 }
1141 } else {
1142 Out << Found->second << '@'; // Outputs a StringRef.
1143 }
1144 } else {
1145 Out << Found->second; // Outputs a back reference (an int).
1146 }
1147 return;
1148 }
1149
1150 switch (Name.getNameKind()) {
1152 if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
1153 bool IsDeviceStub =
1154 ND &&
1155 ((isa<FunctionDecl>(ND) && ND->hasAttr<CUDAGlobalAttr>()) ||
1158 ->getTemplatedDecl()
1160 GD.getKernelReferenceKind() == KernelReferenceKind::Stub;
1161 bool IsOCLDeviceStub =
1162 ND && isa<FunctionDecl>(ND) &&
1163 DeviceKernelAttr::isOpenCLSpelling(
1164 ND->getAttr<DeviceKernelAttr>()) &&
1165 GD.getKernelReferenceKind() == KernelReferenceKind::Stub;
1166 if (IsDeviceStub)
1167 mangleSourceName(
1168 (llvm::Twine("__device_stub__") + II->getName()).str());
1169 else if (IsOCLDeviceStub)
1170 mangleSourceName(
1171 (llvm::Twine("__clang_ocl_kern_imp_") + II->getName()).str());
1172 else
1173 mangleSourceName(II->getName());
1174 break;
1175 }
1176
1177 // Otherwise, an anonymous entity. We must have a declaration.
1178 assert(ND && "mangling empty name without declaration");
1179
1180 if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1181 if (NS->isAnonymousNamespace()) {
1182 llvm::SmallString<16> Name("?A0x");
1183 Name += Context.getAnonymousNamespaceHash();
1184 mangleSourceName(Name);
1185 break;
1186 }
1187 }
1188
1189 if (const DecompositionDecl *DD = dyn_cast<DecompositionDecl>(ND)) {
1190 // Decomposition declarations are considered anonymous, and get
1191 // numbered with a $S prefix.
1192 llvm::SmallString<64> Name("$S");
1193 // Get a unique id for the anonymous struct.
1194 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1195 mangleSourceName(Name);
1196 break;
1197 }
1198
1199 if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1200 // We must have an anonymous union or struct declaration.
1201 const CXXRecordDecl *RD = VD->getType()->getAsCXXRecordDecl();
1202 assert(RD && "expected variable decl to have a record type");
1203 // Anonymous types with no tag or typedef get the name of their
1204 // declarator mangled in. If they have no declarator, number them with
1205 // a $S prefix.
1206 llvm::SmallString<64> Name("$S");
1207 // Get a unique id for the anonymous struct.
1208 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1209 mangleSourceName(Name.str());
1210 break;
1211 }
1212
1213 if (const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1214 // Mangle a GUID object as if it were a variable with the corresponding
1215 // mangled name.
1216 SmallString<sizeof("_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1217 llvm::raw_svector_ostream GUIDOS(GUID);
1218 Context.mangleMSGuidDecl(GD, GUIDOS);
1219 mangleSourceName(GUID);
1220 break;
1221 }
1222
1223 if (const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1224 Out << "?__N";
1225 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1226 TPO->getValue(), TplArgKind::ClassNTTP);
1227 break;
1228 }
1229
1230 // We must have an anonymous struct.
1231 const TagDecl *TD = cast<TagDecl>(ND);
1232 if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {
1233 assert(TD->getDeclContext() == D->getDeclContext() &&
1234 "Typedef should not be in another decl context!");
1235 assert(D->getDeclName().getAsIdentifierInfo() &&
1236 "Typedef was not named!");
1237 mangleSourceName(D->getDeclName().getAsIdentifierInfo()->getName());
1238 break;
1239 }
1240
1241 if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
1242 if (Record->isLambda()) {
1243 llvm::SmallString<10> Name("<lambda_");
1244
1245 Decl *LambdaContextDecl = Record->getLambdaContextDecl();
1246 unsigned LambdaManglingNumber = Record->getLambdaManglingNumber();
1247 unsigned LambdaId;
1248 const ParmVarDecl *Parm =
1249 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1250 const FunctionDecl *Func =
1251 Parm ? dyn_cast<FunctionDecl>(Parm->getDeclContext()) : nullptr;
1252
1253 if (Func) {
1254 unsigned DefaultArgNo =
1255 Func->getNumParams() - Parm->getFunctionScopeIndex();
1256 Name += llvm::utostr(DefaultArgNo);
1257 Name += "_";
1258 }
1259
1260 if (LambdaManglingNumber)
1261 LambdaId = LambdaManglingNumber;
1262 else
1263 LambdaId = Context.getLambdaId(Record);
1264
1265 Name += llvm::utostr(LambdaId);
1266 Name += ">";
1267
1268 mangleSourceName(Name);
1269
1270 // If the context is a variable or a class member and not a parameter,
1271 // it is encoded in a qualified name.
1272 if (LambdaManglingNumber && LambdaContextDecl) {
1273 if ((isa<VarDecl>(LambdaContextDecl) ||
1274 isa<FieldDecl>(LambdaContextDecl)) &&
1275 !isa<ParmVarDecl>(LambdaContextDecl)) {
1276 mangleUnqualifiedName(cast<NamedDecl>(LambdaContextDecl));
1277 }
1278 }
1279 break;
1280 }
1281 }
1282
1283 llvm::SmallString<64> Name;
1284 if (DeclaratorDecl *DD =
1285 Context.getASTContext().getDeclaratorForUnnamedTagDecl(TD)) {
1286 // Anonymous types without a name for linkage purposes have their
1287 // declarator mangled in if they have one.
1288 Name += "<unnamed-type-";
1289 Name += DD->getName();
1290 } else if (TypedefNameDecl *TND =
1291 Context.getASTContext().getTypedefNameForUnnamedTagDecl(
1292 TD)) {
1293 // Anonymous types without a name for linkage purposes have their
1294 // associate typedef mangled in if they have one.
1295 Name += "<unnamed-type-";
1296 Name += TND->getName();
1297 } else if (isa<EnumDecl>(TD) &&
1298 !cast<EnumDecl>(TD)->enumerators().empty()) {
1299 // Anonymous non-empty enums mangle in the first enumerator.
1300 auto *ED = cast<EnumDecl>(TD);
1301 Name += "<unnamed-enum-";
1302 Name += ED->enumerator_begin()->getName();
1303 } else {
1304 // Otherwise, number the types using a $S prefix.
1305 Name += "<unnamed-type-$S";
1306 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1307 }
1308 Name += ">";
1309 mangleSourceName(Name.str());
1310 break;
1311 }
1312
1316 // This is reachable only when constructing an outlined SEH finally
1317 // block. Nothing depends on this mangling and it's used only with
1318 // functinos with internal linkage.
1319 llvm::SmallString<64> Name;
1320 mangleSourceName(Name.str());
1321 break;
1322 }
1323
1325 if (isStructorDecl(ND)) {
1326 if (StructorType == Ctor_CopyingClosure) {
1327 Out << "?_O";
1328 return;
1329 }
1330 if (StructorType == Ctor_DefaultClosure) {
1331 Out << "?_F";
1332 return;
1333 }
1334 }
1335 Out << "?0";
1336 return;
1337
1339 if (isStructorDecl(ND))
1340 // If the named decl is the C++ destructor we're mangling,
1341 // use the type we were given.
1342 mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
1343 else
1344 // Otherwise, use the base destructor name. This is relevant if a
1345 // class with a destructor is declared within a destructor.
1346 mangleCXXDtorType(Dtor_Base);
1347 break;
1348
1350 // <operator-name> ::= ?B # (cast)
1351 // The target type is encoded as the return type.
1352 Out << "?B";
1353 break;
1354
1356 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->getLocation());
1357 break;
1358
1360 Out << "?__K";
1361 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1362 break;
1363 }
1364
1366 llvm_unreachable("Can't mangle a deduction guide name!");
1367
1369 llvm_unreachable("Can't mangle a using directive name!");
1370 }
1371}
1372
1373// <postfix> ::= <unqualified-name> [<postfix>]
1374// ::= <substitution> [<postfix>]
1375void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {
1376 const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
1377
1378 if (const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1379 for (unsigned I = 1, IE = ID->getChainingSize(); I < IE; ++I)
1380 mangleSourceName("<unnamed-tag>");
1381
1382 const DeclContext *DC = getEffectiveDeclContext(ND);
1383 while (!DC->isTranslationUnit()) {
1384 if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
1385 unsigned Disc;
1386 if (Context.getNextDiscriminator(ND, Disc)) {
1387 Out << '?';
1388 mangleNumber(Disc);
1389 Out << '?';
1390 }
1391 }
1392
1393 if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1394 auto Discriminate =
1395 [](StringRef Name, const unsigned Discriminator,
1396 const unsigned ParameterDiscriminator) -> std::string {
1397 std::string Buffer;
1398 llvm::raw_string_ostream Stream(Buffer);
1399 Stream << Name;
1400 if (Discriminator)
1401 Stream << '_' << Discriminator;
1402 if (ParameterDiscriminator)
1403 Stream << '_' << ParameterDiscriminator;
1404 return Buffer;
1405 };
1406
1407 unsigned Discriminator = BD->getBlockManglingNumber();
1408 if (!Discriminator)
1409 Discriminator = Context.getBlockId(BD, /*Local=*/false);
1410
1411 // Mangle the parameter position as a discriminator to deal with unnamed
1412 // parameters. Rather than mangling the unqualified parameter name,
1413 // always use the position to give a uniform mangling.
1414 unsigned ParameterDiscriminator = 0;
1415 if (const auto *MC = BD->getBlockManglingContextDecl())
1416 if (const auto *P = dyn_cast<ParmVarDecl>(MC))
1417 if (const auto *F = dyn_cast<FunctionDecl>(P->getDeclContext()))
1418 ParameterDiscriminator =
1419 F->getNumParams() - P->getFunctionScopeIndex();
1420
1421 DC = getEffectiveDeclContext(BD);
1422
1423 Out << '?';
1424 mangleSourceName(Discriminate("_block_invoke", Discriminator,
1425 ParameterDiscriminator));
1426 // If we have a block mangling context, encode that now. This allows us
1427 // to discriminate between named static data initializers in the same
1428 // scope. This is handled differently from parameters, which use
1429 // positions to discriminate between multiple instances.
1430 if (const auto *MC = BD->getBlockManglingContextDecl())
1431 if (!isa<ParmVarDecl>(MC))
1432 if (const auto *ND = dyn_cast<NamedDecl>(MC))
1433 mangleUnqualifiedName(ND);
1434 // MS ABI and Itanium manglings are in inverted scopes. In the case of a
1435 // RecordDecl, mangle the entire scope hierarchy at this point rather than
1436 // just the unqualified name to get the ordering correct.
1437 if (const auto *RD = dyn_cast<RecordDecl>(DC))
1438 mangleName(RD);
1439 else
1440 Out << '@';
1441 // void __cdecl
1442 Out << "YAX";
1443 // struct __block_literal *
1444 Out << 'P';
1445 // __ptr64
1446 if (PointersAre64Bit)
1447 Out << 'E';
1448 Out << 'A';
1449 mangleArtificialTagType(TagTypeKind::Struct,
1450 Discriminate("__block_literal", Discriminator,
1451 ParameterDiscriminator));
1452 Out << "@Z";
1453
1454 // If the effective context was a Record, we have fully mangled the
1455 // qualified name and do not need to continue.
1456 if (isa<RecordDecl>(DC))
1457 break;
1458 continue;
1459 } else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
1461 } else if (isa<NamedDecl>(DC)) {
1462 ND = cast<NamedDecl>(DC);
1463 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1464 mangle(getGlobalDeclAsDeclContext(FD), "?");
1465 break;
1466 } else {
1467 mangleUnqualifiedName(ND);
1468 // Lambdas in default arguments conceptually belong to the function the
1469 // parameter corresponds to.
1470 if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1471 DC = LDADC;
1472 continue;
1473 }
1474 }
1475 }
1476 DC = DC->getParent();
1477 }
1478}
1479
1480void MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
1481 // Microsoft uses the names on the case labels for these dtor variants. Clang
1482 // uses the Itanium terminology internally. Everything in this ABI delegates
1483 // towards the base dtor.
1484 switch (T) {
1485 // <operator-name> ::= ?1 # destructor
1486 case Dtor_Base: Out << "?1"; return;
1487 // <operator-name> ::= ?_D # vbase destructor
1488 case Dtor_Complete: Out << "?_D"; return;
1489 // <operator-name> ::= ?_G # scalar deleting destructor
1490 case Dtor_Deleting: Out << "?_G"; return;
1491 // <operator-name> ::= ?_E # vector deleting destructor
1493 Out << "?_E";
1494 return;
1495 case Dtor_Comdat:
1496 llvm_unreachable("not expecting a COMDAT");
1497 case Dtor_Unified:
1498 llvm_unreachable("not expecting a unified dtor type");
1499 }
1500 llvm_unreachable("Unsupported dtor type?");
1501}
1502
1503void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
1504 SourceLocation Loc) {
1505 switch (OO) {
1506 // ?0 # constructor
1507 // ?1 # destructor
1508 // <operator-name> ::= ?2 # new
1509 case OO_New: Out << "?2"; break;
1510 // <operator-name> ::= ?3 # delete
1511 case OO_Delete: Out << "?3"; break;
1512 // <operator-name> ::= ?4 # =
1513 case OO_Equal: Out << "?4"; break;
1514 // <operator-name> ::= ?5 # >>
1515 case OO_GreaterGreater: Out << "?5"; break;
1516 // <operator-name> ::= ?6 # <<
1517 case OO_LessLess: Out << "?6"; break;
1518 // <operator-name> ::= ?7 # !
1519 case OO_Exclaim: Out << "?7"; break;
1520 // <operator-name> ::= ?8 # ==
1521 case OO_EqualEqual: Out << "?8"; break;
1522 // <operator-name> ::= ?9 # !=
1523 case OO_ExclaimEqual: Out << "?9"; break;
1524 // <operator-name> ::= ?A # []
1525 case OO_Subscript: Out << "?A"; break;
1526 // ?B # conversion
1527 // <operator-name> ::= ?C # ->
1528 case OO_Arrow: Out << "?C"; break;
1529 // <operator-name> ::= ?D # *
1530 case OO_Star: Out << "?D"; break;
1531 // <operator-name> ::= ?E # ++
1532 case OO_PlusPlus: Out << "?E"; break;
1533 // <operator-name> ::= ?F # --
1534 case OO_MinusMinus: Out << "?F"; break;
1535 // <operator-name> ::= ?G # -
1536 case OO_Minus: Out << "?G"; break;
1537 // <operator-name> ::= ?H # +
1538 case OO_Plus: Out << "?H"; break;
1539 // <operator-name> ::= ?I # &
1540 case OO_Amp: Out << "?I"; break;
1541 // <operator-name> ::= ?J # ->*
1542 case OO_ArrowStar: Out << "?J"; break;
1543 // <operator-name> ::= ?K # /
1544 case OO_Slash: Out << "?K"; break;
1545 // <operator-name> ::= ?L # %
1546 case OO_Percent: Out << "?L"; break;
1547 // <operator-name> ::= ?M # <
1548 case OO_Less: Out << "?M"; break;
1549 // <operator-name> ::= ?N # <=
1550 case OO_LessEqual: Out << "?N"; break;
1551 // <operator-name> ::= ?O # >
1552 case OO_Greater: Out << "?O"; break;
1553 // <operator-name> ::= ?P # >=
1554 case OO_GreaterEqual: Out << "?P"; break;
1555 // <operator-name> ::= ?Q # ,
1556 case OO_Comma: Out << "?Q"; break;
1557 // <operator-name> ::= ?R # ()
1558 case OO_Call: Out << "?R"; break;
1559 // <operator-name> ::= ?S # ~
1560 case OO_Tilde: Out << "?S"; break;
1561 // <operator-name> ::= ?T # ^
1562 case OO_Caret: Out << "?T"; break;
1563 // <operator-name> ::= ?U # |
1564 case OO_Pipe: Out << "?U"; break;
1565 // <operator-name> ::= ?V # &&
1566 case OO_AmpAmp: Out << "?V"; break;
1567 // <operator-name> ::= ?W # ||
1568 case OO_PipePipe: Out << "?W"; break;
1569 // <operator-name> ::= ?X # *=
1570 case OO_StarEqual: Out << "?X"; break;
1571 // <operator-name> ::= ?Y # +=
1572 case OO_PlusEqual: Out << "?Y"; break;
1573 // <operator-name> ::= ?Z # -=
1574 case OO_MinusEqual: Out << "?Z"; break;
1575 // <operator-name> ::= ?_0 # /=
1576 case OO_SlashEqual: Out << "?_0"; break;
1577 // <operator-name> ::= ?_1 # %=
1578 case OO_PercentEqual: Out << "?_1"; break;
1579 // <operator-name> ::= ?_2 # >>=
1580 case OO_GreaterGreaterEqual: Out << "?_2"; break;
1581 // <operator-name> ::= ?_3 # <<=
1582 case OO_LessLessEqual: Out << "?_3"; break;
1583 // <operator-name> ::= ?_4 # &=
1584 case OO_AmpEqual: Out << "?_4"; break;
1585 // <operator-name> ::= ?_5 # |=
1586 case OO_PipeEqual: Out << "?_5"; break;
1587 // <operator-name> ::= ?_6 # ^=
1588 case OO_CaretEqual: Out << "?_6"; break;
1589 // ?_7 # vftable
1590 // ?_8 # vbtable
1591 // ?_9 # vcall
1592 // ?_A # typeof
1593 // ?_B # local static guard
1594 // ?_C # string
1595 // ?_D # vbase destructor
1596 // ?_E # vector deleting destructor
1597 // ?_F # default constructor closure
1598 // ?_G # scalar deleting destructor
1599 // ?_H # vector constructor iterator
1600 // ?_I # vector destructor iterator
1601 // ?_J # vector vbase constructor iterator
1602 // ?_K # virtual displacement map
1603 // ?_L # eh vector constructor iterator
1604 // ?_M # eh vector destructor iterator
1605 // ?_N # eh vector vbase constructor iterator
1606 // ?_O # copy constructor closure
1607 // ?_P<name> # udt returning <name>
1608 // ?_Q # <unknown>
1609 // ?_R0 # RTTI Type Descriptor
1610 // ?_R1 # RTTI Base Class Descriptor at (a,b,c,d)
1611 // ?_R2 # RTTI Base Class Array
1612 // ?_R3 # RTTI Class Hierarchy Descriptor
1613 // ?_R4 # RTTI Complete Object Locator
1614 // ?_S # local vftable
1615 // ?_T # local vftable constructor closure
1616 // <operator-name> ::= ?_U # new[]
1617 case OO_Array_New: Out << "?_U"; break;
1618 // <operator-name> ::= ?_V # delete[]
1619 case OO_Array_Delete: Out << "?_V"; break;
1620 // <operator-name> ::= ?__L # co_await
1621 case OO_Coawait: Out << "?__L"; break;
1622 // <operator-name> ::= ?__M # <=>
1623 case OO_Spaceship: Out << "?__M"; break;
1624
1625 case OO_Conditional: {
1626 Error(Loc, "conditional operator");
1627 break;
1628 }
1629
1630 case OO_None:
1632 llvm_unreachable("Not an overloaded operator");
1633 }
1634}
1635
1636void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1637 // <source name> ::= <identifier> @
1638 BackRefVec::iterator Found = llvm::find(NameBackReferences, Name);
1639 if (Found == NameBackReferences.end()) {
1640 if (NameBackReferences.size() < 10)
1641 NameBackReferences.push_back(std::string(Name));
1642 Out << Name << '@';
1643 } else {
1644 Out << (Found - NameBackReferences.begin());
1645 }
1646}
1647
1648void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
1649 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1650}
1651
1652void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1653 GlobalDecl GD, const TemplateArgumentList &TemplateArgs) {
1654 // <template-name> ::= <unscoped-template-name> <template-args>
1655 // ::= <substitution>
1656 // Always start with the unqualified name.
1657
1658 // Templates have their own context for back references.
1659 ArgBackRefMap OuterFunArgsContext;
1660 ArgBackRefMap OuterTemplateArgsContext;
1661 BackRefVec OuterTemplateContext;
1662 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1663 NameBackReferences.swap(OuterTemplateContext);
1664 FunArgBackReferences.swap(OuterFunArgsContext);
1665 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1666 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1667
1668 mangleUnscopedTemplateName(GD);
1669 mangleTemplateArgs(cast<TemplateDecl>(GD.getDecl()), TemplateArgs);
1670
1671 // Restore the previous back reference contexts.
1672 NameBackReferences.swap(OuterTemplateContext);
1673 FunArgBackReferences.swap(OuterFunArgsContext);
1674 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1675 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1676}
1677
1678void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {
1679 // <unscoped-template-name> ::= ?$ <unqualified-name>
1680 Out << "?$";
1681 mangleUnqualifiedName(GD);
1682}
1683
1684void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1685 const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD,
1686 QualType TemplateArgType) {
1687 // <integer-literal> ::= $0 <number>
1688 // <integer-literal> ::= <auto-nttp>
1689 //
1690 // <auto-nttp> ::= $ M <type> 0 <number>
1691 Out << "$";
1692
1693 // Since MSVC 2019, add 'M[<type>]' after '$' for auto template parameter when
1694 // argument is integer.
1695 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1696 LangOptions::MSVC2019) &&
1697 PD && PD->getType()->getTypeClass() == Type::Auto &&
1698 !TemplateArgType.isNull()) {
1699 Out << "M";
1700 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
1701 }
1702
1703 Out << "0";
1704
1705 mangleNumber(Value);
1706}
1707
1708void MicrosoftCXXNameMangler::mangleExpression(
1709 const Expr *E, const NonTypeTemplateParmDecl *PD) {
1710 // See if this is a constant expression.
1711 if (std::optional<llvm::APSInt> Value =
1712 E->getIntegerConstantExpr(Context.getASTContext())) {
1713 mangleIntegerLiteral(*Value, PD, E->getType());
1714 return;
1715 }
1716
1717 // As bad as this diagnostic is, it's better than crashing.
1718 Error(E->getExprLoc(), "expression type: ", E->getStmtClassName())
1719 << E->getSourceRange();
1720}
1721
1722void MicrosoftCXXNameMangler::mangleTemplateArgs(
1723 const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
1724 // <template-args> ::= <template-arg>+
1725 const TemplateParameterList *TPL = TD->getTemplateParameters();
1726 assert(TPL->size() == TemplateArgs.size() &&
1727 "size mismatch between args and parms!");
1728
1729 for (size_t i = 0; i < TemplateArgs.size(); ++i) {
1730 const TemplateArgument &TA = TemplateArgs[i];
1731
1732 // Separate consecutive packs by $$Z.
1733 if (i > 0 && TA.getKind() == TemplateArgument::Pack &&
1734 TemplateArgs[i - 1].getKind() == TemplateArgument::Pack)
1735 Out << "$$Z";
1736
1737 mangleTemplateArg(TD, TA, TPL->getParam(i));
1738 }
1739}
1740
1741/// If value V (with type T) represents a decayed pointer to the first element
1742/// of an array, return that array.
1744 // Must be a pointer...
1745 if (!T->isPointerType() || !V.isLValue() || !V.hasLValuePath() ||
1746 !V.getLValueBase())
1747 return nullptr;
1748 // ... to element 0 of an array.
1749 QualType BaseT = V.getLValueBase().getType();
1750 if (!BaseT->isArrayType() || V.getLValuePath().size() != 1 ||
1751 V.getLValuePath()[0].getAsArrayIndex() != 0)
1752 return nullptr;
1753 return const_cast<ValueDecl *>(
1754 V.getLValueBase().dyn_cast<const ValueDecl *>());
1755}
1756
1757void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
1758 const TemplateArgument &TA,
1759 const NamedDecl *Parm) {
1760 // <template-arg> ::= <type>
1761 // ::= <integer-literal>
1762 // ::= <member-data-pointer>
1763 // ::= <member-function-pointer>
1764 // ::= $ <constant-value>
1765 // ::= $ <auto-nttp-constant-value>
1766 // ::= <template-args>
1767 //
1768 // <auto-nttp-constant-value> ::= M <type> <constant-value>
1769 //
1770 // <constant-value> ::= 0 <number> # integer
1771 // ::= 1 <mangled-name> # address of D
1772 // ::= 2 <type> <typed-constant-value>* @ # struct
1773 // ::= 3 <type> <constant-value>* @ # array
1774 // ::= 4 ??? # string
1775 // ::= 5 <constant-value> @ # address of subobject
1776 // ::= 6 <constant-value> <unqualified-name> @ # a.b
1777 // ::= 7 <type> [<unqualified-name> <constant-value>] @
1778 // # union, with or without an active member
1779 // # pointer to member, symbolically
1780 // ::= 8 <class> <unqualified-name> @
1781 // ::= A <type> <non-negative integer> # float
1782 // ::= B <type> <non-negative integer> # double
1783 // # pointer to member, by component value
1784 // ::= F <number> <number>
1785 // ::= G <number> <number> <number>
1786 // ::= H <mangled-name> <number>
1787 // ::= I <mangled-name> <number> <number>
1788 // ::= J <mangled-name> <number> <number> <number>
1789 //
1790 // <typed-constant-value> ::= [<type>] <constant-value>
1791 //
1792 // The <type> appears to be included in a <typed-constant-value> only in the
1793 // '0', '1', '8', 'A', 'B', and 'E' cases.
1794
1795 switch (TA.getKind()) {
1797 llvm_unreachable("Can't mangle null template arguments!");
1799 llvm_unreachable("Can't mangle template expansion arguments!");
1801 QualType T = TA.getAsType();
1802 mangleType(T, SourceRange(), QMM_Escape);
1803 break;
1804 }
1806 const NamedDecl *ND = TA.getAsDecl();
1807 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1808 mangleMemberDataPointer(
1809 cast<CXXRecordDecl>(ND->getDeclContext())->getMostRecentDecl(),
1811 TA.getParamTypeForDecl());
1812 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1813 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1814 if (MD && MD->isInstance()) {
1815 mangleMemberFunctionPointer(MD->getParent()->getMostRecentDecl(), MD,
1817 TA.getParamTypeForDecl());
1818 } else {
1819 mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),
1820 TA.getParamTypeForDecl());
1821 }
1822 } else if (TA.getParamTypeForDecl()->isRecordType()) {
1823 Out << "$";
1824 auto *TPO = cast<TemplateParamObjectDecl>(ND);
1825 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1826 TPO->getValue(), TplArgKind::ClassNTTP);
1827 } else if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1828 mangleVarDecl(VD, cast<NonTypeTemplateParmDecl>(Parm),
1829 TA.getParamTypeForDecl());
1830 } else {
1831 mangle(ND, "$1?");
1832 }
1833 break;
1834 }
1836 QualType T = TA.getIntegralType();
1837 mangleIntegerLiteral(TA.getAsIntegral(),
1839 break;
1840 }
1842 QualType T = TA.getNullPtrType();
1843 if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
1844 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1845 if (MPT->isMemberFunctionPointerType() &&
1847 mangleMemberFunctionPointer(RD, nullptr, nullptr, QualType());
1848 return;
1849 }
1850 if (MPT->isMemberDataPointer()) {
1851 if (!isa<FunctionTemplateDecl>(TD)) {
1852 mangleMemberDataPointer(RD, nullptr, nullptr, QualType());
1853 return;
1854 }
1855 // nullptr data pointers are always represented with a single field
1856 // which is initialized with either 0 or -1. Why -1? Well, we need to
1857 // distinguish the case where the data member is at offset zero in the
1858 // record.
1859 // However, we are free to use 0 *if* we would use multiple fields for
1860 // non-nullptr member pointers.
1861 if (!RD->nullFieldOffsetIsZero()) {
1862 mangleIntegerLiteral(llvm::APSInt::get(-1),
1864 return;
1865 }
1866 }
1867 }
1868 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1870 break;
1871 }
1873 if (ValueDecl *D = getAsArrayToPointerDecayedDecl(
1875 // Mangle the result of array-to-pointer decay as if it were a reference
1876 // to the original declaration, to match MSVC's behavior. This can result
1877 // in mangling collisions in some cases!
1878 return mangleTemplateArg(
1879 TD, TemplateArgument(D, TA.getStructuralValueType()), Parm);
1880 }
1881 Out << "$";
1883 ->getType()
1884 ->getContainedDeducedType()) {
1885 Out << "M";
1886 mangleType(TA.getNonTypeTemplateArgumentType(), SourceRange(), QMM_Drop);
1887 }
1888 mangleTemplateArgValue(TA.getStructuralValueType(),
1890 TplArgKind::StructuralValue,
1891 /*WithScalarType=*/false);
1892 break;
1894 mangleExpression(TA.getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
1895 break;
1897 ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();
1898 if (TemplateArgs.empty()) {
1899 if (isa<TemplateTypeParmDecl>(Parm) ||
1901 // MSVC 2015 changed the mangling for empty expanded template packs,
1902 // use the old mangling for link compatibility for old versions.
1903 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(
1904 LangOptions::MSVC2015)
1905 ? "$$V"
1906 : "$$$V");
1907 else if (isa<NonTypeTemplateParmDecl>(Parm))
1908 Out << "$S";
1909 else
1910 llvm_unreachable("unexpected template parameter decl!");
1911 } else {
1912 for (const TemplateArgument &PA : TemplateArgs)
1913 mangleTemplateArg(TD, PA, Parm);
1914 }
1915 break;
1916 }
1918 const NamedDecl *ND =
1920 if (const auto *TD = dyn_cast<TagDecl>(ND)) {
1921 mangleType(TD);
1922 } else if (isa<TypeAliasDecl>(ND)) {
1923 Out << "$$Y";
1924 mangleName(ND);
1925 } else {
1926 llvm_unreachable("unexpected template template NamedDecl!");
1927 }
1928 break;
1929 }
1930 }
1931}
1932
1933void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
1934 const APValue &V,
1935 TplArgKind TAK,
1936 bool WithScalarType) {
1937 switch (V.getKind()) {
1938 case APValue::None:
1940 // FIXME: MSVC doesn't allow this, so we can't be sure how it should be
1941 // mangled.
1942 if (WithScalarType)
1943 mangleType(T, SourceRange(), QMM_Escape);
1944 Out << '@';
1945 return;
1946
1947 case APValue::Int:
1948 if (WithScalarType)
1949 mangleType(T, SourceRange(), QMM_Escape);
1950 Out << '0';
1951 mangleNumber(V.getInt());
1952 return;
1953
1954 case APValue::Float:
1955 if (WithScalarType)
1956 mangleType(T, SourceRange(), QMM_Escape);
1957 mangleFloat(V.getFloat());
1958 return;
1959
1960 case APValue::LValue: {
1961 if (WithScalarType)
1962 mangleType(T, SourceRange(), QMM_Escape);
1963
1964 APValue::LValueBase Base = V.getLValueBase();
1965
1966 // this might not cover every case but did cover issue 97756
1967 // see test CodeGen/ms_mangler_templatearg_opte
1968 if (V.isLValueOnePastTheEnd()) {
1969 Out << "5E";
1970 auto *VD = Base.dyn_cast<const ValueDecl *>();
1971 if (VD)
1972 mangle(VD);
1973 Out << "@";
1974 return;
1975 }
1976
1977 if (!V.hasLValuePath() || V.getLValuePath().empty()) {
1978 // Taking the address of a complete object has a special-case mangling.
1979 if (Base.isNull()) {
1980 // MSVC emits 0A@ for null pointers. Generalize this for arbitrary
1981 // integers cast to pointers.
1982 // FIXME: This mangles 0 cast to a pointer the same as a null pointer,
1983 // even in cases where the two are different values.
1984 Out << "0";
1985 mangleNumber(V.getLValueOffset().getQuantity());
1986 } else if (!V.hasLValuePath()) {
1987 // FIXME: This can only happen as an extension. Invent a mangling.
1988 Error("template argument (extension not comaptible with ms mangler)");
1989 return;
1990 } else if (auto *VD = Base.dyn_cast<const ValueDecl*>()) {
1991 Out << "E";
1992 mangle(VD);
1993 } else {
1994 Error("template argument (undeclared base)");
1995 return;
1996 }
1997 } else {
1998 if (TAK == TplArgKind::ClassNTTP && T->isPointerType())
1999 Out << "5";
2000
2001 SmallVector<char, 2> EntryTypes;
2002 SmallVector<std::function<void()>, 2> EntryManglers;
2003 QualType ET = Base.getType();
2004 for (APValue::LValuePathEntry E : V.getLValuePath()) {
2005 if (auto *AT = ET->getAsArrayTypeUnsafe()) {
2006 EntryTypes.push_back('C');
2007 EntryManglers.push_back([this, I = E.getAsArrayIndex()] {
2008 Out << '0';
2009 mangleNumber(I);
2010 Out << '@';
2011 });
2012 ET = AT->getElementType();
2013 continue;
2014 }
2015
2016 const Decl *D = E.getAsBaseOrMember().getPointer();
2017 if (auto *FD = dyn_cast<FieldDecl>(D)) {
2018 ET = FD->getType();
2019 if (const auto *RD = ET->getAsRecordDecl())
2020 if (RD->isAnonymousStructOrUnion())
2021 continue;
2022 } else {
2023 ET = getASTContext().getCanonicalTagType(cast<CXXRecordDecl>(D));
2024 // Bug in MSVC: fully qualified name of base class should be used for
2025 // mangling to prevent collisions e.g. on base classes with same names
2026 // in different namespaces.
2027 }
2028
2029 EntryTypes.push_back('6');
2030 EntryManglers.push_back([this, D] {
2031 mangleUnqualifiedName(cast<NamedDecl>(D));
2032 Out << '@';
2033 });
2034 }
2035
2036 for (auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
2037 Out << *I;
2038
2039 auto *VD = Base.dyn_cast<const ValueDecl*>();
2040 if (!VD) {
2041 Error("template argument (null value decl)");
2042 return;
2043 }
2044 Out << (TAK == TplArgKind::ClassNTTP ? 'E' : '1');
2045 mangle(VD);
2046
2047 for (const std::function<void()> &Mangler : EntryManglers)
2048 Mangler();
2049 if (TAK == TplArgKind::ClassNTTP && T->isPointerType())
2050 Out << '@';
2051 }
2052
2053 return;
2054 }
2055
2057 if (WithScalarType)
2058 mangleType(T, SourceRange(), QMM_Escape);
2059
2060 const CXXRecordDecl *RD =
2061 T->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
2062 const ValueDecl *D = V.getMemberPointerDecl();
2063 if (TAK == TplArgKind::ClassNTTP) {
2065 mangleMemberDataPointerInClassNTTP(RD, D);
2066 else
2067 mangleMemberFunctionPointerInClassNTTP(RD,
2068 cast_or_null<CXXMethodDecl>(D));
2069 } else {
2071 mangleMemberDataPointer(RD, D, nullptr, QualType(), "");
2072 else
2073 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D), nullptr,
2074 QualType(), "");
2075 }
2076 return;
2077 }
2078
2079 case APValue::Struct: {
2080 Out << '2';
2081 mangleType(T, SourceRange(), QMM_Escape);
2082 const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
2083 assert(RD && "unexpected type for record value");
2084
2085 unsigned BaseIndex = 0;
2086 for (const CXXBaseSpecifier &B : RD->bases())
2087 mangleTemplateArgValue(B.getType(), V.getStructBase(BaseIndex++), TAK);
2088 for (const FieldDecl *FD : RD->fields())
2089 if (!FD->isUnnamedBitField())
2090 mangleTemplateArgValue(FD->getType(),
2091 V.getStructField(FD->getFieldIndex()), TAK,
2092 /*WithScalarType*/ true);
2093 Out << '@';
2094 return;
2095 }
2096
2097 case APValue::Union:
2098 Out << '7';
2099 mangleType(T, SourceRange(), QMM_Escape);
2100 if (const FieldDecl *FD = V.getUnionField()) {
2101 mangleUnqualifiedName(FD);
2102 mangleTemplateArgValue(FD->getType(), V.getUnionValue(), TAK);
2103 }
2104 Out << '@';
2105 return;
2106
2108 // We mangle complex types as structs, so mangle the value as a struct too.
2109 Out << '2';
2110 mangleType(T, SourceRange(), QMM_Escape);
2111 Out << '0';
2112 mangleNumber(V.getComplexIntReal());
2113 Out << '0';
2114 mangleNumber(V.getComplexIntImag());
2115 Out << '@';
2116 return;
2117
2119 Out << '2';
2120 mangleType(T, SourceRange(), QMM_Escape);
2121 mangleFloat(V.getComplexFloatReal());
2122 mangleFloat(V.getComplexFloatImag());
2123 Out << '@';
2124 return;
2125
2126 case APValue::Array: {
2127 Out << '3';
2128 QualType ElemT = getASTContext().getAsArrayType(T)->getElementType();
2129 mangleType(ElemT, SourceRange(), QMM_Escape);
2130 for (unsigned I = 0, N = V.getArraySize(); I != N; ++I) {
2131 const APValue &ElemV = I < V.getArrayInitializedElts()
2132 ? V.getArrayInitializedElt(I)
2133 : V.getArrayFiller();
2134 mangleTemplateArgValue(ElemT, ElemV, TAK);
2135 Out << '@';
2136 }
2137 Out << '@';
2138 return;
2139 }
2140
2141 case APValue::Vector: {
2142 // __m128 is mangled as a struct containing an array. We follow this
2143 // approach for all vector types.
2144 Out << '2';
2145 mangleType(T, SourceRange(), QMM_Escape);
2146 Out << '3';
2147 QualType ElemT = T->castAs<VectorType>()->getElementType();
2148 mangleType(ElemT, SourceRange(), QMM_Escape);
2149 for (unsigned I = 0, N = V.getVectorLength(); I != N; ++I) {
2150 const APValue &ElemV = V.getVectorElt(I);
2151 mangleTemplateArgValue(ElemT, ElemV, TAK);
2152 Out << '@';
2153 }
2154 Out << "@@";
2155 return;
2156 }
2157
2158 case APValue::Matrix: {
2159 Error("template argument (value type: matrix)");
2160 return;
2161 }
2162
2164 Error("template argument (value type: address label diff)");
2165 return;
2166 }
2167
2168 case APValue::FixedPoint: {
2169 Error("template argument (value type: fixed point)");
2170 return;
2171 }
2172 }
2173}
2174
2175void MicrosoftCXXNameMangler::mangleObjCProtocol(const ObjCProtocolDecl *PD) {
2176 llvm::SmallString<64> TemplateMangling;
2177 llvm::raw_svector_ostream Stream(TemplateMangling);
2178 MicrosoftCXXNameMangler Extra(Context, Stream);
2179
2180 Stream << "?$";
2181 Extra.mangleSourceName("Protocol");
2182 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->getName());
2183
2184 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
2185}
2186
2187void MicrosoftCXXNameMangler::mangleObjCLifetime(const QualType Type,
2188 Qualifiers Quals,
2189 SourceRange Range) {
2190 llvm::SmallString<64> TemplateMangling;
2191 llvm::raw_svector_ostream Stream(TemplateMangling);
2192 MicrosoftCXXNameMangler Extra(Context, Stream);
2193
2194 Stream << "?$";
2195 switch (Quals.getObjCLifetime()) {
2198 break;
2200 Extra.mangleSourceName("Autoreleasing");
2201 break;
2203 Extra.mangleSourceName("Strong");
2204 break;
2206 Extra.mangleSourceName("Weak");
2207 break;
2208 }
2209 Extra.manglePointerCVQualifiers(Quals);
2210 Extra.manglePointerExtQualifiers(Quals, Type);
2211 Extra.mangleType(Type, Range);
2212
2213 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
2214}
2215
2216void MicrosoftCXXNameMangler::mangleObjCKindOfType(const ObjCObjectType *T,
2217 Qualifiers Quals,
2218 SourceRange Range) {
2219 llvm::SmallString<64> TemplateMangling;
2220 llvm::raw_svector_ostream Stream(TemplateMangling);
2221 MicrosoftCXXNameMangler Extra(Context, Stream);
2222
2223 Stream << "?$";
2224 Extra.mangleSourceName("KindOf");
2225 Extra.mangleType(QualType(T, 0)
2226 .stripObjCKindOfType(getASTContext())
2227 ->castAs<ObjCObjectType>(),
2228 Quals, Range);
2229
2230 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
2231}
2232
2233void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
2234 bool IsMember) {
2235 // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>
2236 // 'E' means __ptr64 (32-bit only); 'F' means __unaligned (32/64-bit only);
2237 // 'I' means __restrict (32/64-bit).
2238 // Note that the MSVC __restrict keyword isn't the same as the C99 restrict
2239 // keyword!
2240 // <base-cvr-qualifiers> ::= A # near
2241 // ::= B # near const
2242 // ::= C # near volatile
2243 // ::= D # near const volatile
2244 // ::= E # far (16-bit)
2245 // ::= F # far const (16-bit)
2246 // ::= G # far volatile (16-bit)
2247 // ::= H # far const volatile (16-bit)
2248 // ::= I # huge (16-bit)
2249 // ::= J # huge const (16-bit)
2250 // ::= K # huge volatile (16-bit)
2251 // ::= L # huge const volatile (16-bit)
2252 // ::= M <basis> # based
2253 // ::= N <basis> # based const
2254 // ::= O <basis> # based volatile
2255 // ::= P <basis> # based const volatile
2256 // ::= Q # near member
2257 // ::= R # near const member
2258 // ::= S # near volatile member
2259 // ::= T # near const volatile member
2260 // ::= U # far member (16-bit)
2261 // ::= V # far const member (16-bit)
2262 // ::= W # far volatile member (16-bit)
2263 // ::= X # far const volatile member (16-bit)
2264 // ::= Y # huge member (16-bit)
2265 // ::= Z # huge const member (16-bit)
2266 // ::= 0 # huge volatile member (16-bit)
2267 // ::= 1 # huge const volatile member (16-bit)
2268 // ::= 2 <basis> # based member
2269 // ::= 3 <basis> # based const member
2270 // ::= 4 <basis> # based volatile member
2271 // ::= 5 <basis> # based const volatile member
2272 // ::= 6 # near function (pointers only)
2273 // ::= 7 # far function (pointers only)
2274 // ::= 8 # near method (pointers only)
2275 // ::= 9 # far method (pointers only)
2276 // ::= _A <basis> # based function (pointers only)
2277 // ::= _B <basis> # based function (far?) (pointers only)
2278 // ::= _C <basis> # based method (pointers only)
2279 // ::= _D <basis> # based method (far?) (pointers only)
2280 // ::= _E # block (Clang)
2281 // <basis> ::= 0 # __based(void)
2282 // ::= 1 # __based(segment)?
2283 // ::= 2 <name> # __based(name)
2284 // ::= 3 # ?
2285 // ::= 4 # ?
2286 // ::= 5 # not really based
2287 bool HasConst = Quals.hasConst(),
2288 HasVolatile = Quals.hasVolatile();
2289
2290 if (!IsMember) {
2291 if (HasConst && HasVolatile) {
2292 Out << 'D';
2293 } else if (HasVolatile) {
2294 Out << 'C';
2295 } else if (HasConst) {
2296 Out << 'B';
2297 } else {
2298 Out << 'A';
2299 }
2300 } else {
2301 if (HasConst && HasVolatile) {
2302 Out << 'T';
2303 } else if (HasVolatile) {
2304 Out << 'S';
2305 } else if (HasConst) {
2306 Out << 'R';
2307 } else {
2308 Out << 'Q';
2309 }
2310 }
2311
2312 // FIXME: For now, just drop all extension qualifiers on the floor.
2313}
2314
2315void
2316MicrosoftCXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {
2317 // <ref-qualifier> ::= G # lvalue reference
2318 // ::= H # rvalue-reference
2319 switch (RefQualifier) {
2320 case RQ_None:
2321 break;
2322
2323 case RQ_LValue:
2324 Out << 'G';
2325 break;
2326
2327 case RQ_RValue:
2328 Out << 'H';
2329 break;
2330 }
2331}
2332
2333void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
2334 QualType PointeeType) {
2335 // Check if this is a default 64-bit pointer or has __ptr64 qualifier.
2336 bool is64Bit = PointeeType.isNull() ? PointersAre64Bit :
2337 is64BitPointer(PointeeType.getQualifiers());
2338 if (is64Bit && (PointeeType.isNull() || !PointeeType->isFunctionType()))
2339 Out << 'E';
2340
2341 if (Quals.hasRestrict())
2342 Out << 'I';
2343
2344 if (Quals.hasUnaligned() ||
2345 (!PointeeType.isNull() && PointeeType.getLocalQualifiers().hasUnaligned()))
2346 Out << 'F';
2347}
2348
2349void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {
2350 PointerAuthQualifier PointerAuth = Quals.getPointerAuth();
2351 if (!PointerAuth)
2352 return;
2353
2354 Out << "__ptrauth";
2355 mangleNumber(PointerAuth.getKey());
2356 mangleNumber(PointerAuth.isAddressDiscriminated());
2357 mangleNumber(PointerAuth.getExtraDiscriminator());
2358}
2359
2360void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
2361 // <pointer-cv-qualifiers> ::= P # no qualifiers
2362 // ::= Q # const
2363 // ::= R # volatile
2364 // ::= S # const volatile
2365 bool HasConst = Quals.hasConst(),
2366 HasVolatile = Quals.hasVolatile();
2367
2368 if (HasConst && HasVolatile) {
2369 Out << 'S';
2370 } else if (HasVolatile) {
2371 Out << 'R';
2372 } else if (HasConst) {
2373 Out << 'Q';
2374 } else {
2375 Out << 'P';
2376 }
2377}
2378
2379void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType T,
2380 SourceRange Range) {
2381 // MSVC will backreference two canonically equivalent types that have slightly
2382 // different manglings when mangled alone.
2383
2384 // Decayed types do not match up with non-decayed versions of the same type.
2385 //
2386 // e.g.
2387 // void (*x)(void) will not form a backreference with void x(void)
2388 void *TypePtr;
2389 if (const auto *DT = T->getAs<DecayedType>()) {
2390 QualType OriginalType = DT->getOriginalType();
2391 // All decayed ArrayTypes should be treated identically; as-if they were
2392 // a decayed IncompleteArrayType.
2393 if (const auto *AT = getASTContext().getAsArrayType(OriginalType))
2394 OriginalType = getASTContext().getIncompleteArrayType(
2395 AT->getElementType(), AT->getSizeModifier(),
2396 AT->getIndexTypeCVRQualifiers());
2397
2398 TypePtr = OriginalType.getCanonicalType().getAsOpaquePtr();
2399 // If the original parameter was textually written as an array,
2400 // instead treat the decayed parameter like it's const.
2401 //
2402 // e.g.
2403 // int [] -> int * const
2404 if (OriginalType->isArrayType())
2405 T = T.withConst();
2406 } else {
2407 TypePtr = T.getCanonicalType().getAsOpaquePtr();
2408 }
2409
2410 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);
2411
2412 if (Found == FunArgBackReferences.end()) {
2413 size_t OutSizeBefore = Out.tell();
2414
2415 mangleType(T, Range, QMM_Drop);
2416
2417 // See if it's worth creating a back reference.
2418 // Only types longer than 1 character are considered
2419 // and only 10 back references slots are available:
2420 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);
2421 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2422 size_t Size = FunArgBackReferences.size();
2423 FunArgBackReferences[TypePtr] = Size;
2424 }
2425 } else {
2426 Out << Found->second;
2427 }
2428}
2429
2430void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2431 const PassObjectSizeAttr *POSA) {
2432 int Type = POSA->getType();
2433 bool Dynamic = POSA->isDynamic();
2434
2435 auto Iter = PassObjectSizeArgs.insert({Type, Dynamic}).first;
2436 auto *TypePtr = (const void *)&*Iter;
2437 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);
2438
2439 if (Found == FunArgBackReferences.end()) {
2440 std::string Name =
2441 Dynamic ? "__pass_dynamic_object_size" : "__pass_object_size";
2442 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(Type),
2443 {"__clang"});
2444
2445 if (FunArgBackReferences.size() < 10) {
2446 size_t Size = FunArgBackReferences.size();
2447 FunArgBackReferences[TypePtr] = Size;
2448 }
2449 } else {
2450 Out << Found->second;
2451 }
2452}
2453
2454void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
2455 Qualifiers Quals,
2456 SourceRange Range) {
2457 // Address space is mangled as an unqualified templated type in the __clang
2458 // namespace. The demangled version of this is:
2459 // In the case of a language specific address space:
2460 // __clang::struct _AS[language_addr_space]<Type>
2461 // where:
2462 // <language_addr_space> ::= <OpenCL-addrspace> | <CUDA-addrspace>
2463 // <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" |
2464 // "private"| "generic" | "device" | "host" ]
2465 // <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
2466 // Note that the above were chosen to match the Itanium mangling for this.
2467 //
2468 // In the case of a non-language specific address space:
2469 // __clang::struct _AS<TargetAS, Type>
2470 assert(Quals.hasAddressSpace() && "Not valid without address space");
2471 llvm::SmallString<32> ASMangling;
2472 llvm::raw_svector_ostream Stream(ASMangling);
2473 MicrosoftCXXNameMangler Extra(Context, Stream);
2474 Stream << "?$";
2475
2476 LangAS AS = Quals.getAddressSpace();
2477 if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
2478 unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
2479 Extra.mangleSourceName("_AS");
2480 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2481 } else {
2482 switch (AS) {
2483 default:
2484 llvm_unreachable("Not a language specific address space");
2485 case LangAS::opencl_global:
2486 Extra.mangleSourceName("_ASCLglobal");
2487 break;
2488 case LangAS::opencl_global_device:
2489 Extra.mangleSourceName("_ASCLdevice");
2490 break;
2491 case LangAS::opencl_global_host:
2492 Extra.mangleSourceName("_ASCLhost");
2493 break;
2494 case LangAS::opencl_local:
2495 Extra.mangleSourceName("_ASCLlocal");
2496 break;
2497 case LangAS::opencl_constant:
2498 Extra.mangleSourceName("_ASCLconstant");
2499 break;
2500 case LangAS::opencl_private:
2501 Extra.mangleSourceName("_ASCLprivate");
2502 break;
2503 case LangAS::opencl_generic:
2504 Extra.mangleSourceName("_ASCLgeneric");
2505 break;
2506 case LangAS::cuda_device:
2507 Extra.mangleSourceName("_ASCUdevice");
2508 break;
2509 case LangAS::cuda_constant:
2510 Extra.mangleSourceName("_ASCUconstant");
2511 break;
2512 case LangAS::cuda_shared:
2513 Extra.mangleSourceName("_ASCUshared");
2514 break;
2515 case LangAS::ptr32_sptr:
2516 case LangAS::ptr32_uptr:
2517 case LangAS::ptr64:
2518 llvm_unreachable("don't mangle ptr address spaces with _AS");
2519 }
2520 }
2521
2522 Extra.mangleType(T, Range, QMM_Escape);
2523 mangleQualifiers(Qualifiers(), false);
2524 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {"__clang"});
2525}
2526
2527void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T,
2528 QualifierMangleMode QMM) {
2529 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2530 LangOptions::MSVC2019) &&
2531 "Cannot mangle MSVC 2017 auto return types!");
2532
2533 if (isa<AutoType>(T)) {
2534 const auto *AT = T->getContainedAutoType();
2535 Qualifiers Quals = T.getLocalQualifiers();
2536
2537 if (QMM == QMM_Result)
2538 Out << '?';
2539 if (QMM != QMM_Drop)
2540 mangleQualifiers(Quals, false);
2541 Out << (AT->isDecltypeAuto() ? "_T" : "_P");
2542 return;
2543 }
2544
2545 T = T.getDesugaredType(getASTContext());
2546 Qualifiers Quals = T.getLocalQualifiers();
2547
2548 switch (QMM) {
2549 case QMM_Drop:
2550 case QMM_Result:
2551 break;
2552 case QMM_Mangle:
2553 mangleQualifiers(Quals, false);
2554 break;
2555 default:
2556 llvm_unreachable("QMM_Escape unexpected");
2557 }
2558
2559 const Type *ty = T.getTypePtr();
2560 switch (ty->getTypeClass()) {
2561 case Type::MemberPointer:
2562 mangleAutoReturnType(cast<MemberPointerType>(ty), Quals);
2563 break;
2564 case Type::Pointer:
2565 mangleAutoReturnType(cast<PointerType>(ty), Quals);
2566 break;
2567 case Type::LValueReference:
2568 mangleAutoReturnType(cast<LValueReferenceType>(ty), Quals);
2569 break;
2570 case Type::RValueReference:
2571 mangleAutoReturnType(cast<RValueReferenceType>(ty), Quals);
2572 break;
2573 default:
2574 llvm_unreachable("Invalid type expected");
2575 }
2576}
2577
2578void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
2579 QualifierMangleMode QMM) {
2580 // Don't use the canonical types. MSVC includes things like 'const' on
2581 // pointer arguments to function pointers that canonicalization strips away.
2582 T = T.getDesugaredType(getASTContext());
2583 Qualifiers Quals = T.getLocalQualifiers();
2584
2585 if (const ArrayType *AT = getASTContext().getAsArrayType(T)) {
2586 // If there were any Quals, getAsArrayType() pushed them onto the array
2587 // element type.
2588 if (QMM == QMM_Mangle)
2589 Out << 'A';
2590 else if (QMM == QMM_Escape || QMM == QMM_Result)
2591 Out << "$$B";
2592 mangleArrayType(AT);
2593 return;
2594 }
2595
2596 bool IsPointer = T->isAnyPointerType() || T->isMemberPointerType() ||
2598
2599 switch (QMM) {
2600 case QMM_Drop:
2601 if (Quals.hasObjCLifetime())
2602 Quals = Quals.withoutObjCLifetime();
2603 break;
2604 case QMM_Mangle:
2605 if (const FunctionType *FT = dyn_cast<FunctionType>(T)) {
2606 Out << '6';
2607 mangleFunctionType(FT);
2608 return;
2609 }
2610 mangleQualifiers(Quals, false);
2611 break;
2612 case QMM_Escape:
2613 if (!IsPointer && Quals) {
2614 Out << "$$C";
2615 mangleQualifiers(Quals, false);
2616 }
2617 break;
2618 case QMM_Result:
2619 // Presence of __unaligned qualifier shouldn't affect mangling here.
2620 Quals.removeUnaligned();
2621 if (Quals.hasObjCLifetime())
2622 Quals = Quals.withoutObjCLifetime();
2623 if ((!IsPointer && Quals) || isa<TagType>(T) || isArtificialTagType(T)) {
2624 Out << '?';
2625 mangleQualifiers(Quals, false);
2626 }
2627 break;
2628 }
2629
2630 const Type *ty = T.getTypePtr();
2631
2632 switch (ty->getTypeClass()) {
2633#define ABSTRACT_TYPE(CLASS, PARENT)
2634#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2635 case Type::CLASS: \
2636 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2637 return;
2638#define TYPE(CLASS, PARENT) \
2639 case Type::CLASS: \
2640 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2641 break;
2642#include "clang/AST/TypeNodes.inc"
2643#undef ABSTRACT_TYPE
2644#undef NON_CANONICAL_TYPE
2645#undef TYPE
2646 }
2647}
2648
2649void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
2650 SourceRange Range) {
2651 // <type> ::= <builtin-type>
2652 // <builtin-type> ::= X # void
2653 // ::= C # signed char
2654 // ::= D # char
2655 // ::= E # unsigned char
2656 // ::= F # short
2657 // ::= G # unsigned short (or wchar_t if it's not a builtin)
2658 // ::= H # int
2659 // ::= I # unsigned int
2660 // ::= J # long
2661 // ::= K # unsigned long
2662 // L # <none>
2663 // ::= M # float
2664 // ::= N # double
2665 // ::= O # long double (__float80 is mangled differently)
2666 // ::= _J # long long, __int64
2667 // ::= _K # unsigned long long, __int64
2668 // ::= _L # __int128
2669 // ::= _M # unsigned __int128
2670 // ::= _N # bool
2671 // _O # <array in parameter>
2672 // ::= _Q # char8_t
2673 // ::= _S # char16_t
2674 // ::= _T # __float80 (Intel)
2675 // ::= _U # char32_t
2676 // ::= _W # wchar_t
2677 // ::= _Z # __float80 (Digital Mars)
2678 switch (T->getKind()) {
2679 case BuiltinType::Void:
2680 Out << 'X';
2681 break;
2682 case BuiltinType::SChar:
2683 Out << 'C';
2684 break;
2685 case BuiltinType::Char_U:
2686 case BuiltinType::Char_S:
2687 Out << 'D';
2688 break;
2689 case BuiltinType::UChar:
2690 Out << 'E';
2691 break;
2692 case BuiltinType::Short:
2693 Out << 'F';
2694 break;
2695 case BuiltinType::UShort:
2696 Out << 'G';
2697 break;
2698 case BuiltinType::Int:
2699 Out << 'H';
2700 break;
2701 case BuiltinType::UInt:
2702 Out << 'I';
2703 break;
2704 case BuiltinType::Long:
2705 Out << 'J';
2706 break;
2707 case BuiltinType::ULong:
2708 Out << 'K';
2709 break;
2710 case BuiltinType::Float:
2711 Out << 'M';
2712 break;
2713 case BuiltinType::Double:
2714 Out << 'N';
2715 break;
2716 // TODO: Determine size and mangle accordingly
2717 case BuiltinType::LongDouble:
2718 Out << 'O';
2719 break;
2720 case BuiltinType::LongLong:
2721 Out << "_J";
2722 break;
2723 case BuiltinType::ULongLong:
2724 Out << "_K";
2725 break;
2726 case BuiltinType::Int128:
2727 Out << "_L";
2728 break;
2729 case BuiltinType::UInt128:
2730 Out << "_M";
2731 break;
2732 case BuiltinType::Bool:
2733 Out << "_N";
2734 break;
2735 case BuiltinType::Char8:
2736 Out << "_Q";
2737 break;
2738 case BuiltinType::Char16:
2739 Out << "_S";
2740 break;
2741 case BuiltinType::Char32:
2742 Out << "_U";
2743 break;
2744 case BuiltinType::WChar_S:
2745 case BuiltinType::WChar_U:
2746 Out << "_W";
2747 break;
2748
2749#define BUILTIN_TYPE(Id, SingletonId)
2750#define PLACEHOLDER_TYPE(Id, SingletonId) \
2751 case BuiltinType::Id:
2752#include "clang/AST/BuiltinTypes.def"
2753 case BuiltinType::Dependent:
2754 llvm_unreachable("placeholder types shouldn't get to name mangling");
2755
2756 case BuiltinType::ObjCId:
2757 mangleArtificialTagType(TagTypeKind::Struct, "objc_object");
2758 break;
2759 case BuiltinType::ObjCClass:
2760 mangleArtificialTagType(TagTypeKind::Struct, "objc_class");
2761 break;
2762 case BuiltinType::ObjCSel:
2763 mangleArtificialTagType(TagTypeKind::Struct, "objc_selector");
2764 break;
2765
2766#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2767 case BuiltinType::Id: \
2768 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2769 break;
2770#include "clang/Basic/OpenCLImageTypes.def"
2771 case BuiltinType::OCLSampler:
2772 Out << "PA";
2773 mangleArtificialTagType(TagTypeKind::Struct, "ocl_sampler");
2774 break;
2775 case BuiltinType::OCLEvent:
2776 Out << "PA";
2777 mangleArtificialTagType(TagTypeKind::Struct, "ocl_event");
2778 break;
2779 case BuiltinType::OCLClkEvent:
2780 Out << "PA";
2781 mangleArtificialTagType(TagTypeKind::Struct, "ocl_clkevent");
2782 break;
2783 case BuiltinType::OCLQueue:
2784 Out << "PA";
2785 mangleArtificialTagType(TagTypeKind::Struct, "ocl_queue");
2786 break;
2787 case BuiltinType::OCLReserveID:
2788 Out << "PA";
2789 mangleArtificialTagType(TagTypeKind::Struct, "ocl_reserveid");
2790 break;
2791#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2792 case BuiltinType::Id: \
2793 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2794 break;
2795#include "clang/Basic/OpenCLExtensionTypes.def"
2796
2797 case BuiltinType::NullPtr:
2798 Out << "$$T";
2799 break;
2800
2801 case BuiltinType::Float16:
2802 mangleArtificialTagType(TagTypeKind::Struct, "_Float16", {"__clang"});
2803 break;
2804
2805 case BuiltinType::Half:
2806 if (!getASTContext().getLangOpts().HLSL)
2807 mangleArtificialTagType(TagTypeKind::Struct, "_Half", {"__clang"});
2808 else if (getASTContext().getLangOpts().NativeHalfType)
2809 Out << "$f16@";
2810 else
2811 Out << "$halff@";
2812 break;
2813
2814 case BuiltinType::BFloat16:
2815 mangleArtificialTagType(TagTypeKind::Struct, "__bf16", {"__clang"});
2816 break;
2817
2818 case BuiltinType::MFloat8:
2819 mangleArtificialTagType(TagTypeKind::Struct, "__mfp8", {"__clang"});
2820 break;
2821
2822#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2823 case BuiltinType::Id: \
2824 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2825 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2826 break;
2827
2828#include "clang/Basic/WebAssemblyReferenceTypes.def"
2829
2830#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2831 case BuiltinType::Id: \
2832 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2833 break;
2834#include "clang/Basic/HLSLIntangibleTypes.def"
2835
2836 case BuiltinType::SveBool:
2837 Out << "$_CA";
2838 break;
2839
2840 case BuiltinType::SveInt8:
2841 Out << "$_CB";
2842 break;
2843 case BuiltinType::SveInt16:
2844 Out << "$_CC";
2845 break;
2846 case BuiltinType::SveInt32:
2847 Out << "$_CD";
2848 break;
2849 case BuiltinType::SveInt64:
2850 Out << "$_CE";
2851 break;
2852
2853 case BuiltinType::SveUint8:
2854 Out << "$_CF";
2855 break;
2856 case BuiltinType::SveUint16:
2857 Out << "$_CG";
2858 break;
2859 case BuiltinType::SveUint32:
2860 Out << "$_CH";
2861 break;
2862 case BuiltinType::SveUint64:
2863 Out << "$_CI";
2864 break;
2865
2866 case BuiltinType::SveBFloat16:
2867 Out << "$_CJ";
2868 break;
2869 case BuiltinType::SveFloat16:
2870 Out << "$_CK";
2871 break;
2872 case BuiltinType::SveFloat32:
2873 Out << "$_CL";
2874 break;
2875 case BuiltinType::SveFloat64:
2876 Out << "$_CM";
2877 break;
2878
2879 case BuiltinType::SveInt8x2:
2880 Out << "$_C2B";
2881 break;
2882 case BuiltinType::SveInt16x2:
2883 Out << "$_C2C";
2884 break;
2885 case BuiltinType::SveInt32x2:
2886 Out << "$_C2D";
2887 break;
2888 case BuiltinType::SveInt64x2:
2889 Out << "$_C2E";
2890 break;
2891
2892 case BuiltinType::SveUint8x2:
2893 Out << "$_C2F";
2894 break;
2895 case BuiltinType::SveUint16x2:
2896 Out << "$_C2G";
2897 break;
2898 case BuiltinType::SveUint32x2:
2899 Out << "$_C2H";
2900 break;
2901 case BuiltinType::SveUint64x2:
2902 Out << "$_C2I";
2903 break;
2904
2905 case BuiltinType::SveBFloat16x2:
2906 Out << "$_C2J";
2907 break;
2908 case BuiltinType::SveFloat16x2:
2909 Out << "$_C2K";
2910 break;
2911 case BuiltinType::SveFloat32x2:
2912 Out << "$_C2L";
2913 break;
2914 case BuiltinType::SveFloat64x2:
2915 Out << "$_C2M";
2916 break;
2917
2918 case BuiltinType::SveInt8x3:
2919 Out << "$_C3B";
2920 break;
2921 case BuiltinType::SveInt16x3:
2922 Out << "$_C3C";
2923 break;
2924 case BuiltinType::SveInt32x3:
2925 Out << "$_C3D";
2926 break;
2927 case BuiltinType::SveInt64x3:
2928 Out << "$_C3E";
2929 break;
2930
2931 case BuiltinType::SveUint8x3:
2932 Out << "$_C3F";
2933 break;
2934 case BuiltinType::SveUint16x3:
2935 Out << "$_C3G";
2936 break;
2937 case BuiltinType::SveUint32x3:
2938 Out << "$_C3H";
2939 break;
2940 case BuiltinType::SveUint64x3:
2941 Out << "$_C3I";
2942 break;
2943
2944 case BuiltinType::SveBFloat16x3:
2945 Out << "$_C3J";
2946 break;
2947 case BuiltinType::SveFloat16x3:
2948 Out << "$_C3K";
2949 break;
2950 case BuiltinType::SveFloat32x3:
2951 Out << "$_C3L";
2952 break;
2953 case BuiltinType::SveFloat64x3:
2954 Out << "$_C3M";
2955 break;
2956
2957 case BuiltinType::SveInt8x4:
2958 Out << "$_C4B";
2959 break;
2960 case BuiltinType::SveInt16x4:
2961 Out << "$_C4C";
2962 break;
2963 case BuiltinType::SveInt32x4:
2964 Out << "$_C4D";
2965 break;
2966 case BuiltinType::SveInt64x4:
2967 Out << "$_C4E";
2968 break;
2969
2970 case BuiltinType::SveUint8x4:
2971 Out << "$_C4F";
2972 break;
2973 case BuiltinType::SveUint16x4:
2974 Out << "$_C4G";
2975 break;
2976 case BuiltinType::SveUint32x4:
2977 Out << "$_C4H";
2978 break;
2979 case BuiltinType::SveUint64x4:
2980 Out << "$_C4I";
2981 break;
2982
2983 case BuiltinType::SveBFloat16x4:
2984 Out << "$_C4J";
2985 break;
2986 case BuiltinType::SveFloat16x4:
2987 Out << "$_C4K";
2988 break;
2989 case BuiltinType::SveFloat32x4:
2990 Out << "$_C4L";
2991 break;
2992 case BuiltinType::SveFloat64x4:
2993 Out << "$_C4M";
2994 break;
2995
2996 // SVE types not supported by MSVC still use clang-specific
2997 // artificial tag mangling
2998 case BuiltinType::SveMFloat8:
2999 mangleArtificialTagType(TagTypeKind::Struct, "__SVMfloat8_t", {"__clang"});
3000 break;
3001
3002 case BuiltinType::SveMFloat8x2:
3003 mangleArtificialTagType(TagTypeKind::Struct, "__clang_svmfloat8x2_t",
3004 {"__clang"});
3005 break;
3006
3007 case BuiltinType::SveMFloat8x3:
3008 mangleArtificialTagType(TagTypeKind::Struct, "__clang_svmfloat8x3_t",
3009 {"__clang"});
3010 break;
3011
3012 case BuiltinType::SveMFloat8x4:
3013 mangleArtificialTagType(TagTypeKind::Struct, "__clang_svmfloat8x4_t",
3014 {"__clang"});
3015 break;
3016
3017 case BuiltinType::SveBoolx2:
3018 mangleArtificialTagType(TagTypeKind::Struct, "__clang_svboolx2_t",
3019 {"__clang"});
3020 break;
3021
3022 case BuiltinType::SveBoolx4:
3023 mangleArtificialTagType(TagTypeKind::Struct, "__clang_svboolx4_t",
3024 {"__clang"});
3025 break;
3026
3027 case BuiltinType::SveCount:
3028 mangleArtificialTagType(TagTypeKind::Struct, "__SVCount_t", {"__clang"});
3029 break;
3030
3031#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3032#include "clang/Basic/SPIRVTypes.def"
3033 Error(Range.getBegin(), "SPIR-V built-in type") << Range;
3034 break;
3035
3036 // Issue an error for any type not explicitly handled.
3037 default:
3038 Error(Range.getBegin(), "built-in type: ",
3039 T->getName(Context.getASTContext().getPrintingPolicy()))
3040 << Range;
3041 break;
3042 }
3043}
3044
3045// <type> ::= <function-type>
3046void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, Qualifiers,
3047 SourceRange) {
3048 // Structors only appear in decls, so at this point we know it's not a
3049 // structor type.
3050 // FIXME: This may not be lambda-friendly.
3051 if (T->getMethodQuals() || T->getRefQualifier() != RQ_None) {
3052 Out << "$$A8@@";
3053 mangleFunctionType(T, /*D=*/nullptr, /*ForceThisQuals=*/true);
3054 } else {
3055 Out << "$$A6";
3056 mangleFunctionType(T);
3057 }
3058}
3059void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
3060 Qualifiers, SourceRange) {
3061 Out << "$$A6";
3062 mangleFunctionType(T);
3063}
3064
3065void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
3066 const FunctionDecl *D,
3067 bool ForceThisQuals,
3068 bool MangleExceptionSpec) {
3069 // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
3070 // <return-type> <argument-list> <throw-spec>
3071 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);
3072
3073 SourceRange Range;
3074 if (D) Range = D->getSourceRange();
3075
3076 bool IsInLambda = false;
3077 bool IsStructor = false, HasThisQuals = ForceThisQuals, IsCtorClosure = false;
3078 CallingConv CC = T->getCallConv();
3079 if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
3080 if (MD->getParent()->isLambda())
3081 IsInLambda = true;
3083 HasThisQuals = true;
3084 if (isa<CXXDestructorDecl>(MD)) {
3085 IsStructor = true;
3086 } else if (isa<CXXConstructorDecl>(MD)) {
3087 IsStructor = true;
3088 IsCtorClosure = (StructorType == Ctor_CopyingClosure ||
3089 StructorType == Ctor_DefaultClosure) &&
3090 isStructorDecl(MD);
3091 if (IsCtorClosure)
3092 CC = getASTContext().getDefaultCallingConvention(
3093 /*IsVariadic=*/false, /*IsCXXMethod=*/true);
3094 }
3095 }
3096
3097 // If this is a C++ instance method, mangle the CVR qualifiers for the
3098 // this pointer.
3099 if (HasThisQuals) {
3100 Qualifiers Quals = Proto->getMethodQuals();
3101 manglePointerExtQualifiers(Quals, /*PointeeType=*/QualType());
3102 mangleRefQualifier(Proto->getRefQualifier());
3103 mangleQualifiers(Quals, /*IsMember=*/false);
3104 }
3105
3106 mangleCallingConvention(CC, Range);
3107
3108 if (Proto) {
3109 unsigned SMEAttrs = Proto->getAArch64SMEAttributes();
3110 if (SMEAttrs)
3111 Out << "__clang_sme_attr" << SMEAttrs;
3112 }
3113
3114 // <return-type> ::= <type>
3115 // ::= @ # structors (they have no declared return type)
3116 if (IsStructor) {
3117 if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
3118 // The deleting destructors take an extra argument of type int that
3119 // indicates whether the storage for the object should be deleted and
3120 // whether a single object or an array of objects is being destroyed. This
3121 // extra argument is not reflected in the AST.
3122 if (StructorType == Dtor_Deleting ||
3123 StructorType == Dtor_VectorDeleting) {
3124 Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");
3125 return;
3126 }
3127 // The vbase destructor returns void which is not reflected in the AST.
3128 if (StructorType == Dtor_Complete) {
3129 Out << "XXZ";
3130 return;
3131 }
3132 }
3133 if (IsCtorClosure) {
3134 // Default constructor closure and copy constructor closure both return
3135 // void.
3136 Out << 'X';
3137
3138 if (StructorType == Ctor_DefaultClosure) {
3139 // Default constructor closure always has no arguments.
3140 Out << 'X';
3141 } else if (StructorType == Ctor_CopyingClosure) {
3142 // Copy constructor closure always takes an unqualified reference.
3143 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
3144 Proto->getParamType(0)
3145 ->castAs<LValueReferenceType>()
3146 ->getPointeeType(),
3147 /*SpelledAsLValue=*/true),
3148 Range);
3149 Out << '@';
3150 } else {
3151 llvm_unreachable("unexpected constructor closure!");
3152 }
3153 Out << 'Z';
3154 return;
3155 }
3156 Out << '@';
3157 } else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(D)) {
3158 // The only lambda conversion operators are to function pointers, which
3159 // can differ by their calling convention and are typically deduced. So
3160 // we make sure that this type gets mangled properly.
3161 mangleType(T->getReturnType(), Range, QMM_Result);
3162 } else {
3163 QualType ResultType = T->getReturnType();
3164 if (IsInLambda && isa<CXXConversionDecl>(D)) {
3165 // The only lambda conversion operators are to function pointers, which
3166 // can differ by their calling convention and are typically deduced. So
3167 // we make sure that this type gets mangled properly.
3168 mangleType(ResultType, Range, QMM_Result);
3169 } else if (IsInLambda) {
3170 if (const auto *AT = ResultType->getContainedAutoType()) {
3171 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
3172 "shouldn't need to mangle __auto_type!");
3173 Out << '?';
3174 mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
3175 Out << '?';
3176 mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
3177 Out << '@';
3178 } else {
3179 Out << '@';
3180 }
3181 } else if (const auto *AT = ResultType->getContainedAutoType()) {
3182 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
3183 "shouldn't need to mangle __auto_type!");
3184
3185 // If we have any pointer types with the clang address space extension
3186 // then defer to the custom clang mangling to keep backwards
3187 // compatibility. See `mangleType(const PointerType *T, Qualifiers Quals,
3188 // SourceRange Range)` for details.
3189 auto UseClangMangling = [](QualType ResultType) {
3190 QualType T = ResultType;
3191 while (isa<PointerType>(T.getTypePtr())) {
3192 T = T->getPointeeType();
3193 if (T.getQualifiers().hasAddressSpace())
3194 return true;
3195 }
3196 return false;
3197 };
3198
3199 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
3200 LangOptions::MSVC2019) &&
3201 !UseClangMangling(ResultType)) {
3202 if (D && !D->getPrimaryTemplate()) {
3203 Out << '@';
3204 } else {
3205 if (D && D->getPrimaryTemplate()) {
3206 const FunctionProtoType *FPT = D->getPrimaryTemplate()
3208 ->getFirstDecl()
3209 ->getType()
3210 ->castAs<FunctionProtoType>();
3211 ResultType = FPT->getReturnType();
3212 }
3213 mangleAutoReturnType(ResultType, QMM_Result);
3214 }
3215 } else {
3216 Out << '?';
3217 mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
3218 Out << '?';
3219 mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
3220 Out << '@';
3221 }
3222 } else {
3223 if (ResultType->isVoidType())
3224 ResultType = ResultType.getUnqualifiedType();
3225 mangleType(ResultType, Range, QMM_Result);
3226 }
3227 }
3228
3229 // <argument-list> ::= X # void
3230 // ::= <type>+ @
3231 // ::= <type>* Z # varargs
3232 if (!Proto) {
3233 // Function types without prototypes can arise when mangling a function type
3234 // within an overloadable function in C. We mangle these as the absence of
3235 // any parameter types (not even an empty parameter list).
3236 Out << '@';
3237 } else if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
3238 Out << 'X';
3239 } else {
3240 // Happens for function pointer type arguments for example.
3241 for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) {
3242 // Explicit object parameters are prefixed by "_V".
3243 if (I == 0 && D && D->getParamDecl(I)->isExplicitObjectParameter())
3244 Out << "_V";
3245
3246 mangleFunctionArgumentType(Proto->getParamType(I), Range);
3247 // Mangle each pass_object_size parameter as if it's a parameter of enum
3248 // type passed directly after the parameter with the pass_object_size
3249 // attribute. The aforementioned enum's name is __pass_object_size, and we
3250 // pretend it resides in a top-level namespace called __clang.
3251 //
3252 // FIXME: Is there a defined extension notation for the MS ABI, or is it
3253 // necessary to just cross our fingers and hope this type+namespace
3254 // combination doesn't conflict with anything?
3255 if (D)
3256 if (const auto *P = D->getParamDecl(I)->getAttr<PassObjectSizeAttr>())
3257 manglePassObjectSizeArg(P);
3258 }
3259 // <builtin-type> ::= Z # ellipsis
3260 if (Proto->isVariadic())
3261 Out << 'Z';
3262 else
3263 Out << '@';
3264 }
3265
3266 if (MangleExceptionSpec && getASTContext().getLangOpts().CPlusPlus17 &&
3267 getASTContext().getLangOpts().isCompatibleWithMSVC(
3268 LangOptions::MSVC2017_5))
3269 mangleThrowSpecification(Proto);
3270 else
3271 Out << 'Z';
3272}
3273
3274void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
3275 // <function-class> ::= <member-function> E? # E designates a 64-bit 'this'
3276 // # pointer. in 64-bit mode *all*
3277 // # 'this' pointers are 64-bit.
3278 // ::= <global-function>
3279 // <member-function> ::= A # private: near
3280 // ::= B # private: far
3281 // ::= C # private: static near
3282 // ::= D # private: static far
3283 // ::= E # private: virtual near
3284 // ::= F # private: virtual far
3285 // ::= I # protected: near
3286 // ::= J # protected: far
3287 // ::= K # protected: static near
3288 // ::= L # protected: static far
3289 // ::= M # protected: virtual near
3290 // ::= N # protected: virtual far
3291 // ::= Q # public: near
3292 // ::= R # public: far
3293 // ::= S # public: static near
3294 // ::= T # public: static far
3295 // ::= U # public: virtual near
3296 // ::= V # public: virtual far
3297 // <global-function> ::= Y # global near
3298 // ::= Z # global far
3299 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3300 bool IsVirtual = MD->isVirtual();
3301 // When mangling vbase destructor variants, ignore whether or not the
3302 // underlying destructor was defined to be virtual.
3303 if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
3304 StructorType == Dtor_Complete) {
3305 IsVirtual = false;
3306 }
3307 switch (MD->getAccess()) {
3308 case AS_none:
3309 llvm_unreachable("Unsupported access specifier");
3310 case AS_private:
3312 Out << 'C';
3313 else if (IsVirtual)
3314 Out << 'E';
3315 else
3316 Out << 'A';
3317 break;
3318 case AS_protected:
3320 Out << 'K';
3321 else if (IsVirtual)
3322 Out << 'M';
3323 else
3324 Out << 'I';
3325 break;
3326 case AS_public:
3328 Out << 'S';
3329 else if (IsVirtual)
3330 Out << 'U';
3331 else
3332 Out << 'Q';
3333 }
3334 } else {
3335 Out << 'Y';
3336 }
3337}
3338void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC,
3339 SourceRange Range) {
3340 // <calling-convention> ::= A # __cdecl
3341 // ::= B # __export __cdecl
3342 // ::= C # __pascal
3343 // ::= D # __export __pascal
3344 // ::= E # __thiscall
3345 // ::= F # __export __thiscall
3346 // ::= G # __stdcall
3347 // ::= H # __export __stdcall
3348 // ::= I # __fastcall
3349 // ::= J # __export __fastcall
3350 // ::= Q # __vectorcall
3351 // ::= S # __attribute__((__swiftcall__)) // Clang-only
3352 // ::= W # __attribute__((__swiftasynccall__))
3353 // ::= U # __attribute__((__preserve_most__))
3354 // ::= V # __attribute__((__preserve_none__)) //
3355 // Clang-only
3356 // // Clang-only
3357 // ::= w # __regcall
3358 // ::= x # __regcall4
3359 // The 'export' calling conventions are from a bygone era
3360 // (*cough*Win16*cough*) when functions were declared for export with
3361 // that keyword. (It didn't actually export them, it just made them so
3362 // that they could be in a DLL and somebody from another module could call
3363 // them.)
3364
3365 switch (CC) {
3366 default:
3367 break;
3368 case CC_Win64:
3369 case CC_X86_64SysV:
3370 case CC_C:
3371 Out << 'A';
3372 return;
3373 case CC_X86Pascal:
3374 Out << 'C';
3375 return;
3376 case CC_X86ThisCall:
3377 Out << 'E';
3378 return;
3379 case CC_X86StdCall:
3380 Out << 'G';
3381 return;
3382 case CC_X86FastCall:
3383 Out << 'I';
3384 return;
3385 case CC_X86VectorCall:
3386 Out << 'Q';
3387 return;
3388 case CC_Swift:
3389 Out << 'S';
3390 return;
3391 case CC_SwiftAsync:
3392 Out << 'W';
3393 return;
3394 case CC_PreserveMost:
3395 Out << 'U';
3396 return;
3397 case CC_PreserveNone:
3398 Out << 'V';
3399 return;
3400 case CC_X86RegCall:
3401 if (getASTContext().getLangOpts().RegCall4)
3402 Out << "x";
3403 else
3404 Out << "w";
3405 return;
3406 }
3407
3408 Error(Range.getBegin(), "calling convention") << Range;
3409}
3410void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T,
3411 SourceRange Range) {
3412 mangleCallingConvention(T->getCallConv(), Range);
3413}
3414
3415void MicrosoftCXXNameMangler::mangleThrowSpecification(
3416 const FunctionProtoType *FT) {
3417 // <throw-spec> ::= Z # (default)
3418 // ::= _E # noexcept
3419 if (FT->canThrow())
3420 Out << 'Z';
3421 else
3422 Out << "_E";
3423}
3424
3425void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,
3426 Qualifiers, SourceRange Range) {
3427 // Probably should be mangled as a template instantiation; need to see what
3428 // VC does first.
3429 Error(Range.getBegin(), "unresolved dependent type") << Range;
3430}
3431
3432// <type> ::= <union-type> | <struct-type> | <class-type> | <enum-type>
3433// <union-type> ::= T <name>
3434// <struct-type> ::= U <name>
3435// <class-type> ::= V <name>
3436// <enum-type> ::= W4 <name>
3437void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) {
3438 switch (TTK) {
3439 case TagTypeKind::Union:
3440 Out << 'T';
3441 break;
3442 case TagTypeKind::Struct:
3443 case TagTypeKind::Interface:
3444 Out << 'U';
3445 break;
3446 case TagTypeKind::Class:
3447 Out << 'V';
3448 break;
3449 case TagTypeKind::Enum:
3450 Out << "W4";
3451 break;
3452 }
3453}
3454void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers,
3455 SourceRange) {
3456 mangleType(cast<TagType>(T)->getDecl());
3457}
3458void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers,
3459 SourceRange) {
3460 mangleType(cast<TagType>(T)->getDecl());
3461}
3462void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
3463 // MSVC chooses the tag kind of the definition if it exists, otherwise it
3464 // always picks the first declaration.
3465 const auto *Def = TD->getDefinition();
3466 TD = Def ? Def : TD->getFirstDecl();
3467 mangleTagTypeKind(TD->getTagKind());
3468 mangleName(TD);
3469}
3470
3471// If you add a call to this, consider updating isArtificialTagType() too.
3472void MicrosoftCXXNameMangler::mangleArtificialTagType(
3473 TagTypeKind TK, StringRef UnqualifiedName,
3474 ArrayRef<StringRef> NestedNames) {
3475 // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
3476 mangleTagTypeKind(TK);
3477
3478 // Always start with the unqualified name.
3479 mangleSourceName(UnqualifiedName);
3480
3481 for (StringRef N : llvm::reverse(NestedNames))
3482 mangleSourceName(N);
3483
3484 // Terminate the whole name with an '@'.
3485 Out << '@';
3486}
3487
3488// <type> ::= <array-type>
3489// <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
3490// [Y <dimension-count> <dimension>+]
3491// <element-type> # as global, E is never required
3492// It's supposed to be the other way around, but for some strange reason, it
3493// isn't. Today this behavior is retained for the sole purpose of backwards
3494// compatibility.
3495void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) {
3496 // This isn't a recursive mangling, so now we have to do it all in this
3497 // one call.
3498 manglePointerCVQualifiers(T->getElementType().getQualifiers());
3499 mangleType(T->getElementType(), SourceRange());
3500}
3501void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T, Qualifiers,
3502 SourceRange) {
3503 llvm_unreachable("Should have been special cased");
3504}
3505void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T, Qualifiers,
3506 SourceRange) {
3507 llvm_unreachable("Should have been special cased");
3508}
3509void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T,
3510 Qualifiers, SourceRange) {
3511 llvm_unreachable("Should have been special cased");
3512}
3513void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T,
3514 Qualifiers, SourceRange) {
3515 llvm_unreachable("Should have been special cased");
3516}
3517void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) {
3518 QualType ElementTy(T, 0);
3519 SmallVector<llvm::APInt, 3> Dimensions;
3520 for (;;) {
3521 if (ElementTy->isConstantArrayType()) {
3522 const ConstantArrayType *CAT =
3523 getASTContext().getAsConstantArrayType(ElementTy);
3524 Dimensions.push_back(CAT->getSize());
3525 ElementTy = CAT->getElementType();
3526 } else if (ElementTy->isIncompleteArrayType()) {
3527 const IncompleteArrayType *IAT =
3528 getASTContext().getAsIncompleteArrayType(ElementTy);
3529 Dimensions.push_back(llvm::APInt(32, 0));
3530 ElementTy = IAT->getElementType();
3531 } else if (ElementTy->isVariableArrayType()) {
3532 const VariableArrayType *VAT =
3533 getASTContext().getAsVariableArrayType(ElementTy);
3534 Dimensions.push_back(llvm::APInt(32, 0));
3535 ElementTy = VAT->getElementType();
3536 } else if (ElementTy->isDependentSizedArrayType()) {
3537 // The dependent expression has to be folded into a constant (TODO).
3538 const DependentSizedArrayType *DSAT =
3539 getASTContext().getAsDependentSizedArrayType(ElementTy);
3540 Error(DSAT->getSizeExpr()->getExprLoc(), "dependent-length")
3541 << DSAT->getSizeExpr()->getSourceRange();
3542 return;
3543 } else {
3544 break;
3545 }
3546 }
3547 Out << 'Y';
3548 // <dimension-count> ::= <number> # number of extra dimensions
3549 mangleNumber(Dimensions.size());
3550 for (const llvm::APInt &Dimension : Dimensions)
3551 mangleNumber(Dimension.getLimitedValue());
3552 mangleType(ElementTy, SourceRange(), QMM_Escape);
3553}
3554
3555void MicrosoftCXXNameMangler::mangleType(const ArrayParameterType *T,
3556 Qualifiers, SourceRange) {
3557 mangleArrayType(cast<ConstantArrayType>(T));
3558}
3559
3560// <type> ::= <pointer-to-member-type>
3561// <pointer-to-member-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
3562// <class name> <type>
3563void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,
3564 Qualifiers Quals, SourceRange Range) {
3565 QualType PointeeType = T->getPointeeType();
3566 manglePointerCVQualifiers(Quals);
3567 manglePointerExtQualifiers(Quals, PointeeType);
3568 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
3569 Out << '8';
3570 mangleName(T->getMostRecentCXXRecordDecl());
3571 mangleFunctionType(FPT, nullptr, true);
3572 } else {
3573 mangleQualifiers(PointeeType.getQualifiers(), true);
3574 mangleName(T->getMostRecentCXXRecordDecl());
3575 mangleType(PointeeType, Range, QMM_Drop);
3576 }
3577}
3578
3579void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T,
3580 Qualifiers, SourceRange Range) {
3581 Out << '?';
3582
3583 llvm::SmallString<64> Name;
3584 Name += "<TTPT_";
3585 Name += llvm::utostr(T->getDepth());
3586 Name += "_";
3587 Name += llvm::utostr(T->getIndex());
3588 Name += ">";
3589 mangleSourceName(Name);
3590}
3591
3592void MicrosoftCXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T,
3593 Qualifiers, SourceRange Range) {
3594 Error(Range.getBegin(), "substituted parameter pack") << Range;
3595}
3596
3597void MicrosoftCXXNameMangler::mangleType(const SubstBuiltinTemplatePackType *T,
3598 Qualifiers, SourceRange Range) {
3599 Error(Range.getBegin(), "substituted builtin template pack") << Range;
3600}
3601
3602// <type> ::= <pointer-type>
3603// <pointer-type> ::= E? <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
3604// # the E is required for 64-bit non-static pointers
3605void MicrosoftCXXNameMangler::mangleType(const PointerType *T, Qualifiers Quals,
3606 SourceRange Range) {
3607 QualType PointeeType = T->getPointeeType();
3608 manglePointerCVQualifiers(Quals);
3609 manglePointerExtQualifiers(Quals, PointeeType);
3610 manglePointerAuthQualifier(Quals);
3611
3612 // For pointer size address spaces, go down the same type mangling path as
3613 // non address space types.
3614 LangAS AddrSpace = PointeeType.getQualifiers().getAddressSpace();
3615 if (isPtrSizeAddressSpace(AddrSpace) || AddrSpace == LangAS::Default)
3616 mangleType(PointeeType, Range);
3617 else
3618 mangleAddressSpaceType(PointeeType, PointeeType.getQualifiers(), Range);
3619}
3620
3621void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
3622 Qualifiers Quals, SourceRange Range) {
3623 QualType PointeeType = T->getPointeeType();
3624 switch (Quals.getObjCLifetime()) {
3627 break;
3631 return mangleObjCLifetime(PointeeType, Quals, Range);
3632 }
3633 manglePointerCVQualifiers(Quals);
3634 manglePointerExtQualifiers(Quals, PointeeType);
3635 mangleType(PointeeType, Range);
3636}
3637
3638// <type> ::= <reference-type>
3639// <reference-type> ::= A E? <cvr-qualifiers> <type>
3640// # the E is required for 64-bit non-static lvalue references
3641void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,
3642 Qualifiers Quals, SourceRange Range) {
3643 QualType PointeeType = T->getPointeeType();
3644 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
3645 Out << 'A';
3646 manglePointerExtQualifiers(Quals, PointeeType);
3647 mangleType(PointeeType, Range);
3648}
3649
3650// <type> ::= <r-value-reference-type>
3651// <r-value-reference-type> ::= $$Q E? <cvr-qualifiers> <type>
3652// # the E is required for 64-bit non-static rvalue references
3653void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,
3654 Qualifiers Quals, SourceRange Range) {
3655 QualType PointeeType = T->getPointeeType();
3656 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
3657 Out << "$$Q";
3658 manglePointerExtQualifiers(Quals, PointeeType);
3659 mangleType(PointeeType, Range);
3660}
3661
3662void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, Qualifiers,
3663 SourceRange Range) {
3664 QualType ElementType = T->getElementType();
3665
3666 llvm::SmallString<64> TemplateMangling;
3667 llvm::raw_svector_ostream Stream(TemplateMangling);
3668 MicrosoftCXXNameMangler Extra(Context, Stream);
3669 Stream << "?$";
3670 Extra.mangleSourceName("_Complex");
3671 Extra.mangleType(ElementType, Range, QMM_Escape);
3672
3673 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3674}
3675
3676// Returns true for types that mangleArtificialTagType() gets called for with
3677// TagTypeKind Union, Struct, Class and where compatibility with MSVC's
3678// mangling matters.
3679// (It doesn't matter for Objective-C types and the like that cl.exe doesn't
3680// support.)
3681bool MicrosoftCXXNameMangler::isArtificialTagType(QualType T) const {
3682 const Type *ty = T.getTypePtr();
3683 switch (ty->getTypeClass()) {
3684 default:
3685 return false;
3686
3687 case Type::Vector: {
3688 // For ABI compatibility only __m64, __m128(id), and __m256(id) matter,
3689 // but since mangleType(VectorType*) always calls mangleArtificialTagType()
3690 // just always return true (the other vector types are clang-only).
3691 return true;
3692 }
3693 }
3694}
3695
3696void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,
3697 SourceRange Range) {
3698 QualType EltTy = T->getElementType();
3699 const BuiltinType *ET = EltTy->getAs<BuiltinType>();
3700 const BitIntType *BitIntTy = EltTy->getAs<BitIntType>();
3701 assert((ET || BitIntTy) &&
3702 "vectors with non-builtin/_BitInt elements are unsupported");
3703 uint64_t Width = getASTContext().getTypeSize(T);
3704 // Pattern match exactly the typedefs in our intrinsic headers. Anything that
3705 // doesn't match the Intel types uses a custom mangling below.
3706 size_t OutSizeBefore = Out.tell();
3707 if (!isa<ExtVectorType>(T)) {
3708 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
3709 if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {
3710 mangleArtificialTagType(TagTypeKind::Union, "__m64");
3711 } else if (Width >= 128) {
3712 if (ET->getKind() == BuiltinType::Float)
3713 mangleArtificialTagType(TagTypeKind::Union,
3714 "__m" + llvm::utostr(Width));
3715 else if (ET->getKind() == BuiltinType::LongLong)
3716 mangleArtificialTagType(TagTypeKind::Union,
3717 "__m" + llvm::utostr(Width) + 'i');
3718 else if (ET->getKind() == BuiltinType::Double)
3719 mangleArtificialTagType(TagTypeKind::Struct,
3720 "__m" + llvm::utostr(Width) + 'd');
3721 }
3722 }
3723 }
3724
3725 bool IsBuiltin = Out.tell() != OutSizeBefore;
3726 if (!IsBuiltin) {
3727 // The MS ABI doesn't have a special mangling for vector types, so we define
3728 // our own mangling to handle uses of __vector_size__ on user-specified
3729 // types, and for extensions like __v4sf.
3730
3731 llvm::SmallString<64> TemplateMangling;
3732 llvm::raw_svector_ostream Stream(TemplateMangling);
3733 MicrosoftCXXNameMangler Extra(Context, Stream);
3734 Stream << "?$";
3735 Extra.mangleSourceName("__vector");
3736 Extra.mangleType(QualType(ET ? static_cast<const Type *>(ET) : BitIntTy, 0),
3737 Range, QMM_Escape);
3738 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()));
3739
3740 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {"__clang"});
3741 }
3742}
3743
3744void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T,
3745 Qualifiers Quals, SourceRange Range) {
3746 mangleType(static_cast<const VectorType *>(T), Quals, Range);
3747}
3748
3749void MicrosoftCXXNameMangler::mangleType(const DependentVectorType *T,
3750 Qualifiers, SourceRange Range) {
3751 Error(Range.getBegin(), "dependent-sized vector type") << Range;
3752}
3753
3754void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,
3755 Qualifiers, SourceRange Range) {
3756 Error(Range.getBegin(), "dependent-sized extended vector type") << Range;
3757}
3758
3759void MicrosoftCXXNameMangler::mangleType(const ConstantMatrixType *T,
3760 Qualifiers quals, SourceRange Range) {
3761 QualType EltTy = T->getElementType();
3762
3763 llvm::SmallString<64> TemplateMangling;
3764 llvm::raw_svector_ostream Stream(TemplateMangling);
3765 MicrosoftCXXNameMangler Extra(Context, Stream);
3766
3767 Stream << "?$";
3768
3769 Extra.mangleSourceName("__matrix");
3770 Extra.mangleType(EltTy, Range, QMM_Escape);
3771
3772 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumRows()));
3773 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumColumns()));
3774
3775 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3776}
3777
3778void MicrosoftCXXNameMangler::mangleType(const DependentSizedMatrixType *T,
3779 Qualifiers quals, SourceRange Range) {
3780 Error(Range.getBegin(), "dependent-sized matrix type") << Range;
3781}
3782
3783void MicrosoftCXXNameMangler::mangleType(const DependentAddressSpaceType *T,
3784 Qualifiers, SourceRange Range) {
3785 Error(Range.getBegin(), "dependent address space type") << Range;
3786}
3787
3788void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,
3789 SourceRange) {
3790 // ObjC interfaces have structs underlying them.
3791 mangleTagTypeKind(TagTypeKind::Struct);
3792 mangleName(T->getDecl());
3793}
3794
3795void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,
3796 Qualifiers Quals, SourceRange Range) {
3797 if (T->isKindOfType())
3798 return mangleObjCKindOfType(T, Quals, Range);
3799
3800 if (T->qual_empty() && !T->isSpecialized())
3801 return mangleType(T->getBaseType(), Range, QMM_Drop);
3802
3803 ArgBackRefMap OuterFunArgsContext;
3804 ArgBackRefMap OuterTemplateArgsContext;
3805 BackRefVec OuterTemplateContext;
3806
3807 FunArgBackReferences.swap(OuterFunArgsContext);
3808 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3809 NameBackReferences.swap(OuterTemplateContext);
3810
3811 mangleTagTypeKind(TagTypeKind::Struct);
3812
3813 Out << "?$";
3814 if (T->isObjCId())
3815 mangleSourceName("objc_object");
3816 else if (T->isObjCClass())
3817 mangleSourceName("objc_class");
3818 else
3819 mangleSourceName(T->getInterface()->getName());
3820
3821 for (const auto &Q : T->quals())
3822 mangleObjCProtocol(Q);
3823
3824 if (T->isSpecialized())
3825 for (const auto &TA : T->getTypeArgs())
3826 mangleType(TA, Range, QMM_Drop);
3827
3828 Out << '@';
3829
3830 Out << '@';
3831
3832 FunArgBackReferences.swap(OuterFunArgsContext);
3833 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3834 NameBackReferences.swap(OuterTemplateContext);
3835}
3836
3837void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T,
3838 Qualifiers Quals, SourceRange Range) {
3839 QualType PointeeType = T->getPointeeType();
3840 manglePointerCVQualifiers(Quals);
3841 manglePointerExtQualifiers(Quals, PointeeType);
3842
3843 Out << "_E";
3844
3845 mangleFunctionType(PointeeType->castAs<FunctionProtoType>());
3846}
3847
3848void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *,
3849 Qualifiers, SourceRange) {
3850 llvm_unreachable("Cannot mangle injected class name type.");
3851}
3852
3853void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T,
3854 Qualifiers, SourceRange Range) {
3855 Error(Range.getBegin(), "template specialization type") << Range;
3856}
3857
3858void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T, Qualifiers,
3859 SourceRange Range) {
3860 Error(Range.getBegin(), "dependent name type") << Range;
3861}
3862
3863void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T, Qualifiers,
3864 SourceRange Range) {
3865 Error(Range.getBegin(), "pack expansion") << Range;
3866}
3867
3868void MicrosoftCXXNameMangler::mangleType(const PackIndexingType *T,
3869 Qualifiers Quals, SourceRange Range) {
3870 manglePointerCVQualifiers(Quals);
3871 mangleType(T->getSelectedType(), Range);
3872}
3873
3874void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T, Qualifiers,
3875 SourceRange Range) {
3876 Error(Range.getBegin(), "typeof(type)") << Range;
3877}
3878
3879void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T, Qualifiers,
3880 SourceRange Range) {
3881 Error(Range.getBegin(), "typeof(expression)") << Range;
3882}
3883
3884void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T, Qualifiers,
3885 SourceRange Range) {
3886 Error(Range.getBegin(), "decltype()") << Range;
3887}
3888
3889void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T,
3890 Qualifiers, SourceRange Range) {
3891 Error(Range.getBegin(), "unary transform type") << Range;
3892}
3893
3894void MicrosoftCXXNameMangler::mangleType(const AutoType *T, Qualifiers,
3895 SourceRange Range) {
3896 assert(T->getDeducedType().isNull() && "expecting a dependent type!");
3897
3898 Error(Range.getBegin(), "'auto' type") << Range;
3899}
3900
3901void MicrosoftCXXNameMangler::mangleType(
3902 const DeducedTemplateSpecializationType *T, Qualifiers, SourceRange Range) {
3903 assert(T->getDeducedType().isNull() && "expecting a dependent type!");
3904
3905 Error(Range.getBegin(), "deduced class template specialization type")
3906 << Range;
3907}
3908
3909void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers,
3910 SourceRange Range) {
3911 QualType ValueType = T->getValueType();
3912
3913 llvm::SmallString<64> TemplateMangling;
3914 llvm::raw_svector_ostream Stream(TemplateMangling);
3915 MicrosoftCXXNameMangler Extra(Context, Stream);
3916 Stream << "?$";
3917 Extra.mangleSourceName("_Atomic");
3918 Extra.mangleType(ValueType, Range, QMM_Escape);
3919
3920 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3921}
3922
3923void MicrosoftCXXNameMangler::mangleType(const PipeType *T, Qualifiers,
3924 SourceRange Range) {
3925 QualType ElementType = T->getElementType();
3926
3927 llvm::SmallString<64> TemplateMangling;
3928 llvm::raw_svector_ostream Stream(TemplateMangling);
3929 MicrosoftCXXNameMangler Extra(Context, Stream);
3930 Stream << "?$";
3931 Extra.mangleSourceName("ocl_pipe");
3932 Extra.mangleType(ElementType, Range, QMM_Escape);
3933 Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()));
3934
3935 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3936}
3937
3938void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
3939 raw_ostream &Out) {
3940 const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
3941 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
3942 getASTContext().getSourceManager(),
3943 "Mangling declaration");
3944
3945 msvc_hashing_ostream MHO(Out);
3946
3947 if (auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3948 auto Type = GD.getCtorType();
3949 MicrosoftCXXNameMangler mangler(*this, MHO, CD, Type);
3950 return mangler.mangle(GD);
3951 }
3952
3953 if (auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3954 auto Type = GD.getDtorType();
3955 MicrosoftCXXNameMangler mangler(*this, MHO, DD, Type);
3956 return mangler.mangle(GD);
3957 }
3958
3959 MicrosoftCXXNameMangler Mangler(*this, MHO);
3960 return Mangler.mangle(GD);
3961}
3962
3963void MicrosoftCXXNameMangler::mangleType(const BitIntType *T, Qualifiers,
3964 SourceRange Range) {
3965 llvm::SmallString<64> TemplateMangling;
3966 llvm::raw_svector_ostream Stream(TemplateMangling);
3967 MicrosoftCXXNameMangler Extra(Context, Stream);
3968 Stream << "?$";
3969 if (T->isUnsigned())
3970 Extra.mangleSourceName("_UBitInt");
3971 else
3972 Extra.mangleSourceName("_BitInt");
3973 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()));
3974
3975 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3976}
3977
3978void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,
3979 Qualifiers, SourceRange Range) {
3980 Error(Range.getBegin(), "DependentBitInt type") << Range;
3981}
3982
3983void MicrosoftCXXNameMangler::mangleType(const HLSLAttributedResourceType *T,
3984 Qualifiers, SourceRange Range) {
3985 llvm_unreachable("HLSL uses Itanium name mangling");
3986}
3987
3988void MicrosoftCXXNameMangler::mangleType(const HLSLInlineSpirvType *T,
3989 Qualifiers, SourceRange Range) {
3990 llvm_unreachable("HLSL uses Itanium name mangling");
3991}
3992
3993void MicrosoftCXXNameMangler::mangleType(const OverflowBehaviorType *T,
3994 Qualifiers, SourceRange Range) {
3995 QualType UnderlyingType = T->getUnderlyingType();
3996
3997 llvm::SmallString<64> TemplateMangling;
3998 llvm::raw_svector_ostream Stream(TemplateMangling);
3999 MicrosoftCXXNameMangler Extra(Context, Stream);
4000 Stream << "?$";
4001 if (T->isWrapKind()) {
4002 Extra.mangleSourceName("ObtWrap_");
4003 } else {
4004 Extra.mangleSourceName("ObtTrap_");
4005 }
4006 Extra.mangleType(UnderlyingType, Range, QMM_Escape);
4007
4008 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
4009}
4010
4011// <this-adjustment> ::= <no-adjustment> | <static-adjustment> |
4012// <virtual-adjustment>
4013// <no-adjustment> ::= A # private near
4014// ::= B # private far
4015// ::= I # protected near
4016// ::= J # protected far
4017// ::= Q # public near
4018// ::= R # public far
4019// <static-adjustment> ::= G <static-offset> # private near
4020// ::= H <static-offset> # private far
4021// ::= O <static-offset> # protected near
4022// ::= P <static-offset> # protected far
4023// ::= W <static-offset> # public near
4024// ::= X <static-offset> # public far
4025// <virtual-adjustment> ::= $0 <virtual-shift> <static-offset> # private near
4026// ::= $1 <virtual-shift> <static-offset> # private far
4027// ::= $2 <virtual-shift> <static-offset> # protected near
4028// ::= $3 <virtual-shift> <static-offset> # protected far
4029// ::= $4 <virtual-shift> <static-offset> # public near
4030// ::= $5 <virtual-shift> <static-offset> # public far
4031// <virtual-shift> ::= <vtordisp-shift> | <vtordispex-shift>
4032// <vtordisp-shift> ::= <offset-to-vtordisp>
4033// <vtordispex-shift> ::= <offset-to-vbptr> <vbase-offset-offset>
4034// <offset-to-vtordisp>
4036 const ThisAdjustment &Adjustment,
4037 MicrosoftCXXNameMangler &Mangler,
4038 raw_ostream &Out) {
4039 if (!Adjustment.Virtual.isEmpty()) {
4040 Out << '$';
4041 char AccessSpec;
4042 switch (AS) {
4043 case AS_none:
4044 llvm_unreachable("Unsupported access specifier");
4045 case AS_private:
4046 AccessSpec = '0';
4047 break;
4048 case AS_protected:
4049 AccessSpec = '2';
4050 break;
4051 case AS_public:
4052 AccessSpec = '4';
4053 }
4054 if (Adjustment.Virtual.Microsoft.VBPtrOffset) {
4055 Out << 'R' << AccessSpec;
4056 Mangler.mangleNumber(
4057 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBPtrOffset));
4058 Mangler.mangleNumber(
4059 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBOffsetOffset));
4060 Mangler.mangleNumber(
4061 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));
4062 Mangler.mangleNumber(static_cast<uint32_t>(Adjustment.NonVirtual));
4063 } else {
4064 Out << AccessSpec;
4065 Mangler.mangleNumber(
4066 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));
4067 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
4068 }
4069 } else if (Adjustment.NonVirtual != 0) {
4070 switch (AS) {
4071 case AS_none:
4072 llvm_unreachable("Unsupported access specifier");
4073 case AS_private:
4074 Out << 'G';
4075 break;
4076 case AS_protected:
4077 Out << 'O';
4078 break;
4079 case AS_public:
4080 Out << 'W';
4081 }
4082 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
4083 } else {
4084 switch (AS) {
4085 case AS_none:
4086 llvm_unreachable("Unsupported access specifier");
4087 case AS_private:
4088 Out << 'A';
4089 break;
4090 case AS_protected:
4091 Out << 'I';
4092 break;
4093 case AS_public:
4094 Out << 'Q';
4095 }
4096 }
4097}
4098
4099void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
4100 const CXXMethodDecl *MD, const MethodVFTableLocation &ML,
4101 raw_ostream &Out) {
4102 msvc_hashing_ostream MHO(Out);
4103 MicrosoftCXXNameMangler Mangler(*this, MHO);
4104 Mangler.getStream() << '?';
4105 Mangler.mangleVirtualMemPtrThunk(MD, ML);
4106}
4107
4108void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
4109 const ThunkInfo &Thunk,
4110 bool /*ElideOverrideInfo*/,
4111 raw_ostream &Out) {
4112 msvc_hashing_ostream MHO(Out);
4113 MicrosoftCXXNameMangler Mangler(*this, MHO);
4114 Mangler.getStream() << '?';
4115 Mangler.mangleName(MD);
4116
4117 // Usually the thunk uses the access specifier of the new method, but if this
4118 // is a covariant return thunk, then MSVC always uses the public access
4119 // specifier, and we do the same.
4120 AccessSpecifier AS = Thunk.Return.isEmpty() ? MD->getAccess() : AS_public;
4121 mangleThunkThisAdjustment(AS, Thunk.This, Mangler, MHO);
4122
4123 if (!Thunk.Return.isEmpty())
4124 assert(Thunk.Method != nullptr &&
4125 "Thunk info should hold the overridee decl");
4126
4127 const CXXMethodDecl *DeclForFPT = Thunk.Method ? Thunk.Method : MD;
4128 Mangler.mangleFunctionType(
4129 DeclForFPT->getType()->castAs<FunctionProtoType>(), MD);
4130}
4131
4132void MicrosoftMangleContextImpl::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
4134 const ThunkInfo &Thunk,
4135 bool /*ElideOverrideInfo*/,
4136 raw_ostream &Out) {
4137 // The dtor thunk should use vector deleting dtor mangling, however as an
4138 // optimization we may end up emitting only scalar deleting dtor body, so just
4139 // use the vector deleting dtor mangling manually.
4140 assert(Type == Dtor_Deleting || Type == Dtor_VectorDeleting);
4141 msvc_hashing_ostream MHO(Out);
4142 MicrosoftCXXNameMangler Mangler(*this, MHO, DD, Type);
4143 Mangler.getStream() << "??_E";
4144 Mangler.mangleName(DD->getParent());
4145 auto &Adjustment = Thunk.This;
4146 mangleThunkThisAdjustment(DD->getAccess(), Adjustment, Mangler, MHO);
4147 Mangler.mangleFunctionType(DD->getType()->castAs<FunctionProtoType>(), DD);
4148}
4149
4150void MicrosoftMangleContextImpl::mangleCXXVFTable(
4151 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4152 raw_ostream &Out) {
4153 // <mangled-name> ::= ?_7 <class-name> <storage-class>
4154 // <cvr-qualifiers> [<name>] @
4155 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
4156 // is always '6' for vftables.
4157 msvc_hashing_ostream MHO(Out);
4158 MicrosoftCXXNameMangler Mangler(*this, MHO);
4159 if (Derived->hasAttr<DLLImportAttr>())
4160 Mangler.getStream() << "??_S";
4161 else
4162 Mangler.getStream() << "??_7";
4163 Mangler.mangleName(Derived);
4164 Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.
4165 for (const CXXRecordDecl *RD : BasePath)
4166 Mangler.mangleName(RD);
4167 Mangler.getStream() << '@';
4168}
4169
4170void MicrosoftMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *Derived,
4171 raw_ostream &Out) {
4172 // TODO: Determine appropriate mangling for MSABI
4173 mangleCXXVFTable(Derived, {}, Out);
4174}
4175
4176void MicrosoftMangleContextImpl::mangleCXXVBTable(
4177 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4178 raw_ostream &Out) {
4179 // <mangled-name> ::= ?_8 <class-name> <storage-class>
4180 // <cvr-qualifiers> [<name>] @
4181 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
4182 // is always '7' for vbtables.
4183 msvc_hashing_ostream MHO(Out);
4184 MicrosoftCXXNameMangler Mangler(*this, MHO);
4185 Mangler.getStream() << "??_8";
4186 Mangler.mangleName(Derived);
4187 Mangler.getStream() << "7B"; // '7' for vbtable, 'B' for const.
4188 for (const CXXRecordDecl *RD : BasePath)
4189 Mangler.mangleName(RD);
4190 Mangler.getStream() << '@';
4191}
4192
4193void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
4194 msvc_hashing_ostream MHO(Out);
4195 MicrosoftCXXNameMangler Mangler(*this, MHO);
4196 Mangler.getStream() << "??_R0";
4197 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4198 Mangler.getStream() << "@8";
4199}
4200
4201void MicrosoftMangleContextImpl::mangleCXXRTTIName(
4202 QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {
4203 Out << '.';
4204 // MSVC caps the length of the TypeDescriptor's name string the same way it
4205 // caps decorated names, substituting "??@<md5>@" for over-long names. The
4206 // leading '.' counts toward the 4096-character limit but is not part of
4207 // the hashed input, so the threshold is one lower than for symbols.
4208 msvc_hashing_ostream MHO(Out, /*Threshold=*/4095);
4209 MicrosoftCXXNameMangler Mangler(*this, MHO);
4210 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4211}
4212
4213void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
4214 const CXXRecordDecl *SrcRD, const CXXRecordDecl *DstRD, raw_ostream &Out) {
4215 msvc_hashing_ostream MHO(Out);
4216 MicrosoftCXXNameMangler Mangler(*this, MHO);
4217 Mangler.getStream() << "??_K";
4218 Mangler.mangleName(SrcRD);
4219 Mangler.getStream() << "$C";
4220 Mangler.mangleName(DstRD);
4221}
4222
4223void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, bool IsConst,
4224 bool IsVolatile,
4225 bool IsUnaligned,
4226 uint32_t NumEntries,
4227 raw_ostream &Out) {
4228 msvc_hashing_ostream MHO(Out);
4229 MicrosoftCXXNameMangler Mangler(*this, MHO);
4230 Mangler.getStream() << "_TI";
4231 if (IsConst)
4232 Mangler.getStream() << 'C';
4233 if (IsVolatile)
4234 Mangler.getStream() << 'V';
4235 if (IsUnaligned)
4236 Mangler.getStream() << 'U';
4237 Mangler.getStream() << NumEntries;
4238 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4239}
4240
4241void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
4242 QualType T, uint32_t NumEntries, raw_ostream &Out) {
4243 msvc_hashing_ostream MHO(Out);
4244 MicrosoftCXXNameMangler Mangler(*this, MHO);
4245 Mangler.getStream() << "_CTA";
4246 Mangler.getStream() << NumEntries;
4247 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4248}
4249
4250void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4251 QualType T, const CXXConstructorDecl *CD, CXXCtorType CT, uint32_t Size,
4252 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
4253 raw_ostream &Out) {
4254 MicrosoftCXXNameMangler Mangler(*this, Out);
4255 Mangler.getStream() << "_CT";
4256
4257 llvm::SmallString<64> RTTIMangling;
4258 {
4259 llvm::raw_svector_ostream Stream(RTTIMangling);
4260 msvc_hashing_ostream MHO(Stream);
4261 mangleCXXRTTI(T, MHO);
4262 }
4263 Mangler.getStream() << RTTIMangling;
4264
4265 // VS2015 and VS2017.1 omit the copy-constructor in the mangled name but
4266 // both older and newer versions include it.
4267 // FIXME: It is known that the Ctor is present in 2013, and in 2017.7
4268 // (_MSC_VER 1914) and newer, and that it's omitted in 2015 and 2017.4
4269 // (_MSC_VER 1911), but it's unknown when exactly it reappeared (1914?
4270 // Or 1912, 1913 already?).
4271 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4272 LangOptions::MSVC2015) &&
4273 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4274 LangOptions::MSVC2017_7);
4275 llvm::SmallString<64> CopyCtorMangling;
4276 if (!OmitCopyCtor && CD) {
4277 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4278 msvc_hashing_ostream MHO(Stream);
4279 mangleCXXName(GlobalDecl(CD, CT), MHO);
4280 }
4281 Mangler.getStream() << CopyCtorMangling;
4282
4283 Mangler.getStream() << Size;
4284 if (VBPtrOffset == -1) {
4285 if (NVOffset) {
4286 Mangler.getStream() << NVOffset;
4287 }
4288 } else {
4289 Mangler.getStream() << NVOffset;
4290 Mangler.getStream() << VBPtrOffset;
4291 Mangler.getStream() << VBIndex;
4292 }
4293}
4294
4295void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4296 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
4297 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
4298 msvc_hashing_ostream MHO(Out);
4299 MicrosoftCXXNameMangler Mangler(*this, MHO);
4300 Mangler.getStream() << "??_R1";
4301 Mangler.mangleNumber(NVOffset);
4302 Mangler.mangleNumber(VBPtrOffset);
4303 Mangler.mangleNumber(VBTableOffset);
4304 Mangler.mangleNumber(Flags);
4305 Mangler.mangleName(Derived);
4306 Mangler.getStream() << "8";
4307}
4308
4309void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4310 const CXXRecordDecl *Derived, raw_ostream &Out) {
4311 msvc_hashing_ostream MHO(Out);
4312 MicrosoftCXXNameMangler Mangler(*this, MHO);
4313 Mangler.getStream() << "??_R2";
4314 Mangler.mangleName(Derived);
4315 Mangler.getStream() << "8";
4316}
4317
4318void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4319 const CXXRecordDecl *Derived, raw_ostream &Out) {
4320 msvc_hashing_ostream MHO(Out);
4321 MicrosoftCXXNameMangler Mangler(*this, MHO);
4322 Mangler.getStream() << "??_R3";
4323 Mangler.mangleName(Derived);
4324 Mangler.getStream() << "8";
4325}
4326
4327void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4328 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4329 raw_ostream &Out) {
4330 // <mangled-name> ::= ?_R4 <class-name> <storage-class>
4331 // <cvr-qualifiers> [<name>] @
4332 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
4333 // is always '6' for vftables.
4334 llvm::SmallString<64> VFTableMangling;
4335 llvm::raw_svector_ostream Stream(VFTableMangling);
4336 mangleCXXVFTable(Derived, BasePath, Stream);
4337
4338 if (VFTableMangling.starts_with("??@")) {
4339 assert(VFTableMangling.ends_with("@"));
4340 Out << VFTableMangling << "??_R4@";
4341 return;
4342 }
4343
4344 assert(VFTableMangling.starts_with("??_7") ||
4345 VFTableMangling.starts_with("??_S"));
4346
4347 Out << "??_R4" << VFTableMangling.str().drop_front(4);
4348}
4349
4350void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4351 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4352 msvc_hashing_ostream MHO(Out);
4353 MicrosoftCXXNameMangler Mangler(*this, MHO);
4354 // The function body is in the same comdat as the function with the handler,
4355 // so the numbering here doesn't have to be the same across TUs.
4356 //
4357 // <mangled-name> ::= ?filt$ <filter-number> @0
4358 Mangler.getStream() << "?filt$" << SEHFilterIds[EnclosingDecl]++ << "@0@";
4359 Mangler.mangleName(EnclosingDecl);
4360}
4361
4362void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4363 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4364 msvc_hashing_ostream MHO(Out);
4365 MicrosoftCXXNameMangler Mangler(*this, MHO);
4366 // The function body is in the same comdat as the function with the handler,
4367 // so the numbering here doesn't have to be the same across TUs.
4368 //
4369 // <mangled-name> ::= ?fin$ <filter-number> @0
4370 Mangler.getStream() << "?fin$" << SEHFinallyIds[EnclosingDecl]++ << "@0@";
4371 Mangler.mangleName(EnclosingDecl);
4372}
4373
4374void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4375 QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {
4376 // This is just a made up unique string for the purposes of tbaa. undname
4377 // does *not* know how to demangle it.
4378 MicrosoftCXXNameMangler Mangler(*this, Out);
4379 Mangler.getStream() << '?';
4380 Mangler.mangleType(T.getCanonicalType(), SourceRange());
4381}
4382
4383void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4384 const VarDecl *VD, unsigned ManglingNumber, raw_ostream &Out) {
4385 msvc_hashing_ostream MHO(Out);
4386 MicrosoftCXXNameMangler Mangler(*this, MHO);
4387
4388 Mangler.getStream() << "?";
4389 Mangler.mangleSourceName("$RT" + llvm::utostr(ManglingNumber));
4390 Mangler.mangle(VD, "");
4391}
4392
4393void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4394 const VarDecl *VD, unsigned GuardNum, raw_ostream &Out) {
4395 msvc_hashing_ostream MHO(Out);
4396 MicrosoftCXXNameMangler Mangler(*this, MHO);
4397
4398 Mangler.getStream() << "?";
4399 Mangler.mangleSourceName("$TSS" + llvm::utostr(GuardNum));
4400 Mangler.mangleNestedName(VD);
4401 Mangler.getStream() << "@4HA";
4402}
4403
4404void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,
4405 raw_ostream &Out) {
4406 // <guard-name> ::= ?_B <postfix> @5 <scope-depth>
4407 // ::= ?__J <postfix> @5 <scope-depth>
4408 // ::= ?$S <guard-num> @ <postfix> @4IA
4409
4410 // The first mangling is what MSVC uses to guard static locals in inline
4411 // functions. It uses a different mangling in external functions to support
4412 // guarding more than 32 variables. MSVC rejects inline functions with more
4413 // than 32 static locals. We don't fully implement the second mangling
4414 // because those guards are not externally visible, and instead use LLVM's
4415 // default renaming when creating a new guard variable.
4416 msvc_hashing_ostream MHO(Out);
4417 MicrosoftCXXNameMangler Mangler(*this, MHO);
4418
4419 bool Visible = VD->isExternallyVisible();
4420 if (Visible) {
4421 Mangler.getStream() << (VD->getTLSKind() ? "??__J" : "??_B");
4422 } else {
4423 Mangler.getStream() << "?$S1@";
4424 }
4425 unsigned ScopeDepth = 0;
4426 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4427 // If we do not have a discriminator and are emitting a guard variable for
4428 // use at global scope, then mangling the nested name will not be enough to
4429 // remove ambiguities.
4430 Mangler.mangle(VD, "");
4431 else
4432 Mangler.mangleNestedName(VD);
4433 Mangler.getStream() << (Visible ? "@5" : "@4IA");
4434 if (ScopeDepth)
4435 Mangler.mangleNumber(ScopeDepth);
4436}
4437
4438void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D,
4439 char CharCode,
4440 raw_ostream &Out) {
4441 msvc_hashing_ostream MHO(Out);
4442 MicrosoftCXXNameMangler Mangler(*this, MHO);
4443 Mangler.getStream() << "??__" << CharCode;
4444 if (D->isStaticDataMember()) {
4445 Mangler.getStream() << '?';
4446 Mangler.mangleName(D);
4447 Mangler.mangleVariableEncoding(D);
4448 Mangler.getStream() << "@@";
4449 } else {
4450 Mangler.mangleName(D);
4451 }
4452 // This is the function class mangling. These stubs are global, non-variadic,
4453 // cdecl functions that return void and take no args.
4454 Mangler.getStream() << "YAXXZ";
4455}
4456
4457void MicrosoftMangleContextImpl::mangleDynamicInitializer(const VarDecl *D,
4458 raw_ostream &Out) {
4459 // <initializer-name> ::= ?__E <name> YAXXZ
4460 mangleInitFiniStub(D, 'E', Out);
4461}
4462
4463void
4464MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D,
4465 raw_ostream &Out) {
4466 // <destructor-name> ::= ?__F <name> YAXXZ
4467 mangleInitFiniStub(D, 'F', Out);
4468}
4469
4470void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
4471 raw_ostream &Out) {
4472 // <char-type> ::= 0 # char, char16_t, char32_t
4473 // # (little endian char data in mangling)
4474 // ::= 1 # wchar_t (big endian char data in mangling)
4475 //
4476 // <literal-length> ::= <non-negative integer> # the length of the literal
4477 //
4478 // <encoded-crc> ::= <hex digit>+ @ # crc of the literal including
4479 // # trailing null bytes
4480 //
4481 // <encoded-string> ::= <simple character> # uninteresting character
4482 // ::= '?$' <hex digit> <hex digit> # these two nibbles
4483 // # encode the byte for the
4484 // # character
4485 // ::= '?' [a-z] # \xe1 - \xfa
4486 // ::= '?' [A-Z] # \xc1 - \xda
4487 // ::= '?' [0-9] # [,/\:. \n\t'-]
4488 //
4489 // <literal> ::= '??_C@_' <char-type> <literal-length> <encoded-crc>
4490 // <encoded-string> '@'
4491 MicrosoftCXXNameMangler Mangler(*this, Out);
4492 Mangler.getStream() << "??_C@_";
4493
4494 // The actual string length might be different from that of the string literal
4495 // in cases like:
4496 // char foo[3] = "foobar";
4497 // char bar[42] = "foobar";
4498 // Where it is truncated or zero-padded to fit the array. This is the length
4499 // used for mangling, and any trailing null-bytes also need to be mangled.
4500 unsigned StringLength =
4501 getASTContext().getAsConstantArrayType(SL->getType())->getZExtSize();
4502 unsigned StringByteLength = StringLength * SL->getCharByteWidth();
4503
4504 // <char-type>: The "kind" of string literal is encoded into the mangled name.
4505 if (SL->isWide())
4506 Mangler.getStream() << '1';
4507 else
4508 Mangler.getStream() << '0';
4509
4510 // <literal-length>: The next part of the mangled name consists of the length
4511 // of the string in bytes.
4512 Mangler.mangleNumber(StringByteLength);
4513
4514 auto GetLittleEndianByte = [&SL](unsigned Index) {
4515 unsigned CharByteWidth = SL->getCharByteWidth();
4516 if (Index / CharByteWidth >= SL->getLength())
4517 return static_cast<char>(0);
4518 uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
4519 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4520 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4521 };
4522
4523 auto GetBigEndianByte = [&SL](unsigned Index) {
4524 unsigned CharByteWidth = SL->getCharByteWidth();
4525 if (Index / CharByteWidth >= SL->getLength())
4526 return static_cast<char>(0);
4527 uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
4528 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4529 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4530 };
4531
4532 // CRC all the bytes of the StringLiteral.
4533 llvm::JamCRC JC;
4534 for (unsigned I = 0, E = StringByteLength; I != E; ++I)
4535 JC.update(GetLittleEndianByte(I));
4536
4537 // <encoded-crc>: The CRC is encoded utilizing the standard number mangling
4538 // scheme.
4539 Mangler.mangleNumber(JC.getCRC());
4540
4541 // <encoded-string>: The mangled name also contains the first 32 bytes
4542 // (including null-terminator bytes) of the encoded StringLiteral.
4543 // Each character is encoded by splitting them into bytes and then encoding
4544 // the constituent bytes.
4545 auto MangleByte = [&Mangler](char Byte) {
4546 // There are five different manglings for characters:
4547 // - [a-zA-Z0-9_$]: A one-to-one mapping.
4548 // - ?[a-z]: The range from \xe1 to \xfa.
4549 // - ?[A-Z]: The range from \xc1 to \xda.
4550 // - ?[0-9]: The set of [,/\:. \n\t'-].
4551 // - ?$XX: A fallback which maps nibbles.
4552 if (isAsciiIdentifierContinue(Byte, /*AllowDollar=*/true)) {
4553 Mangler.getStream() << Byte;
4554 } else if (isLetter(Byte & 0x7f)) {
4555 Mangler.getStream() << '?' << static_cast<char>(Byte & 0x7f);
4556 } else {
4557 const char SpecialChars[] = {',', '/', '\\', ':', '.',
4558 ' ', '\n', '\t', '\'', '-'};
4559 const char *Pos = llvm::find(SpecialChars, Byte);
4560 if (Pos != std::end(SpecialChars)) {
4561 Mangler.getStream() << '?' << (Pos - std::begin(SpecialChars));
4562 } else {
4563 Mangler.getStream() << "?$";
4564 Mangler.getStream() << static_cast<char>('A' + ((Byte >> 4) & 0xf));
4565 Mangler.getStream() << static_cast<char>('A' + (Byte & 0xf));
4566 }
4567 }
4568 };
4569
4570 // Enforce our 32 bytes max, except wchar_t which gets 32 chars instead.
4571 unsigned MaxBytesToMangle = SL->isWide() ? 64U : 32U;
4572 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4573 for (unsigned I = 0; I != NumBytesToMangle; ++I) {
4574 if (SL->isWide())
4575 MangleByte(GetBigEndianByte(I));
4576 else
4577 MangleByte(GetLittleEndianByte(I));
4578 }
4579
4580 Mangler.getStream() << '@';
4581}
4582
4583void MicrosoftCXXNameMangler::mangleAutoReturnType(const MemberPointerType *T,
4584 Qualifiers Quals) {
4585 QualType PointeeType = T->getPointeeType();
4586 manglePointerCVQualifiers(Quals);
4587 manglePointerExtQualifiers(Quals, PointeeType);
4588 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
4589 Out << '8';
4590 mangleName(T->getMostRecentCXXRecordDecl());
4591 mangleFunctionType(FPT, nullptr, true);
4592 } else {
4593 mangleQualifiers(PointeeType.getQualifiers(), true);
4594 mangleName(T->getMostRecentCXXRecordDecl());
4595 mangleAutoReturnType(PointeeType, QMM_Drop);
4596 }
4597}
4598
4599void MicrosoftCXXNameMangler::mangleAutoReturnType(const PointerType *T,
4600 Qualifiers Quals) {
4601 QualType PointeeType = T->getPointeeType();
4602 assert(!PointeeType.getQualifiers().hasAddressSpace() &&
4603 "Unexpected address space mangling required");
4604
4605 manglePointerCVQualifiers(Quals);
4606 manglePointerExtQualifiers(Quals, PointeeType);
4607
4608 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
4609 Out << '6';
4610 mangleFunctionType(FPT);
4611 } else {
4612 mangleAutoReturnType(PointeeType, QMM_Mangle);
4613 }
4614}
4615
4616void MicrosoftCXXNameMangler::mangleAutoReturnType(const LValueReferenceType *T,
4617 Qualifiers Quals) {
4618 QualType PointeeType = T->getPointeeType();
4619 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
4620 Out << 'A';
4621 manglePointerExtQualifiers(Quals, PointeeType);
4622 mangleAutoReturnType(PointeeType, QMM_Mangle);
4623}
4624
4625void MicrosoftCXXNameMangler::mangleAutoReturnType(const RValueReferenceType *T,
4626 Qualifiers Quals) {
4627 QualType PointeeType = T->getPointeeType();
4628 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
4629 Out << "$$Q";
4630 manglePointerExtQualifiers(Quals, PointeeType);
4631 mangleAutoReturnType(PointeeType, QMM_Mangle);
4632}
4633
4635 DiagnosticsEngine &Diags,
4636 bool IsAux) {
4637 return new MicrosoftMangleContextImpl(Context, Diags, IsAux);
4638}
Enums/classes describing ABI related information about constructors, destructors and thunks.
Defines the clang::ASTContext interface.
#define V(N, I)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
TokenType getType() const
Returns the token's type, e.g.
static const GlobalDecl isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs)
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
llvm::MachO::Record Record
Definition MachO.h:31
static ValueDecl * getAsArrayToPointerDecayedDecl(QualType T, const APValue &V)
If value V (with type T) represents a decayed pointer to the first element of an array,...
static void mangleThunkThisAdjustment(AccessSpecifier AS, const ThisAdjustment &Adjustment, MicrosoftCXXNameMangler &Mangler, raw_ostream &Out)
static StringRef getTriple(const Command &Job)
Defines the clang::Preprocessor interface.
static bool hasAttr(const Decl *D, bool IgnoreImplicitAttr)
Definition SemaCUDA.cpp:183
Defines the SourceManager interface.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
APValue & getVectorElt(unsigned I)
Definition APValue.h:585
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
Definition APValue.h:131
@ None
There is no such object (it's outside its lifetime).
Definition APValue.h:129
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
bool addressSpaceMapManglingFor(LangAS AS) const
const clang::PrintingPolicy & getPrintingPolicy() const
Definition ASTContext.h:876
DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)
unsigned getTargetAddressSpace(LangAS AS) const
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3836
QualType getElementType() const
Definition TypeBase.h:3848
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4806
Kind getKind() const
Definition TypeBase.h:3292
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
Definition DeclCXX.cpp:2726
bool isVirtual() const
Definition DeclCXX.h:2200
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2288
bool isInstance() const
Definition DeclCXX.h:2172
Decl * getLambdaContextDecl() const
Retrieve the declaration that provides additional context for a lambda, when the normal declaration c...
Definition DeclCXX.cpp:1836
CXXRecordDecl * getMostRecentDecl()
Definition DeclCXX.h:539
base_class_range bases()
Definition DeclCXX.h:608
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition DeclCXX.h:1023
unsigned getLambdaManglingNumber() const
If this is the closure type of a lambda expression, retrieve the number to be used for name mangling ...
Definition DeclCXX.h:1784
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
Represents a class template specialization, which refers to a class template with a given set of temp...
llvm::APInt getSize() const
Return the constant array size as an APInt.
Definition TypeBase.h:3930
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
bool isTranslationUnit() const
Definition DeclBase.h:2202
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
bool isFunctionOrMethod() const
Definition DeclBase.h:2178
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
T * getAttr() const
Definition DeclBase.h:581
SourceLocation getLocation() const
Definition DeclBase.h:447
DeclContext * getDeclContext()
Definition DeclBase.h:456
AccessSpecifier getAccess() const
Definition DeclBase.h:515
bool hasAttr() const
Definition DeclBase.h:585
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
NameKind getNameKind() const
Determine what kind of name this is.
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:234
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
This represents one expression.
Definition Expr.h:112
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:283
QualType getType() const
Definition Expr.h:144
Represents a function declaration or definition.
Definition Decl.h:2058
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2927
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition Decl.cpp:4348
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition Decl.cpp:3782
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition Decl.cpp:4364
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Definition Decl.cpp:3653
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4604
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5421
unsigned getNumParams() const
Definition TypeBase.h:5699
Qualifiers getMethodQuals() const
Definition TypeBase.h:5847
QualType getParamType(unsigned i) const
Definition TypeBase.h:5701
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition TypeBase.h:5918
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
Definition Type.cpp:4006
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5825
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition TypeBase.h:5855
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4617
CallingConv getCallConv() const
Definition TypeBase.h:4972
QualType getReturnType() const
Definition TypeBase.h:4957
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:57
CXXCtorType getCtorType() const
Definition GlobalDecl.h:108
KernelReferenceKind getKernelReferenceKind() const
Definition GlobalDecl.h:135
GlobalDecl getWithDecl(const Decl *D)
Definition GlobalDecl.h:172
CXXDtorType getDtorType() const
Definition GlobalDecl.h:113
const Decl * getDecl() const
Definition GlobalDecl.h:106
StringRef getName() const
Return the actual identifier string.
An lvalue reference type, per C++11 [dcl.ref].
Definition TypeBase.h:3731
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3767
static MicrosoftMangleContext * create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux=false)
MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D, bool IsAux=false)
Definition Mangle.h:248
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
This represents a decl that may have a name.
Definition Decl.h:274
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
Definition Decl.cpp:1207
bool isExternallyVisible() const
Definition Decl.h:433
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2090
Represents a parameter to a function.
Definition Decl.h:1819
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
Definition Decl.h:1879
bool isExplicitObjectParameter() const
Definition Decl.h:1907
bool isAddressDiscriminated() const
Definition TypeBase.h:266
unsigned getExtraDiscriminator() const
Definition TypeBase.h:271
unsigned getKey() const
Definition TypeBase.h:259
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3408
A (possibly-)qualified type.
Definition TypeBase.h:938
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
Definition TypeBase.h:1312
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8544
QualType getCanonicalType() const
Definition TypeBase.h:8556
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8598
void * getAsOpaquePtr() const
Definition TypeBase.h:985
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
Definition TypeBase.h:8536
The collection of all-type qualifiers we support.
Definition TypeBase.h:332
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition TypeBase.h:362
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition TypeBase.h:355
@ OCL_None
There is no lifetime qualification on this type.
Definition TypeBase.h:351
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition TypeBase.h:365
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition TypeBase.h:368
bool hasConst() const
Definition TypeBase.h:458
bool hasUnaligned() const
Definition TypeBase.h:512
bool hasAddressSpace() const
Definition TypeBase.h:571
bool hasRestrict() const
Definition TypeBase.h:478
void removeUnaligned()
Definition TypeBase.h:516
bool hasVolatile() const
Definition TypeBase.h:468
PointerAuthQualifier getPointerAuth() const
Definition TypeBase.h:604
bool hasObjCLifetime() const
Definition TypeBase.h:545
ObjCLifetime getObjCLifetime() const
Definition TypeBase.h:546
Qualifiers withoutObjCLifetime() const
Definition TypeBase.h:534
LangAS getAddressSpace() const
Definition TypeBase.h:572
An rvalue reference type, per C++11 [dcl.ref].
Definition TypeBase.h:3749
field_range fields() const
Definition Decl.h:4662
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
Definition Decl.h:4511
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
This class handles loading and caching of source files into memory.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileID getMainFileID() const
Returns the FileID of the main source file.
A trivial tuple used to represent a source range.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
const char * getStmtClassName() const
Definition Stmt.cpp:86
bool isWide() const
Definition Expr.h:1923
unsigned getLength() const
Definition Expr.h:1915
uint32_t getCodeUnit(size_t i) const
Definition Expr.h:1888
unsigned getCharByteWidth() const
Definition Expr.h:1916
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3851
TagDecl * getDefinition() const
Returns the TagDecl that actually defines this struct/union/class/enum.
Definition Decl.cpp:4984
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition Decl.h:4088
TagKind getTagKind() const
Definition Decl.h:4051
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
QualType getIntegralType() const
Retrieve the type of the integral value.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
NamedDecl * getParam(unsigned Idx)
bool isBlockPointerType() const
Definition TypeBase.h:8761
bool isVoidType() const
Definition TypeBase.h:9113
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isArrayType() const
Definition TypeBase.h:8840
bool isPointerType() const
Definition TypeBase.h:8741
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9407
bool isReferenceType() const
Definition TypeBase.h:8765
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:789
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition TypeBase.h:2976
bool isMemberDataPointerType() const
Definition TypeBase.h:8833
bool isMemberPointerType() const
Definition TypeBase.h:8822
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9393
bool isFunctionType() const
Definition TypeBase.h:8737
bool isAnyPointerType() const
Definition TypeBase.h:8749
TypeClass getTypeClass() const
Definition TypeBase.h:2449
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9340
bool isRecordType() const
Definition TypeBase.h:8868
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
QualType getType() const
Definition Decl.h:723
TLSKind getTLSKind() const
Definition Decl.cpp:2149
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2171
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition Decl.h:1306
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition Decl.h:1214
bool isExternC() const
Determines whether this variable is a variable with external, C linkage.
Definition Decl.cpp:2226
Represents a variable template specialization, which refers to a variable template with a given set o...
Defines the clang::TargetInfo interface.
@ Number
Just a number, nothing else.
Definition Primitives.h:26
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
Top level wrappers for InstallAPI frontend operations.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
CXXCtorType
C++ constructor types.
Definition ABI.h:24
@ Ctor_DefaultClosure
Default closure variant of a ctor.
Definition ABI.h:29
@ Ctor_CopyingClosure
Copying closure variant of a ctor.
Definition ABI.h:28
@ Ctor_Complete
Complete object ctor.
Definition ABI.h:25
bool isa(CodeGen::Address addr)
Definition Address.h:330
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
Definition FileEntry.h:196
@ CPlusPlus
@ CPlusPlus17
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
Definition CharInfo.h:61
RefQualifierKind
The kind of C++11 ref-qualifier associated with a function type.
Definition TypeBase.h:1799
@ RQ_None
No ref-qualifier was provided.
Definition TypeBase.h:1801
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition TypeBase.h:1804
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition TypeBase.h:1807
bool inheritanceModelHasNVOffsetField(bool IsMemberFunction, MSInheritanceModel Inheritance)
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition Specifiers.h:124
@ AS_public
Definition Specifiers.h:125
@ AS_protected
Definition Specifiers.h:126
@ AS_none
Definition Specifiers.h:128
@ AS_private
Definition Specifiers.h:127
void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName, bool useDirectABI)
Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...
Definition Mangle.cpp:34
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
LanguageLinkage
Describes the different kinds of language linkage (C++ [dcl.link]) that an entity may have.
Definition Linkage.h:63
@ CLanguageLinkage
Definition Linkage.h:64
@ CXXLanguageLinkage
Definition Linkage.h:65
bool inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance)
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
Definition CharInfo.h:132
bool inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance)
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
Definition TypeBase.h:906
const FunctionProtoType * T
CXXDtorType
C++ destructor types.
Definition ABI.h:34
@ Dtor_VectorDeleting
Vector deleting dtor.
Definition ABI.h:40
@ Dtor_Comdat
The COMDAT used for dtors.
Definition ABI.h:38
@ Dtor_Unified
GCC-style unified dtor.
Definition ABI.h:39
@ Dtor_Base
Base object dtor.
Definition ABI.h:37
@ Dtor_Complete
Complete object dtor.
Definition ABI.h:36
@ Dtor_Deleting
Deleting dtor.
Definition ABI.h:35
TagTypeKind
The kind of a tag type.
Definition TypeBase.h:6045
@ Type
The name was classified as a type.
Definition Sema.h:559
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool isPtrSizeAddressSpace(LangAS AS)
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
Definition Specifiers.h:413
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition Specifiers.h:279
@ CC_X86Pascal
Definition Specifiers.h:285
@ CC_Swift
Definition Specifiers.h:294
@ CC_PreserveMost
Definition Specifiers.h:296
@ CC_Win64
Definition Specifiers.h:286
@ CC_X86ThisCall
Definition Specifiers.h:283
@ CC_PreserveNone
Definition Specifiers.h:301
@ CC_SwiftAsync
Definition Specifiers.h:295
@ CC_X86RegCall
Definition Specifiers.h:288
@ CC_X86VectorCall
Definition Specifiers.h:284
@ CC_X86StdCall
Definition Specifiers.h:281
@ CC_X86_64SysV
Definition Specifiers.h:287
@ CC_X86FastCall
Definition Specifiers.h:282
U cast(CodeGen::Address addr)
Definition Address.h:327
unsigned long uint64_t
long int64_t
int const char * function
Definition c++config.h:31
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to.
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
uint64_t VBTableIndex
If nonzero, holds the vbtable index of the virtual base with the vfptr.
uint64_t Index
Method's index in the vftable.
bool isEmpty() const
Definition Thunk.h:70
A this pointer adjustment.
Definition Thunk.h:92
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
Definition Thunk.h:95
ThisAdjustment This
The this pointer adjustment.
Definition Thunk.h:159
const CXXMethodDecl * Method
Holds a pointer to the overridden method this thunk is for, if needed by the ABI to distinguish diffe...
Definition Thunk.h:172
ReturnAdjustment Return
The return adjustment.
Definition Thunk.h:162
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
Definition Thunk.h:109
struct clang::ThisAdjustment::VirtualAdjustment::@312251255113040203233347230177110330127151157305 Microsoft
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
Definition Thunk.h:116
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...
Definition Thunk.h:113