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