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