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();
507 if (OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getMainFileID())) {
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_Float6E3M2FN:
1023 case APFloat::S_Float6E2M3FN:
1024 case APFloat::S_Float4E2M1FN:
1025 llvm_unreachable("Tried to mangle unexpected APFloat semantics");
1026 }
1027
1028 mangleBits(Number.bitcastToAPInt());
1029}
1030
1031void MicrosoftCXXNameMangler::mangleBits(llvm::APInt Value) {
1032 if (Value == 0)
1033 Out << "A@";
1034 else if (Value.uge(1) && Value.ule(10))
1035 Out << (Value - 1);
1036 else {
1037 // Numbers that are not encoded as decimal digits are represented as nibbles
1038 // in the range of ASCII characters 'A' to 'P'.
1039 // The number 0x123450 would be encoded as 'BCDEFA'
1040 llvm::SmallString<32> EncodedNumberBuffer;
1041 for (; Value != 0; Value.lshrInPlace(4))
1042 EncodedNumberBuffer.push_back('A' + (Value & 0xf).getZExtValue());
1043 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());
1044 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());
1045 Out << '@';
1046 }
1047}
1048
1050 const TemplateArgumentList *&TemplateArgs) {
1051 const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
1052 // Check if we have a function template.
1053 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1054 if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {
1055 TemplateArgs = FD->getTemplateSpecializationArgs();
1056 return GD.getWithDecl(TD);
1057 }
1058 }
1059
1060 // Check if we have a class template.
1061 if (const ClassTemplateSpecializationDecl *Spec =
1062 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
1063 TemplateArgs = &Spec->getTemplateArgs();
1064 return GD.getWithDecl(Spec->getSpecializedTemplate());
1065 }
1066
1067 // Check if we have a variable template.
1068 if (const VarTemplateSpecializationDecl *Spec =
1069 dyn_cast<VarTemplateSpecializationDecl>(ND)) {
1070 TemplateArgs = &Spec->getTemplateArgs();
1071 return GD.getWithDecl(Spec->getSpecializedTemplate());
1072 }
1073
1074 return GlobalDecl();
1075}
1076
1077void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
1078 DeclarationName Name) {
1079 const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
1080 // <unqualified-name> ::= <operator-name>
1081 // ::= <ctor-dtor-name>
1082 // ::= <source-name>
1083 // ::= <template-name>
1084
1085 // Check if we have a template.
1086 const TemplateArgumentList *TemplateArgs = nullptr;
1087 if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) {
1088 // Function templates aren't considered for name back referencing. This
1089 // makes sense since function templates aren't likely to occur multiple
1090 // times in a symbol.
1091 if (isa<FunctionTemplateDecl>(TD.getDecl())) {
1092 mangleTemplateInstantiationName(TD, *TemplateArgs);
1093 Out << '@';
1094 return;
1095 }
1096
1097 // Here comes the tricky thing: if we need to mangle something like
1098 // void foo(A::X<Y>, B::X<Y>),
1099 // the X<Y> part is aliased. However, if you need to mangle
1100 // void foo(A::X<A::Y>, A::X<B::Y>),
1101 // the A::X<> part is not aliased.
1102 // That is, from the mangler's perspective we have a structure like this:
1103 // namespace[s] -> type[ -> template-parameters]
1104 // but from the Clang perspective we have
1105 // type [ -> template-parameters]
1106 // \-> namespace[s]
1107 // What we do is we create a new mangler, mangle the same type (without
1108 // a namespace suffix) to a string using the extra mangler and then use
1109 // the mangled type name as a key to check the mangling of different types
1110 // for aliasing.
1111
1112 // It's important to key cache reads off ND, not TD -- the same TD can
1113 // be used with different TemplateArgs, but ND uniquely identifies
1114 // TD / TemplateArg pairs.
1115 ArgBackRefMap::iterator Found = TemplateArgBackReferences.find(ND);
1116 if (Found == TemplateArgBackReferences.end()) {
1117
1118 TemplateArgStringMap::iterator Found = TemplateArgStrings.find(ND);
1119 if (Found == TemplateArgStrings.end()) {
1120 // Mangle full template name into temporary buffer.
1121 llvm::SmallString<64> TemplateMangling;
1122 llvm::raw_svector_ostream Stream(TemplateMangling);
1123 MicrosoftCXXNameMangler Extra(Context, Stream);
1124 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
1125
1126 // Use the string backref vector to possibly get a back reference.
1127 mangleSourceName(TemplateMangling);
1128
1129 // Memoize back reference for this type if one exist, else memoize
1130 // the mangling itself.
1131 BackRefVec::iterator StringFound =
1132 llvm::find(NameBackReferences, TemplateMangling);
1133 if (StringFound != NameBackReferences.end()) {
1134 TemplateArgBackReferences[ND] =
1135 StringFound - NameBackReferences.begin();
1136 } else {
1137 TemplateArgStrings[ND] =
1138 TemplateArgStringStorage.save(TemplateMangling.str());
1139 }
1140 } else {
1141 Out << Found->second << '@'; // Outputs a StringRef.
1142 }
1143 } else {
1144 Out << Found->second; // Outputs a back reference (an int).
1145 }
1146 return;
1147 }
1148
1149 switch (Name.getNameKind()) {
1151 if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
1152 bool IsDeviceStub =
1153 ND &&
1154 ((isa<FunctionDecl>(ND) && ND->hasAttr<CUDAGlobalAttr>()) ||
1157 ->getTemplatedDecl()
1159 GD.getKernelReferenceKind() == KernelReferenceKind::Stub;
1160 bool IsOCLDeviceStub =
1161 ND && isa<FunctionDecl>(ND) &&
1162 DeviceKernelAttr::isOpenCLSpelling(
1163 ND->getAttr<DeviceKernelAttr>()) &&
1164 GD.getKernelReferenceKind() == KernelReferenceKind::Stub;
1165 if (IsDeviceStub)
1166 mangleSourceName(
1167 (llvm::Twine("__device_stub__") + II->getName()).str());
1168 else if (IsOCLDeviceStub)
1169 mangleSourceName(
1170 (llvm::Twine("__clang_ocl_kern_imp_") + II->getName()).str());
1171 else
1172 mangleSourceName(II->getName());
1173 break;
1174 }
1175
1176 // Otherwise, an anonymous entity. We must have a declaration.
1177 assert(ND && "mangling empty name without declaration");
1178
1179 if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
1180 if (NS->isAnonymousNamespace()) {
1181 llvm::SmallString<16> Name("?A0x");
1182 Name += Context.getAnonymousNamespaceHash();
1183 mangleSourceName(Name);
1184 break;
1185 }
1186 }
1187
1188 if (const DecompositionDecl *DD = dyn_cast<DecompositionDecl>(ND)) {
1189 // Decomposition declarations are considered anonymous, and get
1190 // numbered with a $S prefix.
1191 llvm::SmallString<64> Name("$S");
1192 // Get a unique id for the anonymous struct.
1193 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);
1194 mangleSourceName(Name);
1195 break;
1196 }
1197
1198 if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1199 // We must have an anonymous union or struct declaration.
1200 const CXXRecordDecl *RD = VD->getType()->getAsCXXRecordDecl();
1201 assert(RD && "expected variable decl to have a record type");
1202 // Anonymous types with no tag or typedef get the name of their
1203 // declarator mangled in. If they have no declarator, number them with
1204 // a $S prefix.
1205 llvm::SmallString<64> Name("$S");
1206 // Get a unique id for the anonymous struct.
1207 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
1208 mangleSourceName(Name.str());
1209 break;
1210 }
1211
1212 if (const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {
1213 // Mangle a GUID object as if it were a variable with the corresponding
1214 // mangled name.
1215 SmallString<sizeof("_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;
1216 llvm::raw_svector_ostream GUIDOS(GUID);
1217 Context.mangleMSGuidDecl(GD, GUIDOS);
1218 mangleSourceName(GUID);
1219 break;
1220 }
1221
1222 if (const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
1223 Out << "?__N";
1224 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1225 TPO->getValue(), TplArgKind::ClassNTTP);
1226 break;
1227 }
1228
1229 // We must have an anonymous struct.
1230 const TagDecl *TD = cast<TagDecl>(ND);
1231 if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {
1232 assert(TD->getDeclContext() == D->getDeclContext() &&
1233 "Typedef should not be in another decl context!");
1234 assert(D->getDeclName().getAsIdentifierInfo() &&
1235 "Typedef was not named!");
1236 mangleSourceName(D->getDeclName().getAsIdentifierInfo()->getName());
1237 break;
1238 }
1239
1240 if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
1241 if (Record->isLambda()) {
1242 llvm::SmallString<10> Name("<lambda_");
1243
1244 Decl *LambdaContextDecl = Record->getLambdaContextDecl();
1245 unsigned LambdaManglingNumber = Record->getLambdaManglingNumber();
1246 unsigned LambdaId;
1247 const ParmVarDecl *Parm =
1248 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);
1249 const FunctionDecl *Func =
1250 Parm ? dyn_cast<FunctionDecl>(Parm->getDeclContext()) : nullptr;
1251
1252 if (Func) {
1253 unsigned DefaultArgNo =
1254 Func->getNumParams() - Parm->getFunctionScopeIndex();
1255 Name += llvm::utostr(DefaultArgNo);
1256 Name += "_";
1257 }
1258
1259 if (LambdaManglingNumber)
1260 LambdaId = LambdaManglingNumber;
1261 else
1262 LambdaId = Context.getLambdaId(Record);
1263
1264 Name += llvm::utostr(LambdaId);
1265 Name += ">";
1266
1267 mangleSourceName(Name);
1268
1269 // If the context is a variable or a class member and not a parameter,
1270 // it is encoded in a qualified name.
1271 if (LambdaManglingNumber && LambdaContextDecl) {
1272 if ((isa<VarDecl>(LambdaContextDecl) ||
1273 isa<FieldDecl>(LambdaContextDecl)) &&
1274 !isa<ParmVarDecl>(LambdaContextDecl)) {
1275 mangleUnqualifiedName(cast<NamedDecl>(LambdaContextDecl));
1276 }
1277 }
1278 break;
1279 }
1280 }
1281
1282 llvm::SmallString<64> Name;
1283 if (DeclaratorDecl *DD =
1284 Context.getASTContext().getDeclaratorForUnnamedTagDecl(TD)) {
1285 // Anonymous types without a name for linkage purposes have their
1286 // declarator mangled in if they have one.
1287 Name += "<unnamed-type-";
1288 Name += DD->getName();
1289 } else if (TypedefNameDecl *TND =
1290 Context.getASTContext().getTypedefNameForUnnamedTagDecl(
1291 TD)) {
1292 // Anonymous types without a name for linkage purposes have their
1293 // associate typedef mangled in if they have one.
1294 Name += "<unnamed-type-";
1295 Name += TND->getName();
1296 } else if (isa<EnumDecl>(TD) &&
1297 !cast<EnumDecl>(TD)->enumerators().empty()) {
1298 // Anonymous non-empty enums mangle in the first enumerator.
1299 auto *ED = cast<EnumDecl>(TD);
1300 Name += "<unnamed-enum-";
1301 Name += ED->enumerator_begin()->getName();
1302 } else {
1303 // Otherwise, number the types using a $S prefix.
1304 Name += "<unnamed-type-$S";
1305 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
1306 }
1307 Name += ">";
1308 mangleSourceName(Name.str());
1309 break;
1310 }
1311
1315 // This is reachable only when constructing an outlined SEH finally
1316 // block. Nothing depends on this mangling and it's used only with
1317 // functinos with internal linkage.
1318 llvm::SmallString<64> Name;
1319 mangleSourceName(Name.str());
1320 break;
1321 }
1322
1324 if (isStructorDecl(ND)) {
1325 if (StructorType == Ctor_CopyingClosure) {
1326 Out << "?_O";
1327 return;
1328 }
1329 if (StructorType == Ctor_DefaultClosure) {
1330 Out << "?_F";
1331 return;
1332 }
1333 }
1334 Out << "?0";
1335 return;
1336
1338 if (isStructorDecl(ND))
1339 // If the named decl is the C++ destructor we're mangling,
1340 // use the type we were given.
1341 mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
1342 else
1343 // Otherwise, use the base destructor name. This is relevant if a
1344 // class with a destructor is declared within a destructor.
1345 mangleCXXDtorType(Dtor_Base);
1346 break;
1347
1349 // <operator-name> ::= ?B # (cast)
1350 // The target type is encoded as the return type.
1351 Out << "?B";
1352 break;
1353
1355 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->getLocation());
1356 break;
1357
1359 Out << "?__K";
1360 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
1361 break;
1362 }
1363
1365 llvm_unreachable("Can't mangle a deduction guide name!");
1366
1368 llvm_unreachable("Can't mangle a using directive name!");
1369 }
1370}
1371
1372// <postfix> ::= <unqualified-name> [<postfix>]
1373// ::= <substitution> [<postfix>]
1374void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {
1375 const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
1376
1377 if (const auto *ID = dyn_cast<IndirectFieldDecl>(ND))
1378 for (unsigned I = 1, IE = ID->getChainingSize(); I < IE; ++I)
1379 mangleSourceName("<unnamed-tag>");
1380
1381 const DeclContext *DC = getEffectiveDeclContext(ND);
1382 while (!DC->isTranslationUnit()) {
1383 if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
1384 unsigned Disc;
1385 if (Context.getNextDiscriminator(ND, Disc)) {
1386 Out << '?';
1387 mangleNumber(Disc);
1388 Out << '?';
1389 }
1390 }
1391
1392 if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
1393 auto Discriminate =
1394 [](StringRef Name, const unsigned Discriminator,
1395 const unsigned ParameterDiscriminator) -> std::string {
1396 std::string Buffer;
1397 llvm::raw_string_ostream Stream(Buffer);
1398 Stream << Name;
1399 if (Discriminator)
1400 Stream << '_' << Discriminator;
1401 if (ParameterDiscriminator)
1402 Stream << '_' << ParameterDiscriminator;
1403 return Buffer;
1404 };
1405
1406 unsigned Discriminator = BD->getBlockManglingNumber();
1407 if (!Discriminator)
1408 Discriminator = Context.getBlockId(BD, /*Local=*/false);
1409
1410 // Mangle the parameter position as a discriminator to deal with unnamed
1411 // parameters. Rather than mangling the unqualified parameter name,
1412 // always use the position to give a uniform mangling.
1413 unsigned ParameterDiscriminator = 0;
1414 if (const auto *MC = BD->getBlockManglingContextDecl())
1415 if (const auto *P = dyn_cast<ParmVarDecl>(MC))
1416 if (const auto *F = dyn_cast<FunctionDecl>(P->getDeclContext()))
1417 ParameterDiscriminator =
1418 F->getNumParams() - P->getFunctionScopeIndex();
1419
1420 DC = getEffectiveDeclContext(BD);
1421
1422 Out << '?';
1423 mangleSourceName(Discriminate("_block_invoke", Discriminator,
1424 ParameterDiscriminator));
1425 // If we have a block mangling context, encode that now. This allows us
1426 // to discriminate between named static data initializers in the same
1427 // scope. This is handled differently from parameters, which use
1428 // positions to discriminate between multiple instances.
1429 if (const auto *MC = BD->getBlockManglingContextDecl())
1430 if (!isa<ParmVarDecl>(MC))
1431 if (const auto *ND = dyn_cast<NamedDecl>(MC))
1432 mangleUnqualifiedName(ND);
1433 // MS ABI and Itanium manglings are in inverted scopes. In the case of a
1434 // RecordDecl, mangle the entire scope hierarchy at this point rather than
1435 // just the unqualified name to get the ordering correct.
1436 if (const auto *RD = dyn_cast<RecordDecl>(DC))
1437 mangleName(RD);
1438 else
1439 Out << '@';
1440 // void __cdecl
1441 Out << "YAX";
1442 // struct __block_literal *
1443 Out << 'P';
1444 // __ptr64
1445 if (PointersAre64Bit)
1446 Out << 'E';
1447 Out << 'A';
1448 mangleArtificialTagType(TagTypeKind::Struct,
1449 Discriminate("__block_literal", Discriminator,
1450 ParameterDiscriminator));
1451 Out << "@Z";
1452
1453 // If the effective context was a Record, we have fully mangled the
1454 // qualified name and do not need to continue.
1455 if (isa<RecordDecl>(DC))
1456 break;
1457 continue;
1458 } else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
1460 } else if (isa<NamedDecl>(DC)) {
1461 ND = cast<NamedDecl>(DC);
1462 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1463 mangle(getGlobalDeclAsDeclContext(FD), "?");
1464 break;
1465 } else {
1466 mangleUnqualifiedName(ND);
1467 // Lambdas in default arguments conceptually belong to the function the
1468 // parameter corresponds to.
1469 if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
1470 DC = LDADC;
1471 continue;
1472 }
1473 }
1474 }
1475 DC = DC->getParent();
1476 }
1477}
1478
1479void MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
1480 // Microsoft uses the names on the case labels for these dtor variants. Clang
1481 // uses the Itanium terminology internally. Everything in this ABI delegates
1482 // towards the base dtor.
1483 switch (T) {
1484 // <operator-name> ::= ?1 # destructor
1485 case Dtor_Base: Out << "?1"; return;
1486 // <operator-name> ::= ?_D # vbase destructor
1487 case Dtor_Complete: Out << "?_D"; return;
1488 // <operator-name> ::= ?_G # scalar deleting destructor
1489 case Dtor_Deleting: Out << "?_G"; return;
1490 // <operator-name> ::= ?_E # vector deleting destructor
1492 Out << "?_E";
1493 return;
1494 case Dtor_Comdat:
1495 llvm_unreachable("not expecting a COMDAT");
1496 case Dtor_Unified:
1497 llvm_unreachable("not expecting a unified dtor type");
1498 }
1499 llvm_unreachable("Unsupported dtor type?");
1500}
1501
1502void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
1503 SourceLocation Loc) {
1504 switch (OO) {
1505 // ?0 # constructor
1506 // ?1 # destructor
1507 // <operator-name> ::= ?2 # new
1508 case OO_New: Out << "?2"; break;
1509 // <operator-name> ::= ?3 # delete
1510 case OO_Delete: Out << "?3"; break;
1511 // <operator-name> ::= ?4 # =
1512 case OO_Equal: Out << "?4"; break;
1513 // <operator-name> ::= ?5 # >>
1514 case OO_GreaterGreater: Out << "?5"; break;
1515 // <operator-name> ::= ?6 # <<
1516 case OO_LessLess: Out << "?6"; break;
1517 // <operator-name> ::= ?7 # !
1518 case OO_Exclaim: Out << "?7"; break;
1519 // <operator-name> ::= ?8 # ==
1520 case OO_EqualEqual: Out << "?8"; break;
1521 // <operator-name> ::= ?9 # !=
1522 case OO_ExclaimEqual: Out << "?9"; break;
1523 // <operator-name> ::= ?A # []
1524 case OO_Subscript: Out << "?A"; break;
1525 // ?B # conversion
1526 // <operator-name> ::= ?C # ->
1527 case OO_Arrow: Out << "?C"; break;
1528 // <operator-name> ::= ?D # *
1529 case OO_Star: Out << "?D"; break;
1530 // <operator-name> ::= ?E # ++
1531 case OO_PlusPlus: Out << "?E"; break;
1532 // <operator-name> ::= ?F # --
1533 case OO_MinusMinus: Out << "?F"; break;
1534 // <operator-name> ::= ?G # -
1535 case OO_Minus: Out << "?G"; break;
1536 // <operator-name> ::= ?H # +
1537 case OO_Plus: Out << "?H"; break;
1538 // <operator-name> ::= ?I # &
1539 case OO_Amp: Out << "?I"; break;
1540 // <operator-name> ::= ?J # ->*
1541 case OO_ArrowStar: Out << "?J"; break;
1542 // <operator-name> ::= ?K # /
1543 case OO_Slash: Out << "?K"; break;
1544 // <operator-name> ::= ?L # %
1545 case OO_Percent: Out << "?L"; break;
1546 // <operator-name> ::= ?M # <
1547 case OO_Less: Out << "?M"; break;
1548 // <operator-name> ::= ?N # <=
1549 case OO_LessEqual: Out << "?N"; break;
1550 // <operator-name> ::= ?O # >
1551 case OO_Greater: Out << "?O"; break;
1552 // <operator-name> ::= ?P # >=
1553 case OO_GreaterEqual: Out << "?P"; break;
1554 // <operator-name> ::= ?Q # ,
1555 case OO_Comma: Out << "?Q"; break;
1556 // <operator-name> ::= ?R # ()
1557 case OO_Call: Out << "?R"; break;
1558 // <operator-name> ::= ?S # ~
1559 case OO_Tilde: Out << "?S"; break;
1560 // <operator-name> ::= ?T # ^
1561 case OO_Caret: Out << "?T"; break;
1562 // <operator-name> ::= ?U # |
1563 case OO_Pipe: Out << "?U"; break;
1564 // <operator-name> ::= ?V # &&
1565 case OO_AmpAmp: Out << "?V"; break;
1566 // <operator-name> ::= ?W # ||
1567 case OO_PipePipe: Out << "?W"; break;
1568 // <operator-name> ::= ?X # *=
1569 case OO_StarEqual: Out << "?X"; break;
1570 // <operator-name> ::= ?Y # +=
1571 case OO_PlusEqual: Out << "?Y"; break;
1572 // <operator-name> ::= ?Z # -=
1573 case OO_MinusEqual: Out << "?Z"; break;
1574 // <operator-name> ::= ?_0 # /=
1575 case OO_SlashEqual: Out << "?_0"; break;
1576 // <operator-name> ::= ?_1 # %=
1577 case OO_PercentEqual: Out << "?_1"; break;
1578 // <operator-name> ::= ?_2 # >>=
1579 case OO_GreaterGreaterEqual: Out << "?_2"; break;
1580 // <operator-name> ::= ?_3 # <<=
1581 case OO_LessLessEqual: Out << "?_3"; break;
1582 // <operator-name> ::= ?_4 # &=
1583 case OO_AmpEqual: Out << "?_4"; break;
1584 // <operator-name> ::= ?_5 # |=
1585 case OO_PipeEqual: Out << "?_5"; break;
1586 // <operator-name> ::= ?_6 # ^=
1587 case OO_CaretEqual: Out << "?_6"; break;
1588 // ?_7 # vftable
1589 // ?_8 # vbtable
1590 // ?_9 # vcall
1591 // ?_A # typeof
1592 // ?_B # local static guard
1593 // ?_C # string
1594 // ?_D # vbase destructor
1595 // ?_E # vector deleting destructor
1596 // ?_F # default constructor closure
1597 // ?_G # scalar deleting destructor
1598 // ?_H # vector constructor iterator
1599 // ?_I # vector destructor iterator
1600 // ?_J # vector vbase constructor iterator
1601 // ?_K # virtual displacement map
1602 // ?_L # eh vector constructor iterator
1603 // ?_M # eh vector destructor iterator
1604 // ?_N # eh vector vbase constructor iterator
1605 // ?_O # copy constructor closure
1606 // ?_P<name> # udt returning <name>
1607 // ?_Q # <unknown>
1608 // ?_R0 # RTTI Type Descriptor
1609 // ?_R1 # RTTI Base Class Descriptor at (a,b,c,d)
1610 // ?_R2 # RTTI Base Class Array
1611 // ?_R3 # RTTI Class Hierarchy Descriptor
1612 // ?_R4 # RTTI Complete Object Locator
1613 // ?_S # local vftable
1614 // ?_T # local vftable constructor closure
1615 // <operator-name> ::= ?_U # new[]
1616 case OO_Array_New: Out << "?_U"; break;
1617 // <operator-name> ::= ?_V # delete[]
1618 case OO_Array_Delete: Out << "?_V"; break;
1619 // <operator-name> ::= ?__L # co_await
1620 case OO_Coawait: Out << "?__L"; break;
1621 // <operator-name> ::= ?__M # <=>
1622 case OO_Spaceship: Out << "?__M"; break;
1623
1624 case OO_Conditional: {
1625 Error(Loc, "conditional operator");
1626 break;
1627 }
1628
1629 case OO_None:
1631 llvm_unreachable("Not an overloaded operator");
1632 }
1633}
1634
1635void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1636 // <source name> ::= <identifier> @
1637 BackRefVec::iterator Found = llvm::find(NameBackReferences, Name);
1638 if (Found == NameBackReferences.end()) {
1639 if (NameBackReferences.size() < 10)
1640 NameBackReferences.push_back(std::string(Name));
1641 Out << Name << '@';
1642 } else {
1643 Out << (Found - NameBackReferences.begin());
1644 }
1645}
1646
1647void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
1648 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1649}
1650
1651void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1652 GlobalDecl GD, const TemplateArgumentList &TemplateArgs) {
1653 // <template-name> ::= <unscoped-template-name> <template-args>
1654 // ::= <substitution>
1655 // Always start with the unqualified name.
1656
1657 // Templates have their own context for back references.
1658 ArgBackRefMap OuterFunArgsContext;
1659 ArgBackRefMap OuterTemplateArgsContext;
1660 BackRefVec OuterTemplateContext;
1661 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1662 NameBackReferences.swap(OuterTemplateContext);
1663 FunArgBackReferences.swap(OuterFunArgsContext);
1664 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1665 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1666
1667 mangleUnscopedTemplateName(GD);
1668 mangleTemplateArgs(cast<TemplateDecl>(GD.getDecl()), TemplateArgs);
1669
1670 // Restore the previous back reference contexts.
1671 NameBackReferences.swap(OuterTemplateContext);
1672 FunArgBackReferences.swap(OuterFunArgsContext);
1673 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1674 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1675}
1676
1677void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {
1678 // <unscoped-template-name> ::= ?$ <unqualified-name>
1679 Out << "?$";
1680 mangleUnqualifiedName(GD);
1681}
1682
1683void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1684 const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD,
1685 QualType TemplateArgType) {
1686 // <integer-literal> ::= $0 <number>
1687 // <integer-literal> ::= <auto-nttp>
1688 //
1689 // <auto-nttp> ::= $ M <type> 0 <number>
1690 Out << "$";
1691
1692 // Since MSVC 2019, add 'M[<type>]' after '$' for auto template parameter when
1693 // argument is integer.
1694 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1695 LangOptions::MSVC2019) &&
1696 PD && PD->getType()->getTypeClass() == Type::Auto &&
1697 !TemplateArgType.isNull()) {
1698 Out << "M";
1699 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
1700 }
1701
1702 Out << "0";
1703
1704 mangleNumber(Value);
1705}
1706
1707void MicrosoftCXXNameMangler::mangleExpression(
1708 const Expr *E, const NonTypeTemplateParmDecl *PD) {
1709 // See if this is a constant expression.
1710 if (std::optional<llvm::APSInt> Value =
1711 E->getIntegerConstantExpr(Context.getASTContext())) {
1712 mangleIntegerLiteral(*Value, PD, E->getType());
1713 return;
1714 }
1715
1716 // As bad as this diagnostic is, it's better than crashing.
1717 Error(E->getExprLoc(), "expression type: ", E->getStmtClassName())
1718 << E->getSourceRange();
1719}
1720
1721void MicrosoftCXXNameMangler::mangleTemplateArgs(
1722 const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
1723 // <template-args> ::= <template-arg>+
1724 const TemplateParameterList *TPL = TD->getTemplateParameters();
1725 assert(TPL->size() == TemplateArgs.size() &&
1726 "size mismatch between args and parms!");
1727
1728 for (size_t i = 0; i < TemplateArgs.size(); ++i) {
1729 const TemplateArgument &TA = TemplateArgs[i];
1730
1731 // Separate consecutive packs by $$Z.
1732 if (i > 0 && TA.getKind() == TemplateArgument::Pack &&
1733 TemplateArgs[i - 1].getKind() == TemplateArgument::Pack)
1734 Out << "$$Z";
1735
1736 mangleTemplateArg(TD, TA, TPL->getParam(i));
1737 }
1738}
1739
1740/// If value V (with type T) represents a decayed pointer to the first element
1741/// of an array, return that array.
1743 // Must be a pointer...
1744 if (!T->isPointerType() || !V.isLValue() || !V.hasLValuePath() ||
1745 !V.getLValueBase())
1746 return nullptr;
1747 // ... to element 0 of an array.
1748 QualType BaseT = V.getLValueBase().getType();
1749 if (!BaseT->isArrayType() || V.getLValuePath().size() != 1 ||
1750 V.getLValuePath()[0].getAsArrayIndex() != 0)
1751 return nullptr;
1752 return const_cast<ValueDecl *>(
1753 V.getLValueBase().dyn_cast<const ValueDecl *>());
1754}
1755
1756void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
1757 const TemplateArgument &TA,
1758 const NamedDecl *Parm) {
1759 // <template-arg> ::= <type>
1760 // ::= <integer-literal>
1761 // ::= <member-data-pointer>
1762 // ::= <member-function-pointer>
1763 // ::= $ <constant-value>
1764 // ::= $ <auto-nttp-constant-value>
1765 // ::= <template-args>
1766 //
1767 // <auto-nttp-constant-value> ::= M <type> <constant-value>
1768 //
1769 // <constant-value> ::= 0 <number> # integer
1770 // ::= 1 <mangled-name> # address of D
1771 // ::= 2 <type> <typed-constant-value>* @ # struct
1772 // ::= 3 <type> <constant-value>* @ # array
1773 // ::= 4 ??? # string
1774 // ::= 5 <constant-value> @ # address of subobject
1775 // ::= 6 <constant-value> <unqualified-name> @ # a.b
1776 // ::= 7 <type> [<unqualified-name> <constant-value>] @
1777 // # union, with or without an active member
1778 // # pointer to member, symbolically
1779 // ::= 8 <class> <unqualified-name> @
1780 // ::= A <type> <non-negative integer> # float
1781 // ::= B <type> <non-negative integer> # double
1782 // # pointer to member, by component value
1783 // ::= F <number> <number>
1784 // ::= G <number> <number> <number>
1785 // ::= H <mangled-name> <number>
1786 // ::= I <mangled-name> <number> <number>
1787 // ::= J <mangled-name> <number> <number> <number>
1788 //
1789 // <typed-constant-value> ::= [<type>] <constant-value>
1790 //
1791 // The <type> appears to be included in a <typed-constant-value> only in the
1792 // '0', '1', '8', 'A', 'B', and 'E' cases.
1793
1794 switch (TA.getKind()) {
1796 llvm_unreachable("Can't mangle null template arguments!");
1798 llvm_unreachable("Can't mangle template expansion arguments!");
1800 QualType T = TA.getAsType();
1801 mangleType(T, SourceRange(), QMM_Escape);
1802 break;
1803 }
1805 const NamedDecl *ND = TA.getAsDecl();
1806 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1807 mangleMemberDataPointer(
1808 cast<CXXRecordDecl>(ND->getDeclContext())->getMostRecentDecl(),
1810 TA.getParamTypeForDecl());
1811 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1812 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1813 if (MD && MD->isInstance()) {
1814 mangleMemberFunctionPointer(MD->getParent()->getMostRecentDecl(), MD,
1816 TA.getParamTypeForDecl());
1817 } else {
1818 mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),
1819 TA.getParamTypeForDecl());
1820 }
1821 } else if (TA.getParamTypeForDecl()->isRecordType()) {
1822 Out << "$";
1823 auto *TPO = cast<TemplateParamObjectDecl>(ND);
1824 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1825 TPO->getValue(), TplArgKind::ClassNTTP);
1826 } else if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1827 mangleVarDecl(VD, cast<NonTypeTemplateParmDecl>(Parm),
1828 TA.getParamTypeForDecl());
1829 } else {
1830 mangle(ND, "$1?");
1831 }
1832 break;
1833 }
1835 QualType T = TA.getIntegralType();
1836 mangleIntegerLiteral(TA.getAsIntegral(),
1838 break;
1839 }
1841 QualType T = TA.getNullPtrType();
1842 if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
1843 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1844 if (MPT->isMemberFunctionPointerType() &&
1846 mangleMemberFunctionPointer(RD, nullptr, nullptr, QualType());
1847 return;
1848 }
1849 if (MPT->isMemberDataPointer()) {
1850 if (!isa<FunctionTemplateDecl>(TD)) {
1851 mangleMemberDataPointer(RD, nullptr, nullptr, QualType());
1852 return;
1853 }
1854 // nullptr data pointers are always represented with a single field
1855 // which is initialized with either 0 or -1. Why -1? Well, we need to
1856 // distinguish the case where the data member is at offset zero in the
1857 // record.
1858 // However, we are free to use 0 *if* we would use multiple fields for
1859 // non-nullptr member pointers.
1860 if (!RD->nullFieldOffsetIsZero()) {
1861 mangleIntegerLiteral(llvm::APSInt::get(-1),
1863 return;
1864 }
1865 }
1866 }
1867 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1869 break;
1870 }
1872 if (ValueDecl *D = getAsArrayToPointerDecayedDecl(
1874 // Mangle the result of array-to-pointer decay as if it were a reference
1875 // to the original declaration, to match MSVC's behavior. This can result
1876 // in mangling collisions in some cases!
1877 return mangleTemplateArg(
1878 TD, TemplateArgument(D, TA.getStructuralValueType()), Parm);
1879 }
1880 Out << "$";
1882 ->getType()
1883 ->getContainedDeducedType()) {
1884 Out << "M";
1885 mangleType(TA.getNonTypeTemplateArgumentType(), SourceRange(), QMM_Drop);
1886 }
1887 mangleTemplateArgValue(TA.getStructuralValueType(),
1889 TplArgKind::StructuralValue,
1890 /*WithScalarType=*/false);
1891 break;
1893 mangleExpression(TA.getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
1894 break;
1896 ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();
1897 if (TemplateArgs.empty()) {
1898 if (isa<TemplateTypeParmDecl>(Parm) ||
1900 // MSVC 2015 changed the mangling for empty expanded template packs,
1901 // use the old mangling for link compatibility for old versions.
1902 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(
1903 LangOptions::MSVC2015)
1904 ? "$$V"
1905 : "$$$V");
1906 else if (isa<NonTypeTemplateParmDecl>(Parm))
1907 Out << "$S";
1908 else
1909 llvm_unreachable("unexpected template parameter decl!");
1910 } else {
1911 for (const TemplateArgument &PA : TemplateArgs)
1912 mangleTemplateArg(TD, PA, Parm);
1913 }
1914 break;
1915 }
1917 const NamedDecl *ND =
1919 if (const auto *TD = dyn_cast<TagDecl>(ND)) {
1920 mangleType(TD);
1921 } else if (isa<TypeAliasDecl>(ND)) {
1922 Out << "$$Y";
1923 mangleName(ND);
1924 } else {
1925 llvm_unreachable("unexpected template template NamedDecl!");
1926 }
1927 break;
1928 }
1929 }
1930}
1931
1932void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
1933 const APValue &V,
1934 TplArgKind TAK,
1935 bool WithScalarType) {
1936 switch (V.getKind()) {
1937 case APValue::None:
1939 // FIXME: MSVC doesn't allow this, so we can't be sure how it should be
1940 // mangled.
1941 if (WithScalarType)
1942 mangleType(T, SourceRange(), QMM_Escape);
1943 Out << '@';
1944 return;
1945
1946 case APValue::Int:
1947 if (WithScalarType)
1948 mangleType(T, SourceRange(), QMM_Escape);
1949 Out << '0';
1950 mangleNumber(V.getInt());
1951 return;
1952
1953 case APValue::Float:
1954 if (WithScalarType)
1955 mangleType(T, SourceRange(), QMM_Escape);
1956 mangleFloat(V.getFloat());
1957 return;
1958
1959 case APValue::LValue: {
1960 if (WithScalarType)
1961 mangleType(T, SourceRange(), QMM_Escape);
1962
1963 APValue::LValueBase Base = V.getLValueBase();
1964
1965 // this might not cover every case but did cover issue 97756
1966 // see test CodeGen/ms_mangler_templatearg_opte
1967 if (V.isLValueOnePastTheEnd()) {
1968 Out << "5E";
1969 auto *VD = Base.dyn_cast<const ValueDecl *>();
1970 if (VD)
1971 mangle(VD);
1972 Out << "@";
1973 return;
1974 }
1975
1976 if (!V.hasLValuePath() || V.getLValuePath().empty()) {
1977 // Taking the address of a complete object has a special-case mangling.
1978 if (Base.isNull()) {
1979 // MSVC emits 0A@ for null pointers. Generalize this for arbitrary
1980 // integers cast to pointers.
1981 // FIXME: This mangles 0 cast to a pointer the same as a null pointer,
1982 // even in cases where the two are different values.
1983 Out << "0";
1984 mangleNumber(V.getLValueOffset().getQuantity());
1985 } else if (!V.hasLValuePath()) {
1986 // FIXME: This can only happen as an extension. Invent a mangling.
1987 Error("template argument (extension not comaptible with ms mangler)");
1988 return;
1989 } else if (auto *VD = Base.dyn_cast<const ValueDecl*>()) {
1990 Out << "E";
1991 mangle(VD);
1992 } else {
1993 Error("template argument (undeclared base)");
1994 return;
1995 }
1996 } else {
1997 if (TAK == TplArgKind::ClassNTTP && T->isPointerType())
1998 Out << "5";
1999
2000 SmallVector<char, 2> EntryTypes;
2001 SmallVector<std::function<void()>, 2> EntryManglers;
2002 QualType ET = Base.getType();
2003 for (APValue::LValuePathEntry E : V.getLValuePath()) {
2004 if (auto *AT = ET->getAsArrayTypeUnsafe()) {
2005 EntryTypes.push_back('C');
2006 EntryManglers.push_back([this, I = E.getAsArrayIndex()] {
2007 Out << '0';
2008 mangleNumber(I);
2009 Out << '@';
2010 });
2011 ET = AT->getElementType();
2012 continue;
2013 }
2014
2015 const Decl *D = E.getAsBaseOrMember().getPointer();
2016 if (auto *FD = dyn_cast<FieldDecl>(D)) {
2017 ET = FD->getType();
2018 if (const auto *RD = ET->getAsRecordDecl())
2019 if (RD->isAnonymousStructOrUnion())
2020 continue;
2021 } else {
2022 ET = getASTContext().getCanonicalTagType(cast<CXXRecordDecl>(D));
2023 // Bug in MSVC: fully qualified name of base class should be used for
2024 // mangling to prevent collisions e.g. on base classes with same names
2025 // in different namespaces.
2026 }
2027
2028 EntryTypes.push_back('6');
2029 EntryManglers.push_back([this, D] {
2030 mangleUnqualifiedName(cast<NamedDecl>(D));
2031 Out << '@';
2032 });
2033 }
2034
2035 for (auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
2036 Out << *I;
2037
2038 auto *VD = Base.dyn_cast<const ValueDecl*>();
2039 if (!VD) {
2040 Error("template argument (null value decl)");
2041 return;
2042 }
2043 Out << (TAK == TplArgKind::ClassNTTP ? 'E' : '1');
2044 mangle(VD);
2045
2046 for (const std::function<void()> &Mangler : EntryManglers)
2047 Mangler();
2048 if (TAK == TplArgKind::ClassNTTP && T->isPointerType())
2049 Out << '@';
2050 }
2051
2052 return;
2053 }
2054
2056 if (WithScalarType)
2057 mangleType(T, SourceRange(), QMM_Escape);
2058
2059 const CXXRecordDecl *RD =
2060 T->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
2061 const ValueDecl *D = V.getMemberPointerDecl();
2062 if (TAK == TplArgKind::ClassNTTP) {
2064 mangleMemberDataPointerInClassNTTP(RD, D);
2065 else
2066 mangleMemberFunctionPointerInClassNTTP(RD,
2067 cast_or_null<CXXMethodDecl>(D));
2068 } else {
2070 mangleMemberDataPointer(RD, D, nullptr, QualType(), "");
2071 else
2072 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D), nullptr,
2073 QualType(), "");
2074 }
2075 return;
2076 }
2077
2078 case APValue::Struct: {
2079 Out << '2';
2080 mangleType(T, SourceRange(), QMM_Escape);
2081 const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
2082 assert(RD && "unexpected type for record value");
2083
2084 unsigned BaseIndex = 0;
2085 for (const CXXBaseSpecifier &B : RD->bases())
2086 mangleTemplateArgValue(B.getType(), V.getStructBase(BaseIndex++), TAK);
2087 for (const FieldDecl *FD : RD->fields())
2088 if (!FD->isUnnamedBitField())
2089 mangleTemplateArgValue(FD->getType(),
2090 V.getStructField(FD->getFieldIndex()), TAK,
2091 /*WithScalarType*/ true);
2092 Out << '@';
2093 return;
2094 }
2095
2096 case APValue::Union:
2097 Out << '7';
2098 mangleType(T, SourceRange(), QMM_Escape);
2099 if (const FieldDecl *FD = V.getUnionField()) {
2100 mangleUnqualifiedName(FD);
2101 mangleTemplateArgValue(FD->getType(), V.getUnionValue(), TAK);
2102 }
2103 Out << '@';
2104 return;
2105
2107 // We mangle complex types as structs, so mangle the value as a struct too.
2108 Out << '2';
2109 mangleType(T, SourceRange(), QMM_Escape);
2110 Out << '0';
2111 mangleNumber(V.getComplexIntReal());
2112 Out << '0';
2113 mangleNumber(V.getComplexIntImag());
2114 Out << '@';
2115 return;
2116
2118 Out << '2';
2119 mangleType(T, SourceRange(), QMM_Escape);
2120 mangleFloat(V.getComplexFloatReal());
2121 mangleFloat(V.getComplexFloatImag());
2122 Out << '@';
2123 return;
2124
2125 case APValue::Array: {
2126 Out << '3';
2127 QualType ElemT = getASTContext().getAsArrayType(T)->getElementType();
2128 mangleType(ElemT, SourceRange(), QMM_Escape);
2129 for (unsigned I = 0, N = V.getArraySize(); I != N; ++I) {
2130 const APValue &ElemV = I < V.getArrayInitializedElts()
2131 ? V.getArrayInitializedElt(I)
2132 : V.getArrayFiller();
2133 mangleTemplateArgValue(ElemT, ElemV, TAK);
2134 Out << '@';
2135 }
2136 Out << '@';
2137 return;
2138 }
2139
2140 case APValue::Vector: {
2141 // __m128 is mangled as a struct containing an array. We follow this
2142 // approach for all vector types.
2143 Out << '2';
2144 mangleType(T, SourceRange(), QMM_Escape);
2145 Out << '3';
2146 QualType ElemT = T->castAs<VectorType>()->getElementType();
2147 mangleType(ElemT, SourceRange(), QMM_Escape);
2148 for (unsigned I = 0, N = V.getVectorLength(); I != N; ++I) {
2149 const APValue &ElemV = V.getVectorElt(I);
2150 mangleTemplateArgValue(ElemT, ElemV, TAK);
2151 Out << '@';
2152 }
2153 Out << "@@";
2154 return;
2155 }
2156
2157 case APValue::Matrix: {
2158 Error("template argument (value type: matrix)");
2159 return;
2160 }
2161
2163 Error("template argument (value type: address label diff)");
2164 return;
2165 }
2166
2167 case APValue::FixedPoint: {
2168 Error("template argument (value type: fixed point)");
2169 return;
2170 }
2171 }
2172}
2173
2174void MicrosoftCXXNameMangler::mangleObjCProtocol(const ObjCProtocolDecl *PD) {
2175 llvm::SmallString<64> TemplateMangling;
2176 llvm::raw_svector_ostream Stream(TemplateMangling);
2177 MicrosoftCXXNameMangler Extra(Context, Stream);
2178
2179 Stream << "?$";
2180 Extra.mangleSourceName("Protocol");
2181 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->getName());
2182
2183 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
2184}
2185
2186void MicrosoftCXXNameMangler::mangleObjCLifetime(const QualType Type,
2187 Qualifiers Quals,
2188 SourceRange Range) {
2189 llvm::SmallString<64> TemplateMangling;
2190 llvm::raw_svector_ostream Stream(TemplateMangling);
2191 MicrosoftCXXNameMangler Extra(Context, Stream);
2192
2193 Stream << "?$";
2194 switch (Quals.getObjCLifetime()) {
2197 break;
2199 Extra.mangleSourceName("Autoreleasing");
2200 break;
2202 Extra.mangleSourceName("Strong");
2203 break;
2205 Extra.mangleSourceName("Weak");
2206 break;
2207 }
2208 Extra.manglePointerCVQualifiers(Quals);
2209 Extra.manglePointerExtQualifiers(Quals, Type);
2210 Extra.mangleType(Type, Range);
2211
2212 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
2213}
2214
2215void MicrosoftCXXNameMangler::mangleObjCKindOfType(const ObjCObjectType *T,
2216 Qualifiers Quals,
2217 SourceRange Range) {
2218 llvm::SmallString<64> TemplateMangling;
2219 llvm::raw_svector_ostream Stream(TemplateMangling);
2220 MicrosoftCXXNameMangler Extra(Context, Stream);
2221
2222 Stream << "?$";
2223 Extra.mangleSourceName("KindOf");
2224 Extra.mangleType(QualType(T, 0)
2225 .stripObjCKindOfType(getASTContext())
2226 ->castAs<ObjCObjectType>(),
2227 Quals, Range);
2228
2229 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
2230}
2231
2232void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
2233 bool IsMember) {
2234 // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>
2235 // 'E' means __ptr64 (32-bit only); 'F' means __unaligned (32/64-bit only);
2236 // 'I' means __restrict (32/64-bit).
2237 // Note that the MSVC __restrict keyword isn't the same as the C99 restrict
2238 // keyword!
2239 // <base-cvr-qualifiers> ::= A # near
2240 // ::= B # near const
2241 // ::= C # near volatile
2242 // ::= D # near const volatile
2243 // ::= E # far (16-bit)
2244 // ::= F # far const (16-bit)
2245 // ::= G # far volatile (16-bit)
2246 // ::= H # far const volatile (16-bit)
2247 // ::= I # huge (16-bit)
2248 // ::= J # huge const (16-bit)
2249 // ::= K # huge volatile (16-bit)
2250 // ::= L # huge const volatile (16-bit)
2251 // ::= M <basis> # based
2252 // ::= N <basis> # based const
2253 // ::= O <basis> # based volatile
2254 // ::= P <basis> # based const volatile
2255 // ::= Q # near member
2256 // ::= R # near const member
2257 // ::= S # near volatile member
2258 // ::= T # near const volatile member
2259 // ::= U # far member (16-bit)
2260 // ::= V # far const member (16-bit)
2261 // ::= W # far volatile member (16-bit)
2262 // ::= X # far const volatile member (16-bit)
2263 // ::= Y # huge member (16-bit)
2264 // ::= Z # huge const member (16-bit)
2265 // ::= 0 # huge volatile member (16-bit)
2266 // ::= 1 # huge const volatile member (16-bit)
2267 // ::= 2 <basis> # based member
2268 // ::= 3 <basis> # based const member
2269 // ::= 4 <basis> # based volatile member
2270 // ::= 5 <basis> # based const volatile member
2271 // ::= 6 # near function (pointers only)
2272 // ::= 7 # far function (pointers only)
2273 // ::= 8 # near method (pointers only)
2274 // ::= 9 # far method (pointers only)
2275 // ::= _A <basis> # based function (pointers only)
2276 // ::= _B <basis> # based function (far?) (pointers only)
2277 // ::= _C <basis> # based method (pointers only)
2278 // ::= _D <basis> # based method (far?) (pointers only)
2279 // ::= _E # block (Clang)
2280 // <basis> ::= 0 # __based(void)
2281 // ::= 1 # __based(segment)?
2282 // ::= 2 <name> # __based(name)
2283 // ::= 3 # ?
2284 // ::= 4 # ?
2285 // ::= 5 # not really based
2286 bool HasConst = Quals.hasConst(),
2287 HasVolatile = Quals.hasVolatile();
2288
2289 if (!IsMember) {
2290 if (HasConst && HasVolatile) {
2291 Out << 'D';
2292 } else if (HasVolatile) {
2293 Out << 'C';
2294 } else if (HasConst) {
2295 Out << 'B';
2296 } else {
2297 Out << 'A';
2298 }
2299 } else {
2300 if (HasConst && HasVolatile) {
2301 Out << 'T';
2302 } else if (HasVolatile) {
2303 Out << 'S';
2304 } else if (HasConst) {
2305 Out << 'R';
2306 } else {
2307 Out << 'Q';
2308 }
2309 }
2310
2311 // FIXME: For now, just drop all extension qualifiers on the floor.
2312}
2313
2314void
2315MicrosoftCXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {
2316 // <ref-qualifier> ::= G # lvalue reference
2317 // ::= H # rvalue-reference
2318 switch (RefQualifier) {
2319 case RQ_None:
2320 break;
2321
2322 case RQ_LValue:
2323 Out << 'G';
2324 break;
2325
2326 case RQ_RValue:
2327 Out << 'H';
2328 break;
2329 }
2330}
2331
2332void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
2333 QualType PointeeType) {
2334 // Check if this is a default 64-bit pointer or has __ptr64 qualifier.
2335 bool is64Bit = PointeeType.isNull() ? PointersAre64Bit :
2336 is64BitPointer(PointeeType.getQualifiers());
2337 if (is64Bit && (PointeeType.isNull() || !PointeeType->isFunctionType()))
2338 Out << 'E';
2339
2340 if (Quals.hasRestrict())
2341 Out << 'I';
2342
2343 if (Quals.hasUnaligned() ||
2344 (!PointeeType.isNull() && PointeeType.getLocalQualifiers().hasUnaligned()))
2345 Out << 'F';
2346}
2347
2348void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {
2349 PointerAuthQualifier PointerAuth = Quals.getPointerAuth();
2350 if (!PointerAuth)
2351 return;
2352
2353 Out << "__ptrauth";
2354 mangleNumber(PointerAuth.getKey());
2355 mangleNumber(PointerAuth.isAddressDiscriminated());
2356 mangleNumber(PointerAuth.getExtraDiscriminator());
2357}
2358
2359void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
2360 // <pointer-cv-qualifiers> ::= P # no qualifiers
2361 // ::= Q # const
2362 // ::= R # volatile
2363 // ::= S # const volatile
2364 bool HasConst = Quals.hasConst(),
2365 HasVolatile = Quals.hasVolatile();
2366
2367 if (HasConst && HasVolatile) {
2368 Out << 'S';
2369 } else if (HasVolatile) {
2370 Out << 'R';
2371 } else if (HasConst) {
2372 Out << 'Q';
2373 } else {
2374 Out << 'P';
2375 }
2376}
2377
2378void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType T,
2379 SourceRange Range) {
2380 // MSVC will backreference two canonically equivalent types that have slightly
2381 // different manglings when mangled alone.
2382
2383 // Decayed types do not match up with non-decayed versions of the same type.
2384 //
2385 // e.g.
2386 // void (*x)(void) will not form a backreference with void x(void)
2387 void *TypePtr;
2388 if (const auto *DT = T->getAs<DecayedType>()) {
2389 QualType OriginalType = DT->getOriginalType();
2390 // All decayed ArrayTypes should be treated identically; as-if they were
2391 // a decayed IncompleteArrayType.
2392 if (const auto *AT = getASTContext().getAsArrayType(OriginalType))
2393 OriginalType = getASTContext().getIncompleteArrayType(
2394 AT->getElementType(), AT->getSizeModifier(),
2395 AT->getIndexTypeCVRQualifiers());
2396
2397 TypePtr = OriginalType.getCanonicalType().getAsOpaquePtr();
2398 // If the original parameter was textually written as an array,
2399 // instead treat the decayed parameter like it's const.
2400 //
2401 // e.g.
2402 // int [] -> int * const
2403 if (OriginalType->isArrayType())
2404 T = T.withConst();
2405 } else {
2406 TypePtr = T.getCanonicalType().getAsOpaquePtr();
2407 }
2408
2409 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);
2410
2411 if (Found == FunArgBackReferences.end()) {
2412 size_t OutSizeBefore = Out.tell();
2413
2414 mangleType(T, Range, QMM_Drop);
2415
2416 // See if it's worth creating a back reference.
2417 // Only types longer than 1 character are considered
2418 // and only 10 back references slots are available:
2419 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);
2420 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2421 size_t Size = FunArgBackReferences.size();
2422 FunArgBackReferences[TypePtr] = Size;
2423 }
2424 } else {
2425 Out << Found->second;
2426 }
2427}
2428
2429void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2430 const PassObjectSizeAttr *POSA) {
2431 int Type = POSA->getType();
2432 bool Dynamic = POSA->isDynamic();
2433
2434 auto Iter = PassObjectSizeArgs.insert({Type, Dynamic}).first;
2435 auto *TypePtr = (const void *)&*Iter;
2436 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);
2437
2438 if (Found == FunArgBackReferences.end()) {
2439 std::string Name =
2440 Dynamic ? "__pass_dynamic_object_size" : "__pass_object_size";
2441 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(Type),
2442 {"__clang"});
2443
2444 if (FunArgBackReferences.size() < 10) {
2445 size_t Size = FunArgBackReferences.size();
2446 FunArgBackReferences[TypePtr] = Size;
2447 }
2448 } else {
2449 Out << Found->second;
2450 }
2451}
2452
2453void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
2454 Qualifiers Quals,
2455 SourceRange Range) {
2456 // Address space is mangled as an unqualified templated type in the __clang
2457 // namespace. The demangled version of this is:
2458 // In the case of a language specific address space:
2459 // __clang::struct _AS[language_addr_space]<Type>
2460 // where:
2461 // <language_addr_space> ::= <OpenCL-addrspace> | <CUDA-addrspace>
2462 // <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" |
2463 // "private"| "generic" | "device" | "host" ]
2464 // <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
2465 // Note that the above were chosen to match the Itanium mangling for this.
2466 //
2467 // In the case of a non-language specific address space:
2468 // __clang::struct _AS<TargetAS, Type>
2469 assert(Quals.hasAddressSpace() && "Not valid without address space");
2470 llvm::SmallString<32> ASMangling;
2471 llvm::raw_svector_ostream Stream(ASMangling);
2472 MicrosoftCXXNameMangler Extra(Context, Stream);
2473 Stream << "?$";
2474
2475 LangAS AS = Quals.getAddressSpace();
2476 if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
2477 unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
2478 Extra.mangleSourceName("_AS");
2479 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2480 } else {
2481 switch (AS) {
2482 default:
2483 llvm_unreachable("Not a language specific address space");
2484 case LangAS::opencl_global:
2485 Extra.mangleSourceName("_ASCLglobal");
2486 break;
2487 case LangAS::opencl_global_device:
2488 Extra.mangleSourceName("_ASCLdevice");
2489 break;
2490 case LangAS::opencl_global_host:
2491 Extra.mangleSourceName("_ASCLhost");
2492 break;
2493 case LangAS::opencl_local:
2494 Extra.mangleSourceName("_ASCLlocal");
2495 break;
2496 case LangAS::opencl_constant:
2497 Extra.mangleSourceName("_ASCLconstant");
2498 break;
2499 case LangAS::opencl_private:
2500 Extra.mangleSourceName("_ASCLprivate");
2501 break;
2502 case LangAS::opencl_generic:
2503 Extra.mangleSourceName("_ASCLgeneric");
2504 break;
2505 case LangAS::cuda_device:
2506 Extra.mangleSourceName("_ASCUdevice");
2507 break;
2508 case LangAS::cuda_constant:
2509 Extra.mangleSourceName("_ASCUconstant");
2510 break;
2511 case LangAS::cuda_shared:
2512 Extra.mangleSourceName("_ASCUshared");
2513 break;
2514 case LangAS::ptr32_sptr:
2515 case LangAS::ptr32_uptr:
2516 case LangAS::ptr64:
2517 llvm_unreachable("don't mangle ptr address spaces with _AS");
2518 }
2519 }
2520
2521 Extra.mangleType(T, Range, QMM_Escape);
2522 mangleQualifiers(Qualifiers(), false);
2523 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {"__clang"});
2524}
2525
2526void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T,
2527 QualifierMangleMode QMM) {
2528 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2529 LangOptions::MSVC2019) &&
2530 "Cannot mangle MSVC 2017 auto return types!");
2531
2532 if (isa<AutoType>(T)) {
2533 const auto *AT = T->getContainedAutoType();
2534 Qualifiers Quals = T.getLocalQualifiers();
2535
2536 if (QMM == QMM_Result)
2537 Out << '?';
2538 if (QMM != QMM_Drop)
2539 mangleQualifiers(Quals, false);
2540 Out << (AT->isDecltypeAuto() ? "_T" : "_P");
2541 return;
2542 }
2543
2544 T = T.getDesugaredType(getASTContext());
2545 Qualifiers Quals = T.getLocalQualifiers();
2546
2547 switch (QMM) {
2548 case QMM_Drop:
2549 case QMM_Result:
2550 break;
2551 case QMM_Mangle:
2552 mangleQualifiers(Quals, false);
2553 break;
2554 default:
2555 llvm_unreachable("QMM_Escape unexpected");
2556 }
2557
2558 const Type *ty = T.getTypePtr();
2559 switch (ty->getTypeClass()) {
2560 case Type::MemberPointer:
2561 mangleAutoReturnType(cast<MemberPointerType>(ty), Quals);
2562 break;
2563 case Type::Pointer:
2564 mangleAutoReturnType(cast<PointerType>(ty), Quals);
2565 break;
2566 case Type::LValueReference:
2567 mangleAutoReturnType(cast<LValueReferenceType>(ty), Quals);
2568 break;
2569 case Type::RValueReference:
2570 mangleAutoReturnType(cast<RValueReferenceType>(ty), Quals);
2571 break;
2572 default:
2573 llvm_unreachable("Invalid type expected");
2574 }
2575}
2576
2577void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
2578 QualifierMangleMode QMM) {
2579 // Don't use the canonical types. MSVC includes things like 'const' on
2580 // pointer arguments to function pointers that canonicalization strips away.
2581 T = T.getDesugaredType(getASTContext());
2582 Qualifiers Quals = T.getLocalQualifiers();
2583
2584 if (const ArrayType *AT = getASTContext().getAsArrayType(T)) {
2585 // If there were any Quals, getAsArrayType() pushed them onto the array
2586 // element type.
2587 if (QMM == QMM_Mangle)
2588 Out << 'A';
2589 else if (QMM == QMM_Escape || QMM == QMM_Result)
2590 Out << "$$B";
2591 mangleArrayType(AT);
2592 return;
2593 }
2594
2595 bool IsPointer = T->isAnyPointerType() || T->isMemberPointerType() ||
2597
2598 switch (QMM) {
2599 case QMM_Drop:
2600 if (Quals.hasObjCLifetime())
2601 Quals = Quals.withoutObjCLifetime();
2602 break;
2603 case QMM_Mangle:
2604 if (const FunctionType *FT = dyn_cast<FunctionType>(T)) {
2605 Out << '6';
2606 mangleFunctionType(FT);
2607 return;
2608 }
2609 mangleQualifiers(Quals, false);
2610 break;
2611 case QMM_Escape:
2612 if (!IsPointer && Quals) {
2613 Out << "$$C";
2614 mangleQualifiers(Quals, false);
2615 }
2616 break;
2617 case QMM_Result:
2618 // Presence of __unaligned qualifier shouldn't affect mangling here.
2619 Quals.removeUnaligned();
2620 if (Quals.hasObjCLifetime())
2621 Quals = Quals.withoutObjCLifetime();
2622 if ((!IsPointer && Quals) || isa<TagType>(T) || isArtificialTagType(T)) {
2623 Out << '?';
2624 mangleQualifiers(Quals, false);
2625 }
2626 break;
2627 }
2628
2629 const Type *ty = T.getTypePtr();
2630
2631 switch (ty->getTypeClass()) {
2632#define ABSTRACT_TYPE(CLASS, PARENT)
2633#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2634 case Type::CLASS: \
2635 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2636 return;
2637#define TYPE(CLASS, PARENT) \
2638 case Type::CLASS: \
2639 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2640 break;
2641#include "clang/AST/TypeNodes.inc"
2642#undef ABSTRACT_TYPE
2643#undef NON_CANONICAL_TYPE
2644#undef TYPE
2645 }
2646}
2647
2648void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
2649 SourceRange Range) {
2650 // <type> ::= <builtin-type>
2651 // <builtin-type> ::= X # void
2652 // ::= C # signed char
2653 // ::= D # char
2654 // ::= E # unsigned char
2655 // ::= F # short
2656 // ::= G # unsigned short (or wchar_t if it's not a builtin)
2657 // ::= H # int
2658 // ::= I # unsigned int
2659 // ::= J # long
2660 // ::= K # unsigned long
2661 // L # <none>
2662 // ::= M # float
2663 // ::= N # double
2664 // ::= O # long double (__float80 is mangled differently)
2665 // ::= _J # long long, __int64
2666 // ::= _K # unsigned long long, __int64
2667 // ::= _L # __int128
2668 // ::= _M # unsigned __int128
2669 // ::= _N # bool
2670 // _O # <array in parameter>
2671 // ::= _Q # char8_t
2672 // ::= _S # char16_t
2673 // ::= _T # __float80 (Intel)
2674 // ::= _U # char32_t
2675 // ::= _W # wchar_t
2676 // ::= _Z # __float80 (Digital Mars)
2677 switch (T->getKind()) {
2678 case BuiltinType::Void:
2679 Out << 'X';
2680 break;
2681 case BuiltinType::SChar:
2682 Out << 'C';
2683 break;
2684 case BuiltinType::Char_U:
2685 case BuiltinType::Char_S:
2686 Out << 'D';
2687 break;
2688 case BuiltinType::UChar:
2689 Out << 'E';
2690 break;
2691 case BuiltinType::Short:
2692 Out << 'F';
2693 break;
2694 case BuiltinType::UShort:
2695 Out << 'G';
2696 break;
2697 case BuiltinType::Int:
2698 Out << 'H';
2699 break;
2700 case BuiltinType::UInt:
2701 Out << 'I';
2702 break;
2703 case BuiltinType::Long:
2704 Out << 'J';
2705 break;
2706 case BuiltinType::ULong:
2707 Out << 'K';
2708 break;
2709 case BuiltinType::Float:
2710 Out << 'M';
2711 break;
2712 case BuiltinType::Double:
2713 Out << 'N';
2714 break;
2715 // TODO: Determine size and mangle accordingly
2716 case BuiltinType::LongDouble:
2717 Out << 'O';
2718 break;
2719 case BuiltinType::LongLong:
2720 Out << "_J";
2721 break;
2722 case BuiltinType::ULongLong:
2723 Out << "_K";
2724 break;
2725 case BuiltinType::Int128:
2726 Out << "_L";
2727 break;
2728 case BuiltinType::UInt128:
2729 Out << "_M";
2730 break;
2731 case BuiltinType::Bool:
2732 Out << "_N";
2733 break;
2734 case BuiltinType::Char8:
2735 Out << "_Q";
2736 break;
2737 case BuiltinType::Char16:
2738 Out << "_S";
2739 break;
2740 case BuiltinType::Char32:
2741 Out << "_U";
2742 break;
2743 case BuiltinType::WChar_S:
2744 case BuiltinType::WChar_U:
2745 Out << "_W";
2746 break;
2747
2748#define BUILTIN_TYPE(Id, SingletonId)
2749#define PLACEHOLDER_TYPE(Id, SingletonId) \
2750 case BuiltinType::Id:
2751#include "clang/AST/BuiltinTypes.def"
2752 case BuiltinType::Dependent:
2753 llvm_unreachable("placeholder types shouldn't get to name mangling");
2754
2755 case BuiltinType::ObjCId:
2756 mangleArtificialTagType(TagTypeKind::Struct, "objc_object");
2757 break;
2758 case BuiltinType::ObjCClass:
2759 mangleArtificialTagType(TagTypeKind::Struct, "objc_class");
2760 break;
2761 case BuiltinType::ObjCSel:
2762 mangleArtificialTagType(TagTypeKind::Struct, "objc_selector");
2763 break;
2764
2765#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2766 case BuiltinType::Id: \
2767 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2768 break;
2769#include "clang/Basic/OpenCLImageTypes.def"
2770 case BuiltinType::OCLSampler:
2771 Out << "PA";
2772 mangleArtificialTagType(TagTypeKind::Struct, "ocl_sampler");
2773 break;
2774 case BuiltinType::OCLEvent:
2775 Out << "PA";
2776 mangleArtificialTagType(TagTypeKind::Struct, "ocl_event");
2777 break;
2778 case BuiltinType::OCLClkEvent:
2779 Out << "PA";
2780 mangleArtificialTagType(TagTypeKind::Struct, "ocl_clkevent");
2781 break;
2782 case BuiltinType::OCLQueue:
2783 Out << "PA";
2784 mangleArtificialTagType(TagTypeKind::Struct, "ocl_queue");
2785 break;
2786 case BuiltinType::OCLReserveID:
2787 Out << "PA";
2788 mangleArtificialTagType(TagTypeKind::Struct, "ocl_reserveid");
2789 break;
2790#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2791 case BuiltinType::Id: \
2792 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2793 break;
2794#include "clang/Basic/OpenCLExtensionTypes.def"
2795
2796 case BuiltinType::NullPtr:
2797 Out << "$$T";
2798 break;
2799
2800 case BuiltinType::Float16:
2801 mangleArtificialTagType(TagTypeKind::Struct, "_Float16", {"__clang"});
2802 break;
2803
2804 case BuiltinType::Half:
2805 if (!getASTContext().getLangOpts().HLSL)
2806 mangleArtificialTagType(TagTypeKind::Struct, "_Half", {"__clang"});
2807 else if (getASTContext().getLangOpts().NativeHalfType)
2808 Out << "$f16@";
2809 else
2810 Out << "$halff@";
2811 break;
2812
2813 case BuiltinType::BFloat16:
2814 mangleArtificialTagType(TagTypeKind::Struct, "__bf16", {"__clang"});
2815 break;
2816
2817 case BuiltinType::MFloat8:
2818 mangleArtificialTagType(TagTypeKind::Struct, "__mfp8", {"__clang"});
2819 break;
2820
2821#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2822 case BuiltinType::Id: \
2823 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2824 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2825 break;
2826
2827#include "clang/Basic/WebAssemblyReferenceTypes.def"
2828
2829#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2830 case BuiltinType::Id: \
2831 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2832 break;
2833#include "clang/Basic/HLSLIntangibleTypes.def"
2834
2835 case BuiltinType::SveBool:
2836 Out << "$_CA";
2837 break;
2838
2839 case BuiltinType::SveInt8:
2840 Out << "$_CB";
2841 break;
2842 case BuiltinType::SveInt16:
2843 Out << "$_CC";
2844 break;
2845 case BuiltinType::SveInt32:
2846 Out << "$_CD";
2847 break;
2848 case BuiltinType::SveInt64:
2849 Out << "$_CE";
2850 break;
2851
2852 case BuiltinType::SveUint8:
2853 Out << "$_CF";
2854 break;
2855 case BuiltinType::SveUint16:
2856 Out << "$_CG";
2857 break;
2858 case BuiltinType::SveUint32:
2859 Out << "$_CH";
2860 break;
2861 case BuiltinType::SveUint64:
2862 Out << "$_CI";
2863 break;
2864
2865 case BuiltinType::SveBFloat16:
2866 Out << "$_CJ";
2867 break;
2868 case BuiltinType::SveFloat16:
2869 Out << "$_CK";
2870 break;
2871 case BuiltinType::SveFloat32:
2872 Out << "$_CL";
2873 break;
2874 case BuiltinType::SveFloat64:
2875 Out << "$_CM";
2876 break;
2877
2878 case BuiltinType::SveInt8x2:
2879 Out << "$_C2B";
2880 break;
2881 case BuiltinType::SveInt16x2:
2882 Out << "$_C2C";
2883 break;
2884 case BuiltinType::SveInt32x2:
2885 Out << "$_C2D";
2886 break;
2887 case BuiltinType::SveInt64x2:
2888 Out << "$_C2E";
2889 break;
2890
2891 case BuiltinType::SveUint8x2:
2892 Out << "$_C2F";
2893 break;
2894 case BuiltinType::SveUint16x2:
2895 Out << "$_C2G";
2896 break;
2897 case BuiltinType::SveUint32x2:
2898 Out << "$_C2H";
2899 break;
2900 case BuiltinType::SveUint64x2:
2901 Out << "$_C2I";
2902 break;
2903
2904 case BuiltinType::SveBFloat16x2:
2905 Out << "$_C2J";
2906 break;
2907 case BuiltinType::SveFloat16x2:
2908 Out << "$_C2K";
2909 break;
2910 case BuiltinType::SveFloat32x2:
2911 Out << "$_C2L";
2912 break;
2913 case BuiltinType::SveFloat64x2:
2914 Out << "$_C2M";
2915 break;
2916
2917 case BuiltinType::SveInt8x3:
2918 Out << "$_C3B";
2919 break;
2920 case BuiltinType::SveInt16x3:
2921 Out << "$_C3C";
2922 break;
2923 case BuiltinType::SveInt32x3:
2924 Out << "$_C3D";
2925 break;
2926 case BuiltinType::SveInt64x3:
2927 Out << "$_C3E";
2928 break;
2929
2930 case BuiltinType::SveUint8x3:
2931 Out << "$_C3F";
2932 break;
2933 case BuiltinType::SveUint16x3:
2934 Out << "$_C3G";
2935 break;
2936 case BuiltinType::SveUint32x3:
2937 Out << "$_C3H";
2938 break;
2939 case BuiltinType::SveUint64x3:
2940 Out << "$_C3I";
2941 break;
2942
2943 case BuiltinType::SveBFloat16x3:
2944 Out << "$_C3J";
2945 break;
2946 case BuiltinType::SveFloat16x3:
2947 Out << "$_C3K";
2948 break;
2949 case BuiltinType::SveFloat32x3:
2950 Out << "$_C3L";
2951 break;
2952 case BuiltinType::SveFloat64x3:
2953 Out << "$_C3M";
2954 break;
2955
2956 case BuiltinType::SveInt8x4:
2957 Out << "$_C4B";
2958 break;
2959 case BuiltinType::SveInt16x4:
2960 Out << "$_C4C";
2961 break;
2962 case BuiltinType::SveInt32x4:
2963 Out << "$_C4D";
2964 break;
2965 case BuiltinType::SveInt64x4:
2966 Out << "$_C4E";
2967 break;
2968
2969 case BuiltinType::SveUint8x4:
2970 Out << "$_C4F";
2971 break;
2972 case BuiltinType::SveUint16x4:
2973 Out << "$_C4G";
2974 break;
2975 case BuiltinType::SveUint32x4:
2976 Out << "$_C4H";
2977 break;
2978 case BuiltinType::SveUint64x4:
2979 Out << "$_C4I";
2980 break;
2981
2982 case BuiltinType::SveBFloat16x4:
2983 Out << "$_C4J";
2984 break;
2985 case BuiltinType::SveFloat16x4:
2986 Out << "$_C4K";
2987 break;
2988 case BuiltinType::SveFloat32x4:
2989 Out << "$_C4L";
2990 break;
2991 case BuiltinType::SveFloat64x4:
2992 Out << "$_C4M";
2993 break;
2994
2995 // SVE types not supported by MSVC still use clang-specific
2996 // artificial tag mangling
2997 case BuiltinType::SveMFloat8:
2998 mangleArtificialTagType(TagTypeKind::Struct, "__SVMfloat8_t", {"__clang"});
2999 break;
3000
3001 case BuiltinType::SveMFloat8x2:
3002 mangleArtificialTagType(TagTypeKind::Struct, "__clang_svmfloat8x2_t",
3003 {"__clang"});
3004 break;
3005
3006 case BuiltinType::SveMFloat8x3:
3007 mangleArtificialTagType(TagTypeKind::Struct, "__clang_svmfloat8x3_t",
3008 {"__clang"});
3009 break;
3010
3011 case BuiltinType::SveMFloat8x4:
3012 mangleArtificialTagType(TagTypeKind::Struct, "__clang_svmfloat8x4_t",
3013 {"__clang"});
3014 break;
3015
3016 case BuiltinType::SveBoolx2:
3017 mangleArtificialTagType(TagTypeKind::Struct, "__clang_svboolx2_t",
3018 {"__clang"});
3019 break;
3020
3021 case BuiltinType::SveBoolx4:
3022 mangleArtificialTagType(TagTypeKind::Struct, "__clang_svboolx4_t",
3023 {"__clang"});
3024 break;
3025
3026 case BuiltinType::SveCount:
3027 mangleArtificialTagType(TagTypeKind::Struct, "__SVCount_t", {"__clang"});
3028 break;
3029
3030 // Issue an error for any type not explicitly handled.
3031 default:
3032 Error(Range.getBegin(), "built-in type: ",
3033 T->getName(Context.getASTContext().getPrintingPolicy()))
3034 << Range;
3035 break;
3036 }
3037}
3038
3039// <type> ::= <function-type>
3040void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, Qualifiers,
3041 SourceRange) {
3042 // Structors only appear in decls, so at this point we know it's not a
3043 // structor type.
3044 // FIXME: This may not be lambda-friendly.
3045 if (T->getMethodQuals() || T->getRefQualifier() != RQ_None) {
3046 Out << "$$A8@@";
3047 mangleFunctionType(T, /*D=*/nullptr, /*ForceThisQuals=*/true);
3048 } else {
3049 Out << "$$A6";
3050 mangleFunctionType(T);
3051 }
3052}
3053void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
3054 Qualifiers, SourceRange) {
3055 Out << "$$A6";
3056 mangleFunctionType(T);
3057}
3058
3059void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
3060 const FunctionDecl *D,
3061 bool ForceThisQuals,
3062 bool MangleExceptionSpec) {
3063 // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
3064 // <return-type> <argument-list> <throw-spec>
3065 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);
3066
3067 SourceRange Range;
3068 if (D) Range = D->getSourceRange();
3069
3070 bool IsInLambda = false;
3071 bool IsStructor = false, HasThisQuals = ForceThisQuals, IsCtorClosure = false;
3072 CallingConv CC = T->getCallConv();
3073 if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
3074 if (MD->getParent()->isLambda())
3075 IsInLambda = true;
3077 HasThisQuals = true;
3078 if (isa<CXXDestructorDecl>(MD)) {
3079 IsStructor = true;
3080 } else if (isa<CXXConstructorDecl>(MD)) {
3081 IsStructor = true;
3082 IsCtorClosure = (StructorType == Ctor_CopyingClosure ||
3083 StructorType == Ctor_DefaultClosure) &&
3084 isStructorDecl(MD);
3085 if (IsCtorClosure)
3086 CC = getASTContext().getDefaultCallingConvention(
3087 /*IsVariadic=*/false, /*IsCXXMethod=*/true);
3088 }
3089 }
3090
3091 // If this is a C++ instance method, mangle the CVR qualifiers for the
3092 // this pointer.
3093 if (HasThisQuals) {
3094 Qualifiers Quals = Proto->getMethodQuals();
3095 manglePointerExtQualifiers(Quals, /*PointeeType=*/QualType());
3096 mangleRefQualifier(Proto->getRefQualifier());
3097 mangleQualifiers(Quals, /*IsMember=*/false);
3098 }
3099
3100 mangleCallingConvention(CC, Range);
3101
3102 if (Proto) {
3103 unsigned SMEAttrs = Proto->getAArch64SMEAttributes();
3104 if (SMEAttrs)
3105 Out << "__clang_sme_attr" << SMEAttrs;
3106 }
3107
3108 // <return-type> ::= <type>
3109 // ::= @ # structors (they have no declared return type)
3110 if (IsStructor) {
3111 if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
3112 // The deleting destructors take an extra argument of type int that
3113 // indicates whether the storage for the object should be deleted and
3114 // whether a single object or an array of objects is being destroyed. This
3115 // extra argument is not reflected in the AST.
3116 if (StructorType == Dtor_Deleting ||
3117 StructorType == Dtor_VectorDeleting) {
3118 Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");
3119 return;
3120 }
3121 // The vbase destructor returns void which is not reflected in the AST.
3122 if (StructorType == Dtor_Complete) {
3123 Out << "XXZ";
3124 return;
3125 }
3126 }
3127 if (IsCtorClosure) {
3128 // Default constructor closure and copy constructor closure both return
3129 // void.
3130 Out << 'X';
3131
3132 if (StructorType == Ctor_DefaultClosure) {
3133 // Default constructor closure always has no arguments.
3134 Out << 'X';
3135 } else if (StructorType == Ctor_CopyingClosure) {
3136 // Copy constructor closure always takes an unqualified reference.
3137 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
3138 Proto->getParamType(0)
3139 ->castAs<LValueReferenceType>()
3140 ->getPointeeType(),
3141 /*SpelledAsLValue=*/true),
3142 Range);
3143 Out << '@';
3144 } else {
3145 llvm_unreachable("unexpected constructor closure!");
3146 }
3147 Out << 'Z';
3148 return;
3149 }
3150 Out << '@';
3151 } else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(D)) {
3152 // The only lambda conversion operators are to function pointers, which
3153 // can differ by their calling convention and are typically deduced. So
3154 // we make sure that this type gets mangled properly.
3155 mangleType(T->getReturnType(), Range, QMM_Result);
3156 } else {
3157 QualType ResultType = T->getReturnType();
3158 if (IsInLambda && isa<CXXConversionDecl>(D)) {
3159 // The only lambda conversion operators are to function pointers, which
3160 // can differ by their calling convention and are typically deduced. So
3161 // we make sure that this type gets mangled properly.
3162 mangleType(ResultType, Range, QMM_Result);
3163 } else if (IsInLambda) {
3164 if (const auto *AT = ResultType->getContainedAutoType()) {
3165 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
3166 "shouldn't need to mangle __auto_type!");
3167 Out << '?';
3168 mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
3169 Out << '?';
3170 mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
3171 Out << '@';
3172 } else {
3173 Out << '@';
3174 }
3175 } else if (const auto *AT = ResultType->getContainedAutoType()) {
3176 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
3177 "shouldn't need to mangle __auto_type!");
3178
3179 // If we have any pointer types with the clang address space extension
3180 // then defer to the custom clang mangling to keep backwards
3181 // compatibility. See `mangleType(const PointerType *T, Qualifiers Quals,
3182 // SourceRange Range)` for details.
3183 auto UseClangMangling = [](QualType ResultType) {
3184 QualType T = ResultType;
3185 while (isa<PointerType>(T.getTypePtr())) {
3186 T = T->getPointeeType();
3187 if (T.getQualifiers().hasAddressSpace())
3188 return true;
3189 }
3190 return false;
3191 };
3192
3193 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
3194 LangOptions::MSVC2019) &&
3195 !UseClangMangling(ResultType)) {
3196 if (D && !D->getPrimaryTemplate()) {
3197 Out << '@';
3198 } else {
3199 if (D && D->getPrimaryTemplate()) {
3200 const FunctionProtoType *FPT = D->getPrimaryTemplate()
3202 ->getFirstDecl()
3203 ->getType()
3204 ->castAs<FunctionProtoType>();
3205 ResultType = FPT->getReturnType();
3206 }
3207 mangleAutoReturnType(ResultType, QMM_Result);
3208 }
3209 } else {
3210 Out << '?';
3211 mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
3212 Out << '?';
3213 mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
3214 Out << '@';
3215 }
3216 } else {
3217 if (ResultType->isVoidType())
3218 ResultType = ResultType.getUnqualifiedType();
3219 mangleType(ResultType, Range, QMM_Result);
3220 }
3221 }
3222
3223 // <argument-list> ::= X # void
3224 // ::= <type>+ @
3225 // ::= <type>* Z # varargs
3226 if (!Proto) {
3227 // Function types without prototypes can arise when mangling a function type
3228 // within an overloadable function in C. We mangle these as the absence of
3229 // any parameter types (not even an empty parameter list).
3230 Out << '@';
3231 } else if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
3232 Out << 'X';
3233 } else {
3234 // Happens for function pointer type arguments for example.
3235 for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) {
3236 // Explicit object parameters are prefixed by "_V".
3237 if (I == 0 && D && D->getParamDecl(I)->isExplicitObjectParameter())
3238 Out << "_V";
3239
3240 mangleFunctionArgumentType(Proto->getParamType(I), Range);
3241 // Mangle each pass_object_size parameter as if it's a parameter of enum
3242 // type passed directly after the parameter with the pass_object_size
3243 // attribute. The aforementioned enum's name is __pass_object_size, and we
3244 // pretend it resides in a top-level namespace called __clang.
3245 //
3246 // FIXME: Is there a defined extension notation for the MS ABI, or is it
3247 // necessary to just cross our fingers and hope this type+namespace
3248 // combination doesn't conflict with anything?
3249 if (D)
3250 if (const auto *P = D->getParamDecl(I)->getAttr<PassObjectSizeAttr>())
3251 manglePassObjectSizeArg(P);
3252 }
3253 // <builtin-type> ::= Z # ellipsis
3254 if (Proto->isVariadic())
3255 Out << 'Z';
3256 else
3257 Out << '@';
3258 }
3259
3260 if (MangleExceptionSpec && getASTContext().getLangOpts().CPlusPlus17 &&
3261 getASTContext().getLangOpts().isCompatibleWithMSVC(
3262 LangOptions::MSVC2017_5))
3263 mangleThrowSpecification(Proto);
3264 else
3265 Out << 'Z';
3266}
3267
3268void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
3269 // <function-class> ::= <member-function> E? # E designates a 64-bit 'this'
3270 // # pointer. in 64-bit mode *all*
3271 // # 'this' pointers are 64-bit.
3272 // ::= <global-function>
3273 // <member-function> ::= A # private: near
3274 // ::= B # private: far
3275 // ::= C # private: static near
3276 // ::= D # private: static far
3277 // ::= E # private: virtual near
3278 // ::= F # private: virtual far
3279 // ::= I # protected: near
3280 // ::= J # protected: far
3281 // ::= K # protected: static near
3282 // ::= L # protected: static far
3283 // ::= M # protected: virtual near
3284 // ::= N # protected: virtual far
3285 // ::= Q # public: near
3286 // ::= R # public: far
3287 // ::= S # public: static near
3288 // ::= T # public: static far
3289 // ::= U # public: virtual near
3290 // ::= V # public: virtual far
3291 // <global-function> ::= Y # global near
3292 // ::= Z # global far
3293 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3294 bool IsVirtual = MD->isVirtual();
3295 // When mangling vbase destructor variants, ignore whether or not the
3296 // underlying destructor was defined to be virtual.
3297 if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
3298 StructorType == Dtor_Complete) {
3299 IsVirtual = false;
3300 }
3301 switch (MD->getAccess()) {
3302 case AS_none:
3303 llvm_unreachable("Unsupported access specifier");
3304 case AS_private:
3306 Out << 'C';
3307 else if (IsVirtual)
3308 Out << 'E';
3309 else
3310 Out << 'A';
3311 break;
3312 case AS_protected:
3314 Out << 'K';
3315 else if (IsVirtual)
3316 Out << 'M';
3317 else
3318 Out << 'I';
3319 break;
3320 case AS_public:
3322 Out << 'S';
3323 else if (IsVirtual)
3324 Out << 'U';
3325 else
3326 Out << 'Q';
3327 }
3328 } else {
3329 Out << 'Y';
3330 }
3331}
3332void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC,
3333 SourceRange Range) {
3334 // <calling-convention> ::= A # __cdecl
3335 // ::= B # __export __cdecl
3336 // ::= C # __pascal
3337 // ::= D # __export __pascal
3338 // ::= E # __thiscall
3339 // ::= F # __export __thiscall
3340 // ::= G # __stdcall
3341 // ::= H # __export __stdcall
3342 // ::= I # __fastcall
3343 // ::= J # __export __fastcall
3344 // ::= Q # __vectorcall
3345 // ::= S # __attribute__((__swiftcall__)) // Clang-only
3346 // ::= W # __attribute__((__swiftasynccall__))
3347 // ::= U # __attribute__((__preserve_most__))
3348 // ::= V # __attribute__((__preserve_none__)) //
3349 // Clang-only
3350 // // Clang-only
3351 // ::= w # __regcall
3352 // ::= x # __regcall4
3353 // The 'export' calling conventions are from a bygone era
3354 // (*cough*Win16*cough*) when functions were declared for export with
3355 // that keyword. (It didn't actually export them, it just made them so
3356 // that they could be in a DLL and somebody from another module could call
3357 // them.)
3358
3359 switch (CC) {
3360 default:
3361 break;
3362 case CC_Win64:
3363 case CC_X86_64SysV:
3364 case CC_C:
3365 Out << 'A';
3366 return;
3367 case CC_X86Pascal:
3368 Out << 'C';
3369 return;
3370 case CC_X86ThisCall:
3371 Out << 'E';
3372 return;
3373 case CC_X86StdCall:
3374 Out << 'G';
3375 return;
3376 case CC_X86FastCall:
3377 Out << 'I';
3378 return;
3379 case CC_X86VectorCall:
3380 Out << 'Q';
3381 return;
3382 case CC_Swift:
3383 Out << 'S';
3384 return;
3385 case CC_SwiftAsync:
3386 Out << 'W';
3387 return;
3388 case CC_PreserveMost:
3389 Out << 'U';
3390 return;
3391 case CC_PreserveNone:
3392 Out << 'V';
3393 return;
3394 case CC_X86RegCall:
3395 if (getASTContext().getLangOpts().RegCall4)
3396 Out << "x";
3397 else
3398 Out << "w";
3399 return;
3400 }
3401
3402 Error(Range.getBegin(), "calling convention") << Range;
3403}
3404void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T,
3405 SourceRange Range) {
3406 mangleCallingConvention(T->getCallConv(), Range);
3407}
3408
3409void MicrosoftCXXNameMangler::mangleThrowSpecification(
3410 const FunctionProtoType *FT) {
3411 // <throw-spec> ::= Z # (default)
3412 // ::= _E # noexcept
3413 if (FT->canThrow())
3414 Out << 'Z';
3415 else
3416 Out << "_E";
3417}
3418
3419void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,
3420 Qualifiers, SourceRange Range) {
3421 // Probably should be mangled as a template instantiation; need to see what
3422 // VC does first.
3423 Error(Range.getBegin(), "unresolved dependent type") << Range;
3424}
3425
3426// <type> ::= <union-type> | <struct-type> | <class-type> | <enum-type>
3427// <union-type> ::= T <name>
3428// <struct-type> ::= U <name>
3429// <class-type> ::= V <name>
3430// <enum-type> ::= W4 <name>
3431void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) {
3432 switch (TTK) {
3433 case TagTypeKind::Union:
3434 Out << 'T';
3435 break;
3436 case TagTypeKind::Struct:
3437 case TagTypeKind::Interface:
3438 Out << 'U';
3439 break;
3440 case TagTypeKind::Class:
3441 Out << 'V';
3442 break;
3443 case TagTypeKind::Enum:
3444 Out << "W4";
3445 break;
3446 }
3447}
3448void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers,
3449 SourceRange) {
3450 mangleType(cast<TagType>(T)->getDecl());
3451}
3452void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers,
3453 SourceRange) {
3454 mangleType(cast<TagType>(T)->getDecl());
3455}
3456void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
3457 // MSVC chooses the tag kind of the definition if it exists, otherwise it
3458 // always picks the first declaration.
3459 const auto *Def = TD->getDefinition();
3460 TD = Def ? Def : TD->getFirstDecl();
3461 mangleTagTypeKind(TD->getTagKind());
3462 mangleName(TD);
3463}
3464
3465// If you add a call to this, consider updating isArtificialTagType() too.
3466void MicrosoftCXXNameMangler::mangleArtificialTagType(
3467 TagTypeKind TK, StringRef UnqualifiedName,
3468 ArrayRef<StringRef> NestedNames) {
3469 // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
3470 mangleTagTypeKind(TK);
3471
3472 // Always start with the unqualified name.
3473 mangleSourceName(UnqualifiedName);
3474
3475 for (StringRef N : llvm::reverse(NestedNames))
3476 mangleSourceName(N);
3477
3478 // Terminate the whole name with an '@'.
3479 Out << '@';
3480}
3481
3482// <type> ::= <array-type>
3483// <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
3484// [Y <dimension-count> <dimension>+]
3485// <element-type> # as global, E is never required
3486// It's supposed to be the other way around, but for some strange reason, it
3487// isn't. Today this behavior is retained for the sole purpose of backwards
3488// compatibility.
3489void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) {
3490 // This isn't a recursive mangling, so now we have to do it all in this
3491 // one call.
3492 manglePointerCVQualifiers(T->getElementType().getQualifiers());
3493 mangleType(T->getElementType(), SourceRange());
3494}
3495void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T, Qualifiers,
3496 SourceRange) {
3497 llvm_unreachable("Should have been special cased");
3498}
3499void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T, Qualifiers,
3500 SourceRange) {
3501 llvm_unreachable("Should have been special cased");
3502}
3503void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T,
3504 Qualifiers, SourceRange) {
3505 llvm_unreachable("Should have been special cased");
3506}
3507void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T,
3508 Qualifiers, SourceRange) {
3509 llvm_unreachable("Should have been special cased");
3510}
3511void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) {
3512 QualType ElementTy(T, 0);
3513 SmallVector<llvm::APInt, 3> Dimensions;
3514 for (;;) {
3515 if (ElementTy->isConstantArrayType()) {
3516 const ConstantArrayType *CAT =
3517 getASTContext().getAsConstantArrayType(ElementTy);
3518 Dimensions.push_back(CAT->getSize());
3519 ElementTy = CAT->getElementType();
3520 } else if (ElementTy->isIncompleteArrayType()) {
3521 const IncompleteArrayType *IAT =
3522 getASTContext().getAsIncompleteArrayType(ElementTy);
3523 Dimensions.push_back(llvm::APInt(32, 0));
3524 ElementTy = IAT->getElementType();
3525 } else if (ElementTy->isVariableArrayType()) {
3526 const VariableArrayType *VAT =
3527 getASTContext().getAsVariableArrayType(ElementTy);
3528 Dimensions.push_back(llvm::APInt(32, 0));
3529 ElementTy = VAT->getElementType();
3530 } else if (ElementTy->isDependentSizedArrayType()) {
3531 // The dependent expression has to be folded into a constant (TODO).
3532 const DependentSizedArrayType *DSAT =
3533 getASTContext().getAsDependentSizedArrayType(ElementTy);
3534 Error(DSAT->getSizeExpr()->getExprLoc(), "dependent-length")
3535 << DSAT->getSizeExpr()->getSourceRange();
3536 return;
3537 } else {
3538 break;
3539 }
3540 }
3541 Out << 'Y';
3542 // <dimension-count> ::= <number> # number of extra dimensions
3543 mangleNumber(Dimensions.size());
3544 for (const llvm::APInt &Dimension : Dimensions)
3545 mangleNumber(Dimension.getLimitedValue());
3546 mangleType(ElementTy, SourceRange(), QMM_Escape);
3547}
3548
3549void MicrosoftCXXNameMangler::mangleType(const ArrayParameterType *T,
3550 Qualifiers, SourceRange) {
3551 mangleArrayType(cast<ConstantArrayType>(T));
3552}
3553
3554// <type> ::= <pointer-to-member-type>
3555// <pointer-to-member-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
3556// <class name> <type>
3557void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,
3558 Qualifiers Quals, SourceRange Range) {
3559 QualType PointeeType = T->getPointeeType();
3560 manglePointerCVQualifiers(Quals);
3561 manglePointerExtQualifiers(Quals, PointeeType);
3562 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
3563 Out << '8';
3564 mangleName(T->getMostRecentCXXRecordDecl());
3565 mangleFunctionType(FPT, nullptr, true);
3566 } else {
3567 mangleQualifiers(PointeeType.getQualifiers(), true);
3568 mangleName(T->getMostRecentCXXRecordDecl());
3569 mangleType(PointeeType, Range, QMM_Drop);
3570 }
3571}
3572
3573void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T,
3574 Qualifiers, SourceRange Range) {
3575 Out << '?';
3576
3577 llvm::SmallString<64> Name;
3578 Name += "<TTPT_";
3579 Name += llvm::utostr(T->getDepth());
3580 Name += "_";
3581 Name += llvm::utostr(T->getIndex());
3582 Name += ">";
3583 mangleSourceName(Name);
3584}
3585
3586void MicrosoftCXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T,
3587 Qualifiers, SourceRange Range) {
3588 Error(Range.getBegin(), "substituted parameter pack") << Range;
3589}
3590
3591void MicrosoftCXXNameMangler::mangleType(const SubstBuiltinTemplatePackType *T,
3592 Qualifiers, SourceRange Range) {
3593 Error(Range.getBegin(), "substituted builtin template pack") << Range;
3594}
3595
3596// <type> ::= <pointer-type>
3597// <pointer-type> ::= E? <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
3598// # the E is required for 64-bit non-static pointers
3599void MicrosoftCXXNameMangler::mangleType(const PointerType *T, Qualifiers Quals,
3600 SourceRange Range) {
3601 QualType PointeeType = T->getPointeeType();
3602 manglePointerCVQualifiers(Quals);
3603 manglePointerExtQualifiers(Quals, PointeeType);
3604 manglePointerAuthQualifier(Quals);
3605
3606 // For pointer size address spaces, go down the same type mangling path as
3607 // non address space types.
3608 LangAS AddrSpace = PointeeType.getQualifiers().getAddressSpace();
3609 if (isPtrSizeAddressSpace(AddrSpace) || AddrSpace == LangAS::Default)
3610 mangleType(PointeeType, Range);
3611 else
3612 mangleAddressSpaceType(PointeeType, PointeeType.getQualifiers(), Range);
3613}
3614
3615void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
3616 Qualifiers Quals, SourceRange Range) {
3617 QualType PointeeType = T->getPointeeType();
3618 switch (Quals.getObjCLifetime()) {
3621 break;
3625 return mangleObjCLifetime(PointeeType, Quals, Range);
3626 }
3627 manglePointerCVQualifiers(Quals);
3628 manglePointerExtQualifiers(Quals, PointeeType);
3629 mangleType(PointeeType, Range);
3630}
3631
3632// <type> ::= <reference-type>
3633// <reference-type> ::= A E? <cvr-qualifiers> <type>
3634// # the E is required for 64-bit non-static lvalue references
3635void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,
3636 Qualifiers Quals, SourceRange Range) {
3637 QualType PointeeType = T->getPointeeType();
3638 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
3639 Out << 'A';
3640 manglePointerExtQualifiers(Quals, PointeeType);
3641 mangleType(PointeeType, Range);
3642}
3643
3644// <type> ::= <r-value-reference-type>
3645// <r-value-reference-type> ::= $$Q E? <cvr-qualifiers> <type>
3646// # the E is required for 64-bit non-static rvalue references
3647void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,
3648 Qualifiers Quals, SourceRange Range) {
3649 QualType PointeeType = T->getPointeeType();
3650 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
3651 Out << "$$Q";
3652 manglePointerExtQualifiers(Quals, PointeeType);
3653 mangleType(PointeeType, Range);
3654}
3655
3656void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, Qualifiers,
3657 SourceRange Range) {
3658 QualType ElementType = T->getElementType();
3659
3660 llvm::SmallString<64> TemplateMangling;
3661 llvm::raw_svector_ostream Stream(TemplateMangling);
3662 MicrosoftCXXNameMangler Extra(Context, Stream);
3663 Stream << "?$";
3664 Extra.mangleSourceName("_Complex");
3665 Extra.mangleType(ElementType, Range, QMM_Escape);
3666
3667 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3668}
3669
3670// Returns true for types that mangleArtificialTagType() gets called for with
3671// TagTypeKind Union, Struct, Class and where compatibility with MSVC's
3672// mangling matters.
3673// (It doesn't matter for Objective-C types and the like that cl.exe doesn't
3674// support.)
3675bool MicrosoftCXXNameMangler::isArtificialTagType(QualType T) const {
3676 const Type *ty = T.getTypePtr();
3677 switch (ty->getTypeClass()) {
3678 default:
3679 return false;
3680
3681 case Type::Vector: {
3682 // For ABI compatibility only __m64, __m128(id), and __m256(id) matter,
3683 // but since mangleType(VectorType*) always calls mangleArtificialTagType()
3684 // just always return true (the other vector types are clang-only).
3685 return true;
3686 }
3687 }
3688}
3689
3690void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,
3691 SourceRange Range) {
3692 QualType EltTy = T->getElementType();
3693 const BuiltinType *ET = EltTy->getAs<BuiltinType>();
3694 const BitIntType *BitIntTy = EltTy->getAs<BitIntType>();
3695 assert((ET || BitIntTy) &&
3696 "vectors with non-builtin/_BitInt elements are unsupported");
3697 uint64_t Width = getASTContext().getTypeSize(T);
3698 // Pattern match exactly the typedefs in our intrinsic headers. Anything that
3699 // doesn't match the Intel types uses a custom mangling below.
3700 size_t OutSizeBefore = Out.tell();
3701 if (!isa<ExtVectorType>(T)) {
3702 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
3703 if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {
3704 mangleArtificialTagType(TagTypeKind::Union, "__m64");
3705 } else if (Width >= 128) {
3706 if (ET->getKind() == BuiltinType::Float)
3707 mangleArtificialTagType(TagTypeKind::Union,
3708 "__m" + llvm::utostr(Width));
3709 else if (ET->getKind() == BuiltinType::LongLong)
3710 mangleArtificialTagType(TagTypeKind::Union,
3711 "__m" + llvm::utostr(Width) + 'i');
3712 else if (ET->getKind() == BuiltinType::Double)
3713 mangleArtificialTagType(TagTypeKind::Struct,
3714 "__m" + llvm::utostr(Width) + 'd');
3715 }
3716 }
3717 }
3718
3719 bool IsBuiltin = Out.tell() != OutSizeBefore;
3720 if (!IsBuiltin) {
3721 // The MS ABI doesn't have a special mangling for vector types, so we define
3722 // our own mangling to handle uses of __vector_size__ on user-specified
3723 // types, and for extensions like __v4sf.
3724
3725 llvm::SmallString<64> TemplateMangling;
3726 llvm::raw_svector_ostream Stream(TemplateMangling);
3727 MicrosoftCXXNameMangler Extra(Context, Stream);
3728 Stream << "?$";
3729 Extra.mangleSourceName("__vector");
3730 Extra.mangleType(QualType(ET ? static_cast<const Type *>(ET) : BitIntTy, 0),
3731 Range, QMM_Escape);
3732 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()));
3733
3734 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {"__clang"});
3735 }
3736}
3737
3738void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T,
3739 Qualifiers Quals, SourceRange Range) {
3740 mangleType(static_cast<const VectorType *>(T), Quals, Range);
3741}
3742
3743void MicrosoftCXXNameMangler::mangleType(const DependentVectorType *T,
3744 Qualifiers, SourceRange Range) {
3745 Error(Range.getBegin(), "dependent-sized vector type") << Range;
3746}
3747
3748void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,
3749 Qualifiers, SourceRange Range) {
3750 Error(Range.getBegin(), "dependent-sized extended vector type") << Range;
3751}
3752
3753void MicrosoftCXXNameMangler::mangleType(const ConstantMatrixType *T,
3754 Qualifiers quals, SourceRange Range) {
3755 QualType EltTy = T->getElementType();
3756
3757 llvm::SmallString<64> TemplateMangling;
3758 llvm::raw_svector_ostream Stream(TemplateMangling);
3759 MicrosoftCXXNameMangler Extra(Context, Stream);
3760
3761 Stream << "?$";
3762
3763 Extra.mangleSourceName("__matrix");
3764 Extra.mangleType(EltTy, Range, QMM_Escape);
3765
3766 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumRows()));
3767 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumColumns()));
3768
3769 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3770}
3771
3772void MicrosoftCXXNameMangler::mangleType(const DependentSizedMatrixType *T,
3773 Qualifiers quals, SourceRange Range) {
3774 Error(Range.getBegin(), "dependent-sized matrix type") << Range;
3775}
3776
3777void MicrosoftCXXNameMangler::mangleType(const DependentAddressSpaceType *T,
3778 Qualifiers, SourceRange Range) {
3779 Error(Range.getBegin(), "dependent address space type") << Range;
3780}
3781
3782void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,
3783 SourceRange) {
3784 // ObjC interfaces have structs underlying them.
3785 mangleTagTypeKind(TagTypeKind::Struct);
3786 mangleName(T->getDecl());
3787}
3788
3789void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,
3790 Qualifiers Quals, SourceRange Range) {
3791 if (T->isKindOfType())
3792 return mangleObjCKindOfType(T, Quals, Range);
3793
3794 if (T->qual_empty() && !T->isSpecialized())
3795 return mangleType(T->getBaseType(), Range, QMM_Drop);
3796
3797 ArgBackRefMap OuterFunArgsContext;
3798 ArgBackRefMap OuterTemplateArgsContext;
3799 BackRefVec OuterTemplateContext;
3800
3801 FunArgBackReferences.swap(OuterFunArgsContext);
3802 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3803 NameBackReferences.swap(OuterTemplateContext);
3804
3805 mangleTagTypeKind(TagTypeKind::Struct);
3806
3807 Out << "?$";
3808 if (T->isObjCId())
3809 mangleSourceName("objc_object");
3810 else if (T->isObjCClass())
3811 mangleSourceName("objc_class");
3812 else
3813 mangleSourceName(T->getInterface()->getName());
3814
3815 for (const auto &Q : T->quals())
3816 mangleObjCProtocol(Q);
3817
3818 if (T->isSpecialized())
3819 for (const auto &TA : T->getTypeArgs())
3820 mangleType(TA, Range, QMM_Drop);
3821
3822 Out << '@';
3823
3824 Out << '@';
3825
3826 FunArgBackReferences.swap(OuterFunArgsContext);
3827 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3828 NameBackReferences.swap(OuterTemplateContext);
3829}
3830
3831void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T,
3832 Qualifiers Quals, SourceRange Range) {
3833 QualType PointeeType = T->getPointeeType();
3834 manglePointerCVQualifiers(Quals);
3835 manglePointerExtQualifiers(Quals, PointeeType);
3836
3837 Out << "_E";
3838
3839 mangleFunctionType(PointeeType->castAs<FunctionProtoType>());
3840}
3841
3842void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *,
3843 Qualifiers, SourceRange) {
3844 llvm_unreachable("Cannot mangle injected class name type.");
3845}
3846
3847void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T,
3848 Qualifiers, SourceRange Range) {
3849 Error(Range.getBegin(), "template specialization type") << Range;
3850}
3851
3852void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T, Qualifiers,
3853 SourceRange Range) {
3854 Error(Range.getBegin(), "dependent name type") << Range;
3855}
3856
3857void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T, Qualifiers,
3858 SourceRange Range) {
3859 Error(Range.getBegin(), "pack expansion") << Range;
3860}
3861
3862void MicrosoftCXXNameMangler::mangleType(const PackIndexingType *T,
3863 Qualifiers Quals, SourceRange Range) {
3864 manglePointerCVQualifiers(Quals);
3865 mangleType(T->getSelectedType(), Range);
3866}
3867
3868void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T, Qualifiers,
3869 SourceRange Range) {
3870 Error(Range.getBegin(), "typeof(type)") << Range;
3871}
3872
3873void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T, Qualifiers,
3874 SourceRange Range) {
3875 Error(Range.getBegin(), "typeof(expression)") << Range;
3876}
3877
3878void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T, Qualifiers,
3879 SourceRange Range) {
3880 Error(Range.getBegin(), "decltype()") << Range;
3881}
3882
3883void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T,
3884 Qualifiers, SourceRange Range) {
3885 Error(Range.getBegin(), "unary transform type") << Range;
3886}
3887
3888void MicrosoftCXXNameMangler::mangleType(const AutoType *T, Qualifiers,
3889 SourceRange Range) {
3890 assert(T->getDeducedType().isNull() && "expecting a dependent type!");
3891
3892 Error(Range.getBegin(), "'auto' type") << Range;
3893}
3894
3895void MicrosoftCXXNameMangler::mangleType(
3896 const DeducedTemplateSpecializationType *T, Qualifiers, SourceRange Range) {
3897 assert(T->getDeducedType().isNull() && "expecting a dependent type!");
3898
3899 Error(Range.getBegin(), "deduced class template specialization type")
3900 << Range;
3901}
3902
3903void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers,
3904 SourceRange Range) {
3905 QualType ValueType = T->getValueType();
3906
3907 llvm::SmallString<64> TemplateMangling;
3908 llvm::raw_svector_ostream Stream(TemplateMangling);
3909 MicrosoftCXXNameMangler Extra(Context, Stream);
3910 Stream << "?$";
3911 Extra.mangleSourceName("_Atomic");
3912 Extra.mangleType(ValueType, Range, QMM_Escape);
3913
3914 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3915}
3916
3917void MicrosoftCXXNameMangler::mangleType(const PipeType *T, Qualifiers,
3918 SourceRange Range) {
3919 QualType ElementType = T->getElementType();
3920
3921 llvm::SmallString<64> TemplateMangling;
3922 llvm::raw_svector_ostream Stream(TemplateMangling);
3923 MicrosoftCXXNameMangler Extra(Context, Stream);
3924 Stream << "?$";
3925 Extra.mangleSourceName("ocl_pipe");
3926 Extra.mangleType(ElementType, Range, QMM_Escape);
3927 Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()));
3928
3929 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3930}
3931
3932void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
3933 raw_ostream &Out) {
3934 const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
3935 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
3936 getASTContext().getSourceManager(),
3937 "Mangling declaration");
3938
3939 msvc_hashing_ostream MHO(Out);
3940
3941 if (auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3942 auto Type = GD.getCtorType();
3943 MicrosoftCXXNameMangler mangler(*this, MHO, CD, Type);
3944 return mangler.mangle(GD);
3945 }
3946
3947 if (auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3948 auto Type = GD.getDtorType();
3949 MicrosoftCXXNameMangler mangler(*this, MHO, DD, Type);
3950 return mangler.mangle(GD);
3951 }
3952
3953 MicrosoftCXXNameMangler Mangler(*this, MHO);
3954 return Mangler.mangle(GD);
3955}
3956
3957void MicrosoftCXXNameMangler::mangleType(const BitIntType *T, Qualifiers,
3958 SourceRange Range) {
3959 llvm::SmallString<64> TemplateMangling;
3960 llvm::raw_svector_ostream Stream(TemplateMangling);
3961 MicrosoftCXXNameMangler Extra(Context, Stream);
3962 Stream << "?$";
3963 if (T->isUnsigned())
3964 Extra.mangleSourceName("_UBitInt");
3965 else
3966 Extra.mangleSourceName("_BitInt");
3967 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()));
3968
3969 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3970}
3971
3972void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,
3973 Qualifiers, SourceRange Range) {
3974 Error(Range.getBegin(), "DependentBitInt type") << Range;
3975}
3976
3977void MicrosoftCXXNameMangler::mangleType(const HLSLAttributedResourceType *T,
3978 Qualifiers, SourceRange Range) {
3979 llvm_unreachable("HLSL uses Itanium name mangling");
3980}
3981
3982void MicrosoftCXXNameMangler::mangleType(const HLSLInlineSpirvType *T,
3983 Qualifiers, SourceRange Range) {
3984 llvm_unreachable("HLSL uses Itanium name mangling");
3985}
3986
3987void MicrosoftCXXNameMangler::mangleType(const OverflowBehaviorType *T,
3988 Qualifiers, SourceRange Range) {
3989 QualType UnderlyingType = T->getUnderlyingType();
3990
3991 llvm::SmallString<64> TemplateMangling;
3992 llvm::raw_svector_ostream Stream(TemplateMangling);
3993 MicrosoftCXXNameMangler Extra(Context, Stream);
3994 Stream << "?$";
3995 if (T->isWrapKind()) {
3996 Extra.mangleSourceName("ObtWrap_");
3997 } else {
3998 Extra.mangleSourceName("ObtTrap_");
3999 }
4000 Extra.mangleType(UnderlyingType, Range, QMM_Escape);
4001
4002 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
4003}
4004
4005// <this-adjustment> ::= <no-adjustment> | <static-adjustment> |
4006// <virtual-adjustment>
4007// <no-adjustment> ::= A # private near
4008// ::= B # private far
4009// ::= I # protected near
4010// ::= J # protected far
4011// ::= Q # public near
4012// ::= R # public far
4013// <static-adjustment> ::= G <static-offset> # private near
4014// ::= H <static-offset> # private far
4015// ::= O <static-offset> # protected near
4016// ::= P <static-offset> # protected far
4017// ::= W <static-offset> # public near
4018// ::= X <static-offset> # public far
4019// <virtual-adjustment> ::= $0 <virtual-shift> <static-offset> # private near
4020// ::= $1 <virtual-shift> <static-offset> # private far
4021// ::= $2 <virtual-shift> <static-offset> # protected near
4022// ::= $3 <virtual-shift> <static-offset> # protected far
4023// ::= $4 <virtual-shift> <static-offset> # public near
4024// ::= $5 <virtual-shift> <static-offset> # public far
4025// <virtual-shift> ::= <vtordisp-shift> | <vtordispex-shift>
4026// <vtordisp-shift> ::= <offset-to-vtordisp>
4027// <vtordispex-shift> ::= <offset-to-vbptr> <vbase-offset-offset>
4028// <offset-to-vtordisp>
4030 const ThisAdjustment &Adjustment,
4031 MicrosoftCXXNameMangler &Mangler,
4032 raw_ostream &Out) {
4033 if (!Adjustment.Virtual.isEmpty()) {
4034 Out << '$';
4035 char AccessSpec;
4036 switch (AS) {
4037 case AS_none:
4038 llvm_unreachable("Unsupported access specifier");
4039 case AS_private:
4040 AccessSpec = '0';
4041 break;
4042 case AS_protected:
4043 AccessSpec = '2';
4044 break;
4045 case AS_public:
4046 AccessSpec = '4';
4047 }
4048 if (Adjustment.Virtual.Microsoft.VBPtrOffset) {
4049 Out << 'R' << AccessSpec;
4050 Mangler.mangleNumber(
4051 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBPtrOffset));
4052 Mangler.mangleNumber(
4053 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBOffsetOffset));
4054 Mangler.mangleNumber(
4055 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));
4056 Mangler.mangleNumber(static_cast<uint32_t>(Adjustment.NonVirtual));
4057 } else {
4058 Out << AccessSpec;
4059 Mangler.mangleNumber(
4060 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));
4061 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
4062 }
4063 } else if (Adjustment.NonVirtual != 0) {
4064 switch (AS) {
4065 case AS_none:
4066 llvm_unreachable("Unsupported access specifier");
4067 case AS_private:
4068 Out << 'G';
4069 break;
4070 case AS_protected:
4071 Out << 'O';
4072 break;
4073 case AS_public:
4074 Out << 'W';
4075 }
4076 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
4077 } else {
4078 switch (AS) {
4079 case AS_none:
4080 llvm_unreachable("Unsupported access specifier");
4081 case AS_private:
4082 Out << 'A';
4083 break;
4084 case AS_protected:
4085 Out << 'I';
4086 break;
4087 case AS_public:
4088 Out << 'Q';
4089 }
4090 }
4091}
4092
4093void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
4094 const CXXMethodDecl *MD, const MethodVFTableLocation &ML,
4095 raw_ostream &Out) {
4096 msvc_hashing_ostream MHO(Out);
4097 MicrosoftCXXNameMangler Mangler(*this, MHO);
4098 Mangler.getStream() << '?';
4099 Mangler.mangleVirtualMemPtrThunk(MD, ML);
4100}
4101
4102void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
4103 const ThunkInfo &Thunk,
4104 bool /*ElideOverrideInfo*/,
4105 raw_ostream &Out) {
4106 msvc_hashing_ostream MHO(Out);
4107 MicrosoftCXXNameMangler Mangler(*this, MHO);
4108 Mangler.getStream() << '?';
4109 Mangler.mangleName(MD);
4110
4111 // Usually the thunk uses the access specifier of the new method, but if this
4112 // is a covariant return thunk, then MSVC always uses the public access
4113 // specifier, and we do the same.
4114 AccessSpecifier AS = Thunk.Return.isEmpty() ? MD->getAccess() : AS_public;
4115 mangleThunkThisAdjustment(AS, Thunk.This, Mangler, MHO);
4116
4117 if (!Thunk.Return.isEmpty())
4118 assert(Thunk.Method != nullptr &&
4119 "Thunk info should hold the overridee decl");
4120
4121 const CXXMethodDecl *DeclForFPT = Thunk.Method ? Thunk.Method : MD;
4122 Mangler.mangleFunctionType(
4123 DeclForFPT->getType()->castAs<FunctionProtoType>(), MD);
4124}
4125
4126void MicrosoftMangleContextImpl::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
4128 const ThunkInfo &Thunk,
4129 bool /*ElideOverrideInfo*/,
4130 raw_ostream &Out) {
4131 // The dtor thunk should use vector deleting dtor mangling, however as an
4132 // optimization we may end up emitting only scalar deleting dtor body, so just
4133 // use the vector deleting dtor mangling manually.
4134 assert(Type == Dtor_Deleting || Type == Dtor_VectorDeleting);
4135 msvc_hashing_ostream MHO(Out);
4136 MicrosoftCXXNameMangler Mangler(*this, MHO, DD, Type);
4137 Mangler.getStream() << "??_E";
4138 Mangler.mangleName(DD->getParent());
4139 auto &Adjustment = Thunk.This;
4140 mangleThunkThisAdjustment(DD->getAccess(), Adjustment, Mangler, MHO);
4141 Mangler.mangleFunctionType(DD->getType()->castAs<FunctionProtoType>(), DD);
4142}
4143
4144void MicrosoftMangleContextImpl::mangleCXXVFTable(
4145 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4146 raw_ostream &Out) {
4147 // <mangled-name> ::= ?_7 <class-name> <storage-class>
4148 // <cvr-qualifiers> [<name>] @
4149 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
4150 // is always '6' for vftables.
4151 msvc_hashing_ostream MHO(Out);
4152 MicrosoftCXXNameMangler Mangler(*this, MHO);
4153 if (Derived->hasAttr<DLLImportAttr>())
4154 Mangler.getStream() << "??_S";
4155 else
4156 Mangler.getStream() << "??_7";
4157 Mangler.mangleName(Derived);
4158 Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.
4159 for (const CXXRecordDecl *RD : BasePath)
4160 Mangler.mangleName(RD);
4161 Mangler.getStream() << '@';
4162}
4163
4164void MicrosoftMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *Derived,
4165 raw_ostream &Out) {
4166 // TODO: Determine appropriate mangling for MSABI
4167 mangleCXXVFTable(Derived, {}, Out);
4168}
4169
4170void MicrosoftMangleContextImpl::mangleCXXVBTable(
4171 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4172 raw_ostream &Out) {
4173 // <mangled-name> ::= ?_8 <class-name> <storage-class>
4174 // <cvr-qualifiers> [<name>] @
4175 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
4176 // is always '7' for vbtables.
4177 msvc_hashing_ostream MHO(Out);
4178 MicrosoftCXXNameMangler Mangler(*this, MHO);
4179 Mangler.getStream() << "??_8";
4180 Mangler.mangleName(Derived);
4181 Mangler.getStream() << "7B"; // '7' for vbtable, 'B' for const.
4182 for (const CXXRecordDecl *RD : BasePath)
4183 Mangler.mangleName(RD);
4184 Mangler.getStream() << '@';
4185}
4186
4187void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
4188 msvc_hashing_ostream MHO(Out);
4189 MicrosoftCXXNameMangler Mangler(*this, MHO);
4190 Mangler.getStream() << "??_R0";
4191 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4192 Mangler.getStream() << "@8";
4193}
4194
4195void MicrosoftMangleContextImpl::mangleCXXRTTIName(
4196 QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {
4197 Out << '.';
4198 // MSVC caps the length of the TypeDescriptor's name string the same way it
4199 // caps decorated names, substituting "??@<md5>@" for over-long names. The
4200 // leading '.' counts toward the 4096-character limit but is not part of
4201 // the hashed input, so the threshold is one lower than for symbols.
4202 msvc_hashing_ostream MHO(Out, /*Threshold=*/4095);
4203 MicrosoftCXXNameMangler Mangler(*this, MHO);
4204 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4205}
4206
4207void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
4208 const CXXRecordDecl *SrcRD, const CXXRecordDecl *DstRD, raw_ostream &Out) {
4209 msvc_hashing_ostream MHO(Out);
4210 MicrosoftCXXNameMangler Mangler(*this, MHO);
4211 Mangler.getStream() << "??_K";
4212 Mangler.mangleName(SrcRD);
4213 Mangler.getStream() << "$C";
4214 Mangler.mangleName(DstRD);
4215}
4216
4217void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, bool IsConst,
4218 bool IsVolatile,
4219 bool IsUnaligned,
4220 uint32_t NumEntries,
4221 raw_ostream &Out) {
4222 msvc_hashing_ostream MHO(Out);
4223 MicrosoftCXXNameMangler Mangler(*this, MHO);
4224 Mangler.getStream() << "_TI";
4225 if (IsConst)
4226 Mangler.getStream() << 'C';
4227 if (IsVolatile)
4228 Mangler.getStream() << 'V';
4229 if (IsUnaligned)
4230 Mangler.getStream() << 'U';
4231 Mangler.getStream() << NumEntries;
4232 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4233}
4234
4235void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
4236 QualType T, uint32_t NumEntries, raw_ostream &Out) {
4237 msvc_hashing_ostream MHO(Out);
4238 MicrosoftCXXNameMangler Mangler(*this, MHO);
4239 Mangler.getStream() << "_CTA";
4240 Mangler.getStream() << NumEntries;
4241 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4242}
4243
4244void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4245 QualType T, const CXXConstructorDecl *CD, CXXCtorType CT, uint32_t Size,
4246 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
4247 raw_ostream &Out) {
4248 MicrosoftCXXNameMangler Mangler(*this, Out);
4249 Mangler.getStream() << "_CT";
4250
4251 llvm::SmallString<64> RTTIMangling;
4252 {
4253 llvm::raw_svector_ostream Stream(RTTIMangling);
4254 msvc_hashing_ostream MHO(Stream);
4255 mangleCXXRTTI(T, MHO);
4256 }
4257 Mangler.getStream() << RTTIMangling;
4258
4259 // VS2015 and VS2017.1 omit the copy-constructor in the mangled name but
4260 // both older and newer versions include it.
4261 // FIXME: It is known that the Ctor is present in 2013, and in 2017.7
4262 // (_MSC_VER 1914) and newer, and that it's omitted in 2015 and 2017.4
4263 // (_MSC_VER 1911), but it's unknown when exactly it reappeared (1914?
4264 // Or 1912, 1913 already?).
4265 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4266 LangOptions::MSVC2015) &&
4267 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4268 LangOptions::MSVC2017_7);
4269 llvm::SmallString<64> CopyCtorMangling;
4270 if (!OmitCopyCtor && CD) {
4271 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4272 msvc_hashing_ostream MHO(Stream);
4273 mangleCXXName(GlobalDecl(CD, CT), MHO);
4274 }
4275 Mangler.getStream() << CopyCtorMangling;
4276
4277 Mangler.getStream() << Size;
4278 if (VBPtrOffset == -1) {
4279 if (NVOffset) {
4280 Mangler.getStream() << NVOffset;
4281 }
4282 } else {
4283 Mangler.getStream() << NVOffset;
4284 Mangler.getStream() << VBPtrOffset;
4285 Mangler.getStream() << VBIndex;
4286 }
4287}
4288
4289void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4290 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
4291 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
4292 msvc_hashing_ostream MHO(Out);
4293 MicrosoftCXXNameMangler Mangler(*this, MHO);
4294 Mangler.getStream() << "??_R1";
4295 Mangler.mangleNumber(NVOffset);
4296 Mangler.mangleNumber(VBPtrOffset);
4297 Mangler.mangleNumber(VBTableOffset);
4298 Mangler.mangleNumber(Flags);
4299 Mangler.mangleName(Derived);
4300 Mangler.getStream() << "8";
4301}
4302
4303void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4304 const CXXRecordDecl *Derived, raw_ostream &Out) {
4305 msvc_hashing_ostream MHO(Out);
4306 MicrosoftCXXNameMangler Mangler(*this, MHO);
4307 Mangler.getStream() << "??_R2";
4308 Mangler.mangleName(Derived);
4309 Mangler.getStream() << "8";
4310}
4311
4312void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4313 const CXXRecordDecl *Derived, raw_ostream &Out) {
4314 msvc_hashing_ostream MHO(Out);
4315 MicrosoftCXXNameMangler Mangler(*this, MHO);
4316 Mangler.getStream() << "??_R3";
4317 Mangler.mangleName(Derived);
4318 Mangler.getStream() << "8";
4319}
4320
4321void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4322 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4323 raw_ostream &Out) {
4324 // <mangled-name> ::= ?_R4 <class-name> <storage-class>
4325 // <cvr-qualifiers> [<name>] @
4326 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
4327 // is always '6' for vftables.
4328 llvm::SmallString<64> VFTableMangling;
4329 llvm::raw_svector_ostream Stream(VFTableMangling);
4330 mangleCXXVFTable(Derived, BasePath, Stream);
4331
4332 if (VFTableMangling.starts_with("??@")) {
4333 assert(VFTableMangling.ends_with("@"));
4334 Out << VFTableMangling << "??_R4@";
4335 return;
4336 }
4337
4338 assert(VFTableMangling.starts_with("??_7") ||
4339 VFTableMangling.starts_with("??_S"));
4340
4341 Out << "??_R4" << VFTableMangling.str().drop_front(4);
4342}
4343
4344void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4345 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4346 msvc_hashing_ostream MHO(Out);
4347 MicrosoftCXXNameMangler Mangler(*this, MHO);
4348 // The function body is in the same comdat as the function with the handler,
4349 // so the numbering here doesn't have to be the same across TUs.
4350 //
4351 // <mangled-name> ::= ?filt$ <filter-number> @0
4352 Mangler.getStream() << "?filt$" << SEHFilterIds[EnclosingDecl]++ << "@0@";
4353 Mangler.mangleName(EnclosingDecl);
4354}
4355
4356void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4357 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4358 msvc_hashing_ostream MHO(Out);
4359 MicrosoftCXXNameMangler Mangler(*this, MHO);
4360 // The function body is in the same comdat as the function with the handler,
4361 // so the numbering here doesn't have to be the same across TUs.
4362 //
4363 // <mangled-name> ::= ?fin$ <filter-number> @0
4364 Mangler.getStream() << "?fin$" << SEHFinallyIds[EnclosingDecl]++ << "@0@";
4365 Mangler.mangleName(EnclosingDecl);
4366}
4367
4368void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4369 QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {
4370 // This is just a made up unique string for the purposes of tbaa. undname
4371 // does *not* know how to demangle it.
4372 MicrosoftCXXNameMangler Mangler(*this, Out);
4373 Mangler.getStream() << '?';
4374 Mangler.mangleType(T.getCanonicalType(), SourceRange());
4375}
4376
4377void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4378 const VarDecl *VD, unsigned ManglingNumber, raw_ostream &Out) {
4379 msvc_hashing_ostream MHO(Out);
4380 MicrosoftCXXNameMangler Mangler(*this, MHO);
4381
4382 Mangler.getStream() << "?";
4383 Mangler.mangleSourceName("$RT" + llvm::utostr(ManglingNumber));
4384 Mangler.mangle(VD, "");
4385}
4386
4387void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4388 const VarDecl *VD, unsigned GuardNum, raw_ostream &Out) {
4389 msvc_hashing_ostream MHO(Out);
4390 MicrosoftCXXNameMangler Mangler(*this, MHO);
4391
4392 Mangler.getStream() << "?";
4393 Mangler.mangleSourceName("$TSS" + llvm::utostr(GuardNum));
4394 Mangler.mangleNestedName(VD);
4395 Mangler.getStream() << "@4HA";
4396}
4397
4398void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,
4399 raw_ostream &Out) {
4400 // <guard-name> ::= ?_B <postfix> @5 <scope-depth>
4401 // ::= ?__J <postfix> @5 <scope-depth>
4402 // ::= ?$S <guard-num> @ <postfix> @4IA
4403
4404 // The first mangling is what MSVC uses to guard static locals in inline
4405 // functions. It uses a different mangling in external functions to support
4406 // guarding more than 32 variables. MSVC rejects inline functions with more
4407 // than 32 static locals. We don't fully implement the second mangling
4408 // because those guards are not externally visible, and instead use LLVM's
4409 // default renaming when creating a new guard variable.
4410 msvc_hashing_ostream MHO(Out);
4411 MicrosoftCXXNameMangler Mangler(*this, MHO);
4412
4413 bool Visible = VD->isExternallyVisible();
4414 if (Visible) {
4415 Mangler.getStream() << (VD->getTLSKind() ? "??__J" : "??_B");
4416 } else {
4417 Mangler.getStream() << "?$S1@";
4418 }
4419 unsigned ScopeDepth = 0;
4420 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4421 // If we do not have a discriminator and are emitting a guard variable for
4422 // use at global scope, then mangling the nested name will not be enough to
4423 // remove ambiguities.
4424 Mangler.mangle(VD, "");
4425 else
4426 Mangler.mangleNestedName(VD);
4427 Mangler.getStream() << (Visible ? "@5" : "@4IA");
4428 if (ScopeDepth)
4429 Mangler.mangleNumber(ScopeDepth);
4430}
4431
4432void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D,
4433 char CharCode,
4434 raw_ostream &Out) {
4435 msvc_hashing_ostream MHO(Out);
4436 MicrosoftCXXNameMangler Mangler(*this, MHO);
4437 Mangler.getStream() << "??__" << CharCode;
4438 if (D->isStaticDataMember()) {
4439 Mangler.getStream() << '?';
4440 Mangler.mangleName(D);
4441 Mangler.mangleVariableEncoding(D);
4442 Mangler.getStream() << "@@";
4443 } else {
4444 Mangler.mangleName(D);
4445 }
4446 // This is the function class mangling. These stubs are global, non-variadic,
4447 // cdecl functions that return void and take no args.
4448 Mangler.getStream() << "YAXXZ";
4449}
4450
4451void MicrosoftMangleContextImpl::mangleDynamicInitializer(const VarDecl *D,
4452 raw_ostream &Out) {
4453 // <initializer-name> ::= ?__E <name> YAXXZ
4454 mangleInitFiniStub(D, 'E', Out);
4455}
4456
4457void
4458MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D,
4459 raw_ostream &Out) {
4460 // <destructor-name> ::= ?__F <name> YAXXZ
4461 mangleInitFiniStub(D, 'F', Out);
4462}
4463
4464void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
4465 raw_ostream &Out) {
4466 // <char-type> ::= 0 # char, char16_t, char32_t
4467 // # (little endian char data in mangling)
4468 // ::= 1 # wchar_t (big endian char data in mangling)
4469 //
4470 // <literal-length> ::= <non-negative integer> # the length of the literal
4471 //
4472 // <encoded-crc> ::= <hex digit>+ @ # crc of the literal including
4473 // # trailing null bytes
4474 //
4475 // <encoded-string> ::= <simple character> # uninteresting character
4476 // ::= '?$' <hex digit> <hex digit> # these two nibbles
4477 // # encode the byte for the
4478 // # character
4479 // ::= '?' [a-z] # \xe1 - \xfa
4480 // ::= '?' [A-Z] # \xc1 - \xda
4481 // ::= '?' [0-9] # [,/\:. \n\t'-]
4482 //
4483 // <literal> ::= '??_C@_' <char-type> <literal-length> <encoded-crc>
4484 // <encoded-string> '@'
4485 MicrosoftCXXNameMangler Mangler(*this, Out);
4486 Mangler.getStream() << "??_C@_";
4487
4488 // The actual string length might be different from that of the string literal
4489 // in cases like:
4490 // char foo[3] = "foobar";
4491 // char bar[42] = "foobar";
4492 // Where it is truncated or zero-padded to fit the array. This is the length
4493 // used for mangling, and any trailing null-bytes also need to be mangled.
4494 unsigned StringLength =
4495 getASTContext().getAsConstantArrayType(SL->getType())->getZExtSize();
4496 unsigned StringByteLength = StringLength * SL->getCharByteWidth();
4497
4498 // <char-type>: The "kind" of string literal is encoded into the mangled name.
4499 if (SL->isWide())
4500 Mangler.getStream() << '1';
4501 else
4502 Mangler.getStream() << '0';
4503
4504 // <literal-length>: The next part of the mangled name consists of the length
4505 // of the string in bytes.
4506 Mangler.mangleNumber(StringByteLength);
4507
4508 auto GetLittleEndianByte = [&SL](unsigned Index) {
4509 unsigned CharByteWidth = SL->getCharByteWidth();
4510 if (Index / CharByteWidth >= SL->getLength())
4511 return static_cast<char>(0);
4512 uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
4513 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4514 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4515 };
4516
4517 auto GetBigEndianByte = [&SL](unsigned Index) {
4518 unsigned CharByteWidth = SL->getCharByteWidth();
4519 if (Index / CharByteWidth >= SL->getLength())
4520 return static_cast<char>(0);
4521 uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
4522 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4523 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4524 };
4525
4526 // CRC all the bytes of the StringLiteral.
4527 llvm::JamCRC JC;
4528 for (unsigned I = 0, E = StringByteLength; I != E; ++I)
4529 JC.update(GetLittleEndianByte(I));
4530
4531 // <encoded-crc>: The CRC is encoded utilizing the standard number mangling
4532 // scheme.
4533 Mangler.mangleNumber(JC.getCRC());
4534
4535 // <encoded-string>: The mangled name also contains the first 32 bytes
4536 // (including null-terminator bytes) of the encoded StringLiteral.
4537 // Each character is encoded by splitting them into bytes and then encoding
4538 // the constituent bytes.
4539 auto MangleByte = [&Mangler](char Byte) {
4540 // There are five different manglings for characters:
4541 // - [a-zA-Z0-9_$]: A one-to-one mapping.
4542 // - ?[a-z]: The range from \xe1 to \xfa.
4543 // - ?[A-Z]: The range from \xc1 to \xda.
4544 // - ?[0-9]: The set of [,/\:. \n\t'-].
4545 // - ?$XX: A fallback which maps nibbles.
4546 if (isAsciiIdentifierContinue(Byte, /*AllowDollar=*/true)) {
4547 Mangler.getStream() << Byte;
4548 } else if (isLetter(Byte & 0x7f)) {
4549 Mangler.getStream() << '?' << static_cast<char>(Byte & 0x7f);
4550 } else {
4551 const char SpecialChars[] = {',', '/', '\\', ':', '.',
4552 ' ', '\n', '\t', '\'', '-'};
4553 const char *Pos = llvm::find(SpecialChars, Byte);
4554 if (Pos != std::end(SpecialChars)) {
4555 Mangler.getStream() << '?' << (Pos - std::begin(SpecialChars));
4556 } else {
4557 Mangler.getStream() << "?$";
4558 Mangler.getStream() << static_cast<char>('A' + ((Byte >> 4) & 0xf));
4559 Mangler.getStream() << static_cast<char>('A' + (Byte & 0xf));
4560 }
4561 }
4562 };
4563
4564 // Enforce our 32 bytes max, except wchar_t which gets 32 chars instead.
4565 unsigned MaxBytesToMangle = SL->isWide() ? 64U : 32U;
4566 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4567 for (unsigned I = 0; I != NumBytesToMangle; ++I) {
4568 if (SL->isWide())
4569 MangleByte(GetBigEndianByte(I));
4570 else
4571 MangleByte(GetLittleEndianByte(I));
4572 }
4573
4574 Mangler.getStream() << '@';
4575}
4576
4577void MicrosoftCXXNameMangler::mangleAutoReturnType(const MemberPointerType *T,
4578 Qualifiers Quals) {
4579 QualType PointeeType = T->getPointeeType();
4580 manglePointerCVQualifiers(Quals);
4581 manglePointerExtQualifiers(Quals, PointeeType);
4582 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
4583 Out << '8';
4584 mangleName(T->getMostRecentCXXRecordDecl());
4585 mangleFunctionType(FPT, nullptr, true);
4586 } else {
4587 mangleQualifiers(PointeeType.getQualifiers(), true);
4588 mangleName(T->getMostRecentCXXRecordDecl());
4589 mangleAutoReturnType(PointeeType, QMM_Drop);
4590 }
4591}
4592
4593void MicrosoftCXXNameMangler::mangleAutoReturnType(const PointerType *T,
4594 Qualifiers Quals) {
4595 QualType PointeeType = T->getPointeeType();
4596 assert(!PointeeType.getQualifiers().hasAddressSpace() &&
4597 "Unexpected address space mangling required");
4598
4599 manglePointerCVQualifiers(Quals);
4600 manglePointerExtQualifiers(Quals, PointeeType);
4601
4602 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
4603 Out << '6';
4604 mangleFunctionType(FPT);
4605 } else {
4606 mangleAutoReturnType(PointeeType, QMM_Mangle);
4607 }
4608}
4609
4610void MicrosoftCXXNameMangler::mangleAutoReturnType(const LValueReferenceType *T,
4611 Qualifiers Quals) {
4612 QualType PointeeType = T->getPointeeType();
4613 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
4614 Out << 'A';
4615 manglePointerExtQualifiers(Quals, PointeeType);
4616 mangleAutoReturnType(PointeeType, QMM_Mangle);
4617}
4618
4619void MicrosoftCXXNameMangler::mangleAutoReturnType(const RValueReferenceType *T,
4620 Qualifiers Quals) {
4621 QualType PointeeType = T->getPointeeType();
4622 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
4623 Out << "$$Q";
4624 manglePointerExtQualifiers(Quals, PointeeType);
4625 mangleAutoReturnType(PointeeType, QMM_Mangle);
4626}
4627
4629 DiagnosticsEngine &Diags,
4630 bool IsAux) {
4631 return new MicrosoftMangleContextImpl(Context, Diags, IsAux);
4632}
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)
#define SM(sm)
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:861
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:3821
QualType getElementType() const
Definition TypeBase.h:3833
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4716
Kind getKind() const
Definition TypeBase.h:3277
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:2284
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:3915
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:2029
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2837
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition Decl.cpp:4291
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition Decl.cpp:3725
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition Decl.cpp:4307
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Definition Decl.cpp:3596
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4547
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5406
unsigned getNumParams() const
Definition TypeBase.h:5684
Qualifiers getMethodQuals() const
Definition TypeBase.h:5832
QualType getParamType(unsigned i) const
Definition TypeBase.h:5686
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition TypeBase.h:5903
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
Definition Type.cpp:3976
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5810
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition TypeBase.h:5840
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4602
CallingConv getCallConv() const
Definition TypeBase.h:4957
QualType getReturnType() const
Definition TypeBase.h:4942
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:3716
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3752
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:2084
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:3393
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:8529
QualType getCanonicalType() const
Definition TypeBase.h:8541
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8583
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:8521
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:3734
field_range fields() const
Definition Decl.h:4572
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
Definition Decl.h:4421
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.
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:3761
TagDecl * getDefinition() const
Returns the TagDecl that actually defines this struct/union/class/enum.
Definition Decl.cpp:4927
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition Decl.h:3998
TagKind getTagKind() const
Definition Decl.h:3961
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:8746
bool isVoidType() const
Definition TypeBase.h:9092
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:8825
bool isPointerType() const
Definition TypeBase.h:8726
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9386
bool isReferenceType() const
Definition TypeBase.h:8750
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:2964
bool isMemberDataPointerType() const
Definition TypeBase.h:8818
bool isMemberPointerType() const
Definition TypeBase.h:8807
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9372
bool isFunctionType() const
Definition TypeBase.h:8722
bool isAnyPointerType() const
Definition TypeBase.h:8734
TypeClass getTypeClass() const
Definition TypeBase.h:2446
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9319
bool isRecordType() const
Definition TypeBase.h:8853
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:2147
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2169
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:2224
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.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
CXXCtorType
C++ constructor types.
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:1796
@ RQ_None
No ref-qualifier was provided.
Definition TypeBase.h:1798
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition TypeBase.h:1801
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition TypeBase.h:1804
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:6030
@ Type
The name was classified as a type.
Definition Sema.h:564
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