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