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