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