clang 23.0.0git
MicrosoftMangle.cpp
Go to the documentation of this file.
1//===--- MicrosoftMangle.cpp - Microsoft Visual C++ Name Mangling ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This provides C++ name mangling targeting the Microsoft Visual C++ ABI.
10//
11//===----------------------------------------------------------------------===//
12
14#include "clang/AST/Attr.h"
16#include "clang/AST/CharUnits.h"
17#include "clang/AST/Decl.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/DeclObjC.h"
22#include "clang/AST/Expr.h"
23#include "clang/AST/ExprCXX.h"
25#include "clang/AST/Mangle.h"
27#include "clang/Basic/ABI.h"
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
1496 Out << "?_E";
1497 return;
1498 case Dtor_Comdat:
1499 llvm_unreachable("not expecting a COMDAT");
1500 case Dtor_Unified:
1501 llvm_unreachable("not expecting a unified dtor type");
1502 }
1503 llvm_unreachable("Unsupported dtor type?");
1504}
1505
1506void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
1507 SourceLocation Loc) {
1508 switch (OO) {
1509 // ?0 # constructor
1510 // ?1 # destructor
1511 // <operator-name> ::= ?2 # new
1512 case OO_New: Out << "?2"; break;
1513 // <operator-name> ::= ?3 # delete
1514 case OO_Delete: Out << "?3"; break;
1515 // <operator-name> ::= ?4 # =
1516 case OO_Equal: Out << "?4"; break;
1517 // <operator-name> ::= ?5 # >>
1518 case OO_GreaterGreater: Out << "?5"; break;
1519 // <operator-name> ::= ?6 # <<
1520 case OO_LessLess: Out << "?6"; break;
1521 // <operator-name> ::= ?7 # !
1522 case OO_Exclaim: Out << "?7"; break;
1523 // <operator-name> ::= ?8 # ==
1524 case OO_EqualEqual: Out << "?8"; break;
1525 // <operator-name> ::= ?9 # !=
1526 case OO_ExclaimEqual: Out << "?9"; break;
1527 // <operator-name> ::= ?A # []
1528 case OO_Subscript: Out << "?A"; break;
1529 // ?B # conversion
1530 // <operator-name> ::= ?C # ->
1531 case OO_Arrow: Out << "?C"; break;
1532 // <operator-name> ::= ?D # *
1533 case OO_Star: Out << "?D"; break;
1534 // <operator-name> ::= ?E # ++
1535 case OO_PlusPlus: Out << "?E"; break;
1536 // <operator-name> ::= ?F # --
1537 case OO_MinusMinus: Out << "?F"; break;
1538 // <operator-name> ::= ?G # -
1539 case OO_Minus: Out << "?G"; break;
1540 // <operator-name> ::= ?H # +
1541 case OO_Plus: Out << "?H"; break;
1542 // <operator-name> ::= ?I # &
1543 case OO_Amp: Out << "?I"; break;
1544 // <operator-name> ::= ?J # ->*
1545 case OO_ArrowStar: Out << "?J"; break;
1546 // <operator-name> ::= ?K # /
1547 case OO_Slash: Out << "?K"; break;
1548 // <operator-name> ::= ?L # %
1549 case OO_Percent: Out << "?L"; break;
1550 // <operator-name> ::= ?M # <
1551 case OO_Less: Out << "?M"; break;
1552 // <operator-name> ::= ?N # <=
1553 case OO_LessEqual: Out << "?N"; break;
1554 // <operator-name> ::= ?O # >
1555 case OO_Greater: Out << "?O"; break;
1556 // <operator-name> ::= ?P # >=
1557 case OO_GreaterEqual: Out << "?P"; break;
1558 // <operator-name> ::= ?Q # ,
1559 case OO_Comma: Out << "?Q"; break;
1560 // <operator-name> ::= ?R # ()
1561 case OO_Call: Out << "?R"; break;
1562 // <operator-name> ::= ?S # ~
1563 case OO_Tilde: Out << "?S"; break;
1564 // <operator-name> ::= ?T # ^
1565 case OO_Caret: Out << "?T"; break;
1566 // <operator-name> ::= ?U # |
1567 case OO_Pipe: Out << "?U"; break;
1568 // <operator-name> ::= ?V # &&
1569 case OO_AmpAmp: Out << "?V"; break;
1570 // <operator-name> ::= ?W # ||
1571 case OO_PipePipe: Out << "?W"; break;
1572 // <operator-name> ::= ?X # *=
1573 case OO_StarEqual: Out << "?X"; break;
1574 // <operator-name> ::= ?Y # +=
1575 case OO_PlusEqual: Out << "?Y"; break;
1576 // <operator-name> ::= ?Z # -=
1577 case OO_MinusEqual: Out << "?Z"; break;
1578 // <operator-name> ::= ?_0 # /=
1579 case OO_SlashEqual: Out << "?_0"; break;
1580 // <operator-name> ::= ?_1 # %=
1581 case OO_PercentEqual: Out << "?_1"; break;
1582 // <operator-name> ::= ?_2 # >>=
1583 case OO_GreaterGreaterEqual: Out << "?_2"; break;
1584 // <operator-name> ::= ?_3 # <<=
1585 case OO_LessLessEqual: Out << "?_3"; break;
1586 // <operator-name> ::= ?_4 # &=
1587 case OO_AmpEqual: Out << "?_4"; break;
1588 // <operator-name> ::= ?_5 # |=
1589 case OO_PipeEqual: Out << "?_5"; break;
1590 // <operator-name> ::= ?_6 # ^=
1591 case OO_CaretEqual: Out << "?_6"; break;
1592 // ?_7 # vftable
1593 // ?_8 # vbtable
1594 // ?_9 # vcall
1595 // ?_A # typeof
1596 // ?_B # local static guard
1597 // ?_C # string
1598 // ?_D # vbase destructor
1599 // ?_E # vector deleting destructor
1600 // ?_F # default constructor closure
1601 // ?_G # scalar deleting destructor
1602 // ?_H # vector constructor iterator
1603 // ?_I # vector destructor iterator
1604 // ?_J # vector vbase constructor iterator
1605 // ?_K # virtual displacement map
1606 // ?_L # eh vector constructor iterator
1607 // ?_M # eh vector destructor iterator
1608 // ?_N # eh vector vbase constructor iterator
1609 // ?_O # copy constructor closure
1610 // ?_P<name> # udt returning <name>
1611 // ?_Q # <unknown>
1612 // ?_R0 # RTTI Type Descriptor
1613 // ?_R1 # RTTI Base Class Descriptor at (a,b,c,d)
1614 // ?_R2 # RTTI Base Class Array
1615 // ?_R3 # RTTI Class Hierarchy Descriptor
1616 // ?_R4 # RTTI Complete Object Locator
1617 // ?_S # local vftable
1618 // ?_T # local vftable constructor closure
1619 // <operator-name> ::= ?_U # new[]
1620 case OO_Array_New: Out << "?_U"; break;
1621 // <operator-name> ::= ?_V # delete[]
1622 case OO_Array_Delete: Out << "?_V"; break;
1623 // <operator-name> ::= ?__L # co_await
1624 case OO_Coawait: Out << "?__L"; break;
1625 // <operator-name> ::= ?__M # <=>
1626 case OO_Spaceship: Out << "?__M"; break;
1627
1628 case OO_Conditional: {
1629 Error(Loc, "conditional operator");
1630 break;
1631 }
1632
1633 case OO_None:
1635 llvm_unreachable("Not an overloaded operator");
1636 }
1637}
1638
1639void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
1640 // <source name> ::= <identifier> @
1641 BackRefVec::iterator Found = llvm::find(NameBackReferences, Name);
1642 if (Found == NameBackReferences.end()) {
1643 if (NameBackReferences.size() < 10)
1644 NameBackReferences.push_back(std::string(Name));
1645 Out << Name << '@';
1646 } else {
1647 Out << (Found - NameBackReferences.begin());
1648 }
1649}
1650
1651void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
1652 Context.mangleObjCMethodNameAsSourceName(MD, Out);
1653}
1654
1655void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1656 GlobalDecl GD, const TemplateArgumentList &TemplateArgs) {
1657 // <template-name> ::= <unscoped-template-name> <template-args>
1658 // ::= <substitution>
1659 // Always start with the unqualified name.
1660
1661 // Templates have their own context for back references.
1662 ArgBackRefMap OuterFunArgsContext;
1663 ArgBackRefMap OuterTemplateArgsContext;
1664 BackRefVec OuterTemplateContext;
1665 PassObjectSizeArgsSet OuterPassObjectSizeArgs;
1666 NameBackReferences.swap(OuterTemplateContext);
1667 FunArgBackReferences.swap(OuterFunArgsContext);
1668 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1669 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1670
1671 mangleUnscopedTemplateName(GD);
1672 mangleTemplateArgs(cast<TemplateDecl>(GD.getDecl()), TemplateArgs);
1673
1674 // Restore the previous back reference contexts.
1675 NameBackReferences.swap(OuterTemplateContext);
1676 FunArgBackReferences.swap(OuterFunArgsContext);
1677 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
1678 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
1679}
1680
1681void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {
1682 // <unscoped-template-name> ::= ?$ <unqualified-name>
1683 Out << "?$";
1684 mangleUnqualifiedName(GD);
1685}
1686
1687void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1688 const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD,
1689 QualType TemplateArgType) {
1690 // <integer-literal> ::= $0 <number>
1691 // <integer-literal> ::= <auto-nttp>
1692 //
1693 // <auto-nttp> ::= $ M <type> 0 <number>
1694 Out << "$";
1695
1696 // Since MSVC 2019, add 'M[<type>]' after '$' for auto template parameter when
1697 // argument is integer.
1698 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1699 LangOptions::MSVC2019) &&
1700 PD && PD->getType()->getTypeClass() == Type::Auto &&
1701 !TemplateArgType.isNull()) {
1702 Out << "M";
1703 mangleType(TemplateArgType, SourceRange(), QMM_Drop);
1704 }
1705
1706 Out << "0";
1707
1708 mangleNumber(Value);
1709}
1710
1711void MicrosoftCXXNameMangler::mangleExpression(
1712 const Expr *E, const NonTypeTemplateParmDecl *PD) {
1713 // See if this is a constant expression.
1714 if (std::optional<llvm::APSInt> Value =
1715 E->getIntegerConstantExpr(Context.getASTContext())) {
1716 mangleIntegerLiteral(*Value, PD, E->getType());
1717 return;
1718 }
1719
1720 // As bad as this diagnostic is, it's better than crashing.
1721 Error(E->getExprLoc(), "expression type: ", E->getStmtClassName())
1722 << E->getSourceRange();
1723}
1724
1725void MicrosoftCXXNameMangler::mangleTemplateArgs(
1726 const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
1727 // <template-args> ::= <template-arg>+
1728 const TemplateParameterList *TPL = TD->getTemplateParameters();
1729 assert(TPL->size() == TemplateArgs.size() &&
1730 "size mismatch between args and parms!");
1731
1732 for (size_t i = 0; i < TemplateArgs.size(); ++i) {
1733 const TemplateArgument &TA = TemplateArgs[i];
1734
1735 // Separate consecutive packs by $$Z.
1736 if (i > 0 && TA.getKind() == TemplateArgument::Pack &&
1737 TemplateArgs[i - 1].getKind() == TemplateArgument::Pack)
1738 Out << "$$Z";
1739
1740 mangleTemplateArg(TD, TA, TPL->getParam(i));
1741 }
1742}
1743
1744/// If value V (with type T) represents a decayed pointer to the first element
1745/// of an array, return that array.
1747 // Must be a pointer...
1748 if (!T->isPointerType() || !V.isLValue() || !V.hasLValuePath() ||
1749 !V.getLValueBase())
1750 return nullptr;
1751 // ... to element 0 of an array.
1752 QualType BaseT = V.getLValueBase().getType();
1753 if (!BaseT->isArrayType() || V.getLValuePath().size() != 1 ||
1754 V.getLValuePath()[0].getAsArrayIndex() != 0)
1755 return nullptr;
1756 return const_cast<ValueDecl *>(
1757 V.getLValueBase().dyn_cast<const ValueDecl *>());
1758}
1759
1760void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
1761 const TemplateArgument &TA,
1762 const NamedDecl *Parm) {
1763 // <template-arg> ::= <type>
1764 // ::= <integer-literal>
1765 // ::= <member-data-pointer>
1766 // ::= <member-function-pointer>
1767 // ::= $ <constant-value>
1768 // ::= $ <auto-nttp-constant-value>
1769 // ::= <template-args>
1770 //
1771 // <auto-nttp-constant-value> ::= M <type> <constant-value>
1772 //
1773 // <constant-value> ::= 0 <number> # integer
1774 // ::= 1 <mangled-name> # address of D
1775 // ::= 2 <type> <typed-constant-value>* @ # struct
1776 // ::= 3 <type> <constant-value>* @ # array
1777 // ::= 4 ??? # string
1778 // ::= 5 <constant-value> @ # address of subobject
1779 // ::= 6 <constant-value> <unqualified-name> @ # a.b
1780 // ::= 7 <type> [<unqualified-name> <constant-value>] @
1781 // # union, with or without an active member
1782 // # pointer to member, symbolically
1783 // ::= 8 <class> <unqualified-name> @
1784 // ::= A <type> <non-negative integer> # float
1785 // ::= B <type> <non-negative integer> # double
1786 // # pointer to member, by component value
1787 // ::= F <number> <number>
1788 // ::= G <number> <number> <number>
1789 // ::= H <mangled-name> <number>
1790 // ::= I <mangled-name> <number> <number>
1791 // ::= J <mangled-name> <number> <number> <number>
1792 //
1793 // <typed-constant-value> ::= [<type>] <constant-value>
1794 //
1795 // The <type> appears to be included in a <typed-constant-value> only in the
1796 // '0', '1', '8', 'A', 'B', and 'E' cases.
1797
1798 switch (TA.getKind()) {
1800 llvm_unreachable("Can't mangle null template arguments!");
1802 llvm_unreachable("Can't mangle template expansion arguments!");
1804 QualType T = TA.getAsType();
1805 mangleType(T, SourceRange(), QMM_Escape);
1806 break;
1807 }
1809 const NamedDecl *ND = TA.getAsDecl();
1810 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1811 mangleMemberDataPointer(
1812 cast<CXXRecordDecl>(ND->getDeclContext())->getMostRecentDecl(),
1814 TA.getParamTypeForDecl());
1815 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1816 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1817 if (MD && MD->isInstance()) {
1818 mangleMemberFunctionPointer(MD->getParent()->getMostRecentDecl(), MD,
1820 TA.getParamTypeForDecl());
1821 } else {
1822 mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),
1823 TA.getParamTypeForDecl());
1824 }
1825 } else if (TA.getParamTypeForDecl()->isRecordType()) {
1826 Out << "$";
1827 auto *TPO = cast<TemplateParamObjectDecl>(ND);
1828 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
1829 TPO->getValue(), TplArgKind::ClassNTTP);
1830 } else if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1831 mangleVarDecl(VD, cast<NonTypeTemplateParmDecl>(Parm),
1832 TA.getParamTypeForDecl());
1833 } else {
1834 mangle(ND, "$1?");
1835 }
1836 break;
1837 }
1839 QualType T = TA.getIntegralType();
1840 mangleIntegerLiteral(TA.getAsIntegral(),
1842 break;
1843 }
1845 QualType T = TA.getNullPtrType();
1846 if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
1847 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1848 if (MPT->isMemberFunctionPointerType() &&
1850 mangleMemberFunctionPointer(RD, nullptr, nullptr, QualType());
1851 return;
1852 }
1853 if (MPT->isMemberDataPointer()) {
1854 if (!isa<FunctionTemplateDecl>(TD)) {
1855 mangleMemberDataPointer(RD, nullptr, nullptr, QualType());
1856 return;
1857 }
1858 // nullptr data pointers are always represented with a single field
1859 // which is initialized with either 0 or -1. Why -1? Well, we need to
1860 // distinguish the case where the data member is at offset zero in the
1861 // record.
1862 // However, we are free to use 0 *if* we would use multiple fields for
1863 // non-nullptr member pointers.
1864 if (!RD->nullFieldOffsetIsZero()) {
1865 mangleIntegerLiteral(llvm::APSInt::get(-1),
1867 return;
1868 }
1869 }
1870 }
1871 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1873 break;
1874 }
1876 if (ValueDecl *D = getAsArrayToPointerDecayedDecl(
1878 // Mangle the result of array-to-pointer decay as if it were a reference
1879 // to the original declaration, to match MSVC's behavior. This can result
1880 // in mangling collisions in some cases!
1881 return mangleTemplateArg(
1882 TD, TemplateArgument(D, TA.getStructuralValueType()), Parm);
1883 }
1884 Out << "$";
1886 ->getType()
1887 ->getContainedDeducedType()) {
1888 Out << "M";
1889 mangleType(TA.getNonTypeTemplateArgumentType(), SourceRange(), QMM_Drop);
1890 }
1891 mangleTemplateArgValue(TA.getStructuralValueType(),
1893 TplArgKind::StructuralValue,
1894 /*WithScalarType=*/false);
1895 break;
1897 mangleExpression(TA.getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
1898 break;
1900 ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();
1901 if (TemplateArgs.empty()) {
1902 if (isa<TemplateTypeParmDecl>(Parm) ||
1904 // MSVC 2015 changed the mangling for empty expanded template packs,
1905 // use the old mangling for link compatibility for old versions.
1906 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(
1907 LangOptions::MSVC2015)
1908 ? "$$V"
1909 : "$$$V");
1910 else if (isa<NonTypeTemplateParmDecl>(Parm))
1911 Out << "$S";
1912 else
1913 llvm_unreachable("unexpected template parameter decl!");
1914 } else {
1915 for (const TemplateArgument &PA : TemplateArgs)
1916 mangleTemplateArg(TD, PA, Parm);
1917 }
1918 break;
1919 }
1921 const NamedDecl *ND =
1923 if (const auto *TD = dyn_cast<TagDecl>(ND)) {
1924 mangleType(TD);
1925 } else if (isa<TypeAliasDecl>(ND)) {
1926 Out << "$$Y";
1927 mangleName(ND);
1928 } else {
1929 llvm_unreachable("unexpected template template NamedDecl!");
1930 }
1931 break;
1932 }
1933 }
1934}
1935
1936void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
1937 const APValue &V,
1938 TplArgKind TAK,
1939 bool WithScalarType) {
1940 switch (V.getKind()) {
1941 case APValue::None:
1943 // FIXME: MSVC doesn't allow this, so we can't be sure how it should be
1944 // mangled.
1945 if (WithScalarType)
1946 mangleType(T, SourceRange(), QMM_Escape);
1947 Out << '@';
1948 return;
1949
1950 case APValue::Int:
1951 if (WithScalarType)
1952 mangleType(T, SourceRange(), QMM_Escape);
1953 Out << '0';
1954 mangleNumber(V.getInt());
1955 return;
1956
1957 case APValue::Float:
1958 if (WithScalarType)
1959 mangleType(T, SourceRange(), QMM_Escape);
1960 mangleFloat(V.getFloat());
1961 return;
1962
1963 case APValue::LValue: {
1964 if (WithScalarType)
1965 mangleType(T, SourceRange(), QMM_Escape);
1966
1967 APValue::LValueBase Base = V.getLValueBase();
1968
1969 // this might not cover every case but did cover issue 97756
1970 // see test CodeGen/ms_mangler_templatearg_opte
1971 if (V.isLValueOnePastTheEnd()) {
1972 Out << "5E";
1973 auto *VD = Base.dyn_cast<const ValueDecl *>();
1974 if (VD)
1975 mangle(VD);
1976 Out << "@";
1977 return;
1978 }
1979
1980 if (!V.hasLValuePath() || V.getLValuePath().empty()) {
1981 // Taking the address of a complete object has a special-case mangling.
1982 if (Base.isNull()) {
1983 // MSVC emits 0A@ for null pointers. Generalize this for arbitrary
1984 // integers cast to pointers.
1985 // FIXME: This mangles 0 cast to a pointer the same as a null pointer,
1986 // even in cases where the two are different values.
1987 Out << "0";
1988 mangleNumber(V.getLValueOffset().getQuantity());
1989 } else if (!V.hasLValuePath()) {
1990 // FIXME: This can only happen as an extension. Invent a mangling.
1991 Error("template argument (extension not comaptible with ms mangler)");
1992 return;
1993 } else if (auto *VD = Base.dyn_cast<const ValueDecl*>()) {
1994 Out << "E";
1995 mangle(VD);
1996 } else {
1997 Error("template argument (undeclared base)");
1998 return;
1999 }
2000 } else {
2001 if (TAK == TplArgKind::ClassNTTP && T->isPointerType())
2002 Out << "5";
2003
2004 SmallVector<char, 2> EntryTypes;
2005 SmallVector<std::function<void()>, 2> EntryManglers;
2006 QualType ET = Base.getType();
2007 for (APValue::LValuePathEntry E : V.getLValuePath()) {
2008 if (auto *AT = ET->getAsArrayTypeUnsafe()) {
2009 EntryTypes.push_back('C');
2010 EntryManglers.push_back([this, I = E.getAsArrayIndex()] {
2011 Out << '0';
2012 mangleNumber(I);
2013 Out << '@';
2014 });
2015 ET = AT->getElementType();
2016 continue;
2017 }
2018
2019 const Decl *D = E.getAsBaseOrMember().getPointer();
2020 if (auto *FD = dyn_cast<FieldDecl>(D)) {
2021 ET = FD->getType();
2022 if (const auto *RD = ET->getAsRecordDecl())
2023 if (RD->isAnonymousStructOrUnion())
2024 continue;
2025 } else {
2026 ET = getASTContext().getCanonicalTagType(cast<CXXRecordDecl>(D));
2027 // Bug in MSVC: fully qualified name of base class should be used for
2028 // mangling to prevent collisions e.g. on base classes with same names
2029 // in different namespaces.
2030 }
2031
2032 EntryTypes.push_back('6');
2033 EntryManglers.push_back([this, D] {
2034 mangleUnqualifiedName(cast<NamedDecl>(D));
2035 Out << '@';
2036 });
2037 }
2038
2039 for (auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)
2040 Out << *I;
2041
2042 auto *VD = Base.dyn_cast<const ValueDecl*>();
2043 if (!VD) {
2044 Error("template argument (null value decl)");
2045 return;
2046 }
2047 Out << (TAK == TplArgKind::ClassNTTP ? 'E' : '1');
2048 mangle(VD);
2049
2050 for (const std::function<void()> &Mangler : EntryManglers)
2051 Mangler();
2052 if (TAK == TplArgKind::ClassNTTP && T->isPointerType())
2053 Out << '@';
2054 }
2055
2056 return;
2057 }
2058
2060 if (WithScalarType)
2061 mangleType(T, SourceRange(), QMM_Escape);
2062
2063 const CXXRecordDecl *RD =
2064 T->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
2065 const ValueDecl *D = V.getMemberPointerDecl();
2066 if (TAK == TplArgKind::ClassNTTP) {
2067 if (T->isMemberDataPointerType())
2068 mangleMemberDataPointerInClassNTTP(RD, D);
2069 else
2070 mangleMemberFunctionPointerInClassNTTP(RD,
2071 cast_or_null<CXXMethodDecl>(D));
2072 } else {
2073 if (T->isMemberDataPointerType())
2074 mangleMemberDataPointer(RD, D, nullptr, QualType(), "");
2075 else
2076 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D), nullptr,
2077 QualType(), "");
2078 }
2079 return;
2080 }
2081
2082 case APValue::Struct: {
2083 Out << '2';
2084 mangleType(T, SourceRange(), QMM_Escape);
2085 const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
2086 assert(RD && "unexpected type for record value");
2087
2088 unsigned BaseIndex = 0;
2089 for (const CXXBaseSpecifier &B : RD->bases())
2090 mangleTemplateArgValue(B.getType(), V.getStructBase(BaseIndex++), TAK);
2091 for (const FieldDecl *FD : RD->fields())
2092 if (!FD->isUnnamedBitField())
2093 mangleTemplateArgValue(FD->getType(),
2094 V.getStructField(FD->getFieldIndex()), TAK,
2095 /*WithScalarType*/ true);
2096 Out << '@';
2097 return;
2098 }
2099
2100 case APValue::Union:
2101 Out << '7';
2102 mangleType(T, SourceRange(), QMM_Escape);
2103 if (const FieldDecl *FD = V.getUnionField()) {
2104 mangleUnqualifiedName(FD);
2105 mangleTemplateArgValue(FD->getType(), V.getUnionValue(), TAK);
2106 }
2107 Out << '@';
2108 return;
2109
2111 // We mangle complex types as structs, so mangle the value as a struct too.
2112 Out << '2';
2113 mangleType(T, SourceRange(), QMM_Escape);
2114 Out << '0';
2115 mangleNumber(V.getComplexIntReal());
2116 Out << '0';
2117 mangleNumber(V.getComplexIntImag());
2118 Out << '@';
2119 return;
2120
2122 Out << '2';
2123 mangleType(T, SourceRange(), QMM_Escape);
2124 mangleFloat(V.getComplexFloatReal());
2125 mangleFloat(V.getComplexFloatImag());
2126 Out << '@';
2127 return;
2128
2129 case APValue::Array: {
2130 Out << '3';
2131 QualType ElemT = getASTContext().getAsArrayType(T)->getElementType();
2132 mangleType(ElemT, SourceRange(), QMM_Escape);
2133 for (unsigned I = 0, N = V.getArraySize(); I != N; ++I) {
2134 const APValue &ElemV = I < V.getArrayInitializedElts()
2135 ? V.getArrayInitializedElt(I)
2136 : V.getArrayFiller();
2137 mangleTemplateArgValue(ElemT, ElemV, TAK);
2138 Out << '@';
2139 }
2140 Out << '@';
2141 return;
2142 }
2143
2144 case APValue::Vector: {
2145 // __m128 is mangled as a struct containing an array. We follow this
2146 // approach for all vector types.
2147 Out << '2';
2148 mangleType(T, SourceRange(), QMM_Escape);
2149 Out << '3';
2150 QualType ElemT = T->castAs<VectorType>()->getElementType();
2151 mangleType(ElemT, SourceRange(), QMM_Escape);
2152 for (unsigned I = 0, N = V.getVectorLength(); I != N; ++I) {
2153 const APValue &ElemV = V.getVectorElt(I);
2154 mangleTemplateArgValue(ElemT, ElemV, TAK);
2155 Out << '@';
2156 }
2157 Out << "@@";
2158 return;
2159 }
2160
2162 Error("template argument (value type: address label diff)");
2163 return;
2164 }
2165
2166 case APValue::FixedPoint: {
2167 Error("template argument (value type: fixed point)");
2168 return;
2169 }
2170 }
2171}
2172
2173void MicrosoftCXXNameMangler::mangleObjCProtocol(const ObjCProtocolDecl *PD) {
2174 llvm::SmallString<64> TemplateMangling;
2175 llvm::raw_svector_ostream Stream(TemplateMangling);
2176 MicrosoftCXXNameMangler Extra(Context, Stream);
2177
2178 Stream << "?$";
2179 Extra.mangleSourceName("Protocol");
2180 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->getName());
2181
2182 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
2183}
2184
2185void MicrosoftCXXNameMangler::mangleObjCLifetime(const QualType Type,
2186 Qualifiers Quals,
2187 SourceRange Range) {
2188 llvm::SmallString<64> TemplateMangling;
2189 llvm::raw_svector_ostream Stream(TemplateMangling);
2190 MicrosoftCXXNameMangler Extra(Context, Stream);
2191
2192 Stream << "?$";
2193 switch (Quals.getObjCLifetime()) {
2196 break;
2198 Extra.mangleSourceName("Autoreleasing");
2199 break;
2201 Extra.mangleSourceName("Strong");
2202 break;
2204 Extra.mangleSourceName("Weak");
2205 break;
2206 }
2207 Extra.manglePointerCVQualifiers(Quals);
2208 Extra.manglePointerExtQualifiers(Quals, Type);
2209 Extra.mangleType(Type, Range);
2210
2211 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
2212}
2213
2214void MicrosoftCXXNameMangler::mangleObjCKindOfType(const ObjCObjectType *T,
2215 Qualifiers Quals,
2216 SourceRange Range) {
2217 llvm::SmallString<64> TemplateMangling;
2218 llvm::raw_svector_ostream Stream(TemplateMangling);
2219 MicrosoftCXXNameMangler Extra(Context, Stream);
2220
2221 Stream << "?$";
2222 Extra.mangleSourceName("KindOf");
2223 Extra.mangleType(QualType(T, 0)
2224 .stripObjCKindOfType(getASTContext())
2225 ->castAs<ObjCObjectType>(),
2226 Quals, Range);
2227
2228 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});
2229}
2230
2231void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
2232 bool IsMember) {
2233 // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>
2234 // 'E' means __ptr64 (32-bit only); 'F' means __unaligned (32/64-bit only);
2235 // 'I' means __restrict (32/64-bit).
2236 // Note that the MSVC __restrict keyword isn't the same as the C99 restrict
2237 // keyword!
2238 // <base-cvr-qualifiers> ::= A # near
2239 // ::= B # near const
2240 // ::= C # near volatile
2241 // ::= D # near const volatile
2242 // ::= E # far (16-bit)
2243 // ::= F # far const (16-bit)
2244 // ::= G # far volatile (16-bit)
2245 // ::= H # far const volatile (16-bit)
2246 // ::= I # huge (16-bit)
2247 // ::= J # huge const (16-bit)
2248 // ::= K # huge volatile (16-bit)
2249 // ::= L # huge const volatile (16-bit)
2250 // ::= M <basis> # based
2251 // ::= N <basis> # based const
2252 // ::= O <basis> # based volatile
2253 // ::= P <basis> # based const volatile
2254 // ::= Q # near member
2255 // ::= R # near const member
2256 // ::= S # near volatile member
2257 // ::= T # near const volatile member
2258 // ::= U # far member (16-bit)
2259 // ::= V # far const member (16-bit)
2260 // ::= W # far volatile member (16-bit)
2261 // ::= X # far const volatile member (16-bit)
2262 // ::= Y # huge member (16-bit)
2263 // ::= Z # huge const member (16-bit)
2264 // ::= 0 # huge volatile member (16-bit)
2265 // ::= 1 # huge const volatile member (16-bit)
2266 // ::= 2 <basis> # based member
2267 // ::= 3 <basis> # based const member
2268 // ::= 4 <basis> # based volatile member
2269 // ::= 5 <basis> # based const volatile member
2270 // ::= 6 # near function (pointers only)
2271 // ::= 7 # far function (pointers only)
2272 // ::= 8 # near method (pointers only)
2273 // ::= 9 # far method (pointers only)
2274 // ::= _A <basis> # based function (pointers only)
2275 // ::= _B <basis> # based function (far?) (pointers only)
2276 // ::= _C <basis> # based method (pointers only)
2277 // ::= _D <basis> # based method (far?) (pointers only)
2278 // ::= _E # block (Clang)
2279 // <basis> ::= 0 # __based(void)
2280 // ::= 1 # __based(segment)?
2281 // ::= 2 <name> # __based(name)
2282 // ::= 3 # ?
2283 // ::= 4 # ?
2284 // ::= 5 # not really based
2285 bool HasConst = Quals.hasConst(),
2286 HasVolatile = Quals.hasVolatile();
2287
2288 if (!IsMember) {
2289 if (HasConst && HasVolatile) {
2290 Out << 'D';
2291 } else if (HasVolatile) {
2292 Out << 'C';
2293 } else if (HasConst) {
2294 Out << 'B';
2295 } else {
2296 Out << 'A';
2297 }
2298 } else {
2299 if (HasConst && HasVolatile) {
2300 Out << 'T';
2301 } else if (HasVolatile) {
2302 Out << 'S';
2303 } else if (HasConst) {
2304 Out << 'R';
2305 } else {
2306 Out << 'Q';
2307 }
2308 }
2309
2310 // FIXME: For now, just drop all extension qualifiers on the floor.
2311}
2312
2313void
2314MicrosoftCXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {
2315 // <ref-qualifier> ::= G # lvalue reference
2316 // ::= H # rvalue-reference
2317 switch (RefQualifier) {
2318 case RQ_None:
2319 break;
2320
2321 case RQ_LValue:
2322 Out << 'G';
2323 break;
2324
2325 case RQ_RValue:
2326 Out << 'H';
2327 break;
2328 }
2329}
2330
2331void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
2332 QualType PointeeType) {
2333 // Check if this is a default 64-bit pointer or has __ptr64 qualifier.
2334 bool is64Bit = PointeeType.isNull() ? PointersAre64Bit :
2335 is64BitPointer(PointeeType.getQualifiers());
2336 if (is64Bit && (PointeeType.isNull() || !PointeeType->isFunctionType()))
2337 Out << 'E';
2338
2339 if (Quals.hasRestrict())
2340 Out << 'I';
2341
2342 if (Quals.hasUnaligned() ||
2343 (!PointeeType.isNull() && PointeeType.getLocalQualifiers().hasUnaligned()))
2344 Out << 'F';
2345}
2346
2347void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {
2348 PointerAuthQualifier PointerAuth = Quals.getPointerAuth();
2349 if (!PointerAuth)
2350 return;
2351
2352 Out << "__ptrauth";
2353 mangleNumber(PointerAuth.getKey());
2354 mangleNumber(PointerAuth.isAddressDiscriminated());
2355 mangleNumber(PointerAuth.getExtraDiscriminator());
2356}
2357
2358void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
2359 // <pointer-cv-qualifiers> ::= P # no qualifiers
2360 // ::= Q # const
2361 // ::= R # volatile
2362 // ::= S # const volatile
2363 bool HasConst = Quals.hasConst(),
2364 HasVolatile = Quals.hasVolatile();
2365
2366 if (HasConst && HasVolatile) {
2367 Out << 'S';
2368 } else if (HasVolatile) {
2369 Out << 'R';
2370 } else if (HasConst) {
2371 Out << 'Q';
2372 } else {
2373 Out << 'P';
2374 }
2375}
2376
2377void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType T,
2378 SourceRange Range) {
2379 // MSVC will backreference two canonically equivalent types that have slightly
2380 // different manglings when mangled alone.
2381
2382 // Decayed types do not match up with non-decayed versions of the same type.
2383 //
2384 // e.g.
2385 // void (*x)(void) will not form a backreference with void x(void)
2386 void *TypePtr;
2387 if (const auto *DT = T->getAs<DecayedType>()) {
2388 QualType OriginalType = DT->getOriginalType();
2389 // All decayed ArrayTypes should be treated identically; as-if they were
2390 // a decayed IncompleteArrayType.
2391 if (const auto *AT = getASTContext().getAsArrayType(OriginalType))
2392 OriginalType = getASTContext().getIncompleteArrayType(
2393 AT->getElementType(), AT->getSizeModifier(),
2394 AT->getIndexTypeCVRQualifiers());
2395
2396 TypePtr = OriginalType.getCanonicalType().getAsOpaquePtr();
2397 // If the original parameter was textually written as an array,
2398 // instead treat the decayed parameter like it's const.
2399 //
2400 // e.g.
2401 // int [] -> int * const
2402 if (OriginalType->isArrayType())
2403 T = T.withConst();
2404 } else {
2405 TypePtr = T.getCanonicalType().getAsOpaquePtr();
2406 }
2407
2408 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);
2409
2410 if (Found == FunArgBackReferences.end()) {
2411 size_t OutSizeBefore = Out.tell();
2412
2413 mangleType(T, Range, QMM_Drop);
2414
2415 // See if it's worth creating a back reference.
2416 // Only types longer than 1 character are considered
2417 // and only 10 back references slots are available:
2418 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);
2419 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {
2420 size_t Size = FunArgBackReferences.size();
2421 FunArgBackReferences[TypePtr] = Size;
2422 }
2423 } else {
2424 Out << Found->second;
2425 }
2426}
2427
2428void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
2429 const PassObjectSizeAttr *POSA) {
2430 int Type = POSA->getType();
2431 bool Dynamic = POSA->isDynamic();
2432
2433 auto Iter = PassObjectSizeArgs.insert({Type, Dynamic}).first;
2434 auto *TypePtr = (const void *)&*Iter;
2435 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);
2436
2437 if (Found == FunArgBackReferences.end()) {
2438 std::string Name =
2439 Dynamic ? "__pass_dynamic_object_size" : "__pass_object_size";
2440 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(Type),
2441 {"__clang"});
2442
2443 if (FunArgBackReferences.size() < 10) {
2444 size_t Size = FunArgBackReferences.size();
2445 FunArgBackReferences[TypePtr] = Size;
2446 }
2447 } else {
2448 Out << Found->second;
2449 }
2450}
2451
2452void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
2453 Qualifiers Quals,
2454 SourceRange Range) {
2455 // Address space is mangled as an unqualified templated type in the __clang
2456 // namespace. The demangled version of this is:
2457 // In the case of a language specific address space:
2458 // __clang::struct _AS[language_addr_space]<Type>
2459 // where:
2460 // <language_addr_space> ::= <OpenCL-addrspace> | <CUDA-addrspace>
2461 // <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" |
2462 // "private"| "generic" | "device" | "host" ]
2463 // <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
2464 // Note that the above were chosen to match the Itanium mangling for this.
2465 //
2466 // In the case of a non-language specific address space:
2467 // __clang::struct _AS<TargetAS, Type>
2468 assert(Quals.hasAddressSpace() && "Not valid without address space");
2469 llvm::SmallString<32> ASMangling;
2470 llvm::raw_svector_ostream Stream(ASMangling);
2471 MicrosoftCXXNameMangler Extra(Context, Stream);
2472 Stream << "?$";
2473
2474 LangAS AS = Quals.getAddressSpace();
2475 if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
2476 unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
2477 Extra.mangleSourceName("_AS");
2478 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
2479 } else {
2480 switch (AS) {
2481 default:
2482 llvm_unreachable("Not a language specific address space");
2483 case LangAS::opencl_global:
2484 Extra.mangleSourceName("_ASCLglobal");
2485 break;
2486 case LangAS::opencl_global_device:
2487 Extra.mangleSourceName("_ASCLdevice");
2488 break;
2489 case LangAS::opencl_global_host:
2490 Extra.mangleSourceName("_ASCLhost");
2491 break;
2492 case LangAS::opencl_local:
2493 Extra.mangleSourceName("_ASCLlocal");
2494 break;
2495 case LangAS::opencl_constant:
2496 Extra.mangleSourceName("_ASCLconstant");
2497 break;
2498 case LangAS::opencl_private:
2499 Extra.mangleSourceName("_ASCLprivate");
2500 break;
2501 case LangAS::opencl_generic:
2502 Extra.mangleSourceName("_ASCLgeneric");
2503 break;
2504 case LangAS::cuda_device:
2505 Extra.mangleSourceName("_ASCUdevice");
2506 break;
2507 case LangAS::cuda_constant:
2508 Extra.mangleSourceName("_ASCUconstant");
2509 break;
2510 case LangAS::cuda_shared:
2511 Extra.mangleSourceName("_ASCUshared");
2512 break;
2513 case LangAS::ptr32_sptr:
2514 case LangAS::ptr32_uptr:
2515 case LangAS::ptr64:
2516 llvm_unreachable("don't mangle ptr address spaces with _AS");
2517 }
2518 }
2519
2520 Extra.mangleType(T, Range, QMM_Escape);
2521 mangleQualifiers(Qualifiers(), false);
2522 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {"__clang"});
2523}
2524
2525void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T,
2526 QualifierMangleMode QMM) {
2527 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(
2528 LangOptions::MSVC2019) &&
2529 "Cannot mangle MSVC 2017 auto return types!");
2530
2531 if (isa<AutoType>(T)) {
2532 const auto *AT = T->getContainedAutoType();
2533 Qualifiers Quals = T.getLocalQualifiers();
2534
2535 if (QMM == QMM_Result)
2536 Out << '?';
2537 if (QMM != QMM_Drop)
2538 mangleQualifiers(Quals, false);
2539 Out << (AT->isDecltypeAuto() ? "_T" : "_P");
2540 return;
2541 }
2542
2543 T = T.getDesugaredType(getASTContext());
2544 Qualifiers Quals = T.getLocalQualifiers();
2545
2546 switch (QMM) {
2547 case QMM_Drop:
2548 case QMM_Result:
2549 break;
2550 case QMM_Mangle:
2551 mangleQualifiers(Quals, false);
2552 break;
2553 default:
2554 llvm_unreachable("QMM_Escape unexpected");
2555 }
2556
2557 const Type *ty = T.getTypePtr();
2558 switch (ty->getTypeClass()) {
2559 case Type::MemberPointer:
2560 mangleAutoReturnType(cast<MemberPointerType>(ty), Quals);
2561 break;
2562 case Type::Pointer:
2563 mangleAutoReturnType(cast<PointerType>(ty), Quals);
2564 break;
2565 case Type::LValueReference:
2566 mangleAutoReturnType(cast<LValueReferenceType>(ty), Quals);
2567 break;
2568 case Type::RValueReference:
2569 mangleAutoReturnType(cast<RValueReferenceType>(ty), Quals);
2570 break;
2571 default:
2572 llvm_unreachable("Invalid type expected");
2573 }
2574}
2575
2576void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
2577 QualifierMangleMode QMM) {
2578 // Don't use the canonical types. MSVC includes things like 'const' on
2579 // pointer arguments to function pointers that canonicalization strips away.
2580 T = T.getDesugaredType(getASTContext());
2581 Qualifiers Quals = T.getLocalQualifiers();
2582
2583 if (const ArrayType *AT = getASTContext().getAsArrayType(T)) {
2584 // If there were any Quals, getAsArrayType() pushed them onto the array
2585 // element type.
2586 if (QMM == QMM_Mangle)
2587 Out << 'A';
2588 else if (QMM == QMM_Escape || QMM == QMM_Result)
2589 Out << "$$B";
2590 mangleArrayType(AT);
2591 return;
2592 }
2593
2594 bool IsPointer = T->isAnyPointerType() || T->isMemberPointerType() ||
2596
2597 switch (QMM) {
2598 case QMM_Drop:
2599 if (Quals.hasObjCLifetime())
2600 Quals = Quals.withoutObjCLifetime();
2601 break;
2602 case QMM_Mangle:
2603 if (const FunctionType *FT = dyn_cast<FunctionType>(T)) {
2604 Out << '6';
2605 mangleFunctionType(FT);
2606 return;
2607 }
2608 mangleQualifiers(Quals, false);
2609 break;
2610 case QMM_Escape:
2611 if (!IsPointer && Quals) {
2612 Out << "$$C";
2613 mangleQualifiers(Quals, false);
2614 }
2615 break;
2616 case QMM_Result:
2617 // Presence of __unaligned qualifier shouldn't affect mangling here.
2618 Quals.removeUnaligned();
2619 if (Quals.hasObjCLifetime())
2620 Quals = Quals.withoutObjCLifetime();
2621 if ((!IsPointer && Quals) || isa<TagType>(T) || isArtificialTagType(T)) {
2622 Out << '?';
2623 mangleQualifiers(Quals, false);
2624 }
2625 break;
2626 }
2627
2628 const Type *ty = T.getTypePtr();
2629
2630 switch (ty->getTypeClass()) {
2631#define ABSTRACT_TYPE(CLASS, PARENT)
2632#define NON_CANONICAL_TYPE(CLASS, PARENT) \
2633 case Type::CLASS: \
2634 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
2635 return;
2636#define TYPE(CLASS, PARENT) \
2637 case Type::CLASS: \
2638 mangleType(cast<CLASS##Type>(ty), Quals, Range); \
2639 break;
2640#include "clang/AST/TypeNodes.inc"
2641#undef ABSTRACT_TYPE
2642#undef NON_CANONICAL_TYPE
2643#undef TYPE
2644 }
2645}
2646
2647void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
2648 SourceRange Range) {
2649 // <type> ::= <builtin-type>
2650 // <builtin-type> ::= X # void
2651 // ::= C # signed char
2652 // ::= D # char
2653 // ::= E # unsigned char
2654 // ::= F # short
2655 // ::= G # unsigned short (or wchar_t if it's not a builtin)
2656 // ::= H # int
2657 // ::= I # unsigned int
2658 // ::= J # long
2659 // ::= K # unsigned long
2660 // L # <none>
2661 // ::= M # float
2662 // ::= N # double
2663 // ::= O # long double (__float80 is mangled differently)
2664 // ::= _J # long long, __int64
2665 // ::= _K # unsigned long long, __int64
2666 // ::= _L # __int128
2667 // ::= _M # unsigned __int128
2668 // ::= _N # bool
2669 // _O # <array in parameter>
2670 // ::= _Q # char8_t
2671 // ::= _S # char16_t
2672 // ::= _T # __float80 (Intel)
2673 // ::= _U # char32_t
2674 // ::= _W # wchar_t
2675 // ::= _Z # __float80 (Digital Mars)
2676 switch (T->getKind()) {
2677 case BuiltinType::Void:
2678 Out << 'X';
2679 break;
2680 case BuiltinType::SChar:
2681 Out << 'C';
2682 break;
2683 case BuiltinType::Char_U:
2684 case BuiltinType::Char_S:
2685 Out << 'D';
2686 break;
2687 case BuiltinType::UChar:
2688 Out << 'E';
2689 break;
2690 case BuiltinType::Short:
2691 Out << 'F';
2692 break;
2693 case BuiltinType::UShort:
2694 Out << 'G';
2695 break;
2696 case BuiltinType::Int:
2697 Out << 'H';
2698 break;
2699 case BuiltinType::UInt:
2700 Out << 'I';
2701 break;
2702 case BuiltinType::Long:
2703 Out << 'J';
2704 break;
2705 case BuiltinType::ULong:
2706 Out << 'K';
2707 break;
2708 case BuiltinType::Float:
2709 Out << 'M';
2710 break;
2711 case BuiltinType::Double:
2712 Out << 'N';
2713 break;
2714 // TODO: Determine size and mangle accordingly
2715 case BuiltinType::LongDouble:
2716 Out << 'O';
2717 break;
2718 case BuiltinType::LongLong:
2719 Out << "_J";
2720 break;
2721 case BuiltinType::ULongLong:
2722 Out << "_K";
2723 break;
2724 case BuiltinType::Int128:
2725 Out << "_L";
2726 break;
2727 case BuiltinType::UInt128:
2728 Out << "_M";
2729 break;
2730 case BuiltinType::Bool:
2731 Out << "_N";
2732 break;
2733 case BuiltinType::Char8:
2734 Out << "_Q";
2735 break;
2736 case BuiltinType::Char16:
2737 Out << "_S";
2738 break;
2739 case BuiltinType::Char32:
2740 Out << "_U";
2741 break;
2742 case BuiltinType::WChar_S:
2743 case BuiltinType::WChar_U:
2744 Out << "_W";
2745 break;
2746
2747#define BUILTIN_TYPE(Id, SingletonId)
2748#define PLACEHOLDER_TYPE(Id, SingletonId) \
2749 case BuiltinType::Id:
2750#include "clang/AST/BuiltinTypes.def"
2751 case BuiltinType::Dependent:
2752 llvm_unreachable("placeholder types shouldn't get to name mangling");
2753
2754 case BuiltinType::ObjCId:
2755 mangleArtificialTagType(TagTypeKind::Struct, "objc_object");
2756 break;
2757 case BuiltinType::ObjCClass:
2758 mangleArtificialTagType(TagTypeKind::Struct, "objc_class");
2759 break;
2760 case BuiltinType::ObjCSel:
2761 mangleArtificialTagType(TagTypeKind::Struct, "objc_selector");
2762 break;
2763
2764#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2765 case BuiltinType::Id: \
2766 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \
2767 break;
2768#include "clang/Basic/OpenCLImageTypes.def"
2769 case BuiltinType::OCLSampler:
2770 Out << "PA";
2771 mangleArtificialTagType(TagTypeKind::Struct, "ocl_sampler");
2772 break;
2773 case BuiltinType::OCLEvent:
2774 Out << "PA";
2775 mangleArtificialTagType(TagTypeKind::Struct, "ocl_event");
2776 break;
2777 case BuiltinType::OCLClkEvent:
2778 Out << "PA";
2779 mangleArtificialTagType(TagTypeKind::Struct, "ocl_clkevent");
2780 break;
2781 case BuiltinType::OCLQueue:
2782 Out << "PA";
2783 mangleArtificialTagType(TagTypeKind::Struct, "ocl_queue");
2784 break;
2785 case BuiltinType::OCLReserveID:
2786 Out << "PA";
2787 mangleArtificialTagType(TagTypeKind::Struct, "ocl_reserveid");
2788 break;
2789#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2790 case BuiltinType::Id: \
2791 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \
2792 break;
2793#include "clang/Basic/OpenCLExtensionTypes.def"
2794
2795 case BuiltinType::NullPtr:
2796 Out << "$$T";
2797 break;
2798
2799 case BuiltinType::Float16:
2800 mangleArtificialTagType(TagTypeKind::Struct, "_Float16", {"__clang"});
2801 break;
2802
2803 case BuiltinType::Half:
2804 if (!getASTContext().getLangOpts().HLSL)
2805 mangleArtificialTagType(TagTypeKind::Struct, "_Half", {"__clang"});
2806 else if (getASTContext().getLangOpts().NativeHalfType)
2807 Out << "$f16@";
2808 else
2809 Out << "$halff@";
2810 break;
2811
2812 case BuiltinType::BFloat16:
2813 mangleArtificialTagType(TagTypeKind::Struct, "__bf16", {"__clang"});
2814 break;
2815
2816 case BuiltinType::MFloat8:
2817 mangleArtificialTagType(TagTypeKind::Struct, "__mfp8", {"__clang"});
2818 break;
2819
2820#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \
2821 case BuiltinType::Id: \
2822 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \
2823 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \
2824 break;
2825
2826#include "clang/Basic/WebAssemblyReferenceTypes.def"
2827
2828#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
2829 case BuiltinType::Id: \
2830 mangleArtificialTagType(TagTypeKind::Struct, #Name); \
2831 break;
2832#include "clang/Basic/HLSLIntangibleTypes.def"
2833
2834#define SVE_TYPE(Name, Id, SingletonId) \
2835 case BuiltinType::Id: \
2836 mangleArtificialTagType(TagTypeKind::Struct, #Name, {"__clang"}); \
2837 break;
2838#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits)
2839#include "clang/Basic/AArch64ACLETypes.def"
2840
2841 // Issue an error for any type not explicitly handled.
2842 default:
2843 Error(Range.getBegin(), "built-in type: ",
2844 T->getName(Context.getASTContext().getPrintingPolicy()))
2845 << Range;
2846 break;
2847 }
2848}
2849
2850// <type> ::= <function-type>
2851void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, Qualifiers,
2852 SourceRange) {
2853 // Structors only appear in decls, so at this point we know it's not a
2854 // structor type.
2855 // FIXME: This may not be lambda-friendly.
2856 if (T->getMethodQuals() || T->getRefQualifier() != RQ_None) {
2857 Out << "$$A8@@";
2858 mangleFunctionType(T, /*D=*/nullptr, /*ForceThisQuals=*/true);
2859 } else {
2860 Out << "$$A6";
2861 mangleFunctionType(T);
2862 }
2863}
2864void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
2865 Qualifiers, SourceRange) {
2866 Out << "$$A6";
2867 mangleFunctionType(T);
2868}
2869
2870void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
2871 const FunctionDecl *D,
2872 bool ForceThisQuals,
2873 bool MangleExceptionSpec) {
2874 // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
2875 // <return-type> <argument-list> <throw-spec>
2876 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);
2877
2878 SourceRange Range;
2879 if (D) Range = D->getSourceRange();
2880
2881 bool IsInLambda = false;
2882 bool IsStructor = false, HasThisQuals = ForceThisQuals, IsCtorClosure = false;
2883 CallingConv CC = T->getCallConv();
2884 if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
2885 if (MD->getParent()->isLambda())
2886 IsInLambda = true;
2888 HasThisQuals = true;
2889 if (isa<CXXDestructorDecl>(MD)) {
2890 IsStructor = true;
2891 } else if (isa<CXXConstructorDecl>(MD)) {
2892 IsStructor = true;
2893 IsCtorClosure = (StructorType == Ctor_CopyingClosure ||
2894 StructorType == Ctor_DefaultClosure) &&
2895 isStructorDecl(MD);
2896 if (IsCtorClosure)
2897 CC = getASTContext().getDefaultCallingConvention(
2898 /*IsVariadic=*/false, /*IsCXXMethod=*/true);
2899 }
2900 }
2901
2902 // If this is a C++ instance method, mangle the CVR qualifiers for the
2903 // this pointer.
2904 if (HasThisQuals) {
2905 Qualifiers Quals = Proto->getMethodQuals();
2906 manglePointerExtQualifiers(Quals, /*PointeeType=*/QualType());
2907 mangleRefQualifier(Proto->getRefQualifier());
2908 mangleQualifiers(Quals, /*IsMember=*/false);
2909 }
2910
2911 mangleCallingConvention(CC, Range);
2912
2913 // <return-type> ::= <type>
2914 // ::= @ # structors (they have no declared return type)
2915 if (IsStructor) {
2916 if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
2917 // The deleting destructors take an extra argument of type int that
2918 // indicates whether the storage for the object should be deleted and
2919 // whether a single object or an array of objects is being destroyed. This
2920 // extra argument is not reflected in the AST.
2921 if (StructorType == Dtor_Deleting ||
2922 StructorType == Dtor_VectorDeleting) {
2923 Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");
2924 return;
2925 }
2926 // The vbase destructor returns void which is not reflected in the AST.
2927 if (StructorType == Dtor_Complete) {
2928 Out << "XXZ";
2929 return;
2930 }
2931 }
2932 if (IsCtorClosure) {
2933 // Default constructor closure and copy constructor closure both return
2934 // void.
2935 Out << 'X';
2936
2937 if (StructorType == Ctor_DefaultClosure) {
2938 // Default constructor closure always has no arguments.
2939 Out << 'X';
2940 } else if (StructorType == Ctor_CopyingClosure) {
2941 // Copy constructor closure always takes an unqualified reference.
2942 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(
2943 Proto->getParamType(0)
2944 ->castAs<LValueReferenceType>()
2945 ->getPointeeType(),
2946 /*SpelledAsLValue=*/true),
2947 Range);
2948 Out << '@';
2949 } else {
2950 llvm_unreachable("unexpected constructor closure!");
2951 }
2952 Out << 'Z';
2953 return;
2954 }
2955 Out << '@';
2956 } else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(D)) {
2957 // The only lambda conversion operators are to function pointers, which
2958 // can differ by their calling convention and are typically deduced. So
2959 // we make sure that this type gets mangled properly.
2960 mangleType(T->getReturnType(), Range, QMM_Result);
2961 } else {
2962 QualType ResultType = T->getReturnType();
2963 if (IsInLambda && isa<CXXConversionDecl>(D)) {
2964 // The only lambda conversion operators are to function pointers, which
2965 // can differ by their calling convention and are typically deduced. So
2966 // we make sure that this type gets mangled properly.
2967 mangleType(ResultType, Range, QMM_Result);
2968 } else if (IsInLambda) {
2969 if (const auto *AT = ResultType->getContainedAutoType()) {
2970 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2971 "shouldn't need to mangle __auto_type!");
2972 Out << '?';
2973 mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
2974 Out << '?';
2975 mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
2976 Out << '@';
2977 } else {
2978 Out << '@';
2979 }
2980 } else if (const auto *AT = ResultType->getContainedAutoType()) {
2981 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
2982 "shouldn't need to mangle __auto_type!");
2983
2984 // If we have any pointer types with the clang address space extension
2985 // then defer to the custom clang mangling to keep backwards
2986 // compatibility. See `mangleType(const PointerType *T, Qualifiers Quals,
2987 // SourceRange Range)` for details.
2988 auto UseClangMangling = [](QualType ResultType) {
2989 QualType T = ResultType;
2990 while (isa<PointerType>(T.getTypePtr())) {
2991 T = T->getPointeeType();
2993 return true;
2994 }
2995 return false;
2996 };
2997
2998 if (getASTContext().getLangOpts().isCompatibleWithMSVC(
2999 LangOptions::MSVC2019) &&
3000 !UseClangMangling(ResultType)) {
3001 if (D && !D->getPrimaryTemplate()) {
3002 Out << '@';
3003 } else {
3004 if (D && D->getPrimaryTemplate()) {
3005 const FunctionProtoType *FPT = D->getPrimaryTemplate()
3007 ->getFirstDecl()
3008 ->getType()
3009 ->castAs<FunctionProtoType>();
3010 ResultType = FPT->getReturnType();
3011 }
3012 mangleAutoReturnType(ResultType, QMM_Result);
3013 }
3014 } else {
3015 Out << '?';
3016 mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
3017 Out << '?';
3018 mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
3019 Out << '@';
3020 }
3021 } else {
3022 if (ResultType->isVoidType())
3023 ResultType = ResultType.getUnqualifiedType();
3024 mangleType(ResultType, Range, QMM_Result);
3025 }
3026 }
3027
3028 // <argument-list> ::= X # void
3029 // ::= <type>+ @
3030 // ::= <type>* Z # varargs
3031 if (!Proto) {
3032 // Function types without prototypes can arise when mangling a function type
3033 // within an overloadable function in C. We mangle these as the absence of
3034 // any parameter types (not even an empty parameter list).
3035 Out << '@';
3036 } else if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
3037 Out << 'X';
3038 } else {
3039 // Happens for function pointer type arguments for example.
3040 for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) {
3041 // Explicit object parameters are prefixed by "_V".
3042 if (I == 0 && D && D->getParamDecl(I)->isExplicitObjectParameter())
3043 Out << "_V";
3044
3045 mangleFunctionArgumentType(Proto->getParamType(I), Range);
3046 // Mangle each pass_object_size parameter as if it's a parameter of enum
3047 // type passed directly after the parameter with the pass_object_size
3048 // attribute. The aforementioned enum's name is __pass_object_size, and we
3049 // pretend it resides in a top-level namespace called __clang.
3050 //
3051 // FIXME: Is there a defined extension notation for the MS ABI, or is it
3052 // necessary to just cross our fingers and hope this type+namespace
3053 // combination doesn't conflict with anything?
3054 if (D)
3055 if (const auto *P = D->getParamDecl(I)->getAttr<PassObjectSizeAttr>())
3056 manglePassObjectSizeArg(P);
3057 }
3058 // <builtin-type> ::= Z # ellipsis
3059 if (Proto->isVariadic())
3060 Out << 'Z';
3061 else
3062 Out << '@';
3063 }
3064
3065 if (MangleExceptionSpec && getASTContext().getLangOpts().CPlusPlus17 &&
3066 getASTContext().getLangOpts().isCompatibleWithMSVC(
3067 LangOptions::MSVC2017_5))
3068 mangleThrowSpecification(Proto);
3069 else
3070 Out << 'Z';
3071}
3072
3073void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
3074 // <function-class> ::= <member-function> E? # E designates a 64-bit 'this'
3075 // # pointer. in 64-bit mode *all*
3076 // # 'this' pointers are 64-bit.
3077 // ::= <global-function>
3078 // <member-function> ::= A # private: near
3079 // ::= B # private: far
3080 // ::= C # private: static near
3081 // ::= D # private: static far
3082 // ::= E # private: virtual near
3083 // ::= F # private: virtual far
3084 // ::= I # protected: near
3085 // ::= J # protected: far
3086 // ::= K # protected: static near
3087 // ::= L # protected: static far
3088 // ::= M # protected: virtual near
3089 // ::= N # protected: virtual far
3090 // ::= Q # public: near
3091 // ::= R # public: far
3092 // ::= S # public: static near
3093 // ::= T # public: static far
3094 // ::= U # public: virtual near
3095 // ::= V # public: virtual far
3096 // <global-function> ::= Y # global near
3097 // ::= Z # global far
3098 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
3099 bool IsVirtual = MD->isVirtual();
3100 // When mangling vbase destructor variants, ignore whether or not the
3101 // underlying destructor was defined to be virtual.
3102 if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
3103 StructorType == Dtor_Complete) {
3104 IsVirtual = false;
3105 }
3106 switch (MD->getAccess()) {
3107 case AS_none:
3108 llvm_unreachable("Unsupported access specifier");
3109 case AS_private:
3111 Out << 'C';
3112 else if (IsVirtual)
3113 Out << 'E';
3114 else
3115 Out << 'A';
3116 break;
3117 case AS_protected:
3119 Out << 'K';
3120 else if (IsVirtual)
3121 Out << 'M';
3122 else
3123 Out << 'I';
3124 break;
3125 case AS_public:
3127 Out << 'S';
3128 else if (IsVirtual)
3129 Out << 'U';
3130 else
3131 Out << 'Q';
3132 }
3133 } else {
3134 Out << 'Y';
3135 }
3136}
3137void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC,
3138 SourceRange Range) {
3139 // <calling-convention> ::= A # __cdecl
3140 // ::= B # __export __cdecl
3141 // ::= C # __pascal
3142 // ::= D # __export __pascal
3143 // ::= E # __thiscall
3144 // ::= F # __export __thiscall
3145 // ::= G # __stdcall
3146 // ::= H # __export __stdcall
3147 // ::= I # __fastcall
3148 // ::= J # __export __fastcall
3149 // ::= Q # __vectorcall
3150 // ::= S # __attribute__((__swiftcall__)) // Clang-only
3151 // ::= W # __attribute__((__swiftasynccall__))
3152 // ::= U # __attribute__((__preserve_most__))
3153 // ::= V # __attribute__((__preserve_none__)) //
3154 // Clang-only
3155 // // Clang-only
3156 // ::= w # __regcall
3157 // ::= x # __regcall4
3158 // The 'export' calling conventions are from a bygone era
3159 // (*cough*Win16*cough*) when functions were declared for export with
3160 // that keyword. (It didn't actually export them, it just made them so
3161 // that they could be in a DLL and somebody from another module could call
3162 // them.)
3163
3164 switch (CC) {
3165 default:
3166 break;
3167 case CC_Win64:
3168 case CC_X86_64SysV:
3169 case CC_C:
3170 Out << 'A';
3171 return;
3172 case CC_X86Pascal:
3173 Out << 'C';
3174 return;
3175 case CC_X86ThisCall:
3176 Out << 'E';
3177 return;
3178 case CC_X86StdCall:
3179 Out << 'G';
3180 return;
3181 case CC_X86FastCall:
3182 Out << 'I';
3183 return;
3184 case CC_X86VectorCall:
3185 Out << 'Q';
3186 return;
3187 case CC_Swift:
3188 Out << 'S';
3189 return;
3190 case CC_SwiftAsync:
3191 Out << 'W';
3192 return;
3193 case CC_PreserveMost:
3194 Out << 'U';
3195 return;
3196 case CC_PreserveNone:
3197 Out << 'V';
3198 return;
3199 case CC_X86RegCall:
3200 if (getASTContext().getLangOpts().RegCall4)
3201 Out << "x";
3202 else
3203 Out << "w";
3204 return;
3205 }
3206
3207 Error(Range.getBegin(), "calling convention") << Range;
3208}
3209void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T,
3210 SourceRange Range) {
3211 mangleCallingConvention(T->getCallConv(), Range);
3212}
3213
3214void MicrosoftCXXNameMangler::mangleThrowSpecification(
3215 const FunctionProtoType *FT) {
3216 // <throw-spec> ::= Z # (default)
3217 // ::= _E # noexcept
3218 if (FT->canThrow())
3219 Out << 'Z';
3220 else
3221 Out << "_E";
3222}
3223
3224void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,
3225 Qualifiers, SourceRange Range) {
3226 // Probably should be mangled as a template instantiation; need to see what
3227 // VC does first.
3228 Error(Range.getBegin(), "unresolved dependent type") << Range;
3229}
3230
3231// <type> ::= <union-type> | <struct-type> | <class-type> | <enum-type>
3232// <union-type> ::= T <name>
3233// <struct-type> ::= U <name>
3234// <class-type> ::= V <name>
3235// <enum-type> ::= W4 <name>
3236void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) {
3237 switch (TTK) {
3238 case TagTypeKind::Union:
3239 Out << 'T';
3240 break;
3241 case TagTypeKind::Struct:
3242 case TagTypeKind::Interface:
3243 Out << 'U';
3244 break;
3245 case TagTypeKind::Class:
3246 Out << 'V';
3247 break;
3248 case TagTypeKind::Enum:
3249 Out << "W4";
3250 break;
3251 }
3252}
3253void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers,
3254 SourceRange) {
3255 mangleType(cast<TagType>(T)->getDecl());
3256}
3257void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers,
3258 SourceRange) {
3259 mangleType(cast<TagType>(T)->getDecl());
3260}
3261void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
3262 // MSVC chooses the tag kind of the definition if it exists, otherwise it
3263 // always picks the first declaration.
3264 const auto *Def = TD->getDefinition();
3265 TD = Def ? Def : TD->getFirstDecl();
3266 mangleTagTypeKind(TD->getTagKind());
3267 mangleName(TD);
3268}
3269
3270// If you add a call to this, consider updating isArtificialTagType() too.
3271void MicrosoftCXXNameMangler::mangleArtificialTagType(
3272 TagTypeKind TK, StringRef UnqualifiedName,
3273 ArrayRef<StringRef> NestedNames) {
3274 // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
3275 mangleTagTypeKind(TK);
3276
3277 // Always start with the unqualified name.
3278 mangleSourceName(UnqualifiedName);
3279
3280 for (StringRef N : llvm::reverse(NestedNames))
3281 mangleSourceName(N);
3282
3283 // Terminate the whole name with an '@'.
3284 Out << '@';
3285}
3286
3287// <type> ::= <array-type>
3288// <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
3289// [Y <dimension-count> <dimension>+]
3290// <element-type> # as global, E is never required
3291// It's supposed to be the other way around, but for some strange reason, it
3292// isn't. Today this behavior is retained for the sole purpose of backwards
3293// compatibility.
3294void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) {
3295 // This isn't a recursive mangling, so now we have to do it all in this
3296 // one call.
3297 manglePointerCVQualifiers(T->getElementType().getQualifiers());
3298 mangleType(T->getElementType(), SourceRange());
3299}
3300void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T, Qualifiers,
3301 SourceRange) {
3302 llvm_unreachable("Should have been special cased");
3303}
3304void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T, Qualifiers,
3305 SourceRange) {
3306 llvm_unreachable("Should have been special cased");
3307}
3308void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T,
3309 Qualifiers, SourceRange) {
3310 llvm_unreachable("Should have been special cased");
3311}
3312void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T,
3313 Qualifiers, SourceRange) {
3314 llvm_unreachable("Should have been special cased");
3315}
3316void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) {
3317 QualType ElementTy(T, 0);
3318 SmallVector<llvm::APInt, 3> Dimensions;
3319 for (;;) {
3320 if (ElementTy->isConstantArrayType()) {
3321 const ConstantArrayType *CAT =
3322 getASTContext().getAsConstantArrayType(ElementTy);
3323 Dimensions.push_back(CAT->getSize());
3324 ElementTy = CAT->getElementType();
3325 } else if (ElementTy->isIncompleteArrayType()) {
3326 const IncompleteArrayType *IAT =
3327 getASTContext().getAsIncompleteArrayType(ElementTy);
3328 Dimensions.push_back(llvm::APInt(32, 0));
3329 ElementTy = IAT->getElementType();
3330 } else if (ElementTy->isVariableArrayType()) {
3331 const VariableArrayType *VAT =
3332 getASTContext().getAsVariableArrayType(ElementTy);
3333 Dimensions.push_back(llvm::APInt(32, 0));
3334 ElementTy = VAT->getElementType();
3335 } else if (ElementTy->isDependentSizedArrayType()) {
3336 // The dependent expression has to be folded into a constant (TODO).
3337 const DependentSizedArrayType *DSAT =
3338 getASTContext().getAsDependentSizedArrayType(ElementTy);
3339 Error(DSAT->getSizeExpr()->getExprLoc(), "dependent-length")
3340 << DSAT->getSizeExpr()->getSourceRange();
3341 return;
3342 } else {
3343 break;
3344 }
3345 }
3346 Out << 'Y';
3347 // <dimension-count> ::= <number> # number of extra dimensions
3348 mangleNumber(Dimensions.size());
3349 for (const llvm::APInt &Dimension : Dimensions)
3350 mangleNumber(Dimension.getLimitedValue());
3351 mangleType(ElementTy, SourceRange(), QMM_Escape);
3352}
3353
3354void MicrosoftCXXNameMangler::mangleType(const ArrayParameterType *T,
3355 Qualifiers, SourceRange) {
3356 mangleArrayType(cast<ConstantArrayType>(T));
3357}
3358
3359// <type> ::= <pointer-to-member-type>
3360// <pointer-to-member-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
3361// <class name> <type>
3362void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,
3363 Qualifiers Quals, SourceRange Range) {
3364 QualType PointeeType = T->getPointeeType();
3365 manglePointerCVQualifiers(Quals);
3366 manglePointerExtQualifiers(Quals, PointeeType);
3367 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
3368 Out << '8';
3369 mangleName(T->getMostRecentCXXRecordDecl());
3370 mangleFunctionType(FPT, nullptr, true);
3371 } else {
3372 mangleQualifiers(PointeeType.getQualifiers(), true);
3373 mangleName(T->getMostRecentCXXRecordDecl());
3374 mangleType(PointeeType, Range, QMM_Drop);
3375 }
3376}
3377
3378void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T,
3379 Qualifiers, SourceRange Range) {
3380 Out << '?';
3381
3382 llvm::SmallString<64> Name;
3383 Name += "<TTPT_";
3384 Name += llvm::utostr(T->getDepth());
3385 Name += "_";
3386 Name += llvm::utostr(T->getIndex());
3387 Name += ">";
3388 mangleSourceName(Name);
3389}
3390
3391void MicrosoftCXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T,
3392 Qualifiers, SourceRange Range) {
3393 Error(Range.getBegin(), "substituted parameter pack") << Range;
3394}
3395
3396void MicrosoftCXXNameMangler::mangleType(const SubstBuiltinTemplatePackType *T,
3397 Qualifiers, SourceRange Range) {
3398 Error(Range.getBegin(), "substituted builtin template pack") << Range;
3399}
3400
3401// <type> ::= <pointer-type>
3402// <pointer-type> ::= E? <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
3403// # the E is required for 64-bit non-static pointers
3404void MicrosoftCXXNameMangler::mangleType(const PointerType *T, Qualifiers Quals,
3405 SourceRange Range) {
3406 QualType PointeeType = T->getPointeeType();
3407 manglePointerCVQualifiers(Quals);
3408 manglePointerExtQualifiers(Quals, PointeeType);
3409 manglePointerAuthQualifier(Quals);
3410
3411 // For pointer size address spaces, go down the same type mangling path as
3412 // non address space types.
3413 LangAS AddrSpace = PointeeType.getQualifiers().getAddressSpace();
3414 if (isPtrSizeAddressSpace(AddrSpace) || AddrSpace == LangAS::Default)
3415 mangleType(PointeeType, Range);
3416 else
3417 mangleAddressSpaceType(PointeeType, PointeeType.getQualifiers(), Range);
3418}
3419
3420void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
3421 Qualifiers Quals, SourceRange Range) {
3422 QualType PointeeType = T->getPointeeType();
3423 switch (Quals.getObjCLifetime()) {
3426 break;
3430 return mangleObjCLifetime(PointeeType, Quals, Range);
3431 }
3432 manglePointerCVQualifiers(Quals);
3433 manglePointerExtQualifiers(Quals, PointeeType);
3434 mangleType(PointeeType, Range);
3435}
3436
3437// <type> ::= <reference-type>
3438// <reference-type> ::= A E? <cvr-qualifiers> <type>
3439// # the E is required for 64-bit non-static lvalue references
3440void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,
3441 Qualifiers Quals, SourceRange Range) {
3442 QualType PointeeType = T->getPointeeType();
3443 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
3444 Out << 'A';
3445 manglePointerExtQualifiers(Quals, PointeeType);
3446 mangleType(PointeeType, Range);
3447}
3448
3449// <type> ::= <r-value-reference-type>
3450// <r-value-reference-type> ::= $$Q E? <cvr-qualifiers> <type>
3451// # the E is required for 64-bit non-static rvalue references
3452void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,
3453 Qualifiers Quals, SourceRange Range) {
3454 QualType PointeeType = T->getPointeeType();
3455 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
3456 Out << "$$Q";
3457 manglePointerExtQualifiers(Quals, PointeeType);
3458 mangleType(PointeeType, Range);
3459}
3460
3461void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, Qualifiers,
3462 SourceRange Range) {
3463 QualType ElementType = T->getElementType();
3464
3465 llvm::SmallString<64> TemplateMangling;
3466 llvm::raw_svector_ostream Stream(TemplateMangling);
3467 MicrosoftCXXNameMangler Extra(Context, Stream);
3468 Stream << "?$";
3469 Extra.mangleSourceName("_Complex");
3470 Extra.mangleType(ElementType, Range, QMM_Escape);
3471
3472 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3473}
3474
3475// Returns true for types that mangleArtificialTagType() gets called for with
3476// TagTypeKind Union, Struct, Class and where compatibility with MSVC's
3477// mangling matters.
3478// (It doesn't matter for Objective-C types and the like that cl.exe doesn't
3479// support.)
3480bool MicrosoftCXXNameMangler::isArtificialTagType(QualType T) const {
3481 const Type *ty = T.getTypePtr();
3482 switch (ty->getTypeClass()) {
3483 default:
3484 return false;
3485
3486 case Type::Vector: {
3487 // For ABI compatibility only __m64, __m128(id), and __m256(id) matter,
3488 // but since mangleType(VectorType*) always calls mangleArtificialTagType()
3489 // just always return true (the other vector types are clang-only).
3490 return true;
3491 }
3492 }
3493}
3494
3495void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,
3496 SourceRange Range) {
3497 QualType EltTy = T->getElementType();
3498 const BuiltinType *ET = EltTy->getAs<BuiltinType>();
3499 const BitIntType *BitIntTy = EltTy->getAs<BitIntType>();
3500 assert((ET || BitIntTy) &&
3501 "vectors with non-builtin/_BitInt elements are unsupported");
3502 uint64_t Width = getASTContext().getTypeSize(T);
3503 // Pattern match exactly the typedefs in our intrinsic headers. Anything that
3504 // doesn't match the Intel types uses a custom mangling below.
3505 size_t OutSizeBefore = Out.tell();
3506 if (!isa<ExtVectorType>(T)) {
3507 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {
3508 if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {
3509 mangleArtificialTagType(TagTypeKind::Union, "__m64");
3510 } else if (Width >= 128) {
3511 if (ET->getKind() == BuiltinType::Float)
3512 mangleArtificialTagType(TagTypeKind::Union,
3513 "__m" + llvm::utostr(Width));
3514 else if (ET->getKind() == BuiltinType::LongLong)
3515 mangleArtificialTagType(TagTypeKind::Union,
3516 "__m" + llvm::utostr(Width) + 'i');
3517 else if (ET->getKind() == BuiltinType::Double)
3518 mangleArtificialTagType(TagTypeKind::Struct,
3519 "__m" + llvm::utostr(Width) + 'd');
3520 }
3521 }
3522 }
3523
3524 bool IsBuiltin = Out.tell() != OutSizeBefore;
3525 if (!IsBuiltin) {
3526 // The MS ABI doesn't have a special mangling for vector types, so we define
3527 // our own mangling to handle uses of __vector_size__ on user-specified
3528 // types, and for extensions like __v4sf.
3529
3530 llvm::SmallString<64> TemplateMangling;
3531 llvm::raw_svector_ostream Stream(TemplateMangling);
3532 MicrosoftCXXNameMangler Extra(Context, Stream);
3533 Stream << "?$";
3534 Extra.mangleSourceName("__vector");
3535 Extra.mangleType(QualType(ET ? static_cast<const Type *>(ET) : BitIntTy, 0),
3536 Range, QMM_Escape);
3537 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()));
3538
3539 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {"__clang"});
3540 }
3541}
3542
3543void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T,
3544 Qualifiers Quals, SourceRange Range) {
3545 mangleType(static_cast<const VectorType *>(T), Quals, Range);
3546}
3547
3548void MicrosoftCXXNameMangler::mangleType(const DependentVectorType *T,
3549 Qualifiers, SourceRange Range) {
3550 Error(Range.getBegin(), "dependent-sized vector type") << Range;
3551}
3552
3553void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,
3554 Qualifiers, SourceRange Range) {
3555 Error(Range.getBegin(), "dependent-sized extended vector type") << Range;
3556}
3557
3558void MicrosoftCXXNameMangler::mangleType(const ConstantMatrixType *T,
3559 Qualifiers quals, SourceRange Range) {
3560 QualType EltTy = T->getElementType();
3561
3562 llvm::SmallString<64> TemplateMangling;
3563 llvm::raw_svector_ostream Stream(TemplateMangling);
3564 MicrosoftCXXNameMangler Extra(Context, Stream);
3565
3566 Stream << "?$";
3567
3568 Extra.mangleSourceName("__matrix");
3569 Extra.mangleType(EltTy, Range, QMM_Escape);
3570
3571 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumRows()));
3572 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumColumns()));
3573
3574 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3575}
3576
3577void MicrosoftCXXNameMangler::mangleType(const DependentSizedMatrixType *T,
3578 Qualifiers quals, SourceRange Range) {
3579 Error(Range.getBegin(), "dependent-sized matrix type") << Range;
3580}
3581
3582void MicrosoftCXXNameMangler::mangleType(const DependentAddressSpaceType *T,
3583 Qualifiers, SourceRange Range) {
3584 Error(Range.getBegin(), "dependent address space type") << Range;
3585}
3586
3587void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,
3588 SourceRange) {
3589 // ObjC interfaces have structs underlying them.
3590 mangleTagTypeKind(TagTypeKind::Struct);
3591 mangleName(T->getDecl());
3592}
3593
3594void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,
3595 Qualifiers Quals, SourceRange Range) {
3596 if (T->isKindOfType())
3597 return mangleObjCKindOfType(T, Quals, Range);
3598
3599 if (T->qual_empty() && !T->isSpecialized())
3600 return mangleType(T->getBaseType(), Range, QMM_Drop);
3601
3602 ArgBackRefMap OuterFunArgsContext;
3603 ArgBackRefMap OuterTemplateArgsContext;
3604 BackRefVec OuterTemplateContext;
3605
3606 FunArgBackReferences.swap(OuterFunArgsContext);
3607 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3608 NameBackReferences.swap(OuterTemplateContext);
3609
3610 mangleTagTypeKind(TagTypeKind::Struct);
3611
3612 Out << "?$";
3613 if (T->isObjCId())
3614 mangleSourceName("objc_object");
3615 else if (T->isObjCClass())
3616 mangleSourceName("objc_class");
3617 else
3618 mangleSourceName(T->getInterface()->getName());
3619
3620 for (const auto &Q : T->quals())
3621 mangleObjCProtocol(Q);
3622
3623 if (T->isSpecialized())
3624 for (const auto &TA : T->getTypeArgs())
3625 mangleType(TA, Range, QMM_Drop);
3626
3627 Out << '@';
3628
3629 Out << '@';
3630
3631 FunArgBackReferences.swap(OuterFunArgsContext);
3632 TemplateArgBackReferences.swap(OuterTemplateArgsContext);
3633 NameBackReferences.swap(OuterTemplateContext);
3634}
3635
3636void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T,
3637 Qualifiers Quals, SourceRange Range) {
3638 QualType PointeeType = T->getPointeeType();
3639 manglePointerCVQualifiers(Quals);
3640 manglePointerExtQualifiers(Quals, PointeeType);
3641
3642 Out << "_E";
3643
3644 mangleFunctionType(PointeeType->castAs<FunctionProtoType>());
3645}
3646
3647void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *,
3648 Qualifiers, SourceRange) {
3649 llvm_unreachable("Cannot mangle injected class name type.");
3650}
3651
3652void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T,
3653 Qualifiers, SourceRange Range) {
3654 Error(Range.getBegin(), "template specialization type") << Range;
3655}
3656
3657void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T, Qualifiers,
3658 SourceRange Range) {
3659 Error(Range.getBegin(), "dependent name type") << Range;
3660}
3661
3662void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T, Qualifiers,
3663 SourceRange Range) {
3664 Error(Range.getBegin(), "pack expansion") << Range;
3665}
3666
3667void MicrosoftCXXNameMangler::mangleType(const PackIndexingType *T,
3668 Qualifiers Quals, SourceRange Range) {
3669 manglePointerCVQualifiers(Quals);
3670 mangleType(T->getSelectedType(), Range);
3671}
3672
3673void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T, Qualifiers,
3674 SourceRange Range) {
3675 Error(Range.getBegin(), "typeof(type)") << Range;
3676}
3677
3678void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T, Qualifiers,
3679 SourceRange Range) {
3680 Error(Range.getBegin(), "typeof(expression)") << Range;
3681}
3682
3683void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T, Qualifiers,
3684 SourceRange Range) {
3685 Error(Range.getBegin(), "decltype()") << Range;
3686}
3687
3688void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T,
3689 Qualifiers, SourceRange Range) {
3690 Error(Range.getBegin(), "unary transform type") << Range;
3691}
3692
3693void MicrosoftCXXNameMangler::mangleType(const AutoType *T, Qualifiers,
3694 SourceRange Range) {
3695 assert(T->getDeducedType().isNull() && "expecting a dependent type!");
3696
3697 Error(Range.getBegin(), "'auto' type") << Range;
3698}
3699
3700void MicrosoftCXXNameMangler::mangleType(
3701 const DeducedTemplateSpecializationType *T, Qualifiers, SourceRange Range) {
3702 assert(T->getDeducedType().isNull() && "expecting a dependent type!");
3703
3704 Error(Range.getBegin(), "deduced class template specialization type")
3705 << Range;
3706}
3707
3708void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers,
3709 SourceRange Range) {
3710 QualType ValueType = T->getValueType();
3711
3712 llvm::SmallString<64> TemplateMangling;
3713 llvm::raw_svector_ostream Stream(TemplateMangling);
3714 MicrosoftCXXNameMangler Extra(Context, Stream);
3715 Stream << "?$";
3716 Extra.mangleSourceName("_Atomic");
3717 Extra.mangleType(ValueType, Range, QMM_Escape);
3718
3719 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3720}
3721
3722void MicrosoftCXXNameMangler::mangleType(const PipeType *T, Qualifiers,
3723 SourceRange Range) {
3724 QualType ElementType = T->getElementType();
3725
3726 llvm::SmallString<64> TemplateMangling;
3727 llvm::raw_svector_ostream Stream(TemplateMangling);
3728 MicrosoftCXXNameMangler Extra(Context, Stream);
3729 Stream << "?$";
3730 Extra.mangleSourceName("ocl_pipe");
3731 Extra.mangleType(ElementType, Range, QMM_Escape);
3732 Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()));
3733
3734 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3735}
3736
3737void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,
3738 raw_ostream &Out) {
3739 const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
3740 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
3741 getASTContext().getSourceManager(),
3742 "Mangling declaration");
3743
3744 msvc_hashing_ostream MHO(Out);
3745
3746 if (auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
3747 auto Type = GD.getCtorType();
3748 MicrosoftCXXNameMangler mangler(*this, MHO, CD, Type);
3749 return mangler.mangle(GD);
3750 }
3751
3752 if (auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
3753 auto Type = GD.getDtorType();
3754 MicrosoftCXXNameMangler mangler(*this, MHO, DD, Type);
3755 return mangler.mangle(GD);
3756 }
3757
3758 MicrosoftCXXNameMangler Mangler(*this, MHO);
3759 return Mangler.mangle(GD);
3760}
3761
3762void MicrosoftCXXNameMangler::mangleType(const BitIntType *T, Qualifiers,
3763 SourceRange Range) {
3764 llvm::SmallString<64> TemplateMangling;
3765 llvm::raw_svector_ostream Stream(TemplateMangling);
3766 MicrosoftCXXNameMangler Extra(Context, Stream);
3767 Stream << "?$";
3768 if (T->isUnsigned())
3769 Extra.mangleSourceName("_UBitInt");
3770 else
3771 Extra.mangleSourceName("_BitInt");
3772 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()));
3773
3774 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3775}
3776
3777void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,
3778 Qualifiers, SourceRange Range) {
3779 Error(Range.getBegin(), "DependentBitInt type") << Range;
3780}
3781
3782void MicrosoftCXXNameMangler::mangleType(const HLSLAttributedResourceType *T,
3783 Qualifiers, SourceRange Range) {
3784 llvm_unreachable("HLSL uses Itanium name mangling");
3785}
3786
3787void MicrosoftCXXNameMangler::mangleType(const HLSLInlineSpirvType *T,
3788 Qualifiers, SourceRange Range) {
3789 llvm_unreachable("HLSL uses Itanium name mangling");
3790}
3791
3792void MicrosoftCXXNameMangler::mangleType(const OverflowBehaviorType *T,
3793 Qualifiers, SourceRange Range) {
3794 QualType UnderlyingType = T->getUnderlyingType();
3795
3796 llvm::SmallString<64> TemplateMangling;
3797 llvm::raw_svector_ostream Stream(TemplateMangling);
3798 MicrosoftCXXNameMangler Extra(Context, Stream);
3799 Stream << "?$";
3800 if (T->isWrapKind()) {
3801 Extra.mangleSourceName("ObtWrap_");
3802 } else {
3803 Extra.mangleSourceName("ObtTrap_");
3804 }
3805 Extra.mangleType(UnderlyingType, Range, QMM_Escape);
3806
3807 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});
3808}
3809
3810// <this-adjustment> ::= <no-adjustment> | <static-adjustment> |
3811// <virtual-adjustment>
3812// <no-adjustment> ::= A # private near
3813// ::= B # private far
3814// ::= I # protected near
3815// ::= J # protected far
3816// ::= Q # public near
3817// ::= R # public far
3818// <static-adjustment> ::= G <static-offset> # private near
3819// ::= H <static-offset> # private far
3820// ::= O <static-offset> # protected near
3821// ::= P <static-offset> # protected far
3822// ::= W <static-offset> # public near
3823// ::= X <static-offset> # public far
3824// <virtual-adjustment> ::= $0 <virtual-shift> <static-offset> # private near
3825// ::= $1 <virtual-shift> <static-offset> # private far
3826// ::= $2 <virtual-shift> <static-offset> # protected near
3827// ::= $3 <virtual-shift> <static-offset> # protected far
3828// ::= $4 <virtual-shift> <static-offset> # public near
3829// ::= $5 <virtual-shift> <static-offset> # public far
3830// <virtual-shift> ::= <vtordisp-shift> | <vtordispex-shift>
3831// <vtordisp-shift> ::= <offset-to-vtordisp>
3832// <vtordispex-shift> ::= <offset-to-vbptr> <vbase-offset-offset>
3833// <offset-to-vtordisp>
3835 const ThisAdjustment &Adjustment,
3836 MicrosoftCXXNameMangler &Mangler,
3837 raw_ostream &Out) {
3838 if (!Adjustment.Virtual.isEmpty()) {
3839 Out << '$';
3840 char AccessSpec;
3841 switch (AS) {
3842 case AS_none:
3843 llvm_unreachable("Unsupported access specifier");
3844 case AS_private:
3845 AccessSpec = '0';
3846 break;
3847 case AS_protected:
3848 AccessSpec = '2';
3849 break;
3850 case AS_public:
3851 AccessSpec = '4';
3852 }
3853 if (Adjustment.Virtual.Microsoft.VBPtrOffset) {
3854 Out << 'R' << AccessSpec;
3855 Mangler.mangleNumber(
3856 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBPtrOffset));
3857 Mangler.mangleNumber(
3858 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBOffsetOffset));
3859 Mangler.mangleNumber(
3860 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));
3861 Mangler.mangleNumber(static_cast<uint32_t>(Adjustment.NonVirtual));
3862 } else {
3863 Out << AccessSpec;
3864 Mangler.mangleNumber(
3865 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));
3866 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
3867 }
3868 } else if (Adjustment.NonVirtual != 0) {
3869 switch (AS) {
3870 case AS_none:
3871 llvm_unreachable("Unsupported access specifier");
3872 case AS_private:
3873 Out << 'G';
3874 break;
3875 case AS_protected:
3876 Out << 'O';
3877 break;
3878 case AS_public:
3879 Out << 'W';
3880 }
3881 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
3882 } else {
3883 switch (AS) {
3884 case AS_none:
3885 llvm_unreachable("Unsupported access specifier");
3886 case AS_private:
3887 Out << 'A';
3888 break;
3889 case AS_protected:
3890 Out << 'I';
3891 break;
3892 case AS_public:
3893 Out << 'Q';
3894 }
3895 }
3896}
3897
3898void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
3899 const CXXMethodDecl *MD, const MethodVFTableLocation &ML,
3900 raw_ostream &Out) {
3901 msvc_hashing_ostream MHO(Out);
3902 MicrosoftCXXNameMangler Mangler(*this, MHO);
3903 Mangler.getStream() << '?';
3904 Mangler.mangleVirtualMemPtrThunk(MD, ML);
3905}
3906
3907void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
3908 const ThunkInfo &Thunk,
3909 bool /*ElideOverrideInfo*/,
3910 raw_ostream &Out) {
3911 msvc_hashing_ostream MHO(Out);
3912 MicrosoftCXXNameMangler Mangler(*this, MHO);
3913 Mangler.getStream() << '?';
3914 Mangler.mangleName(MD);
3915
3916 // Usually the thunk uses the access specifier of the new method, but if this
3917 // is a covariant return thunk, then MSVC always uses the public access
3918 // specifier, and we do the same.
3919 AccessSpecifier AS = Thunk.Return.isEmpty() ? MD->getAccess() : AS_public;
3920 mangleThunkThisAdjustment(AS, Thunk.This, Mangler, MHO);
3921
3922 if (!Thunk.Return.isEmpty())
3923 assert(Thunk.Method != nullptr &&
3924 "Thunk info should hold the overridee decl");
3925
3926 const CXXMethodDecl *DeclForFPT = Thunk.Method ? Thunk.Method : MD;
3927 Mangler.mangleFunctionType(
3928 DeclForFPT->getType()->castAs<FunctionProtoType>(), MD);
3929}
3930
3931void MicrosoftMangleContextImpl::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
3933 const ThunkInfo &Thunk,
3934 bool /*ElideOverrideInfo*/,
3935 raw_ostream &Out) {
3936 // The dtor thunk should use vector deleting dtor mangling, however as an
3937 // optimization we may end up emitting only scalar deleting dtor body, so just
3938 // use the vector deleting dtor mangling manually.
3939 assert(Type == Dtor_Deleting || Type == Dtor_VectorDeleting);
3940 msvc_hashing_ostream MHO(Out);
3941 MicrosoftCXXNameMangler Mangler(*this, MHO, DD, Type);
3942 Mangler.getStream() << "??_E";
3943 Mangler.mangleName(DD->getParent());
3944 auto &Adjustment = Thunk.This;
3945 mangleThunkThisAdjustment(DD->getAccess(), Adjustment, Mangler, MHO);
3946 Mangler.mangleFunctionType(DD->getType()->castAs<FunctionProtoType>(), DD);
3947}
3948
3949void MicrosoftMangleContextImpl::mangleCXXVFTable(
3950 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
3951 raw_ostream &Out) {
3952 // <mangled-name> ::= ?_7 <class-name> <storage-class>
3953 // <cvr-qualifiers> [<name>] @
3954 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
3955 // is always '6' for vftables.
3956 msvc_hashing_ostream MHO(Out);
3957 MicrosoftCXXNameMangler Mangler(*this, MHO);
3958 if (Derived->hasAttr<DLLImportAttr>())
3959 Mangler.getStream() << "??_S";
3960 else
3961 Mangler.getStream() << "??_7";
3962 Mangler.mangleName(Derived);
3963 Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.
3964 for (const CXXRecordDecl *RD : BasePath)
3965 Mangler.mangleName(RD);
3966 Mangler.getStream() << '@';
3967}
3968
3969void MicrosoftMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *Derived,
3970 raw_ostream &Out) {
3971 // TODO: Determine appropriate mangling for MSABI
3972 mangleCXXVFTable(Derived, {}, Out);
3973}
3974
3975void MicrosoftMangleContextImpl::mangleCXXVBTable(
3976 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
3977 raw_ostream &Out) {
3978 // <mangled-name> ::= ?_8 <class-name> <storage-class>
3979 // <cvr-qualifiers> [<name>] @
3980 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
3981 // is always '7' for vbtables.
3982 msvc_hashing_ostream MHO(Out);
3983 MicrosoftCXXNameMangler Mangler(*this, MHO);
3984 Mangler.getStream() << "??_8";
3985 Mangler.mangleName(Derived);
3986 Mangler.getStream() << "7B"; // '7' for vbtable, 'B' for const.
3987 for (const CXXRecordDecl *RD : BasePath)
3988 Mangler.mangleName(RD);
3989 Mangler.getStream() << '@';
3990}
3991
3992void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
3993 msvc_hashing_ostream MHO(Out);
3994 MicrosoftCXXNameMangler Mangler(*this, MHO);
3995 Mangler.getStream() << "??_R0";
3996 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
3997 Mangler.getStream() << "@8";
3998}
3999
4000void MicrosoftMangleContextImpl::mangleCXXRTTIName(
4001 QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {
4002 MicrosoftCXXNameMangler Mangler(*this, Out);
4003 Mangler.getStream() << '.';
4004 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4005}
4006
4007void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(
4008 const CXXRecordDecl *SrcRD, const CXXRecordDecl *DstRD, raw_ostream &Out) {
4009 msvc_hashing_ostream MHO(Out);
4010 MicrosoftCXXNameMangler Mangler(*this, MHO);
4011 Mangler.getStream() << "??_K";
4012 Mangler.mangleName(SrcRD);
4013 Mangler.getStream() << "$C";
4014 Mangler.mangleName(DstRD);
4015}
4016
4017void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, bool IsConst,
4018 bool IsVolatile,
4019 bool IsUnaligned,
4020 uint32_t NumEntries,
4021 raw_ostream &Out) {
4022 msvc_hashing_ostream MHO(Out);
4023 MicrosoftCXXNameMangler Mangler(*this, MHO);
4024 Mangler.getStream() << "_TI";
4025 if (IsConst)
4026 Mangler.getStream() << 'C';
4027 if (IsVolatile)
4028 Mangler.getStream() << 'V';
4029 if (IsUnaligned)
4030 Mangler.getStream() << 'U';
4031 Mangler.getStream() << NumEntries;
4032 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4033}
4034
4035void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(
4036 QualType T, uint32_t NumEntries, raw_ostream &Out) {
4037 msvc_hashing_ostream MHO(Out);
4038 MicrosoftCXXNameMangler Mangler(*this, MHO);
4039 Mangler.getStream() << "_CTA";
4040 Mangler.getStream() << NumEntries;
4041 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
4042}
4043
4044void MicrosoftMangleContextImpl::mangleCXXCatchableType(
4045 QualType T, const CXXConstructorDecl *CD, CXXCtorType CT, uint32_t Size,
4046 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,
4047 raw_ostream &Out) {
4048 MicrosoftCXXNameMangler Mangler(*this, Out);
4049 Mangler.getStream() << "_CT";
4050
4051 llvm::SmallString<64> RTTIMangling;
4052 {
4053 llvm::raw_svector_ostream Stream(RTTIMangling);
4054 msvc_hashing_ostream MHO(Stream);
4055 mangleCXXRTTI(T, MHO);
4056 }
4057 Mangler.getStream() << RTTIMangling;
4058
4059 // VS2015 and VS2017.1 omit the copy-constructor in the mangled name but
4060 // both older and newer versions include it.
4061 // FIXME: It is known that the Ctor is present in 2013, and in 2017.7
4062 // (_MSC_VER 1914) and newer, and that it's omitted in 2015 and 2017.4
4063 // (_MSC_VER 1911), but it's unknown when exactly it reappeared (1914?
4064 // Or 1912, 1913 already?).
4065 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(
4066 LangOptions::MSVC2015) &&
4067 !getASTContext().getLangOpts().isCompatibleWithMSVC(
4068 LangOptions::MSVC2017_7);
4069 llvm::SmallString<64> CopyCtorMangling;
4070 if (!OmitCopyCtor && CD) {
4071 llvm::raw_svector_ostream Stream(CopyCtorMangling);
4072 msvc_hashing_ostream MHO(Stream);
4073 mangleCXXName(GlobalDecl(CD, CT), MHO);
4074 }
4075 Mangler.getStream() << CopyCtorMangling;
4076
4077 Mangler.getStream() << Size;
4078 if (VBPtrOffset == -1) {
4079 if (NVOffset) {
4080 Mangler.getStream() << NVOffset;
4081 }
4082 } else {
4083 Mangler.getStream() << NVOffset;
4084 Mangler.getStream() << VBPtrOffset;
4085 Mangler.getStream() << VBIndex;
4086 }
4087}
4088
4089void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
4090 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
4091 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
4092 msvc_hashing_ostream MHO(Out);
4093 MicrosoftCXXNameMangler Mangler(*this, MHO);
4094 Mangler.getStream() << "??_R1";
4095 Mangler.mangleNumber(NVOffset);
4096 Mangler.mangleNumber(VBPtrOffset);
4097 Mangler.mangleNumber(VBTableOffset);
4098 Mangler.mangleNumber(Flags);
4099 Mangler.mangleName(Derived);
4100 Mangler.getStream() << "8";
4101}
4102
4103void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
4104 const CXXRecordDecl *Derived, raw_ostream &Out) {
4105 msvc_hashing_ostream MHO(Out);
4106 MicrosoftCXXNameMangler Mangler(*this, MHO);
4107 Mangler.getStream() << "??_R2";
4108 Mangler.mangleName(Derived);
4109 Mangler.getStream() << "8";
4110}
4111
4112void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
4113 const CXXRecordDecl *Derived, raw_ostream &Out) {
4114 msvc_hashing_ostream MHO(Out);
4115 MicrosoftCXXNameMangler Mangler(*this, MHO);
4116 Mangler.getStream() << "??_R3";
4117 Mangler.mangleName(Derived);
4118 Mangler.getStream() << "8";
4119}
4120
4121void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
4122 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
4123 raw_ostream &Out) {
4124 // <mangled-name> ::= ?_R4 <class-name> <storage-class>
4125 // <cvr-qualifiers> [<name>] @
4126 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
4127 // is always '6' for vftables.
4128 llvm::SmallString<64> VFTableMangling;
4129 llvm::raw_svector_ostream Stream(VFTableMangling);
4130 mangleCXXVFTable(Derived, BasePath, Stream);
4131
4132 if (VFTableMangling.starts_with("??@")) {
4133 assert(VFTableMangling.ends_with("@"));
4134 Out << VFTableMangling << "??_R4@";
4135 return;
4136 }
4137
4138 assert(VFTableMangling.starts_with("??_7") ||
4139 VFTableMangling.starts_with("??_S"));
4140
4141 Out << "??_R4" << VFTableMangling.str().drop_front(4);
4142}
4143
4144void MicrosoftMangleContextImpl::mangleSEHFilterExpression(
4145 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4146 msvc_hashing_ostream MHO(Out);
4147 MicrosoftCXXNameMangler Mangler(*this, MHO);
4148 // The function body is in the same comdat as the function with the handler,
4149 // so the numbering here doesn't have to be the same across TUs.
4150 //
4151 // <mangled-name> ::= ?filt$ <filter-number> @0
4152 Mangler.getStream() << "?filt$" << SEHFilterIds[EnclosingDecl]++ << "@0@";
4153 Mangler.mangleName(EnclosingDecl);
4154}
4155
4156void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
4157 GlobalDecl EnclosingDecl, raw_ostream &Out) {
4158 msvc_hashing_ostream MHO(Out);
4159 MicrosoftCXXNameMangler Mangler(*this, MHO);
4160 // The function body is in the same comdat as the function with the handler,
4161 // so the numbering here doesn't have to be the same across TUs.
4162 //
4163 // <mangled-name> ::= ?fin$ <filter-number> @0
4164 Mangler.getStream() << "?fin$" << SEHFinallyIds[EnclosingDecl]++ << "@0@";
4165 Mangler.mangleName(EnclosingDecl);
4166}
4167
4168void MicrosoftMangleContextImpl::mangleCanonicalTypeName(
4169 QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {
4170 // This is just a made up unique string for the purposes of tbaa. undname
4171 // does *not* know how to demangle it.
4172 MicrosoftCXXNameMangler Mangler(*this, Out);
4173 Mangler.getStream() << '?';
4174 Mangler.mangleType(T.getCanonicalType(), SourceRange());
4175}
4176
4177void MicrosoftMangleContextImpl::mangleReferenceTemporary(
4178 const VarDecl *VD, unsigned ManglingNumber, raw_ostream &Out) {
4179 msvc_hashing_ostream MHO(Out);
4180 MicrosoftCXXNameMangler Mangler(*this, MHO);
4181
4182 Mangler.getStream() << "?";
4183 Mangler.mangleSourceName("$RT" + llvm::utostr(ManglingNumber));
4184 Mangler.mangle(VD, "");
4185}
4186
4187void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(
4188 const VarDecl *VD, unsigned GuardNum, raw_ostream &Out) {
4189 msvc_hashing_ostream MHO(Out);
4190 MicrosoftCXXNameMangler Mangler(*this, MHO);
4191
4192 Mangler.getStream() << "?";
4193 Mangler.mangleSourceName("$TSS" + llvm::utostr(GuardNum));
4194 Mangler.mangleNestedName(VD);
4195 Mangler.getStream() << "@4HA";
4196}
4197
4198void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,
4199 raw_ostream &Out) {
4200 // <guard-name> ::= ?_B <postfix> @5 <scope-depth>
4201 // ::= ?__J <postfix> @5 <scope-depth>
4202 // ::= ?$S <guard-num> @ <postfix> @4IA
4203
4204 // The first mangling is what MSVC uses to guard static locals in inline
4205 // functions. It uses a different mangling in external functions to support
4206 // guarding more than 32 variables. MSVC rejects inline functions with more
4207 // than 32 static locals. We don't fully implement the second mangling
4208 // because those guards are not externally visible, and instead use LLVM's
4209 // default renaming when creating a new guard variable.
4210 msvc_hashing_ostream MHO(Out);
4211 MicrosoftCXXNameMangler Mangler(*this, MHO);
4212
4213 bool Visible = VD->isExternallyVisible();
4214 if (Visible) {
4215 Mangler.getStream() << (VD->getTLSKind() ? "??__J" : "??_B");
4216 } else {
4217 Mangler.getStream() << "?$S1@";
4218 }
4219 unsigned ScopeDepth = 0;
4220 if (Visible && !getNextDiscriminator(VD, ScopeDepth))
4221 // If we do not have a discriminator and are emitting a guard variable for
4222 // use at global scope, then mangling the nested name will not be enough to
4223 // remove ambiguities.
4224 Mangler.mangle(VD, "");
4225 else
4226 Mangler.mangleNestedName(VD);
4227 Mangler.getStream() << (Visible ? "@5" : "@4IA");
4228 if (ScopeDepth)
4229 Mangler.mangleNumber(ScopeDepth);
4230}
4231
4232void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D,
4233 char CharCode,
4234 raw_ostream &Out) {
4235 msvc_hashing_ostream MHO(Out);
4236 MicrosoftCXXNameMangler Mangler(*this, MHO);
4237 Mangler.getStream() << "??__" << CharCode;
4238 if (D->isStaticDataMember()) {
4239 Mangler.getStream() << '?';
4240 Mangler.mangleName(D);
4241 Mangler.mangleVariableEncoding(D);
4242 Mangler.getStream() << "@@";
4243 } else {
4244 Mangler.mangleName(D);
4245 }
4246 // This is the function class mangling. These stubs are global, non-variadic,
4247 // cdecl functions that return void and take no args.
4248 Mangler.getStream() << "YAXXZ";
4249}
4250
4251void MicrosoftMangleContextImpl::mangleDynamicInitializer(const VarDecl *D,
4252 raw_ostream &Out) {
4253 // <initializer-name> ::= ?__E <name> YAXXZ
4254 mangleInitFiniStub(D, 'E', Out);
4255}
4256
4257void
4258MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D,
4259 raw_ostream &Out) {
4260 // <destructor-name> ::= ?__F <name> YAXXZ
4261 mangleInitFiniStub(D, 'F', Out);
4262}
4263
4264void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
4265 raw_ostream &Out) {
4266 // <char-type> ::= 0 # char, char16_t, char32_t
4267 // # (little endian char data in mangling)
4268 // ::= 1 # wchar_t (big endian char data in mangling)
4269 //
4270 // <literal-length> ::= <non-negative integer> # the length of the literal
4271 //
4272 // <encoded-crc> ::= <hex digit>+ @ # crc of the literal including
4273 // # trailing null bytes
4274 //
4275 // <encoded-string> ::= <simple character> # uninteresting character
4276 // ::= '?$' <hex digit> <hex digit> # these two nibbles
4277 // # encode the byte for the
4278 // # character
4279 // ::= '?' [a-z] # \xe1 - \xfa
4280 // ::= '?' [A-Z] # \xc1 - \xda
4281 // ::= '?' [0-9] # [,/\:. \n\t'-]
4282 //
4283 // <literal> ::= '??_C@_' <char-type> <literal-length> <encoded-crc>
4284 // <encoded-string> '@'
4285 MicrosoftCXXNameMangler Mangler(*this, Out);
4286 Mangler.getStream() << "??_C@_";
4287
4288 // The actual string length might be different from that of the string literal
4289 // in cases like:
4290 // char foo[3] = "foobar";
4291 // char bar[42] = "foobar";
4292 // Where it is truncated or zero-padded to fit the array. This is the length
4293 // used for mangling, and any trailing null-bytes also need to be mangled.
4294 unsigned StringLength =
4295 getASTContext().getAsConstantArrayType(SL->getType())->getZExtSize();
4296 unsigned StringByteLength = StringLength * SL->getCharByteWidth();
4297
4298 // <char-type>: The "kind" of string literal is encoded into the mangled name.
4299 if (SL->isWide())
4300 Mangler.getStream() << '1';
4301 else
4302 Mangler.getStream() << '0';
4303
4304 // <literal-length>: The next part of the mangled name consists of the length
4305 // of the string in bytes.
4306 Mangler.mangleNumber(StringByteLength);
4307
4308 auto GetLittleEndianByte = [&SL](unsigned Index) {
4309 unsigned CharByteWidth = SL->getCharByteWidth();
4310 if (Index / CharByteWidth >= SL->getLength())
4311 return static_cast<char>(0);
4312 uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
4313 unsigned OffsetInCodeUnit = Index % CharByteWidth;
4314 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4315 };
4316
4317 auto GetBigEndianByte = [&SL](unsigned Index) {
4318 unsigned CharByteWidth = SL->getCharByteWidth();
4319 if (Index / CharByteWidth >= SL->getLength())
4320 return static_cast<char>(0);
4321 uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
4322 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
4323 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
4324 };
4325
4326 // CRC all the bytes of the StringLiteral.
4327 llvm::JamCRC JC;
4328 for (unsigned I = 0, E = StringByteLength; I != E; ++I)
4329 JC.update(GetLittleEndianByte(I));
4330
4331 // <encoded-crc>: The CRC is encoded utilizing the standard number mangling
4332 // scheme.
4333 Mangler.mangleNumber(JC.getCRC());
4334
4335 // <encoded-string>: The mangled name also contains the first 32 bytes
4336 // (including null-terminator bytes) of the encoded StringLiteral.
4337 // Each character is encoded by splitting them into bytes and then encoding
4338 // the constituent bytes.
4339 auto MangleByte = [&Mangler](char Byte) {
4340 // There are five different manglings for characters:
4341 // - [a-zA-Z0-9_$]: A one-to-one mapping.
4342 // - ?[a-z]: The range from \xe1 to \xfa.
4343 // - ?[A-Z]: The range from \xc1 to \xda.
4344 // - ?[0-9]: The set of [,/\:. \n\t'-].
4345 // - ?$XX: A fallback which maps nibbles.
4346 if (isAsciiIdentifierContinue(Byte, /*AllowDollar=*/true)) {
4347 Mangler.getStream() << Byte;
4348 } else if (isLetter(Byte & 0x7f)) {
4349 Mangler.getStream() << '?' << static_cast<char>(Byte & 0x7f);
4350 } else {
4351 const char SpecialChars[] = {',', '/', '\\', ':', '.',
4352 ' ', '\n', '\t', '\'', '-'};
4353 const char *Pos = llvm::find(SpecialChars, Byte);
4354 if (Pos != std::end(SpecialChars)) {
4355 Mangler.getStream() << '?' << (Pos - std::begin(SpecialChars));
4356 } else {
4357 Mangler.getStream() << "?$";
4358 Mangler.getStream() << static_cast<char>('A' + ((Byte >> 4) & 0xf));
4359 Mangler.getStream() << static_cast<char>('A' + (Byte & 0xf));
4360 }
4361 }
4362 };
4363
4364 // Enforce our 32 bytes max, except wchar_t which gets 32 chars instead.
4365 unsigned MaxBytesToMangle = SL->isWide() ? 64U : 32U;
4366 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);
4367 for (unsigned I = 0; I != NumBytesToMangle; ++I) {
4368 if (SL->isWide())
4369 MangleByte(GetBigEndianByte(I));
4370 else
4371 MangleByte(GetLittleEndianByte(I));
4372 }
4373
4374 Mangler.getStream() << '@';
4375}
4376
4377void MicrosoftCXXNameMangler::mangleAutoReturnType(const MemberPointerType *T,
4378 Qualifiers Quals) {
4379 QualType PointeeType = T->getPointeeType();
4380 manglePointerCVQualifiers(Quals);
4381 manglePointerExtQualifiers(Quals, PointeeType);
4382 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
4383 Out << '8';
4384 mangleName(T->getMostRecentCXXRecordDecl());
4385 mangleFunctionType(FPT, nullptr, true);
4386 } else {
4387 mangleQualifiers(PointeeType.getQualifiers(), true);
4388 mangleName(T->getMostRecentCXXRecordDecl());
4389 mangleAutoReturnType(PointeeType, QMM_Drop);
4390 }
4391}
4392
4393void MicrosoftCXXNameMangler::mangleAutoReturnType(const PointerType *T,
4394 Qualifiers Quals) {
4395 QualType PointeeType = T->getPointeeType();
4396 assert(!PointeeType.getQualifiers().hasAddressSpace() &&
4397 "Unexpected address space mangling required");
4398
4399 manglePointerCVQualifiers(Quals);
4400 manglePointerExtQualifiers(Quals, PointeeType);
4401
4402 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
4403 Out << '6';
4404 mangleFunctionType(FPT);
4405 } else {
4406 mangleAutoReturnType(PointeeType, QMM_Mangle);
4407 }
4408}
4409
4410void MicrosoftCXXNameMangler::mangleAutoReturnType(const LValueReferenceType *T,
4411 Qualifiers Quals) {
4412 QualType PointeeType = T->getPointeeType();
4413 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
4414 Out << 'A';
4415 manglePointerExtQualifiers(Quals, PointeeType);
4416 mangleAutoReturnType(PointeeType, QMM_Mangle);
4417}
4418
4419void MicrosoftCXXNameMangler::mangleAutoReturnType(const RValueReferenceType *T,
4420 Qualifiers Quals) {
4421 QualType PointeeType = T->getPointeeType();
4422 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
4423 Out << "$$Q";
4424 manglePointerExtQualifiers(Quals, PointeeType);
4425 mangleAutoReturnType(PointeeType, QMM_Mangle);
4426}
4427
4429 DiagnosticsEngine &Diags,
4430 bool IsAux) {
4431 return new MicrosoftMangleContextImpl(Context, Diags, IsAux);
4432}
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:187
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:226
TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)
bool addressSpaceMapManglingFor(LangAS AS) const
const clang::PrintingPolicy & getPrintingPolicy() const
Definition ASTContext.h:850
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:3730
QualType getElementType() const
Definition TypeBase.h:3742
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Definition TypeBase.h:8148
bool isUnsigned() const
Definition TypeBase.h:8211
unsigned getNumBits() const
Definition TypeBase.h:8213
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4671
QualType getPointeeType() const
Definition TypeBase.h:3562
Kind getKind() const
Definition TypeBase.h:3220
StringRef getName(const PrintingPolicy &Policy) const
Definition Type.cpp:3427
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
Definition DeclCXX.cpp:2724
bool isVirtual() const
Definition DeclCXX.h:2190
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2261
bool isInstance() const
Definition DeclCXX.h:2162
Decl * getLambdaContextDecl() const
Retrieve the declaration that provides additional context for a lambda, when the normal declaration c...
Definition DeclCXX.cpp:1834
CXXRecordDecl * getMostRecentDecl()
Definition DeclCXX.h:539
base_class_range bases()
Definition DeclCXX.h:608
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition DeclCXX.h: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:1771
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
Represents a class template specialization, which refers to a class template with a given set of temp...
QualType getElementType() const
Definition TypeBase.h:3293
llvm::APInt getSize() const
Return the constant array size as an APInt.
Definition TypeBase.h:3824
unsigned getNumColumns() const
Returns the number of columns in the matrix.
Definition TypeBase.h:4414
unsigned getNumRows() const
Returns the number of rows in the matrix.
Definition TypeBase.h:4411
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:232
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:913
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:277
QualType getType() const
Definition Expr.h:144
Represents a function declaration or definition.
Definition Decl.h:2000
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2797
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition Decl.cpp:4314
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition Decl.cpp:3748
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition Decl.cpp:4330
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Definition Decl.cpp:3619
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4550
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5276
unsigned getNumParams() const
Definition TypeBase.h:5554
Qualifiers getMethodQuals() const
Definition TypeBase.h:5702
QualType getParamType(unsigned i) const
Definition TypeBase.h:5556
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
Definition Type.cpp:3910
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5680
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition TypeBase.h:5710
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4472
CallingConv getCallConv() const
Definition TypeBase.h:4827
QualType getReturnType() const
Definition TypeBase.h:4812
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:3625
QualType getElementType() const
Returns type of the elements being stored in the matrix.
Definition TypeBase.h:4359
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3661
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
Definition Type.cpp:5526
QualType getPointeeType() const
Definition TypeBase.h:3679
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:274
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
Definition Decl.cpp:1206
bool hasLinkage() const
Determine whether this declaration has linkage.
Definition Decl.cpp:1942
bool isExternallyVisible() const
Definition Decl.h:433
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
Definition Type.cpp:952
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
Definition TypeBase.h:7979
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2084
Represents a parameter to a function.
Definition Decl.h:1790
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
Definition Decl.h:1850
bool isExplicitObjectParameter() const
Definition Decl.h:1878
QualType getElementType() const
Definition TypeBase.h:8178
bool isReadOnly() const
Definition TypeBase.h:8197
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:3336
QualType getPointeeType() const
Definition TypeBase.h:3346
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:1302
QualType withConst() const
Definition TypeBase.h:1165
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8349
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8389
QualType getCanonicalType() const
Definition TypeBase.h:8401
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8443
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:8381
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:3643
field_range fields() const
Definition Decl.h:4527
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
Definition Decl.h:4376
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
QualType getPointeeType() const
Definition TypeBase.h:3599
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
const char * getStmtClassName() const
Definition Stmt.cpp:86
bool isWide() const
Definition Expr.h:1920
unsigned getLength() const
Definition Expr.h:1912
uint32_t getCodeUnit(size_t i) const
Definition Expr.h:1885
unsigned getCharByteWidth() const
Definition Expr.h:1913
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3717
TagDecl * getDefinition() const
Returns the TagDecl that actually defines this struct/union/class/enum.
Definition Decl.cpp:4930
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition Decl.h:3951
TagKind getTagKind() const
Definition Decl.h:3914
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:8606
bool isVoidType() const
Definition TypeBase.h:8952
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:8685
bool isPointerType() const
Definition TypeBase.h:8586
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9246
bool isReferenceType() const
Definition TypeBase.h:8610
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:753
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition TypeBase.h:2907
bool isMemberDataPointerType() const
Definition TypeBase.h:8678
bool isMemberPointerType() const
Definition TypeBase.h:8667
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9232
bool isFunctionType() const
Definition TypeBase.h:8582
bool isAnyPointerType() const
Definition TypeBase.h:8594
TypeClass getTypeClass() const
Definition TypeBase.h:2391
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9179
bool isRecordType() const
Definition TypeBase.h:8713
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
QualType getType() const
Definition Decl.h:723
TLSKind getTLSKind() const
Definition Decl.cpp:2180
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2202
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition Decl.h:1283
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition Decl.h:1208
bool isExternC() const
Determines whether this variable is a variable with external, C linkage.
Definition Decl.cpp:2257
Represents a variable template specialization, which refers to a variable template with a given set o...
unsigned getNumElements() const
Definition TypeBase.h:4198
QualType getElementType() const
Definition TypeBase.h:4197
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:1786
@ RQ_None
No ref-qualifier was provided.
Definition TypeBase.h:1788
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition TypeBase.h:1791
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition TypeBase.h:1794
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
CXXDtorType
C++ destructor types.
Definition ABI.h:34
@ Dtor_VectorDeleting
Vector deleting dtor.
Definition ABI.h:40
@ Dtor_Comdat
The COMDAT used for dtors.
Definition ABI.h:38
@ Dtor_Unified
GCC-style unified dtor.
Definition ABI.h:39
@ Dtor_Base
Base object dtor.
Definition ABI.h:37
@ Dtor_Complete
Complete object dtor.
Definition ABI.h:36
@ Dtor_Deleting
Deleting dtor.
Definition ABI.h:35
TagTypeKind
The kind of a tag type.
Definition TypeBase.h:5900
@ Type
The name was classified as a type.
Definition Sema.h:564
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool isPtrSizeAddressSpace(LangAS AS)
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
Definition Specifiers.h: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