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