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