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