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