1f4a2713aSLionel Sambuc //===--- MicrosoftMangle.cpp - Microsoft Visual C++ Name Mangling ---------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This provides C++ name mangling targeting the Microsoft Visual C++ ABI.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc
14f4a2713aSLionel Sambuc #include "clang/AST/Mangle.h"
15f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
16f4a2713aSLionel Sambuc #include "clang/AST/Attr.h"
17f4a2713aSLionel Sambuc #include "clang/AST/CXXInheritance.h"
18*0a6a1f1dSLionel Sambuc #include "clang/AST/CharUnits.h"
19f4a2713aSLionel Sambuc #include "clang/AST/Decl.h"
20f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
21f4a2713aSLionel Sambuc #include "clang/AST/DeclObjC.h"
22f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h"
23*0a6a1f1dSLionel Sambuc #include "clang/AST/Expr.h"
24f4a2713aSLionel Sambuc #include "clang/AST/ExprCXX.h"
25*0a6a1f1dSLionel Sambuc #include "clang/AST/VTableBuilder.h"
26f4a2713aSLionel Sambuc #include "clang/Basic/ABI.h"
27f4a2713aSLionel Sambuc #include "clang/Basic/DiagnosticOptions.h"
28f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h"
29*0a6a1f1dSLionel Sambuc #include "llvm/ADT/StringExtras.h"
30*0a6a1f1dSLionel Sambuc #include "llvm/Support/MathExtras.h"
31f4a2713aSLionel Sambuc
32f4a2713aSLionel Sambuc using namespace clang;
33f4a2713aSLionel Sambuc
34f4a2713aSLionel Sambuc namespace {
35f4a2713aSLionel Sambuc
36f4a2713aSLionel Sambuc /// \brief Retrieve the declaration context that should be used when mangling
37f4a2713aSLionel Sambuc /// the given declaration.
getEffectiveDeclContext(const Decl * D)38f4a2713aSLionel Sambuc static const DeclContext *getEffectiveDeclContext(const Decl *D) {
39f4a2713aSLionel Sambuc // The ABI assumes that lambda closure types that occur within
40f4a2713aSLionel Sambuc // default arguments live in the context of the function. However, due to
41f4a2713aSLionel Sambuc // the way in which Clang parses and creates function declarations, this is
42f4a2713aSLionel Sambuc // not the case: the lambda closure type ends up living in the context
43f4a2713aSLionel Sambuc // where the function itself resides, because the function declaration itself
44f4a2713aSLionel Sambuc // had not yet been created. Fix the context here.
45f4a2713aSLionel Sambuc if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
46f4a2713aSLionel Sambuc if (RD->isLambda())
47f4a2713aSLionel Sambuc if (ParmVarDecl *ContextParam =
48f4a2713aSLionel Sambuc dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
49f4a2713aSLionel Sambuc return ContextParam->getDeclContext();
50f4a2713aSLionel Sambuc }
51f4a2713aSLionel Sambuc
52f4a2713aSLionel Sambuc // Perform the same check for block literals.
53f4a2713aSLionel Sambuc if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
54f4a2713aSLionel Sambuc if (ParmVarDecl *ContextParam =
55f4a2713aSLionel Sambuc dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
56f4a2713aSLionel Sambuc return ContextParam->getDeclContext();
57f4a2713aSLionel Sambuc }
58f4a2713aSLionel Sambuc
59f4a2713aSLionel Sambuc const DeclContext *DC = D->getDeclContext();
60f4a2713aSLionel Sambuc if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(DC))
61f4a2713aSLionel Sambuc return getEffectiveDeclContext(CD);
62f4a2713aSLionel Sambuc
63f4a2713aSLionel Sambuc return DC;
64f4a2713aSLionel Sambuc }
65f4a2713aSLionel Sambuc
getEffectiveParentContext(const DeclContext * DC)66f4a2713aSLionel Sambuc static const DeclContext *getEffectiveParentContext(const DeclContext *DC) {
67f4a2713aSLionel Sambuc return getEffectiveDeclContext(cast<Decl>(DC));
68f4a2713aSLionel Sambuc }
69f4a2713aSLionel Sambuc
getStructor(const FunctionDecl * fn)70f4a2713aSLionel Sambuc static const FunctionDecl *getStructor(const FunctionDecl *fn) {
71f4a2713aSLionel Sambuc if (const FunctionTemplateDecl *ftd = fn->getPrimaryTemplate())
72f4a2713aSLionel Sambuc return ftd->getTemplatedDecl();
73f4a2713aSLionel Sambuc
74f4a2713aSLionel Sambuc return fn;
75f4a2713aSLionel Sambuc }
76f4a2713aSLionel Sambuc
isLambda(const NamedDecl * ND)77*0a6a1f1dSLionel Sambuc static bool isLambda(const NamedDecl *ND) {
78*0a6a1f1dSLionel Sambuc const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);
79*0a6a1f1dSLionel Sambuc if (!Record)
80*0a6a1f1dSLionel Sambuc return false;
81*0a6a1f1dSLionel Sambuc
82*0a6a1f1dSLionel Sambuc return Record->isLambda();
83*0a6a1f1dSLionel Sambuc }
84*0a6a1f1dSLionel Sambuc
85*0a6a1f1dSLionel Sambuc /// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
86*0a6a1f1dSLionel Sambuc /// Microsoft Visual C++ ABI.
87*0a6a1f1dSLionel Sambuc class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
88*0a6a1f1dSLionel Sambuc typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
89*0a6a1f1dSLionel Sambuc llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
90*0a6a1f1dSLionel Sambuc llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
91*0a6a1f1dSLionel Sambuc llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
92*0a6a1f1dSLionel Sambuc
93*0a6a1f1dSLionel Sambuc public:
MicrosoftMangleContextImpl(ASTContext & Context,DiagnosticsEngine & Diags)94*0a6a1f1dSLionel Sambuc MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags)
95*0a6a1f1dSLionel Sambuc : MicrosoftMangleContext(Context, Diags) {}
96*0a6a1f1dSLionel Sambuc bool shouldMangleCXXName(const NamedDecl *D) override;
97*0a6a1f1dSLionel Sambuc bool shouldMangleStringLiteral(const StringLiteral *SL) override;
98*0a6a1f1dSLionel Sambuc void mangleCXXName(const NamedDecl *D, raw_ostream &Out) override;
99*0a6a1f1dSLionel Sambuc void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
100*0a6a1f1dSLionel Sambuc raw_ostream &) override;
101*0a6a1f1dSLionel Sambuc void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk,
102*0a6a1f1dSLionel Sambuc raw_ostream &) override;
103*0a6a1f1dSLionel Sambuc void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
104*0a6a1f1dSLionel Sambuc const ThisAdjustment &ThisAdjustment,
105*0a6a1f1dSLionel Sambuc raw_ostream &) override;
106*0a6a1f1dSLionel Sambuc void mangleCXXVFTable(const CXXRecordDecl *Derived,
107*0a6a1f1dSLionel Sambuc ArrayRef<const CXXRecordDecl *> BasePath,
108*0a6a1f1dSLionel Sambuc raw_ostream &Out) override;
109*0a6a1f1dSLionel Sambuc void mangleCXXVBTable(const CXXRecordDecl *Derived,
110*0a6a1f1dSLionel Sambuc ArrayRef<const CXXRecordDecl *> BasePath,
111*0a6a1f1dSLionel Sambuc raw_ostream &Out) override;
112*0a6a1f1dSLionel Sambuc void mangleCXXRTTI(QualType T, raw_ostream &Out) override;
113*0a6a1f1dSLionel Sambuc void mangleCXXRTTIName(QualType T, raw_ostream &Out) override;
114*0a6a1f1dSLionel Sambuc void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived,
115*0a6a1f1dSLionel Sambuc uint32_t NVOffset, int32_t VBPtrOffset,
116*0a6a1f1dSLionel Sambuc uint32_t VBTableOffset, uint32_t Flags,
117*0a6a1f1dSLionel Sambuc raw_ostream &Out) override;
118*0a6a1f1dSLionel Sambuc void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
119*0a6a1f1dSLionel Sambuc raw_ostream &Out) override;
120*0a6a1f1dSLionel Sambuc void mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
121*0a6a1f1dSLionel Sambuc raw_ostream &Out) override;
122*0a6a1f1dSLionel Sambuc void
123*0a6a1f1dSLionel Sambuc mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
124*0a6a1f1dSLionel Sambuc ArrayRef<const CXXRecordDecl *> BasePath,
125*0a6a1f1dSLionel Sambuc raw_ostream &Out) override;
126*0a6a1f1dSLionel Sambuc void mangleTypeName(QualType T, raw_ostream &) override;
127*0a6a1f1dSLionel Sambuc void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
128*0a6a1f1dSLionel Sambuc raw_ostream &) override;
129*0a6a1f1dSLionel Sambuc void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
130*0a6a1f1dSLionel Sambuc raw_ostream &) override;
131*0a6a1f1dSLionel Sambuc void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber,
132*0a6a1f1dSLionel Sambuc raw_ostream &) override;
133*0a6a1f1dSLionel Sambuc void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override;
134*0a6a1f1dSLionel Sambuc void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
135*0a6a1f1dSLionel Sambuc void mangleDynamicAtExitDestructor(const VarDecl *D,
136*0a6a1f1dSLionel Sambuc raw_ostream &Out) override;
137*0a6a1f1dSLionel Sambuc void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override;
getNextDiscriminator(const NamedDecl * ND,unsigned & disc)138*0a6a1f1dSLionel Sambuc bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
139*0a6a1f1dSLionel Sambuc // Lambda closure types are already numbered.
140*0a6a1f1dSLionel Sambuc if (isLambda(ND))
141*0a6a1f1dSLionel Sambuc return false;
142*0a6a1f1dSLionel Sambuc
143*0a6a1f1dSLionel Sambuc const DeclContext *DC = getEffectiveDeclContext(ND);
144*0a6a1f1dSLionel Sambuc if (!DC->isFunctionOrMethod())
145*0a6a1f1dSLionel Sambuc return false;
146*0a6a1f1dSLionel Sambuc
147*0a6a1f1dSLionel Sambuc // Use the canonical number for externally visible decls.
148*0a6a1f1dSLionel Sambuc if (ND->isExternallyVisible()) {
149*0a6a1f1dSLionel Sambuc disc = getASTContext().getManglingNumber(ND);
150*0a6a1f1dSLionel Sambuc return true;
151*0a6a1f1dSLionel Sambuc }
152*0a6a1f1dSLionel Sambuc
153*0a6a1f1dSLionel Sambuc // Anonymous tags are already numbered.
154*0a6a1f1dSLionel Sambuc if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
155*0a6a1f1dSLionel Sambuc if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl())
156*0a6a1f1dSLionel Sambuc return false;
157*0a6a1f1dSLionel Sambuc }
158*0a6a1f1dSLionel Sambuc
159*0a6a1f1dSLionel Sambuc // Make up a reasonable number for internal decls.
160*0a6a1f1dSLionel Sambuc unsigned &discriminator = Uniquifier[ND];
161*0a6a1f1dSLionel Sambuc if (!discriminator)
162*0a6a1f1dSLionel Sambuc discriminator = ++Discriminator[std::make_pair(DC, ND->getIdentifier())];
163*0a6a1f1dSLionel Sambuc disc = discriminator + 1;
164*0a6a1f1dSLionel Sambuc return true;
165*0a6a1f1dSLionel Sambuc }
166*0a6a1f1dSLionel Sambuc
getLambdaId(const CXXRecordDecl * RD)167*0a6a1f1dSLionel Sambuc unsigned getLambdaId(const CXXRecordDecl *RD) {
168*0a6a1f1dSLionel Sambuc assert(RD->isLambda() && "RD must be a lambda!");
169*0a6a1f1dSLionel Sambuc assert(!RD->isExternallyVisible() && "RD must not be visible!");
170*0a6a1f1dSLionel Sambuc assert(RD->getLambdaManglingNumber() == 0 &&
171*0a6a1f1dSLionel Sambuc "RD must not have a mangling number!");
172*0a6a1f1dSLionel Sambuc std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator, bool>
173*0a6a1f1dSLionel Sambuc Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
174*0a6a1f1dSLionel Sambuc return Result.first->second;
175*0a6a1f1dSLionel Sambuc }
176*0a6a1f1dSLionel Sambuc
177*0a6a1f1dSLionel Sambuc private:
178*0a6a1f1dSLionel Sambuc void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode);
179*0a6a1f1dSLionel Sambuc };
180*0a6a1f1dSLionel Sambuc
181f4a2713aSLionel Sambuc /// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
182f4a2713aSLionel Sambuc /// Microsoft Visual C++ ABI.
183f4a2713aSLionel Sambuc class MicrosoftCXXNameMangler {
184*0a6a1f1dSLionel Sambuc MicrosoftMangleContextImpl &Context;
185f4a2713aSLionel Sambuc raw_ostream &Out;
186f4a2713aSLionel Sambuc
187f4a2713aSLionel Sambuc /// The "structor" is the top-level declaration being mangled, if
188f4a2713aSLionel Sambuc /// that's not a template specialization; otherwise it's the pattern
189f4a2713aSLionel Sambuc /// for that specialization.
190f4a2713aSLionel Sambuc const NamedDecl *Structor;
191f4a2713aSLionel Sambuc unsigned StructorType;
192f4a2713aSLionel Sambuc
193*0a6a1f1dSLionel Sambuc typedef llvm::SmallVector<std::string, 10> BackRefVec;
194*0a6a1f1dSLionel Sambuc BackRefVec NameBackReferences;
195f4a2713aSLionel Sambuc
196f4a2713aSLionel Sambuc typedef llvm::DenseMap<void *, unsigned> ArgBackRefMap;
197f4a2713aSLionel Sambuc ArgBackRefMap TypeBackReferences;
198f4a2713aSLionel Sambuc
getASTContext() const199f4a2713aSLionel Sambuc ASTContext &getASTContext() const { return Context.getASTContext(); }
200f4a2713aSLionel Sambuc
201f4a2713aSLionel Sambuc // FIXME: If we add support for __ptr32/64 qualifiers, then we should push
202f4a2713aSLionel Sambuc // this check into mangleQualifiers().
203f4a2713aSLionel Sambuc const bool PointersAre64Bit;
204f4a2713aSLionel Sambuc
205f4a2713aSLionel Sambuc public:
206f4a2713aSLionel Sambuc enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
207f4a2713aSLionel Sambuc
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl & C,raw_ostream & Out_)208*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
209*0a6a1f1dSLionel Sambuc : Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
210f4a2713aSLionel Sambuc PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
211f4a2713aSLionel Sambuc 64) {}
212f4a2713aSLionel Sambuc
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl & C,raw_ostream & Out_,const CXXDestructorDecl * D,CXXDtorType Type)213*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
214f4a2713aSLionel Sambuc const CXXDestructorDecl *D, CXXDtorType Type)
215*0a6a1f1dSLionel Sambuc : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
216f4a2713aSLionel Sambuc PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
217f4a2713aSLionel Sambuc 64) {}
218f4a2713aSLionel Sambuc
getStream() const219f4a2713aSLionel Sambuc raw_ostream &getStream() const { return Out; }
220f4a2713aSLionel Sambuc
221f4a2713aSLionel Sambuc void mangle(const NamedDecl *D, StringRef Prefix = "\01?");
222f4a2713aSLionel Sambuc void mangleName(const NamedDecl *ND);
223f4a2713aSLionel Sambuc void mangleFunctionEncoding(const FunctionDecl *FD);
224f4a2713aSLionel Sambuc void mangleVariableEncoding(const VarDecl *VD);
225*0a6a1f1dSLionel Sambuc void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD);
226*0a6a1f1dSLionel Sambuc void mangleMemberFunctionPointer(const CXXRecordDecl *RD,
227*0a6a1f1dSLionel Sambuc const CXXMethodDecl *MD);
228*0a6a1f1dSLionel Sambuc void mangleVirtualMemPtrThunk(
229*0a6a1f1dSLionel Sambuc const CXXMethodDecl *MD,
230*0a6a1f1dSLionel Sambuc const MicrosoftVTableContext::MethodVFTableLocation &ML);
231*0a6a1f1dSLionel Sambuc void mangleNumber(int64_t Number);
232f4a2713aSLionel Sambuc void mangleType(QualType T, SourceRange Range,
233f4a2713aSLionel Sambuc QualifierMangleMode QMM = QMM_Mangle);
234*0a6a1f1dSLionel Sambuc void mangleFunctionType(const FunctionType *T,
235*0a6a1f1dSLionel Sambuc const FunctionDecl *D = nullptr,
236*0a6a1f1dSLionel Sambuc bool ForceThisQuals = false);
237*0a6a1f1dSLionel Sambuc void mangleNestedName(const NamedDecl *ND);
238f4a2713aSLionel Sambuc
239f4a2713aSLionel Sambuc private:
mangleUnqualifiedName(const NamedDecl * ND)240f4a2713aSLionel Sambuc void mangleUnqualifiedName(const NamedDecl *ND) {
241f4a2713aSLionel Sambuc mangleUnqualifiedName(ND, ND->getDeclName());
242f4a2713aSLionel Sambuc }
243f4a2713aSLionel Sambuc void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name);
244f4a2713aSLionel Sambuc void mangleSourceName(StringRef Name);
245f4a2713aSLionel Sambuc void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc);
246f4a2713aSLionel Sambuc void mangleCXXDtorType(CXXDtorType T);
247f4a2713aSLionel Sambuc void mangleQualifiers(Qualifiers Quals, bool IsMember);
248*0a6a1f1dSLionel Sambuc void mangleRefQualifier(RefQualifierKind RefQualifier);
249*0a6a1f1dSLionel Sambuc void manglePointerCVQualifiers(Qualifiers Quals);
250*0a6a1f1dSLionel Sambuc void manglePointerExtQualifiers(Qualifiers Quals, const Type *PointeeType);
251f4a2713aSLionel Sambuc
252f4a2713aSLionel Sambuc void mangleUnscopedTemplateName(const TemplateDecl *ND);
253*0a6a1f1dSLionel Sambuc void
254*0a6a1f1dSLionel Sambuc mangleTemplateInstantiationName(const TemplateDecl *TD,
255f4a2713aSLionel Sambuc const TemplateArgumentList &TemplateArgs);
256f4a2713aSLionel Sambuc void mangleObjCMethodName(const ObjCMethodDecl *MD);
257f4a2713aSLionel Sambuc
258f4a2713aSLionel Sambuc void mangleArgumentType(QualType T, SourceRange Range);
259f4a2713aSLionel Sambuc
260f4a2713aSLionel Sambuc // Declare manglers for every type class.
261f4a2713aSLionel Sambuc #define ABSTRACT_TYPE(CLASS, PARENT)
262f4a2713aSLionel Sambuc #define NON_CANONICAL_TYPE(CLASS, PARENT)
263f4a2713aSLionel Sambuc #define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \
264f4a2713aSLionel Sambuc SourceRange Range);
265f4a2713aSLionel Sambuc #include "clang/AST/TypeNodes.def"
266f4a2713aSLionel Sambuc #undef ABSTRACT_TYPE
267f4a2713aSLionel Sambuc #undef NON_CANONICAL_TYPE
268f4a2713aSLionel Sambuc #undef TYPE
269f4a2713aSLionel Sambuc
270f4a2713aSLionel Sambuc void mangleType(const TagDecl *TD);
271f4a2713aSLionel Sambuc void mangleDecayedArrayType(const ArrayType *T);
272f4a2713aSLionel Sambuc void mangleArrayType(const ArrayType *T);
273f4a2713aSLionel Sambuc void mangleFunctionClass(const FunctionDecl *FD);
274f4a2713aSLionel Sambuc void mangleCallingConvention(const FunctionType *T);
275f4a2713aSLionel Sambuc void mangleIntegerLiteral(const llvm::APSInt &Number, bool IsBoolean);
276f4a2713aSLionel Sambuc void mangleExpression(const Expr *E);
277f4a2713aSLionel Sambuc void mangleThrowSpecification(const FunctionProtoType *T);
278f4a2713aSLionel Sambuc
279f4a2713aSLionel Sambuc void mangleTemplateArgs(const TemplateDecl *TD,
280f4a2713aSLionel Sambuc const TemplateArgumentList &TemplateArgs);
281*0a6a1f1dSLionel Sambuc void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA,
282*0a6a1f1dSLionel Sambuc const NamedDecl *Parm);
283f4a2713aSLionel Sambuc };
284f4a2713aSLionel Sambuc }
285f4a2713aSLionel Sambuc
shouldMangleCXXName(const NamedDecl * D)286f4a2713aSLionel Sambuc bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
287f4a2713aSLionel Sambuc if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
288f4a2713aSLionel Sambuc LanguageLinkage L = FD->getLanguageLinkage();
289f4a2713aSLionel Sambuc // Overloadable functions need mangling.
290f4a2713aSLionel Sambuc if (FD->hasAttr<OverloadableAttr>())
291f4a2713aSLionel Sambuc return true;
292f4a2713aSLionel Sambuc
293f4a2713aSLionel Sambuc // The ABI expects that we would never mangle "typical" user-defined entry
294f4a2713aSLionel Sambuc // points regardless of visibility or freestanding-ness.
295f4a2713aSLionel Sambuc //
296f4a2713aSLionel Sambuc // N.B. This is distinct from asking about "main". "main" has a lot of
297f4a2713aSLionel Sambuc // special rules associated with it in the standard while these
298f4a2713aSLionel Sambuc // user-defined entry points are outside of the purview of the standard.
299f4a2713aSLionel Sambuc // For example, there can be only one definition for "main" in a standards
300f4a2713aSLionel Sambuc // compliant program; however nothing forbids the existence of wmain and
301f4a2713aSLionel Sambuc // WinMain in the same translation unit.
302f4a2713aSLionel Sambuc if (FD->isMSVCRTEntryPoint())
303f4a2713aSLionel Sambuc return false;
304f4a2713aSLionel Sambuc
305f4a2713aSLionel Sambuc // C++ functions and those whose names are not a simple identifier need
306f4a2713aSLionel Sambuc // mangling.
307f4a2713aSLionel Sambuc if (!FD->getDeclName().isIdentifier() || L == CXXLanguageLinkage)
308f4a2713aSLionel Sambuc return true;
309f4a2713aSLionel Sambuc
310f4a2713aSLionel Sambuc // C functions are not mangled.
311f4a2713aSLionel Sambuc if (L == CLanguageLinkage)
312f4a2713aSLionel Sambuc return false;
313f4a2713aSLionel Sambuc }
314f4a2713aSLionel Sambuc
315f4a2713aSLionel Sambuc // Otherwise, no mangling is done outside C++ mode.
316f4a2713aSLionel Sambuc if (!getASTContext().getLangOpts().CPlusPlus)
317f4a2713aSLionel Sambuc return false;
318f4a2713aSLionel Sambuc
319f4a2713aSLionel Sambuc if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
320f4a2713aSLionel Sambuc // C variables are not mangled.
321f4a2713aSLionel Sambuc if (VD->isExternC())
322f4a2713aSLionel Sambuc return false;
323f4a2713aSLionel Sambuc
324f4a2713aSLionel Sambuc // Variables at global scope with non-internal linkage are not mangled.
325f4a2713aSLionel Sambuc const DeclContext *DC = getEffectiveDeclContext(D);
326f4a2713aSLionel Sambuc // Check for extern variable declared locally.
327f4a2713aSLionel Sambuc if (DC->isFunctionOrMethod() && D->hasLinkage())
328f4a2713aSLionel Sambuc while (!DC->isNamespace() && !DC->isTranslationUnit())
329f4a2713aSLionel Sambuc DC = getEffectiveParentContext(DC);
330f4a2713aSLionel Sambuc
331f4a2713aSLionel Sambuc if (DC->isTranslationUnit() && D->getFormalLinkage() == InternalLinkage &&
332f4a2713aSLionel Sambuc !isa<VarTemplateSpecializationDecl>(D))
333f4a2713aSLionel Sambuc return false;
334f4a2713aSLionel Sambuc }
335f4a2713aSLionel Sambuc
336f4a2713aSLionel Sambuc return true;
337f4a2713aSLionel Sambuc }
338f4a2713aSLionel Sambuc
339*0a6a1f1dSLionel Sambuc bool
shouldMangleStringLiteral(const StringLiteral * SL)340*0a6a1f1dSLionel Sambuc MicrosoftMangleContextImpl::shouldMangleStringLiteral(const StringLiteral *SL) {
341*0a6a1f1dSLionel Sambuc return true;
342*0a6a1f1dSLionel Sambuc }
343*0a6a1f1dSLionel Sambuc
mangle(const NamedDecl * D,StringRef Prefix)344*0a6a1f1dSLionel Sambuc void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) {
345f4a2713aSLionel Sambuc // MSVC doesn't mangle C++ names the same way it mangles extern "C" names.
346f4a2713aSLionel Sambuc // Therefore it's really important that we don't decorate the
347f4a2713aSLionel Sambuc // name with leading underscores or leading/trailing at signs. So, by
348f4a2713aSLionel Sambuc // default, we emit an asm marker at the start so we get the name right.
349f4a2713aSLionel Sambuc // Callers can override this with a custom prefix.
350f4a2713aSLionel Sambuc
351f4a2713aSLionel Sambuc // <mangled-name> ::= ? <name> <type-encoding>
352f4a2713aSLionel Sambuc Out << Prefix;
353f4a2713aSLionel Sambuc mangleName(D);
354f4a2713aSLionel Sambuc if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
355f4a2713aSLionel Sambuc mangleFunctionEncoding(FD);
356f4a2713aSLionel Sambuc else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
357f4a2713aSLionel Sambuc mangleVariableEncoding(VD);
358f4a2713aSLionel Sambuc else {
359f4a2713aSLionel Sambuc // TODO: Fields? Can MSVC even mangle them?
360f4a2713aSLionel Sambuc // Issue a diagnostic for now.
361f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
362*0a6a1f1dSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(
363*0a6a1f1dSLionel Sambuc DiagnosticsEngine::Error, "cannot mangle this declaration yet");
364*0a6a1f1dSLionel Sambuc Diags.Report(D->getLocation(), DiagID) << D->getSourceRange();
365f4a2713aSLionel Sambuc }
366f4a2713aSLionel Sambuc }
367f4a2713aSLionel Sambuc
mangleFunctionEncoding(const FunctionDecl * FD)368f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
369f4a2713aSLionel Sambuc // <type-encoding> ::= <function-class> <function-type>
370f4a2713aSLionel Sambuc
371f4a2713aSLionel Sambuc // Since MSVC operates on the type as written and not the canonical type, it
372f4a2713aSLionel Sambuc // actually matters which decl we have here. MSVC appears to choose the
373f4a2713aSLionel Sambuc // first, since it is most likely to be the declaration in a header file.
374f4a2713aSLionel Sambuc FD = FD->getFirstDecl();
375f4a2713aSLionel Sambuc
376f4a2713aSLionel Sambuc // We should never ever see a FunctionNoProtoType at this point.
377f4a2713aSLionel Sambuc // We don't even know how to mangle their types anyway :).
378f4a2713aSLionel Sambuc const FunctionProtoType *FT = FD->getType()->castAs<FunctionProtoType>();
379f4a2713aSLionel Sambuc
380f4a2713aSLionel Sambuc // extern "C" functions can hold entities that must be mangled.
381f4a2713aSLionel Sambuc // As it stands, these functions still need to get expressed in the full
382f4a2713aSLionel Sambuc // external name. They have their class and type omitted, replaced with '9'.
383f4a2713aSLionel Sambuc if (Context.shouldMangleDeclName(FD)) {
384f4a2713aSLionel Sambuc // First, the function class.
385f4a2713aSLionel Sambuc mangleFunctionClass(FD);
386f4a2713aSLionel Sambuc
387f4a2713aSLionel Sambuc mangleFunctionType(FT, FD);
388f4a2713aSLionel Sambuc } else
389f4a2713aSLionel Sambuc Out << '9';
390f4a2713aSLionel Sambuc }
391f4a2713aSLionel Sambuc
mangleVariableEncoding(const VarDecl * VD)392f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
393f4a2713aSLionel Sambuc // <type-encoding> ::= <storage-class> <variable-type>
394f4a2713aSLionel Sambuc // <storage-class> ::= 0 # private static member
395f4a2713aSLionel Sambuc // ::= 1 # protected static member
396f4a2713aSLionel Sambuc // ::= 2 # public static member
397f4a2713aSLionel Sambuc // ::= 3 # global
398f4a2713aSLionel Sambuc // ::= 4 # static local
399f4a2713aSLionel Sambuc
400f4a2713aSLionel Sambuc // The first character in the encoding (after the name) is the storage class.
401f4a2713aSLionel Sambuc if (VD->isStaticDataMember()) {
402f4a2713aSLionel Sambuc // If it's a static member, it also encodes the access level.
403f4a2713aSLionel Sambuc switch (VD->getAccess()) {
404f4a2713aSLionel Sambuc default:
405f4a2713aSLionel Sambuc case AS_private: Out << '0'; break;
406f4a2713aSLionel Sambuc case AS_protected: Out << '1'; break;
407f4a2713aSLionel Sambuc case AS_public: Out << '2'; break;
408f4a2713aSLionel Sambuc }
409f4a2713aSLionel Sambuc }
410f4a2713aSLionel Sambuc else if (!VD->isStaticLocal())
411f4a2713aSLionel Sambuc Out << '3';
412f4a2713aSLionel Sambuc else
413f4a2713aSLionel Sambuc Out << '4';
414f4a2713aSLionel Sambuc // Now mangle the type.
415f4a2713aSLionel Sambuc // <variable-type> ::= <type> <cvr-qualifiers>
416f4a2713aSLionel Sambuc // ::= <type> <pointee-cvr-qualifiers> # pointers, references
417f4a2713aSLionel Sambuc // Pointers and references are odd. The type of 'int * const foo;' gets
418f4a2713aSLionel Sambuc // mangled as 'QAHA' instead of 'PAHB', for example.
419*0a6a1f1dSLionel Sambuc SourceRange SR = VD->getSourceRange();
420*0a6a1f1dSLionel Sambuc QualType Ty = VD->getType();
421f4a2713aSLionel Sambuc if (Ty->isPointerType() || Ty->isReferenceType() ||
422f4a2713aSLionel Sambuc Ty->isMemberPointerType()) {
423*0a6a1f1dSLionel Sambuc mangleType(Ty, SR, QMM_Drop);
424*0a6a1f1dSLionel Sambuc manglePointerExtQualifiers(
425*0a6a1f1dSLionel Sambuc Ty.getDesugaredType(getASTContext()).getLocalQualifiers(), nullptr);
426f4a2713aSLionel Sambuc if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()) {
427f4a2713aSLionel Sambuc mangleQualifiers(MPT->getPointeeType().getQualifiers(), true);
428f4a2713aSLionel Sambuc // Member pointers are suffixed with a back reference to the member
429f4a2713aSLionel Sambuc // pointer's class name.
430f4a2713aSLionel Sambuc mangleName(MPT->getClass()->getAsCXXRecordDecl());
431f4a2713aSLionel Sambuc } else
432f4a2713aSLionel Sambuc mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
433f4a2713aSLionel Sambuc } else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
434f4a2713aSLionel Sambuc // Global arrays are funny, too.
435f4a2713aSLionel Sambuc mangleDecayedArrayType(AT);
436f4a2713aSLionel Sambuc if (AT->getElementType()->isArrayType())
437f4a2713aSLionel Sambuc Out << 'A';
438f4a2713aSLionel Sambuc else
439f4a2713aSLionel Sambuc mangleQualifiers(Ty.getQualifiers(), false);
440f4a2713aSLionel Sambuc } else {
441*0a6a1f1dSLionel Sambuc mangleType(Ty, SR, QMM_Drop);
442*0a6a1f1dSLionel Sambuc mangleQualifiers(Ty.getQualifiers(), false);
443f4a2713aSLionel Sambuc }
444f4a2713aSLionel Sambuc }
445f4a2713aSLionel Sambuc
mangleMemberDataPointer(const CXXRecordDecl * RD,const ValueDecl * VD)446*0a6a1f1dSLionel Sambuc void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD,
447*0a6a1f1dSLionel Sambuc const ValueDecl *VD) {
448*0a6a1f1dSLionel Sambuc // <member-data-pointer> ::= <integer-literal>
449*0a6a1f1dSLionel Sambuc // ::= $F <number> <number>
450*0a6a1f1dSLionel Sambuc // ::= $G <number> <number> <number>
451*0a6a1f1dSLionel Sambuc
452*0a6a1f1dSLionel Sambuc int64_t FieldOffset;
453*0a6a1f1dSLionel Sambuc int64_t VBTableOffset;
454*0a6a1f1dSLionel Sambuc MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel();
455*0a6a1f1dSLionel Sambuc if (VD) {
456*0a6a1f1dSLionel Sambuc FieldOffset = getASTContext().getFieldOffset(VD);
457*0a6a1f1dSLionel Sambuc assert(FieldOffset % getASTContext().getCharWidth() == 0 &&
458*0a6a1f1dSLionel Sambuc "cannot take address of bitfield");
459*0a6a1f1dSLionel Sambuc FieldOffset /= getASTContext().getCharWidth();
460*0a6a1f1dSLionel Sambuc
461*0a6a1f1dSLionel Sambuc VBTableOffset = 0;
462*0a6a1f1dSLionel Sambuc } else {
463*0a6a1f1dSLionel Sambuc FieldOffset = RD->nullFieldOffsetIsZero() ? 0 : -1;
464*0a6a1f1dSLionel Sambuc
465*0a6a1f1dSLionel Sambuc VBTableOffset = -1;
466*0a6a1f1dSLionel Sambuc }
467*0a6a1f1dSLionel Sambuc
468*0a6a1f1dSLionel Sambuc char Code = '\0';
469*0a6a1f1dSLionel Sambuc switch (IM) {
470*0a6a1f1dSLionel Sambuc case MSInheritanceAttr::Keyword_single_inheritance: Code = '0'; break;
471*0a6a1f1dSLionel Sambuc case MSInheritanceAttr::Keyword_multiple_inheritance: Code = '0'; break;
472*0a6a1f1dSLionel Sambuc case MSInheritanceAttr::Keyword_virtual_inheritance: Code = 'F'; break;
473*0a6a1f1dSLionel Sambuc case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'G'; break;
474*0a6a1f1dSLionel Sambuc }
475*0a6a1f1dSLionel Sambuc
476*0a6a1f1dSLionel Sambuc Out << '$' << Code;
477*0a6a1f1dSLionel Sambuc
478*0a6a1f1dSLionel Sambuc mangleNumber(FieldOffset);
479*0a6a1f1dSLionel Sambuc
480*0a6a1f1dSLionel Sambuc // The C++ standard doesn't allow base-to-derived member pointer conversions
481*0a6a1f1dSLionel Sambuc // in template parameter contexts, so the vbptr offset of data member pointers
482*0a6a1f1dSLionel Sambuc // is always zero.
483*0a6a1f1dSLionel Sambuc if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
484*0a6a1f1dSLionel Sambuc mangleNumber(0);
485*0a6a1f1dSLionel Sambuc if (MSInheritanceAttr::hasVBTableOffsetField(IM))
486*0a6a1f1dSLionel Sambuc mangleNumber(VBTableOffset);
487*0a6a1f1dSLionel Sambuc }
488*0a6a1f1dSLionel Sambuc
489*0a6a1f1dSLionel Sambuc void
mangleMemberFunctionPointer(const CXXRecordDecl * RD,const CXXMethodDecl * MD)490*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
491*0a6a1f1dSLionel Sambuc const CXXMethodDecl *MD) {
492*0a6a1f1dSLionel Sambuc // <member-function-pointer> ::= $1? <name>
493*0a6a1f1dSLionel Sambuc // ::= $H? <name> <number>
494*0a6a1f1dSLionel Sambuc // ::= $I? <name> <number> <number>
495*0a6a1f1dSLionel Sambuc // ::= $J? <name> <number> <number> <number>
496*0a6a1f1dSLionel Sambuc
497*0a6a1f1dSLionel Sambuc MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel();
498*0a6a1f1dSLionel Sambuc
499*0a6a1f1dSLionel Sambuc char Code = '\0';
500*0a6a1f1dSLionel Sambuc switch (IM) {
501*0a6a1f1dSLionel Sambuc case MSInheritanceAttr::Keyword_single_inheritance: Code = '1'; break;
502*0a6a1f1dSLionel Sambuc case MSInheritanceAttr::Keyword_multiple_inheritance: Code = 'H'; break;
503*0a6a1f1dSLionel Sambuc case MSInheritanceAttr::Keyword_virtual_inheritance: Code = 'I'; break;
504*0a6a1f1dSLionel Sambuc case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'J'; break;
505*0a6a1f1dSLionel Sambuc }
506*0a6a1f1dSLionel Sambuc
507*0a6a1f1dSLionel Sambuc // If non-virtual, mangle the name. If virtual, mangle as a virtual memptr
508*0a6a1f1dSLionel Sambuc // thunk.
509*0a6a1f1dSLionel Sambuc uint64_t NVOffset = 0;
510*0a6a1f1dSLionel Sambuc uint64_t VBTableOffset = 0;
511*0a6a1f1dSLionel Sambuc uint64_t VBPtrOffset = 0;
512*0a6a1f1dSLionel Sambuc if (MD) {
513*0a6a1f1dSLionel Sambuc Out << '$' << Code << '?';
514*0a6a1f1dSLionel Sambuc if (MD->isVirtual()) {
515*0a6a1f1dSLionel Sambuc MicrosoftVTableContext *VTContext =
516*0a6a1f1dSLionel Sambuc cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
517*0a6a1f1dSLionel Sambuc const MicrosoftVTableContext::MethodVFTableLocation &ML =
518*0a6a1f1dSLionel Sambuc VTContext->getMethodVFTableLocation(GlobalDecl(MD));
519*0a6a1f1dSLionel Sambuc mangleVirtualMemPtrThunk(MD, ML);
520*0a6a1f1dSLionel Sambuc NVOffset = ML.VFPtrOffset.getQuantity();
521*0a6a1f1dSLionel Sambuc VBTableOffset = ML.VBTableIndex * 4;
522*0a6a1f1dSLionel Sambuc if (ML.VBase) {
523*0a6a1f1dSLionel Sambuc const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
524*0a6a1f1dSLionel Sambuc VBPtrOffset = Layout.getVBPtrOffset().getQuantity();
525*0a6a1f1dSLionel Sambuc }
526*0a6a1f1dSLionel Sambuc } else {
527*0a6a1f1dSLionel Sambuc mangleName(MD);
528*0a6a1f1dSLionel Sambuc mangleFunctionEncoding(MD);
529*0a6a1f1dSLionel Sambuc }
530*0a6a1f1dSLionel Sambuc } else {
531*0a6a1f1dSLionel Sambuc // Null single inheritance member functions are encoded as a simple nullptr.
532*0a6a1f1dSLionel Sambuc if (IM == MSInheritanceAttr::Keyword_single_inheritance) {
533*0a6a1f1dSLionel Sambuc Out << "$0A@";
534*0a6a1f1dSLionel Sambuc return;
535*0a6a1f1dSLionel Sambuc }
536*0a6a1f1dSLionel Sambuc if (IM == MSInheritanceAttr::Keyword_unspecified_inheritance)
537*0a6a1f1dSLionel Sambuc VBTableOffset = -1;
538*0a6a1f1dSLionel Sambuc Out << '$' << Code;
539*0a6a1f1dSLionel Sambuc }
540*0a6a1f1dSLionel Sambuc
541*0a6a1f1dSLionel Sambuc if (MSInheritanceAttr::hasNVOffsetField(/*IsMemberFunction=*/true, IM))
542*0a6a1f1dSLionel Sambuc mangleNumber(NVOffset);
543*0a6a1f1dSLionel Sambuc if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
544*0a6a1f1dSLionel Sambuc mangleNumber(VBPtrOffset);
545*0a6a1f1dSLionel Sambuc if (MSInheritanceAttr::hasVBTableOffsetField(IM))
546*0a6a1f1dSLionel Sambuc mangleNumber(VBTableOffset);
547*0a6a1f1dSLionel Sambuc }
548*0a6a1f1dSLionel Sambuc
mangleVirtualMemPtrThunk(const CXXMethodDecl * MD,const MicrosoftVTableContext::MethodVFTableLocation & ML)549*0a6a1f1dSLionel Sambuc void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
550*0a6a1f1dSLionel Sambuc const CXXMethodDecl *MD,
551*0a6a1f1dSLionel Sambuc const MicrosoftVTableContext::MethodVFTableLocation &ML) {
552*0a6a1f1dSLionel Sambuc // Get the vftable offset.
553*0a6a1f1dSLionel Sambuc CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
554*0a6a1f1dSLionel Sambuc getASTContext().getTargetInfo().getPointerWidth(0));
555*0a6a1f1dSLionel Sambuc uint64_t OffsetInVFTable = ML.Index * PointerWidth.getQuantity();
556*0a6a1f1dSLionel Sambuc
557*0a6a1f1dSLionel Sambuc Out << "?_9";
558*0a6a1f1dSLionel Sambuc mangleName(MD->getParent());
559*0a6a1f1dSLionel Sambuc Out << "$B";
560*0a6a1f1dSLionel Sambuc mangleNumber(OffsetInVFTable);
561*0a6a1f1dSLionel Sambuc Out << 'A';
562*0a6a1f1dSLionel Sambuc Out << (PointersAre64Bit ? 'A' : 'E');
563*0a6a1f1dSLionel Sambuc }
564*0a6a1f1dSLionel Sambuc
mangleName(const NamedDecl * ND)565f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {
566f4a2713aSLionel Sambuc // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
567f4a2713aSLionel Sambuc
568f4a2713aSLionel Sambuc // Always start with the unqualified name.
569f4a2713aSLionel Sambuc mangleUnqualifiedName(ND);
570f4a2713aSLionel Sambuc
571*0a6a1f1dSLionel Sambuc mangleNestedName(ND);
572f4a2713aSLionel Sambuc
573f4a2713aSLionel Sambuc // Terminate the whole name with an '@'.
574f4a2713aSLionel Sambuc Out << '@';
575f4a2713aSLionel Sambuc }
576f4a2713aSLionel Sambuc
mangleNumber(int64_t Number)577*0a6a1f1dSLionel Sambuc void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
578*0a6a1f1dSLionel Sambuc // <non-negative integer> ::= A@ # when Number == 0
579*0a6a1f1dSLionel Sambuc // ::= <decimal digit> # when 1 <= Number <= 10
580*0a6a1f1dSLionel Sambuc // ::= <hex digit>+ @ # when Number >= 10
581*0a6a1f1dSLionel Sambuc //
582*0a6a1f1dSLionel Sambuc // <number> ::= [?] <non-negative integer>
583*0a6a1f1dSLionel Sambuc
584*0a6a1f1dSLionel Sambuc uint64_t Value = static_cast<uint64_t>(Number);
585*0a6a1f1dSLionel Sambuc if (Number < 0) {
586*0a6a1f1dSLionel Sambuc Value = -Value;
587*0a6a1f1dSLionel Sambuc Out << '?';
588f4a2713aSLionel Sambuc }
589f4a2713aSLionel Sambuc
590*0a6a1f1dSLionel Sambuc if (Value == 0)
591*0a6a1f1dSLionel Sambuc Out << "A@";
592*0a6a1f1dSLionel Sambuc else if (Value >= 1 && Value <= 10)
593*0a6a1f1dSLionel Sambuc Out << (Value - 1);
594*0a6a1f1dSLionel Sambuc else {
595*0a6a1f1dSLionel Sambuc // Numbers that are not encoded as decimal digits are represented as nibbles
596*0a6a1f1dSLionel Sambuc // in the range of ASCII characters 'A' to 'P'.
597*0a6a1f1dSLionel Sambuc // The number 0x123450 would be encoded as 'BCDEFA'
598*0a6a1f1dSLionel Sambuc char EncodedNumberBuffer[sizeof(uint64_t) * 2];
599*0a6a1f1dSLionel Sambuc MutableArrayRef<char> BufferRef(EncodedNumberBuffer);
600*0a6a1f1dSLionel Sambuc MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
601*0a6a1f1dSLionel Sambuc for (; Value != 0; Value >>= 4)
602*0a6a1f1dSLionel Sambuc *I++ = 'A' + (Value & 0xf);
603*0a6a1f1dSLionel Sambuc Out.write(I.base(), I - BufferRef.rbegin());
604f4a2713aSLionel Sambuc Out << '@';
605f4a2713aSLionel Sambuc }
606f4a2713aSLionel Sambuc }
607f4a2713aSLionel Sambuc
608f4a2713aSLionel Sambuc static const TemplateDecl *
isTemplate(const NamedDecl * ND,const TemplateArgumentList * & TemplateArgs)609f4a2713aSLionel Sambuc isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
610f4a2713aSLionel Sambuc // Check if we have a function template.
611f4a2713aSLionel Sambuc if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
612f4a2713aSLionel Sambuc if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {
613f4a2713aSLionel Sambuc TemplateArgs = FD->getTemplateSpecializationArgs();
614f4a2713aSLionel Sambuc return TD;
615f4a2713aSLionel Sambuc }
616f4a2713aSLionel Sambuc }
617f4a2713aSLionel Sambuc
618f4a2713aSLionel Sambuc // Check if we have a class template.
619f4a2713aSLionel Sambuc if (const ClassTemplateSpecializationDecl *Spec =
620f4a2713aSLionel Sambuc dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
621f4a2713aSLionel Sambuc TemplateArgs = &Spec->getTemplateArgs();
622f4a2713aSLionel Sambuc return Spec->getSpecializedTemplate();
623f4a2713aSLionel Sambuc }
624f4a2713aSLionel Sambuc
625*0a6a1f1dSLionel Sambuc // Check if we have a variable template.
626*0a6a1f1dSLionel Sambuc if (const VarTemplateSpecializationDecl *Spec =
627*0a6a1f1dSLionel Sambuc dyn_cast<VarTemplateSpecializationDecl>(ND)) {
628*0a6a1f1dSLionel Sambuc TemplateArgs = &Spec->getTemplateArgs();
629*0a6a1f1dSLionel Sambuc return Spec->getSpecializedTemplate();
630f4a2713aSLionel Sambuc }
631f4a2713aSLionel Sambuc
632*0a6a1f1dSLionel Sambuc return nullptr;
633*0a6a1f1dSLionel Sambuc }
634*0a6a1f1dSLionel Sambuc
mangleUnqualifiedName(const NamedDecl * ND,DeclarationName Name)635*0a6a1f1dSLionel Sambuc void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
636f4a2713aSLionel Sambuc DeclarationName Name) {
637f4a2713aSLionel Sambuc // <unqualified-name> ::= <operator-name>
638f4a2713aSLionel Sambuc // ::= <ctor-dtor-name>
639f4a2713aSLionel Sambuc // ::= <source-name>
640f4a2713aSLionel Sambuc // ::= <template-name>
641f4a2713aSLionel Sambuc
642f4a2713aSLionel Sambuc // Check if we have a template.
643*0a6a1f1dSLionel Sambuc const TemplateArgumentList *TemplateArgs = nullptr;
644f4a2713aSLionel Sambuc if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
645f4a2713aSLionel Sambuc // Function templates aren't considered for name back referencing. This
646f4a2713aSLionel Sambuc // makes sense since function templates aren't likely to occur multiple
647f4a2713aSLionel Sambuc // times in a symbol.
648f4a2713aSLionel Sambuc // FIXME: Test alias template mangling with MSVC 2013.
649f4a2713aSLionel Sambuc if (!isa<ClassTemplateDecl>(TD)) {
650f4a2713aSLionel Sambuc mangleTemplateInstantiationName(TD, *TemplateArgs);
651*0a6a1f1dSLionel Sambuc Out << '@';
652f4a2713aSLionel Sambuc return;
653f4a2713aSLionel Sambuc }
654f4a2713aSLionel Sambuc
655f4a2713aSLionel Sambuc // Here comes the tricky thing: if we need to mangle something like
656f4a2713aSLionel Sambuc // void foo(A::X<Y>, B::X<Y>),
657f4a2713aSLionel Sambuc // the X<Y> part is aliased. However, if you need to mangle
658f4a2713aSLionel Sambuc // void foo(A::X<A::Y>, A::X<B::Y>),
659f4a2713aSLionel Sambuc // the A::X<> part is not aliased.
660f4a2713aSLionel Sambuc // That said, from the mangler's perspective we have a structure like this:
661f4a2713aSLionel Sambuc // namespace[s] -> type[ -> template-parameters]
662f4a2713aSLionel Sambuc // but from the Clang perspective we have
663f4a2713aSLionel Sambuc // type [ -> template-parameters]
664f4a2713aSLionel Sambuc // \-> namespace[s]
665f4a2713aSLionel Sambuc // What we do is we create a new mangler, mangle the same type (without
666*0a6a1f1dSLionel Sambuc // a namespace suffix) to a string using the extra mangler and then use
667*0a6a1f1dSLionel Sambuc // the mangled type name as a key to check the mangling of different types
668*0a6a1f1dSLionel Sambuc // for aliasing.
669f4a2713aSLionel Sambuc
670*0a6a1f1dSLionel Sambuc llvm::SmallString<64> TemplateMangling;
671*0a6a1f1dSLionel Sambuc llvm::raw_svector_ostream Stream(TemplateMangling);
672f4a2713aSLionel Sambuc MicrosoftCXXNameMangler Extra(Context, Stream);
673*0a6a1f1dSLionel Sambuc Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
674f4a2713aSLionel Sambuc Stream.flush();
675f4a2713aSLionel Sambuc
676*0a6a1f1dSLionel Sambuc mangleSourceName(TemplateMangling);
677f4a2713aSLionel Sambuc return;
678f4a2713aSLionel Sambuc }
679f4a2713aSLionel Sambuc
680f4a2713aSLionel Sambuc switch (Name.getNameKind()) {
681f4a2713aSLionel Sambuc case DeclarationName::Identifier: {
682f4a2713aSLionel Sambuc if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
683f4a2713aSLionel Sambuc mangleSourceName(II->getName());
684f4a2713aSLionel Sambuc break;
685f4a2713aSLionel Sambuc }
686f4a2713aSLionel Sambuc
687f4a2713aSLionel Sambuc // Otherwise, an anonymous entity. We must have a declaration.
688f4a2713aSLionel Sambuc assert(ND && "mangling empty name without declaration");
689f4a2713aSLionel Sambuc
690f4a2713aSLionel Sambuc if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
691f4a2713aSLionel Sambuc if (NS->isAnonymousNamespace()) {
692f4a2713aSLionel Sambuc Out << "?A@";
693f4a2713aSLionel Sambuc break;
694f4a2713aSLionel Sambuc }
695f4a2713aSLionel Sambuc }
696f4a2713aSLionel Sambuc
697*0a6a1f1dSLionel Sambuc if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
698*0a6a1f1dSLionel Sambuc // We must have an anonymous union or struct declaration.
699*0a6a1f1dSLionel Sambuc const CXXRecordDecl *RD = VD->getType()->getAsCXXRecordDecl();
700*0a6a1f1dSLionel Sambuc assert(RD && "expected variable decl to have a record type");
701*0a6a1f1dSLionel Sambuc // Anonymous types with no tag or typedef get the name of their
702*0a6a1f1dSLionel Sambuc // declarator mangled in. If they have no declarator, number them with
703*0a6a1f1dSLionel Sambuc // a $S prefix.
704*0a6a1f1dSLionel Sambuc llvm::SmallString<64> Name("$S");
705*0a6a1f1dSLionel Sambuc // Get a unique id for the anonymous struct.
706*0a6a1f1dSLionel Sambuc Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
707*0a6a1f1dSLionel Sambuc mangleSourceName(Name.str());
708*0a6a1f1dSLionel Sambuc break;
709*0a6a1f1dSLionel Sambuc }
710*0a6a1f1dSLionel Sambuc
711f4a2713aSLionel Sambuc // We must have an anonymous struct.
712f4a2713aSLionel Sambuc const TagDecl *TD = cast<TagDecl>(ND);
713f4a2713aSLionel Sambuc if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {
714f4a2713aSLionel Sambuc assert(TD->getDeclContext() == D->getDeclContext() &&
715f4a2713aSLionel Sambuc "Typedef should not be in another decl context!");
716f4a2713aSLionel Sambuc assert(D->getDeclName().getAsIdentifierInfo() &&
717f4a2713aSLionel Sambuc "Typedef was not named!");
718f4a2713aSLionel Sambuc mangleSourceName(D->getDeclName().getAsIdentifierInfo()->getName());
719f4a2713aSLionel Sambuc break;
720f4a2713aSLionel Sambuc }
721f4a2713aSLionel Sambuc
722*0a6a1f1dSLionel Sambuc if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
723*0a6a1f1dSLionel Sambuc if (Record->isLambda()) {
724*0a6a1f1dSLionel Sambuc llvm::SmallString<10> Name("<lambda_");
725*0a6a1f1dSLionel Sambuc unsigned LambdaId;
726*0a6a1f1dSLionel Sambuc if (Record->getLambdaManglingNumber())
727*0a6a1f1dSLionel Sambuc LambdaId = Record->getLambdaManglingNumber();
728*0a6a1f1dSLionel Sambuc else
729*0a6a1f1dSLionel Sambuc LambdaId = Context.getLambdaId(Record);
730*0a6a1f1dSLionel Sambuc
731*0a6a1f1dSLionel Sambuc Name += llvm::utostr(LambdaId);
732*0a6a1f1dSLionel Sambuc Name += ">";
733*0a6a1f1dSLionel Sambuc
734*0a6a1f1dSLionel Sambuc mangleSourceName(Name);
735*0a6a1f1dSLionel Sambuc break;
736*0a6a1f1dSLionel Sambuc }
737*0a6a1f1dSLionel Sambuc }
738*0a6a1f1dSLionel Sambuc
739*0a6a1f1dSLionel Sambuc llvm::SmallString<64> Name("<unnamed-type-");
740f4a2713aSLionel Sambuc if (TD->hasDeclaratorForAnonDecl()) {
741f4a2713aSLionel Sambuc // Anonymous types with no tag or typedef get the name of their
742*0a6a1f1dSLionel Sambuc // declarator mangled in if they have one.
743f4a2713aSLionel Sambuc Name += TD->getDeclaratorForAnonDecl()->getName();
744*0a6a1f1dSLionel Sambuc } else {
745*0a6a1f1dSLionel Sambuc // Otherwise, number the types using a $S prefix.
746*0a6a1f1dSLionel Sambuc Name += "$S";
747*0a6a1f1dSLionel Sambuc Name += llvm::utostr(Context.getAnonymousStructId(TD));
748*0a6a1f1dSLionel Sambuc }
749f4a2713aSLionel Sambuc Name += ">";
750f4a2713aSLionel Sambuc mangleSourceName(Name.str());
751f4a2713aSLionel Sambuc break;
752f4a2713aSLionel Sambuc }
753f4a2713aSLionel Sambuc
754f4a2713aSLionel Sambuc case DeclarationName::ObjCZeroArgSelector:
755f4a2713aSLionel Sambuc case DeclarationName::ObjCOneArgSelector:
756f4a2713aSLionel Sambuc case DeclarationName::ObjCMultiArgSelector:
757f4a2713aSLionel Sambuc llvm_unreachable("Can't mangle Objective-C selector names here!");
758f4a2713aSLionel Sambuc
759f4a2713aSLionel Sambuc case DeclarationName::CXXConstructorName:
760f4a2713aSLionel Sambuc if (ND == Structor) {
761f4a2713aSLionel Sambuc assert(StructorType == Ctor_Complete &&
762f4a2713aSLionel Sambuc "Should never be asked to mangle a ctor other than complete");
763f4a2713aSLionel Sambuc }
764f4a2713aSLionel Sambuc Out << "?0";
765f4a2713aSLionel Sambuc break;
766f4a2713aSLionel Sambuc
767f4a2713aSLionel Sambuc case DeclarationName::CXXDestructorName:
768f4a2713aSLionel Sambuc if (ND == Structor)
769f4a2713aSLionel Sambuc // If the named decl is the C++ destructor we're mangling,
770f4a2713aSLionel Sambuc // use the type we were given.
771f4a2713aSLionel Sambuc mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
772f4a2713aSLionel Sambuc else
773f4a2713aSLionel Sambuc // Otherwise, use the base destructor name. This is relevant if a
774f4a2713aSLionel Sambuc // class with a destructor is declared within a destructor.
775f4a2713aSLionel Sambuc mangleCXXDtorType(Dtor_Base);
776f4a2713aSLionel Sambuc break;
777f4a2713aSLionel Sambuc
778f4a2713aSLionel Sambuc case DeclarationName::CXXConversionFunctionName:
779f4a2713aSLionel Sambuc // <operator-name> ::= ?B # (cast)
780f4a2713aSLionel Sambuc // The target type is encoded as the return type.
781f4a2713aSLionel Sambuc Out << "?B";
782f4a2713aSLionel Sambuc break;
783f4a2713aSLionel Sambuc
784f4a2713aSLionel Sambuc case DeclarationName::CXXOperatorName:
785f4a2713aSLionel Sambuc mangleOperatorName(Name.getCXXOverloadedOperator(), ND->getLocation());
786f4a2713aSLionel Sambuc break;
787f4a2713aSLionel Sambuc
788f4a2713aSLionel Sambuc case DeclarationName::CXXLiteralOperatorName: {
789*0a6a1f1dSLionel Sambuc Out << "?__K";
790*0a6a1f1dSLionel Sambuc mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
791f4a2713aSLionel Sambuc break;
792f4a2713aSLionel Sambuc }
793f4a2713aSLionel Sambuc
794f4a2713aSLionel Sambuc case DeclarationName::CXXUsingDirective:
795f4a2713aSLionel Sambuc llvm_unreachable("Can't mangle a using directive name!");
796f4a2713aSLionel Sambuc }
797f4a2713aSLionel Sambuc }
798f4a2713aSLionel Sambuc
mangleNestedName(const NamedDecl * ND)799*0a6a1f1dSLionel Sambuc void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) {
800f4a2713aSLionel Sambuc // <postfix> ::= <unqualified-name> [<postfix>]
801f4a2713aSLionel Sambuc // ::= <substitution> [<postfix>]
802*0a6a1f1dSLionel Sambuc const DeclContext *DC = getEffectiveDeclContext(ND);
803f4a2713aSLionel Sambuc
804*0a6a1f1dSLionel Sambuc while (!DC->isTranslationUnit()) {
805*0a6a1f1dSLionel Sambuc if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
806*0a6a1f1dSLionel Sambuc unsigned Disc;
807*0a6a1f1dSLionel Sambuc if (Context.getNextDiscriminator(ND, Disc)) {
808*0a6a1f1dSLionel Sambuc Out << '?';
809*0a6a1f1dSLionel Sambuc mangleNumber(Disc);
810*0a6a1f1dSLionel Sambuc Out << '?';
811*0a6a1f1dSLionel Sambuc }
812*0a6a1f1dSLionel Sambuc }
813f4a2713aSLionel Sambuc
814f4a2713aSLionel Sambuc if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
815*0a6a1f1dSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
816*0a6a1f1dSLionel Sambuc unsigned DiagID =
817*0a6a1f1dSLionel Sambuc Diags.getCustomDiagID(DiagnosticsEngine::Error,
818f4a2713aSLionel Sambuc "cannot mangle a local inside this block yet");
819f4a2713aSLionel Sambuc Diags.Report(BD->getLocation(), DiagID);
820f4a2713aSLionel Sambuc
821f4a2713aSLionel Sambuc // FIXME: This is completely, utterly, wrong; see ItaniumMangle
822f4a2713aSLionel Sambuc // for how this should be done.
823f4a2713aSLionel Sambuc Out << "__block_invoke" << Context.getBlockId(BD, false);
824f4a2713aSLionel Sambuc Out << '@';
825*0a6a1f1dSLionel Sambuc continue;
826*0a6a1f1dSLionel Sambuc } else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
827f4a2713aSLionel Sambuc mangleObjCMethodName(Method);
828*0a6a1f1dSLionel Sambuc } else if (isa<NamedDecl>(DC)) {
829*0a6a1f1dSLionel Sambuc ND = cast<NamedDecl>(DC);
830*0a6a1f1dSLionel Sambuc if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
831*0a6a1f1dSLionel Sambuc mangle(FD, "?");
832*0a6a1f1dSLionel Sambuc break;
833*0a6a1f1dSLionel Sambuc } else
834*0a6a1f1dSLionel Sambuc mangleUnqualifiedName(ND);
835*0a6a1f1dSLionel Sambuc }
836*0a6a1f1dSLionel Sambuc DC = DC->getParent();
837f4a2713aSLionel Sambuc }
838f4a2713aSLionel Sambuc }
839f4a2713aSLionel Sambuc
mangleCXXDtorType(CXXDtorType T)840f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
841f4a2713aSLionel Sambuc // Microsoft uses the names on the case labels for these dtor variants. Clang
842f4a2713aSLionel Sambuc // uses the Itanium terminology internally. Everything in this ABI delegates
843f4a2713aSLionel Sambuc // towards the base dtor.
844f4a2713aSLionel Sambuc switch (T) {
845f4a2713aSLionel Sambuc // <operator-name> ::= ?1 # destructor
846f4a2713aSLionel Sambuc case Dtor_Base: Out << "?1"; return;
847f4a2713aSLionel Sambuc // <operator-name> ::= ?_D # vbase destructor
848f4a2713aSLionel Sambuc case Dtor_Complete: Out << "?_D"; return;
849f4a2713aSLionel Sambuc // <operator-name> ::= ?_G # scalar deleting destructor
850f4a2713aSLionel Sambuc case Dtor_Deleting: Out << "?_G"; return;
851f4a2713aSLionel Sambuc // <operator-name> ::= ?_E # vector deleting destructor
852f4a2713aSLionel Sambuc // FIXME: Add a vector deleting dtor type. It goes in the vtable, so we need
853f4a2713aSLionel Sambuc // it.
854*0a6a1f1dSLionel Sambuc case Dtor_Comdat:
855*0a6a1f1dSLionel Sambuc llvm_unreachable("not expecting a COMDAT");
856f4a2713aSLionel Sambuc }
857f4a2713aSLionel Sambuc llvm_unreachable("Unsupported dtor type?");
858f4a2713aSLionel Sambuc }
859f4a2713aSLionel Sambuc
mangleOperatorName(OverloadedOperatorKind OO,SourceLocation Loc)860f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
861f4a2713aSLionel Sambuc SourceLocation Loc) {
862f4a2713aSLionel Sambuc switch (OO) {
863f4a2713aSLionel Sambuc // ?0 # constructor
864f4a2713aSLionel Sambuc // ?1 # destructor
865f4a2713aSLionel Sambuc // <operator-name> ::= ?2 # new
866f4a2713aSLionel Sambuc case OO_New: Out << "?2"; break;
867f4a2713aSLionel Sambuc // <operator-name> ::= ?3 # delete
868f4a2713aSLionel Sambuc case OO_Delete: Out << "?3"; break;
869f4a2713aSLionel Sambuc // <operator-name> ::= ?4 # =
870f4a2713aSLionel Sambuc case OO_Equal: Out << "?4"; break;
871f4a2713aSLionel Sambuc // <operator-name> ::= ?5 # >>
872f4a2713aSLionel Sambuc case OO_GreaterGreater: Out << "?5"; break;
873f4a2713aSLionel Sambuc // <operator-name> ::= ?6 # <<
874f4a2713aSLionel Sambuc case OO_LessLess: Out << "?6"; break;
875f4a2713aSLionel Sambuc // <operator-name> ::= ?7 # !
876f4a2713aSLionel Sambuc case OO_Exclaim: Out << "?7"; break;
877f4a2713aSLionel Sambuc // <operator-name> ::= ?8 # ==
878f4a2713aSLionel Sambuc case OO_EqualEqual: Out << "?8"; break;
879f4a2713aSLionel Sambuc // <operator-name> ::= ?9 # !=
880f4a2713aSLionel Sambuc case OO_ExclaimEqual: Out << "?9"; break;
881f4a2713aSLionel Sambuc // <operator-name> ::= ?A # []
882f4a2713aSLionel Sambuc case OO_Subscript: Out << "?A"; break;
883f4a2713aSLionel Sambuc // ?B # conversion
884f4a2713aSLionel Sambuc // <operator-name> ::= ?C # ->
885f4a2713aSLionel Sambuc case OO_Arrow: Out << "?C"; break;
886f4a2713aSLionel Sambuc // <operator-name> ::= ?D # *
887f4a2713aSLionel Sambuc case OO_Star: Out << "?D"; break;
888f4a2713aSLionel Sambuc // <operator-name> ::= ?E # ++
889f4a2713aSLionel Sambuc case OO_PlusPlus: Out << "?E"; break;
890f4a2713aSLionel Sambuc // <operator-name> ::= ?F # --
891f4a2713aSLionel Sambuc case OO_MinusMinus: Out << "?F"; break;
892f4a2713aSLionel Sambuc // <operator-name> ::= ?G # -
893f4a2713aSLionel Sambuc case OO_Minus: Out << "?G"; break;
894f4a2713aSLionel Sambuc // <operator-name> ::= ?H # +
895f4a2713aSLionel Sambuc case OO_Plus: Out << "?H"; break;
896f4a2713aSLionel Sambuc // <operator-name> ::= ?I # &
897f4a2713aSLionel Sambuc case OO_Amp: Out << "?I"; break;
898f4a2713aSLionel Sambuc // <operator-name> ::= ?J # ->*
899f4a2713aSLionel Sambuc case OO_ArrowStar: Out << "?J"; break;
900f4a2713aSLionel Sambuc // <operator-name> ::= ?K # /
901f4a2713aSLionel Sambuc case OO_Slash: Out << "?K"; break;
902f4a2713aSLionel Sambuc // <operator-name> ::= ?L # %
903f4a2713aSLionel Sambuc case OO_Percent: Out << "?L"; break;
904f4a2713aSLionel Sambuc // <operator-name> ::= ?M # <
905f4a2713aSLionel Sambuc case OO_Less: Out << "?M"; break;
906f4a2713aSLionel Sambuc // <operator-name> ::= ?N # <=
907f4a2713aSLionel Sambuc case OO_LessEqual: Out << "?N"; break;
908f4a2713aSLionel Sambuc // <operator-name> ::= ?O # >
909f4a2713aSLionel Sambuc case OO_Greater: Out << "?O"; break;
910f4a2713aSLionel Sambuc // <operator-name> ::= ?P # >=
911f4a2713aSLionel Sambuc case OO_GreaterEqual: Out << "?P"; break;
912f4a2713aSLionel Sambuc // <operator-name> ::= ?Q # ,
913f4a2713aSLionel Sambuc case OO_Comma: Out << "?Q"; break;
914f4a2713aSLionel Sambuc // <operator-name> ::= ?R # ()
915f4a2713aSLionel Sambuc case OO_Call: Out << "?R"; break;
916f4a2713aSLionel Sambuc // <operator-name> ::= ?S # ~
917f4a2713aSLionel Sambuc case OO_Tilde: Out << "?S"; break;
918f4a2713aSLionel Sambuc // <operator-name> ::= ?T # ^
919f4a2713aSLionel Sambuc case OO_Caret: Out << "?T"; break;
920f4a2713aSLionel Sambuc // <operator-name> ::= ?U # |
921f4a2713aSLionel Sambuc case OO_Pipe: Out << "?U"; break;
922f4a2713aSLionel Sambuc // <operator-name> ::= ?V # &&
923f4a2713aSLionel Sambuc case OO_AmpAmp: Out << "?V"; break;
924f4a2713aSLionel Sambuc // <operator-name> ::= ?W # ||
925f4a2713aSLionel Sambuc case OO_PipePipe: Out << "?W"; break;
926f4a2713aSLionel Sambuc // <operator-name> ::= ?X # *=
927f4a2713aSLionel Sambuc case OO_StarEqual: Out << "?X"; break;
928f4a2713aSLionel Sambuc // <operator-name> ::= ?Y # +=
929f4a2713aSLionel Sambuc case OO_PlusEqual: Out << "?Y"; break;
930f4a2713aSLionel Sambuc // <operator-name> ::= ?Z # -=
931f4a2713aSLionel Sambuc case OO_MinusEqual: Out << "?Z"; break;
932f4a2713aSLionel Sambuc // <operator-name> ::= ?_0 # /=
933f4a2713aSLionel Sambuc case OO_SlashEqual: Out << "?_0"; break;
934f4a2713aSLionel Sambuc // <operator-name> ::= ?_1 # %=
935f4a2713aSLionel Sambuc case OO_PercentEqual: Out << "?_1"; break;
936f4a2713aSLionel Sambuc // <operator-name> ::= ?_2 # >>=
937f4a2713aSLionel Sambuc case OO_GreaterGreaterEqual: Out << "?_2"; break;
938f4a2713aSLionel Sambuc // <operator-name> ::= ?_3 # <<=
939f4a2713aSLionel Sambuc case OO_LessLessEqual: Out << "?_3"; break;
940f4a2713aSLionel Sambuc // <operator-name> ::= ?_4 # &=
941f4a2713aSLionel Sambuc case OO_AmpEqual: Out << "?_4"; break;
942f4a2713aSLionel Sambuc // <operator-name> ::= ?_5 # |=
943f4a2713aSLionel Sambuc case OO_PipeEqual: Out << "?_5"; break;
944f4a2713aSLionel Sambuc // <operator-name> ::= ?_6 # ^=
945f4a2713aSLionel Sambuc case OO_CaretEqual: Out << "?_6"; break;
946f4a2713aSLionel Sambuc // ?_7 # vftable
947f4a2713aSLionel Sambuc // ?_8 # vbtable
948f4a2713aSLionel Sambuc // ?_9 # vcall
949f4a2713aSLionel Sambuc // ?_A # typeof
950f4a2713aSLionel Sambuc // ?_B # local static guard
951f4a2713aSLionel Sambuc // ?_C # string
952f4a2713aSLionel Sambuc // ?_D # vbase destructor
953f4a2713aSLionel Sambuc // ?_E # vector deleting destructor
954f4a2713aSLionel Sambuc // ?_F # default constructor closure
955f4a2713aSLionel Sambuc // ?_G # scalar deleting destructor
956f4a2713aSLionel Sambuc // ?_H # vector constructor iterator
957f4a2713aSLionel Sambuc // ?_I # vector destructor iterator
958f4a2713aSLionel Sambuc // ?_J # vector vbase constructor iterator
959f4a2713aSLionel Sambuc // ?_K # virtual displacement map
960f4a2713aSLionel Sambuc // ?_L # eh vector constructor iterator
961f4a2713aSLionel Sambuc // ?_M # eh vector destructor iterator
962f4a2713aSLionel Sambuc // ?_N # eh vector vbase constructor iterator
963f4a2713aSLionel Sambuc // ?_O # copy constructor closure
964f4a2713aSLionel Sambuc // ?_P<name> # udt returning <name>
965f4a2713aSLionel Sambuc // ?_Q # <unknown>
966f4a2713aSLionel Sambuc // ?_R0 # RTTI Type Descriptor
967f4a2713aSLionel Sambuc // ?_R1 # RTTI Base Class Descriptor at (a,b,c,d)
968f4a2713aSLionel Sambuc // ?_R2 # RTTI Base Class Array
969f4a2713aSLionel Sambuc // ?_R3 # RTTI Class Hierarchy Descriptor
970f4a2713aSLionel Sambuc // ?_R4 # RTTI Complete Object Locator
971f4a2713aSLionel Sambuc // ?_S # local vftable
972f4a2713aSLionel Sambuc // ?_T # local vftable constructor closure
973f4a2713aSLionel Sambuc // <operator-name> ::= ?_U # new[]
974f4a2713aSLionel Sambuc case OO_Array_New: Out << "?_U"; break;
975f4a2713aSLionel Sambuc // <operator-name> ::= ?_V # delete[]
976f4a2713aSLionel Sambuc case OO_Array_Delete: Out << "?_V"; break;
977f4a2713aSLionel Sambuc
978f4a2713aSLionel Sambuc case OO_Conditional: {
979f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
980f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
981f4a2713aSLionel Sambuc "cannot mangle this conditional operator yet");
982f4a2713aSLionel Sambuc Diags.Report(Loc, DiagID);
983f4a2713aSLionel Sambuc break;
984f4a2713aSLionel Sambuc }
985f4a2713aSLionel Sambuc
986f4a2713aSLionel Sambuc case OO_None:
987f4a2713aSLionel Sambuc case NUM_OVERLOADED_OPERATORS:
988f4a2713aSLionel Sambuc llvm_unreachable("Not an overloaded operator");
989f4a2713aSLionel Sambuc }
990f4a2713aSLionel Sambuc }
991f4a2713aSLionel Sambuc
mangleSourceName(StringRef Name)992f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
993f4a2713aSLionel Sambuc // <source name> ::= <identifier> @
994*0a6a1f1dSLionel Sambuc BackRefVec::iterator Found =
995*0a6a1f1dSLionel Sambuc std::find(NameBackReferences.begin(), NameBackReferences.end(), Name);
996*0a6a1f1dSLionel Sambuc if (Found == NameBackReferences.end()) {
997*0a6a1f1dSLionel Sambuc if (NameBackReferences.size() < 10)
998*0a6a1f1dSLionel Sambuc NameBackReferences.push_back(Name);
999f4a2713aSLionel Sambuc Out << Name << '@';
1000f4a2713aSLionel Sambuc } else {
1001*0a6a1f1dSLionel Sambuc Out << (Found - NameBackReferences.begin());
1002f4a2713aSLionel Sambuc }
1003f4a2713aSLionel Sambuc }
1004f4a2713aSLionel Sambuc
mangleObjCMethodName(const ObjCMethodDecl * MD)1005f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
1006f4a2713aSLionel Sambuc Context.mangleObjCMethodName(MD, Out);
1007f4a2713aSLionel Sambuc }
1008f4a2713aSLionel Sambuc
mangleTemplateInstantiationName(const TemplateDecl * TD,const TemplateArgumentList & TemplateArgs)1009f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
1010*0a6a1f1dSLionel Sambuc const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
1011f4a2713aSLionel Sambuc // <template-name> ::= <unscoped-template-name> <template-args>
1012f4a2713aSLionel Sambuc // ::= <substitution>
1013f4a2713aSLionel Sambuc // Always start with the unqualified name.
1014f4a2713aSLionel Sambuc
1015f4a2713aSLionel Sambuc // Templates have their own context for back references.
1016f4a2713aSLionel Sambuc ArgBackRefMap OuterArgsContext;
1017*0a6a1f1dSLionel Sambuc BackRefVec OuterTemplateContext;
1018f4a2713aSLionel Sambuc NameBackReferences.swap(OuterTemplateContext);
1019f4a2713aSLionel Sambuc TypeBackReferences.swap(OuterArgsContext);
1020f4a2713aSLionel Sambuc
1021f4a2713aSLionel Sambuc mangleUnscopedTemplateName(TD);
1022f4a2713aSLionel Sambuc mangleTemplateArgs(TD, TemplateArgs);
1023f4a2713aSLionel Sambuc
1024f4a2713aSLionel Sambuc // Restore the previous back reference contexts.
1025f4a2713aSLionel Sambuc NameBackReferences.swap(OuterTemplateContext);
1026f4a2713aSLionel Sambuc TypeBackReferences.swap(OuterArgsContext);
1027f4a2713aSLionel Sambuc }
1028f4a2713aSLionel Sambuc
1029f4a2713aSLionel Sambuc void
mangleUnscopedTemplateName(const TemplateDecl * TD)1030f4a2713aSLionel Sambuc MicrosoftCXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *TD) {
1031f4a2713aSLionel Sambuc // <unscoped-template-name> ::= ?$ <unqualified-name>
1032f4a2713aSLionel Sambuc Out << "?$";
1033f4a2713aSLionel Sambuc mangleUnqualifiedName(TD);
1034f4a2713aSLionel Sambuc }
1035f4a2713aSLionel Sambuc
mangleIntegerLiteral(const llvm::APSInt & Value,bool IsBoolean)1036*0a6a1f1dSLionel Sambuc void MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value,
1037f4a2713aSLionel Sambuc bool IsBoolean) {
1038f4a2713aSLionel Sambuc // <integer-literal> ::= $0 <number>
1039f4a2713aSLionel Sambuc Out << "$0";
1040f4a2713aSLionel Sambuc // Make sure booleans are encoded as 0/1.
1041f4a2713aSLionel Sambuc if (IsBoolean && Value.getBoolValue())
1042f4a2713aSLionel Sambuc mangleNumber(1);
1043*0a6a1f1dSLionel Sambuc else if (Value.isSigned())
1044*0a6a1f1dSLionel Sambuc mangleNumber(Value.getSExtValue());
1045f4a2713aSLionel Sambuc else
1046*0a6a1f1dSLionel Sambuc mangleNumber(Value.getZExtValue());
1047f4a2713aSLionel Sambuc }
1048f4a2713aSLionel Sambuc
mangleExpression(const Expr * E)1049*0a6a1f1dSLionel Sambuc void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
1050f4a2713aSLionel Sambuc // See if this is a constant expression.
1051f4a2713aSLionel Sambuc llvm::APSInt Value;
1052f4a2713aSLionel Sambuc if (E->isIntegerConstantExpr(Value, Context.getASTContext())) {
1053f4a2713aSLionel Sambuc mangleIntegerLiteral(Value, E->getType()->isBooleanType());
1054f4a2713aSLionel Sambuc return;
1055f4a2713aSLionel Sambuc }
1056f4a2713aSLionel Sambuc
1057*0a6a1f1dSLionel Sambuc // Look through no-op casts like template parameter substitutions.
1058*0a6a1f1dSLionel Sambuc E = E->IgnoreParenNoopCasts(Context.getASTContext());
1059*0a6a1f1dSLionel Sambuc
1060*0a6a1f1dSLionel Sambuc const CXXUuidofExpr *UE = nullptr;
1061f4a2713aSLionel Sambuc if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
1062f4a2713aSLionel Sambuc if (UO->getOpcode() == UO_AddrOf)
1063f4a2713aSLionel Sambuc UE = dyn_cast<CXXUuidofExpr>(UO->getSubExpr());
1064f4a2713aSLionel Sambuc } else
1065f4a2713aSLionel Sambuc UE = dyn_cast<CXXUuidofExpr>(E);
1066f4a2713aSLionel Sambuc
1067f4a2713aSLionel Sambuc if (UE) {
1068f4a2713aSLionel Sambuc // This CXXUuidofExpr is mangled as-if it were actually a VarDecl from
1069f4a2713aSLionel Sambuc // const __s_GUID _GUID_{lower case UUID with underscores}
1070f4a2713aSLionel Sambuc StringRef Uuid = UE->getUuidAsStringRef(Context.getASTContext());
1071f4a2713aSLionel Sambuc std::string Name = "_GUID_" + Uuid.lower();
1072f4a2713aSLionel Sambuc std::replace(Name.begin(), Name.end(), '-', '_');
1073f4a2713aSLionel Sambuc
1074f4a2713aSLionel Sambuc // If we had to peek through an address-of operator, treat this like we are
1075f4a2713aSLionel Sambuc // dealing with a pointer type. Otherwise, treat it like a const reference.
1076f4a2713aSLionel Sambuc //
1077f4a2713aSLionel Sambuc // N.B. This matches up with the handling of TemplateArgument::Declaration
1078f4a2713aSLionel Sambuc // in mangleTemplateArg
1079f4a2713aSLionel Sambuc if (UE == E)
1080f4a2713aSLionel Sambuc Out << "$E?";
1081f4a2713aSLionel Sambuc else
1082f4a2713aSLionel Sambuc Out << "$1?";
1083f4a2713aSLionel Sambuc Out << Name << "@@3U__s_GUID@@B";
1084f4a2713aSLionel Sambuc return;
1085f4a2713aSLionel Sambuc }
1086f4a2713aSLionel Sambuc
1087f4a2713aSLionel Sambuc // As bad as this diagnostic is, it's better than crashing.
1088f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
1089*0a6a1f1dSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(
1090*0a6a1f1dSLionel Sambuc DiagnosticsEngine::Error, "cannot yet mangle expression type %0");
1091*0a6a1f1dSLionel Sambuc Diags.Report(E->getExprLoc(), DiagID) << E->getStmtClassName()
1092*0a6a1f1dSLionel Sambuc << E->getSourceRange();
1093f4a2713aSLionel Sambuc }
1094f4a2713aSLionel Sambuc
mangleTemplateArgs(const TemplateDecl * TD,const TemplateArgumentList & TemplateArgs)1095*0a6a1f1dSLionel Sambuc void MicrosoftCXXNameMangler::mangleTemplateArgs(
1096*0a6a1f1dSLionel Sambuc const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
1097*0a6a1f1dSLionel Sambuc // <template-args> ::= <template-arg>+
1098*0a6a1f1dSLionel Sambuc const TemplateParameterList *TPL = TD->getTemplateParameters();
1099*0a6a1f1dSLionel Sambuc assert(TPL->size() == TemplateArgs.size() &&
1100*0a6a1f1dSLionel Sambuc "size mismatch between args and parms!");
1101*0a6a1f1dSLionel Sambuc
1102*0a6a1f1dSLionel Sambuc unsigned Idx = 0;
1103*0a6a1f1dSLionel Sambuc for (const TemplateArgument &TA : TemplateArgs.asArray())
1104*0a6a1f1dSLionel Sambuc mangleTemplateArg(TD, TA, TPL->getParam(Idx++));
1105f4a2713aSLionel Sambuc }
1106f4a2713aSLionel Sambuc
mangleTemplateArg(const TemplateDecl * TD,const TemplateArgument & TA,const NamedDecl * Parm)1107f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
1108*0a6a1f1dSLionel Sambuc const TemplateArgument &TA,
1109*0a6a1f1dSLionel Sambuc const NamedDecl *Parm) {
1110*0a6a1f1dSLionel Sambuc // <template-arg> ::= <type>
1111*0a6a1f1dSLionel Sambuc // ::= <integer-literal>
1112*0a6a1f1dSLionel Sambuc // ::= <member-data-pointer>
1113*0a6a1f1dSLionel Sambuc // ::= <member-function-pointer>
1114*0a6a1f1dSLionel Sambuc // ::= $E? <name> <type-encoding>
1115*0a6a1f1dSLionel Sambuc // ::= $1? <name> <type-encoding>
1116*0a6a1f1dSLionel Sambuc // ::= $0A@
1117*0a6a1f1dSLionel Sambuc // ::= <template-args>
1118*0a6a1f1dSLionel Sambuc
1119f4a2713aSLionel Sambuc switch (TA.getKind()) {
1120f4a2713aSLionel Sambuc case TemplateArgument::Null:
1121f4a2713aSLionel Sambuc llvm_unreachable("Can't mangle null template arguments!");
1122f4a2713aSLionel Sambuc case TemplateArgument::TemplateExpansion:
1123f4a2713aSLionel Sambuc llvm_unreachable("Can't mangle template expansion arguments!");
1124f4a2713aSLionel Sambuc case TemplateArgument::Type: {
1125f4a2713aSLionel Sambuc QualType T = TA.getAsType();
1126f4a2713aSLionel Sambuc mangleType(T, SourceRange(), QMM_Escape);
1127f4a2713aSLionel Sambuc break;
1128f4a2713aSLionel Sambuc }
1129f4a2713aSLionel Sambuc case TemplateArgument::Declaration: {
1130f4a2713aSLionel Sambuc const NamedDecl *ND = cast<NamedDecl>(TA.getAsDecl());
1131*0a6a1f1dSLionel Sambuc if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
1132*0a6a1f1dSLionel Sambuc mangleMemberDataPointer(
1133*0a6a1f1dSLionel Sambuc cast<CXXRecordDecl>(ND->getDeclContext())->getMostRecentDecl(),
1134*0a6a1f1dSLionel Sambuc cast<ValueDecl>(ND));
1135*0a6a1f1dSLionel Sambuc } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1136*0a6a1f1dSLionel Sambuc const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
1137*0a6a1f1dSLionel Sambuc if (MD && MD->isInstance())
1138*0a6a1f1dSLionel Sambuc mangleMemberFunctionPointer(MD->getParent()->getMostRecentDecl(), MD);
1139*0a6a1f1dSLionel Sambuc else
1140*0a6a1f1dSLionel Sambuc mangle(FD, "$1?");
1141*0a6a1f1dSLionel Sambuc } else {
1142*0a6a1f1dSLionel Sambuc mangle(ND, TA.getParamTypeForDecl()->isReferenceType() ? "$E?" : "$1?");
1143*0a6a1f1dSLionel Sambuc }
1144f4a2713aSLionel Sambuc break;
1145f4a2713aSLionel Sambuc }
1146f4a2713aSLionel Sambuc case TemplateArgument::Integral:
1147f4a2713aSLionel Sambuc mangleIntegerLiteral(TA.getAsIntegral(),
1148f4a2713aSLionel Sambuc TA.getIntegralType()->isBooleanType());
1149f4a2713aSLionel Sambuc break;
1150*0a6a1f1dSLionel Sambuc case TemplateArgument::NullPtr: {
1151*0a6a1f1dSLionel Sambuc QualType T = TA.getNullPtrType();
1152*0a6a1f1dSLionel Sambuc if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
1153*0a6a1f1dSLionel Sambuc const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
1154*0a6a1f1dSLionel Sambuc if (MPT->isMemberFunctionPointerType() && isa<ClassTemplateDecl>(TD)) {
1155*0a6a1f1dSLionel Sambuc mangleMemberFunctionPointer(RD, nullptr);
1156*0a6a1f1dSLionel Sambuc return;
1157*0a6a1f1dSLionel Sambuc }
1158*0a6a1f1dSLionel Sambuc if (MPT->isMemberDataPointer()) {
1159*0a6a1f1dSLionel Sambuc mangleMemberDataPointer(RD, nullptr);
1160*0a6a1f1dSLionel Sambuc return;
1161*0a6a1f1dSLionel Sambuc }
1162*0a6a1f1dSLionel Sambuc }
1163f4a2713aSLionel Sambuc Out << "$0A@";
1164f4a2713aSLionel Sambuc break;
1165*0a6a1f1dSLionel Sambuc }
1166f4a2713aSLionel Sambuc case TemplateArgument::Expression:
1167f4a2713aSLionel Sambuc mangleExpression(TA.getAsExpr());
1168f4a2713aSLionel Sambuc break;
1169*0a6a1f1dSLionel Sambuc case TemplateArgument::Pack: {
1170*0a6a1f1dSLionel Sambuc ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();
1171*0a6a1f1dSLionel Sambuc if (TemplateArgs.empty()) {
1172*0a6a1f1dSLionel Sambuc if (isa<TemplateTypeParmDecl>(Parm) ||
1173*0a6a1f1dSLionel Sambuc isa<TemplateTemplateParmDecl>(Parm))
1174*0a6a1f1dSLionel Sambuc Out << "$$V";
1175*0a6a1f1dSLionel Sambuc else if (isa<NonTypeTemplateParmDecl>(Parm))
1176*0a6a1f1dSLionel Sambuc Out << "$S";
1177*0a6a1f1dSLionel Sambuc else
1178*0a6a1f1dSLionel Sambuc llvm_unreachable("unexpected template parameter decl!");
1179*0a6a1f1dSLionel Sambuc } else {
1180*0a6a1f1dSLionel Sambuc for (const TemplateArgument &PA : TemplateArgs)
1181*0a6a1f1dSLionel Sambuc mangleTemplateArg(TD, PA, Parm);
1182*0a6a1f1dSLionel Sambuc }
1183f4a2713aSLionel Sambuc break;
1184*0a6a1f1dSLionel Sambuc }
1185*0a6a1f1dSLionel Sambuc case TemplateArgument::Template: {
1186*0a6a1f1dSLionel Sambuc const NamedDecl *ND =
1187*0a6a1f1dSLionel Sambuc TA.getAsTemplate().getAsTemplateDecl()->getTemplatedDecl();
1188*0a6a1f1dSLionel Sambuc if (const auto *TD = dyn_cast<TagDecl>(ND)) {
1189*0a6a1f1dSLionel Sambuc mangleType(TD);
1190*0a6a1f1dSLionel Sambuc } else if (isa<TypeAliasDecl>(ND)) {
1191*0a6a1f1dSLionel Sambuc Out << "$$Y";
1192*0a6a1f1dSLionel Sambuc mangleName(ND);
1193*0a6a1f1dSLionel Sambuc } else {
1194*0a6a1f1dSLionel Sambuc llvm_unreachable("unexpected template template NamedDecl!");
1195*0a6a1f1dSLionel Sambuc }
1196f4a2713aSLionel Sambuc break;
1197f4a2713aSLionel Sambuc }
1198f4a2713aSLionel Sambuc }
1199*0a6a1f1dSLionel Sambuc }
1200f4a2713aSLionel Sambuc
mangleQualifiers(Qualifiers Quals,bool IsMember)1201f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
1202f4a2713aSLionel Sambuc bool IsMember) {
1203f4a2713aSLionel Sambuc // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>
1204f4a2713aSLionel Sambuc // 'E' means __ptr64 (32-bit only); 'F' means __unaligned (32/64-bit only);
1205f4a2713aSLionel Sambuc // 'I' means __restrict (32/64-bit).
1206f4a2713aSLionel Sambuc // Note that the MSVC __restrict keyword isn't the same as the C99 restrict
1207f4a2713aSLionel Sambuc // keyword!
1208f4a2713aSLionel Sambuc // <base-cvr-qualifiers> ::= A # near
1209f4a2713aSLionel Sambuc // ::= B # near const
1210f4a2713aSLionel Sambuc // ::= C # near volatile
1211f4a2713aSLionel Sambuc // ::= D # near const volatile
1212f4a2713aSLionel Sambuc // ::= E # far (16-bit)
1213f4a2713aSLionel Sambuc // ::= F # far const (16-bit)
1214f4a2713aSLionel Sambuc // ::= G # far volatile (16-bit)
1215f4a2713aSLionel Sambuc // ::= H # far const volatile (16-bit)
1216f4a2713aSLionel Sambuc // ::= I # huge (16-bit)
1217f4a2713aSLionel Sambuc // ::= J # huge const (16-bit)
1218f4a2713aSLionel Sambuc // ::= K # huge volatile (16-bit)
1219f4a2713aSLionel Sambuc // ::= L # huge const volatile (16-bit)
1220f4a2713aSLionel Sambuc // ::= M <basis> # based
1221f4a2713aSLionel Sambuc // ::= N <basis> # based const
1222f4a2713aSLionel Sambuc // ::= O <basis> # based volatile
1223f4a2713aSLionel Sambuc // ::= P <basis> # based const volatile
1224f4a2713aSLionel Sambuc // ::= Q # near member
1225f4a2713aSLionel Sambuc // ::= R # near const member
1226f4a2713aSLionel Sambuc // ::= S # near volatile member
1227f4a2713aSLionel Sambuc // ::= T # near const volatile member
1228f4a2713aSLionel Sambuc // ::= U # far member (16-bit)
1229f4a2713aSLionel Sambuc // ::= V # far const member (16-bit)
1230f4a2713aSLionel Sambuc // ::= W # far volatile member (16-bit)
1231f4a2713aSLionel Sambuc // ::= X # far const volatile member (16-bit)
1232f4a2713aSLionel Sambuc // ::= Y # huge member (16-bit)
1233f4a2713aSLionel Sambuc // ::= Z # huge const member (16-bit)
1234f4a2713aSLionel Sambuc // ::= 0 # huge volatile member (16-bit)
1235f4a2713aSLionel Sambuc // ::= 1 # huge const volatile member (16-bit)
1236f4a2713aSLionel Sambuc // ::= 2 <basis> # based member
1237f4a2713aSLionel Sambuc // ::= 3 <basis> # based const member
1238f4a2713aSLionel Sambuc // ::= 4 <basis> # based volatile member
1239f4a2713aSLionel Sambuc // ::= 5 <basis> # based const volatile member
1240f4a2713aSLionel Sambuc // ::= 6 # near function (pointers only)
1241f4a2713aSLionel Sambuc // ::= 7 # far function (pointers only)
1242f4a2713aSLionel Sambuc // ::= 8 # near method (pointers only)
1243f4a2713aSLionel Sambuc // ::= 9 # far method (pointers only)
1244f4a2713aSLionel Sambuc // ::= _A <basis> # based function (pointers only)
1245f4a2713aSLionel Sambuc // ::= _B <basis> # based function (far?) (pointers only)
1246f4a2713aSLionel Sambuc // ::= _C <basis> # based method (pointers only)
1247f4a2713aSLionel Sambuc // ::= _D <basis> # based method (far?) (pointers only)
1248f4a2713aSLionel Sambuc // ::= _E # block (Clang)
1249f4a2713aSLionel Sambuc // <basis> ::= 0 # __based(void)
1250f4a2713aSLionel Sambuc // ::= 1 # __based(segment)?
1251f4a2713aSLionel Sambuc // ::= 2 <name> # __based(name)
1252f4a2713aSLionel Sambuc // ::= 3 # ?
1253f4a2713aSLionel Sambuc // ::= 4 # ?
1254f4a2713aSLionel Sambuc // ::= 5 # not really based
1255f4a2713aSLionel Sambuc bool HasConst = Quals.hasConst(),
1256f4a2713aSLionel Sambuc HasVolatile = Quals.hasVolatile();
1257f4a2713aSLionel Sambuc
1258f4a2713aSLionel Sambuc if (!IsMember) {
1259f4a2713aSLionel Sambuc if (HasConst && HasVolatile) {
1260f4a2713aSLionel Sambuc Out << 'D';
1261f4a2713aSLionel Sambuc } else if (HasVolatile) {
1262f4a2713aSLionel Sambuc Out << 'C';
1263f4a2713aSLionel Sambuc } else if (HasConst) {
1264f4a2713aSLionel Sambuc Out << 'B';
1265f4a2713aSLionel Sambuc } else {
1266f4a2713aSLionel Sambuc Out << 'A';
1267f4a2713aSLionel Sambuc }
1268f4a2713aSLionel Sambuc } else {
1269f4a2713aSLionel Sambuc if (HasConst && HasVolatile) {
1270f4a2713aSLionel Sambuc Out << 'T';
1271f4a2713aSLionel Sambuc } else if (HasVolatile) {
1272f4a2713aSLionel Sambuc Out << 'S';
1273f4a2713aSLionel Sambuc } else if (HasConst) {
1274f4a2713aSLionel Sambuc Out << 'R';
1275f4a2713aSLionel Sambuc } else {
1276f4a2713aSLionel Sambuc Out << 'Q';
1277f4a2713aSLionel Sambuc }
1278f4a2713aSLionel Sambuc }
1279f4a2713aSLionel Sambuc
1280f4a2713aSLionel Sambuc // FIXME: For now, just drop all extension qualifiers on the floor.
1281f4a2713aSLionel Sambuc }
1282f4a2713aSLionel Sambuc
1283*0a6a1f1dSLionel Sambuc void
mangleRefQualifier(RefQualifierKind RefQualifier)1284*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {
1285*0a6a1f1dSLionel Sambuc // <ref-qualifier> ::= G # lvalue reference
1286*0a6a1f1dSLionel Sambuc // ::= H # rvalue-reference
1287*0a6a1f1dSLionel Sambuc switch (RefQualifier) {
1288*0a6a1f1dSLionel Sambuc case RQ_None:
1289*0a6a1f1dSLionel Sambuc break;
1290*0a6a1f1dSLionel Sambuc
1291*0a6a1f1dSLionel Sambuc case RQ_LValue:
1292*0a6a1f1dSLionel Sambuc Out << 'G';
1293*0a6a1f1dSLionel Sambuc break;
1294*0a6a1f1dSLionel Sambuc
1295*0a6a1f1dSLionel Sambuc case RQ_RValue:
1296*0a6a1f1dSLionel Sambuc Out << 'H';
1297*0a6a1f1dSLionel Sambuc break;
1298*0a6a1f1dSLionel Sambuc }
1299*0a6a1f1dSLionel Sambuc }
1300*0a6a1f1dSLionel Sambuc
1301*0a6a1f1dSLionel Sambuc void
manglePointerExtQualifiers(Qualifiers Quals,const Type * PointeeType)1302*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
1303*0a6a1f1dSLionel Sambuc const Type *PointeeType) {
1304*0a6a1f1dSLionel Sambuc bool HasRestrict = Quals.hasRestrict();
1305*0a6a1f1dSLionel Sambuc if (PointersAre64Bit && (!PointeeType || !PointeeType->isFunctionType()))
1306*0a6a1f1dSLionel Sambuc Out << 'E';
1307*0a6a1f1dSLionel Sambuc
1308*0a6a1f1dSLionel Sambuc if (HasRestrict)
1309*0a6a1f1dSLionel Sambuc Out << 'I';
1310*0a6a1f1dSLionel Sambuc }
1311*0a6a1f1dSLionel Sambuc
manglePointerCVQualifiers(Qualifiers Quals)1312*0a6a1f1dSLionel Sambuc void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
1313*0a6a1f1dSLionel Sambuc // <pointer-cv-qualifiers> ::= P # no qualifiers
1314f4a2713aSLionel Sambuc // ::= Q # const
1315f4a2713aSLionel Sambuc // ::= R # volatile
1316f4a2713aSLionel Sambuc // ::= S # const volatile
1317f4a2713aSLionel Sambuc bool HasConst = Quals.hasConst(),
1318f4a2713aSLionel Sambuc HasVolatile = Quals.hasVolatile();
1319*0a6a1f1dSLionel Sambuc
1320f4a2713aSLionel Sambuc if (HasConst && HasVolatile) {
1321f4a2713aSLionel Sambuc Out << 'S';
1322f4a2713aSLionel Sambuc } else if (HasVolatile) {
1323f4a2713aSLionel Sambuc Out << 'R';
1324f4a2713aSLionel Sambuc } else if (HasConst) {
1325f4a2713aSLionel Sambuc Out << 'Q';
1326f4a2713aSLionel Sambuc } else {
1327f4a2713aSLionel Sambuc Out << 'P';
1328f4a2713aSLionel Sambuc }
1329f4a2713aSLionel Sambuc }
1330f4a2713aSLionel Sambuc
mangleArgumentType(QualType T,SourceRange Range)1331f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleArgumentType(QualType T,
1332f4a2713aSLionel Sambuc SourceRange Range) {
1333f4a2713aSLionel Sambuc // MSVC will backreference two canonically equivalent types that have slightly
1334f4a2713aSLionel Sambuc // different manglings when mangled alone.
1335f4a2713aSLionel Sambuc
1336f4a2713aSLionel Sambuc // Decayed types do not match up with non-decayed versions of the same type.
1337f4a2713aSLionel Sambuc //
1338f4a2713aSLionel Sambuc // e.g.
1339f4a2713aSLionel Sambuc // void (*x)(void) will not form a backreference with void x(void)
1340f4a2713aSLionel Sambuc void *TypePtr;
1341f4a2713aSLionel Sambuc if (const DecayedType *DT = T->getAs<DecayedType>()) {
1342f4a2713aSLionel Sambuc TypePtr = DT->getOriginalType().getCanonicalType().getAsOpaquePtr();
1343f4a2713aSLionel Sambuc // If the original parameter was textually written as an array,
1344f4a2713aSLionel Sambuc // instead treat the decayed parameter like it's const.
1345f4a2713aSLionel Sambuc //
1346f4a2713aSLionel Sambuc // e.g.
1347f4a2713aSLionel Sambuc // int [] -> int * const
1348f4a2713aSLionel Sambuc if (DT->getOriginalType()->isArrayType())
1349f4a2713aSLionel Sambuc T = T.withConst();
1350f4a2713aSLionel Sambuc } else
1351f4a2713aSLionel Sambuc TypePtr = T.getCanonicalType().getAsOpaquePtr();
1352f4a2713aSLionel Sambuc
1353f4a2713aSLionel Sambuc ArgBackRefMap::iterator Found = TypeBackReferences.find(TypePtr);
1354f4a2713aSLionel Sambuc
1355f4a2713aSLionel Sambuc if (Found == TypeBackReferences.end()) {
1356f4a2713aSLionel Sambuc size_t OutSizeBefore = Out.GetNumBytesInBuffer();
1357f4a2713aSLionel Sambuc
1358f4a2713aSLionel Sambuc mangleType(T, Range, QMM_Drop);
1359f4a2713aSLionel Sambuc
1360f4a2713aSLionel Sambuc // See if it's worth creating a back reference.
1361f4a2713aSLionel Sambuc // Only types longer than 1 character are considered
1362f4a2713aSLionel Sambuc // and only 10 back references slots are available:
1363f4a2713aSLionel Sambuc bool LongerThanOneChar = (Out.GetNumBytesInBuffer() - OutSizeBefore > 1);
1364f4a2713aSLionel Sambuc if (LongerThanOneChar && TypeBackReferences.size() < 10) {
1365f4a2713aSLionel Sambuc size_t Size = TypeBackReferences.size();
1366f4a2713aSLionel Sambuc TypeBackReferences[TypePtr] = Size;
1367f4a2713aSLionel Sambuc }
1368f4a2713aSLionel Sambuc } else {
1369f4a2713aSLionel Sambuc Out << Found->second;
1370f4a2713aSLionel Sambuc }
1371f4a2713aSLionel Sambuc }
1372f4a2713aSLionel Sambuc
mangleType(QualType T,SourceRange Range,QualifierMangleMode QMM)1373f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
1374f4a2713aSLionel Sambuc QualifierMangleMode QMM) {
1375f4a2713aSLionel Sambuc // Don't use the canonical types. MSVC includes things like 'const' on
1376f4a2713aSLionel Sambuc // pointer arguments to function pointers that canonicalization strips away.
1377f4a2713aSLionel Sambuc T = T.getDesugaredType(getASTContext());
1378f4a2713aSLionel Sambuc Qualifiers Quals = T.getLocalQualifiers();
1379f4a2713aSLionel Sambuc if (const ArrayType *AT = getASTContext().getAsArrayType(T)) {
1380f4a2713aSLionel Sambuc // If there were any Quals, getAsArrayType() pushed them onto the array
1381f4a2713aSLionel Sambuc // element type.
1382f4a2713aSLionel Sambuc if (QMM == QMM_Mangle)
1383f4a2713aSLionel Sambuc Out << 'A';
1384f4a2713aSLionel Sambuc else if (QMM == QMM_Escape || QMM == QMM_Result)
1385f4a2713aSLionel Sambuc Out << "$$B";
1386f4a2713aSLionel Sambuc mangleArrayType(AT);
1387f4a2713aSLionel Sambuc return;
1388f4a2713aSLionel Sambuc }
1389f4a2713aSLionel Sambuc
1390f4a2713aSLionel Sambuc bool IsPointer = T->isAnyPointerType() || T->isMemberPointerType() ||
1391f4a2713aSLionel Sambuc T->isBlockPointerType();
1392f4a2713aSLionel Sambuc
1393f4a2713aSLionel Sambuc switch (QMM) {
1394f4a2713aSLionel Sambuc case QMM_Drop:
1395f4a2713aSLionel Sambuc break;
1396f4a2713aSLionel Sambuc case QMM_Mangle:
1397f4a2713aSLionel Sambuc if (const FunctionType *FT = dyn_cast<FunctionType>(T)) {
1398f4a2713aSLionel Sambuc Out << '6';
1399f4a2713aSLionel Sambuc mangleFunctionType(FT);
1400f4a2713aSLionel Sambuc return;
1401f4a2713aSLionel Sambuc }
1402f4a2713aSLionel Sambuc mangleQualifiers(Quals, false);
1403f4a2713aSLionel Sambuc break;
1404f4a2713aSLionel Sambuc case QMM_Escape:
1405f4a2713aSLionel Sambuc if (!IsPointer && Quals) {
1406f4a2713aSLionel Sambuc Out << "$$C";
1407f4a2713aSLionel Sambuc mangleQualifiers(Quals, false);
1408f4a2713aSLionel Sambuc }
1409f4a2713aSLionel Sambuc break;
1410f4a2713aSLionel Sambuc case QMM_Result:
1411f4a2713aSLionel Sambuc if ((!IsPointer && Quals) || isa<TagType>(T)) {
1412f4a2713aSLionel Sambuc Out << '?';
1413f4a2713aSLionel Sambuc mangleQualifiers(Quals, false);
1414f4a2713aSLionel Sambuc }
1415f4a2713aSLionel Sambuc break;
1416f4a2713aSLionel Sambuc }
1417f4a2713aSLionel Sambuc
1418f4a2713aSLionel Sambuc // We have to mangle these now, while we still have enough information.
1419*0a6a1f1dSLionel Sambuc if (IsPointer) {
1420*0a6a1f1dSLionel Sambuc manglePointerCVQualifiers(Quals);
1421*0a6a1f1dSLionel Sambuc manglePointerExtQualifiers(Quals, T->getPointeeType().getTypePtr());
1422*0a6a1f1dSLionel Sambuc }
1423f4a2713aSLionel Sambuc const Type *ty = T.getTypePtr();
1424f4a2713aSLionel Sambuc
1425f4a2713aSLionel Sambuc switch (ty->getTypeClass()) {
1426f4a2713aSLionel Sambuc #define ABSTRACT_TYPE(CLASS, PARENT)
1427f4a2713aSLionel Sambuc #define NON_CANONICAL_TYPE(CLASS, PARENT) \
1428f4a2713aSLionel Sambuc case Type::CLASS: \
1429f4a2713aSLionel Sambuc llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
1430f4a2713aSLionel Sambuc return;
1431f4a2713aSLionel Sambuc #define TYPE(CLASS, PARENT) \
1432f4a2713aSLionel Sambuc case Type::CLASS: \
1433f4a2713aSLionel Sambuc mangleType(cast<CLASS##Type>(ty), Range); \
1434f4a2713aSLionel Sambuc break;
1435f4a2713aSLionel Sambuc #include "clang/AST/TypeNodes.def"
1436f4a2713aSLionel Sambuc #undef ABSTRACT_TYPE
1437f4a2713aSLionel Sambuc #undef NON_CANONICAL_TYPE
1438f4a2713aSLionel Sambuc #undef TYPE
1439f4a2713aSLionel Sambuc }
1440f4a2713aSLionel Sambuc }
1441f4a2713aSLionel Sambuc
mangleType(const BuiltinType * T,SourceRange Range)1442f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T,
1443f4a2713aSLionel Sambuc SourceRange Range) {
1444f4a2713aSLionel Sambuc // <type> ::= <builtin-type>
1445f4a2713aSLionel Sambuc // <builtin-type> ::= X # void
1446f4a2713aSLionel Sambuc // ::= C # signed char
1447f4a2713aSLionel Sambuc // ::= D # char
1448f4a2713aSLionel Sambuc // ::= E # unsigned char
1449f4a2713aSLionel Sambuc // ::= F # short
1450f4a2713aSLionel Sambuc // ::= G # unsigned short (or wchar_t if it's not a builtin)
1451f4a2713aSLionel Sambuc // ::= H # int
1452f4a2713aSLionel Sambuc // ::= I # unsigned int
1453f4a2713aSLionel Sambuc // ::= J # long
1454f4a2713aSLionel Sambuc // ::= K # unsigned long
1455f4a2713aSLionel Sambuc // L # <none>
1456f4a2713aSLionel Sambuc // ::= M # float
1457f4a2713aSLionel Sambuc // ::= N # double
1458f4a2713aSLionel Sambuc // ::= O # long double (__float80 is mangled differently)
1459f4a2713aSLionel Sambuc // ::= _J # long long, __int64
1460f4a2713aSLionel Sambuc // ::= _K # unsigned long long, __int64
1461f4a2713aSLionel Sambuc // ::= _L # __int128
1462f4a2713aSLionel Sambuc // ::= _M # unsigned __int128
1463f4a2713aSLionel Sambuc // ::= _N # bool
1464f4a2713aSLionel Sambuc // _O # <array in parameter>
1465f4a2713aSLionel Sambuc // ::= _T # __float80 (Intel)
1466f4a2713aSLionel Sambuc // ::= _W # wchar_t
1467f4a2713aSLionel Sambuc // ::= _Z # __float80 (Digital Mars)
1468f4a2713aSLionel Sambuc switch (T->getKind()) {
1469f4a2713aSLionel Sambuc case BuiltinType::Void: Out << 'X'; break;
1470f4a2713aSLionel Sambuc case BuiltinType::SChar: Out << 'C'; break;
1471f4a2713aSLionel Sambuc case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'D'; break;
1472f4a2713aSLionel Sambuc case BuiltinType::UChar: Out << 'E'; break;
1473f4a2713aSLionel Sambuc case BuiltinType::Short: Out << 'F'; break;
1474f4a2713aSLionel Sambuc case BuiltinType::UShort: Out << 'G'; break;
1475f4a2713aSLionel Sambuc case BuiltinType::Int: Out << 'H'; break;
1476f4a2713aSLionel Sambuc case BuiltinType::UInt: Out << 'I'; break;
1477f4a2713aSLionel Sambuc case BuiltinType::Long: Out << 'J'; break;
1478f4a2713aSLionel Sambuc case BuiltinType::ULong: Out << 'K'; break;
1479f4a2713aSLionel Sambuc case BuiltinType::Float: Out << 'M'; break;
1480f4a2713aSLionel Sambuc case BuiltinType::Double: Out << 'N'; break;
1481f4a2713aSLionel Sambuc // TODO: Determine size and mangle accordingly
1482f4a2713aSLionel Sambuc case BuiltinType::LongDouble: Out << 'O'; break;
1483f4a2713aSLionel Sambuc case BuiltinType::LongLong: Out << "_J"; break;
1484f4a2713aSLionel Sambuc case BuiltinType::ULongLong: Out << "_K"; break;
1485f4a2713aSLionel Sambuc case BuiltinType::Int128: Out << "_L"; break;
1486f4a2713aSLionel Sambuc case BuiltinType::UInt128: Out << "_M"; break;
1487f4a2713aSLionel Sambuc case BuiltinType::Bool: Out << "_N"; break;
1488*0a6a1f1dSLionel Sambuc case BuiltinType::Char16: Out << "_S"; break;
1489*0a6a1f1dSLionel Sambuc case BuiltinType::Char32: Out << "_U"; break;
1490f4a2713aSLionel Sambuc case BuiltinType::WChar_S:
1491f4a2713aSLionel Sambuc case BuiltinType::WChar_U: Out << "_W"; break;
1492f4a2713aSLionel Sambuc
1493f4a2713aSLionel Sambuc #define BUILTIN_TYPE(Id, SingletonId)
1494f4a2713aSLionel Sambuc #define PLACEHOLDER_TYPE(Id, SingletonId) \
1495f4a2713aSLionel Sambuc case BuiltinType::Id:
1496f4a2713aSLionel Sambuc #include "clang/AST/BuiltinTypes.def"
1497f4a2713aSLionel Sambuc case BuiltinType::Dependent:
1498f4a2713aSLionel Sambuc llvm_unreachable("placeholder types shouldn't get to name mangling");
1499f4a2713aSLionel Sambuc
1500f4a2713aSLionel Sambuc case BuiltinType::ObjCId: Out << "PAUobjc_object@@"; break;
1501f4a2713aSLionel Sambuc case BuiltinType::ObjCClass: Out << "PAUobjc_class@@"; break;
1502f4a2713aSLionel Sambuc case BuiltinType::ObjCSel: Out << "PAUobjc_selector@@"; break;
1503f4a2713aSLionel Sambuc
1504f4a2713aSLionel Sambuc case BuiltinType::OCLImage1d: Out << "PAUocl_image1d@@"; break;
1505f4a2713aSLionel Sambuc case BuiltinType::OCLImage1dArray: Out << "PAUocl_image1darray@@"; break;
1506f4a2713aSLionel Sambuc case BuiltinType::OCLImage1dBuffer: Out << "PAUocl_image1dbuffer@@"; break;
1507f4a2713aSLionel Sambuc case BuiltinType::OCLImage2d: Out << "PAUocl_image2d@@"; break;
1508f4a2713aSLionel Sambuc case BuiltinType::OCLImage2dArray: Out << "PAUocl_image2darray@@"; break;
1509f4a2713aSLionel Sambuc case BuiltinType::OCLImage3d: Out << "PAUocl_image3d@@"; break;
1510f4a2713aSLionel Sambuc case BuiltinType::OCLSampler: Out << "PAUocl_sampler@@"; break;
1511f4a2713aSLionel Sambuc case BuiltinType::OCLEvent: Out << "PAUocl_event@@"; break;
1512f4a2713aSLionel Sambuc
1513f4a2713aSLionel Sambuc case BuiltinType::NullPtr: Out << "$$T"; break;
1514f4a2713aSLionel Sambuc
1515f4a2713aSLionel Sambuc case BuiltinType::Half: {
1516f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
1517f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1518f4a2713aSLionel Sambuc "cannot mangle this built-in %0 type yet");
1519f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
1520f4a2713aSLionel Sambuc << T->getName(Context.getASTContext().getPrintingPolicy())
1521f4a2713aSLionel Sambuc << Range;
1522f4a2713aSLionel Sambuc break;
1523f4a2713aSLionel Sambuc }
1524f4a2713aSLionel Sambuc }
1525f4a2713aSLionel Sambuc }
1526f4a2713aSLionel Sambuc
1527f4a2713aSLionel Sambuc // <type> ::= <function-type>
mangleType(const FunctionProtoType * T,SourceRange)1528f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T,
1529f4a2713aSLionel Sambuc SourceRange) {
1530f4a2713aSLionel Sambuc // Structors only appear in decls, so at this point we know it's not a
1531f4a2713aSLionel Sambuc // structor type.
1532f4a2713aSLionel Sambuc // FIXME: This may not be lambda-friendly.
1533*0a6a1f1dSLionel Sambuc if (T->getTypeQuals() || T->getRefQualifier() != RQ_None) {
1534*0a6a1f1dSLionel Sambuc Out << "$$A8@@";
1535*0a6a1f1dSLionel Sambuc mangleFunctionType(T, /*D=*/nullptr, /*ForceThisQuals=*/true);
1536*0a6a1f1dSLionel Sambuc } else {
1537f4a2713aSLionel Sambuc Out << "$$A6";
1538f4a2713aSLionel Sambuc mangleFunctionType(T);
1539f4a2713aSLionel Sambuc }
1540*0a6a1f1dSLionel Sambuc }
mangleType(const FunctionNoProtoType * T,SourceRange)1541f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
1542f4a2713aSLionel Sambuc SourceRange) {
1543f4a2713aSLionel Sambuc llvm_unreachable("Can't mangle K&R function prototypes");
1544f4a2713aSLionel Sambuc }
1545f4a2713aSLionel Sambuc
mangleFunctionType(const FunctionType * T,const FunctionDecl * D,bool ForceThisQuals)1546f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
1547f4a2713aSLionel Sambuc const FunctionDecl *D,
1548*0a6a1f1dSLionel Sambuc bool ForceThisQuals) {
1549f4a2713aSLionel Sambuc // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
1550f4a2713aSLionel Sambuc // <return-type> <argument-list> <throw-spec>
1551f4a2713aSLionel Sambuc const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
1552f4a2713aSLionel Sambuc
1553f4a2713aSLionel Sambuc SourceRange Range;
1554f4a2713aSLionel Sambuc if (D) Range = D->getSourceRange();
1555f4a2713aSLionel Sambuc
1556*0a6a1f1dSLionel Sambuc bool IsStructor = false, HasThisQuals = ForceThisQuals;
1557f4a2713aSLionel Sambuc if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
1558f4a2713aSLionel Sambuc if (MD->isInstance())
1559*0a6a1f1dSLionel Sambuc HasThisQuals = true;
1560f4a2713aSLionel Sambuc if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD))
1561f4a2713aSLionel Sambuc IsStructor = true;
1562f4a2713aSLionel Sambuc }
1563f4a2713aSLionel Sambuc
1564f4a2713aSLionel Sambuc // If this is a C++ instance method, mangle the CVR qualifiers for the
1565f4a2713aSLionel Sambuc // this pointer.
1566*0a6a1f1dSLionel Sambuc if (HasThisQuals) {
1567*0a6a1f1dSLionel Sambuc Qualifiers Quals = Qualifiers::fromCVRMask(Proto->getTypeQuals());
1568*0a6a1f1dSLionel Sambuc manglePointerExtQualifiers(Quals, /*PointeeType=*/nullptr);
1569*0a6a1f1dSLionel Sambuc mangleRefQualifier(Proto->getRefQualifier());
1570*0a6a1f1dSLionel Sambuc mangleQualifiers(Quals, /*IsMember=*/false);
1571f4a2713aSLionel Sambuc }
1572f4a2713aSLionel Sambuc
1573f4a2713aSLionel Sambuc mangleCallingConvention(T);
1574f4a2713aSLionel Sambuc
1575f4a2713aSLionel Sambuc // <return-type> ::= <type>
1576f4a2713aSLionel Sambuc // ::= @ # structors (they have no declared return type)
1577f4a2713aSLionel Sambuc if (IsStructor) {
1578f4a2713aSLionel Sambuc if (isa<CXXDestructorDecl>(D) && D == Structor &&
1579f4a2713aSLionel Sambuc StructorType == Dtor_Deleting) {
1580f4a2713aSLionel Sambuc // The scalar deleting destructor takes an extra int argument.
1581f4a2713aSLionel Sambuc // However, the FunctionType generated has 0 arguments.
1582f4a2713aSLionel Sambuc // FIXME: This is a temporary hack.
1583f4a2713aSLionel Sambuc // Maybe should fix the FunctionType creation instead?
1584f4a2713aSLionel Sambuc Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");
1585f4a2713aSLionel Sambuc return;
1586f4a2713aSLionel Sambuc }
1587f4a2713aSLionel Sambuc Out << '@';
1588f4a2713aSLionel Sambuc } else {
1589*0a6a1f1dSLionel Sambuc QualType ResultType = Proto->getReturnType();
1590*0a6a1f1dSLionel Sambuc if (const auto *AT =
1591*0a6a1f1dSLionel Sambuc dyn_cast_or_null<AutoType>(ResultType->getContainedAutoType())) {
1592*0a6a1f1dSLionel Sambuc Out << '?';
1593*0a6a1f1dSLionel Sambuc mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
1594*0a6a1f1dSLionel Sambuc Out << '?';
1595*0a6a1f1dSLionel Sambuc mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
1596*0a6a1f1dSLionel Sambuc Out << '@';
1597*0a6a1f1dSLionel Sambuc } else {
1598f4a2713aSLionel Sambuc if (ResultType->isVoidType())
1599f4a2713aSLionel Sambuc ResultType = ResultType.getUnqualifiedType();
1600f4a2713aSLionel Sambuc mangleType(ResultType, Range, QMM_Result);
1601f4a2713aSLionel Sambuc }
1602*0a6a1f1dSLionel Sambuc }
1603f4a2713aSLionel Sambuc
1604f4a2713aSLionel Sambuc // <argument-list> ::= X # void
1605f4a2713aSLionel Sambuc // ::= <type>+ @
1606f4a2713aSLionel Sambuc // ::= <type>* Z # varargs
1607*0a6a1f1dSLionel Sambuc if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
1608f4a2713aSLionel Sambuc Out << 'X';
1609f4a2713aSLionel Sambuc } else {
1610f4a2713aSLionel Sambuc // Happens for function pointer type arguments for example.
1611*0a6a1f1dSLionel Sambuc for (const QualType Arg : Proto->param_types())
1612*0a6a1f1dSLionel Sambuc mangleArgumentType(Arg, Range);
1613f4a2713aSLionel Sambuc // <builtin-type> ::= Z # ellipsis
1614f4a2713aSLionel Sambuc if (Proto->isVariadic())
1615f4a2713aSLionel Sambuc Out << 'Z';
1616f4a2713aSLionel Sambuc else
1617f4a2713aSLionel Sambuc Out << '@';
1618f4a2713aSLionel Sambuc }
1619f4a2713aSLionel Sambuc
1620f4a2713aSLionel Sambuc mangleThrowSpecification(Proto);
1621f4a2713aSLionel Sambuc }
1622f4a2713aSLionel Sambuc
mangleFunctionClass(const FunctionDecl * FD)1623f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
1624f4a2713aSLionel Sambuc // <function-class> ::= <member-function> E? # E designates a 64-bit 'this'
1625f4a2713aSLionel Sambuc // # pointer. in 64-bit mode *all*
1626f4a2713aSLionel Sambuc // # 'this' pointers are 64-bit.
1627f4a2713aSLionel Sambuc // ::= <global-function>
1628f4a2713aSLionel Sambuc // <member-function> ::= A # private: near
1629f4a2713aSLionel Sambuc // ::= B # private: far
1630f4a2713aSLionel Sambuc // ::= C # private: static near
1631f4a2713aSLionel Sambuc // ::= D # private: static far
1632f4a2713aSLionel Sambuc // ::= E # private: virtual near
1633f4a2713aSLionel Sambuc // ::= F # private: virtual far
1634f4a2713aSLionel Sambuc // ::= I # protected: near
1635f4a2713aSLionel Sambuc // ::= J # protected: far
1636f4a2713aSLionel Sambuc // ::= K # protected: static near
1637f4a2713aSLionel Sambuc // ::= L # protected: static far
1638f4a2713aSLionel Sambuc // ::= M # protected: virtual near
1639f4a2713aSLionel Sambuc // ::= N # protected: virtual far
1640f4a2713aSLionel Sambuc // ::= Q # public: near
1641f4a2713aSLionel Sambuc // ::= R # public: far
1642f4a2713aSLionel Sambuc // ::= S # public: static near
1643f4a2713aSLionel Sambuc // ::= T # public: static far
1644f4a2713aSLionel Sambuc // ::= U # public: virtual near
1645f4a2713aSLionel Sambuc // ::= V # public: virtual far
1646f4a2713aSLionel Sambuc // <global-function> ::= Y # global near
1647f4a2713aSLionel Sambuc // ::= Z # global far
1648f4a2713aSLionel Sambuc if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
1649f4a2713aSLionel Sambuc switch (MD->getAccess()) {
1650f4a2713aSLionel Sambuc case AS_none:
1651f4a2713aSLionel Sambuc llvm_unreachable("Unsupported access specifier");
1652f4a2713aSLionel Sambuc case AS_private:
1653f4a2713aSLionel Sambuc if (MD->isStatic())
1654f4a2713aSLionel Sambuc Out << 'C';
1655f4a2713aSLionel Sambuc else if (MD->isVirtual())
1656f4a2713aSLionel Sambuc Out << 'E';
1657f4a2713aSLionel Sambuc else
1658f4a2713aSLionel Sambuc Out << 'A';
1659f4a2713aSLionel Sambuc break;
1660f4a2713aSLionel Sambuc case AS_protected:
1661f4a2713aSLionel Sambuc if (MD->isStatic())
1662f4a2713aSLionel Sambuc Out << 'K';
1663f4a2713aSLionel Sambuc else if (MD->isVirtual())
1664f4a2713aSLionel Sambuc Out << 'M';
1665f4a2713aSLionel Sambuc else
1666f4a2713aSLionel Sambuc Out << 'I';
1667f4a2713aSLionel Sambuc break;
1668f4a2713aSLionel Sambuc case AS_public:
1669f4a2713aSLionel Sambuc if (MD->isStatic())
1670f4a2713aSLionel Sambuc Out << 'S';
1671f4a2713aSLionel Sambuc else if (MD->isVirtual())
1672f4a2713aSLionel Sambuc Out << 'U';
1673f4a2713aSLionel Sambuc else
1674f4a2713aSLionel Sambuc Out << 'Q';
1675f4a2713aSLionel Sambuc }
1676f4a2713aSLionel Sambuc } else
1677f4a2713aSLionel Sambuc Out << 'Y';
1678f4a2713aSLionel Sambuc }
mangleCallingConvention(const FunctionType * T)1679f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T) {
1680f4a2713aSLionel Sambuc // <calling-convention> ::= A # __cdecl
1681f4a2713aSLionel Sambuc // ::= B # __export __cdecl
1682f4a2713aSLionel Sambuc // ::= C # __pascal
1683f4a2713aSLionel Sambuc // ::= D # __export __pascal
1684f4a2713aSLionel Sambuc // ::= E # __thiscall
1685f4a2713aSLionel Sambuc // ::= F # __export __thiscall
1686f4a2713aSLionel Sambuc // ::= G # __stdcall
1687f4a2713aSLionel Sambuc // ::= H # __export __stdcall
1688f4a2713aSLionel Sambuc // ::= I # __fastcall
1689f4a2713aSLionel Sambuc // ::= J # __export __fastcall
1690*0a6a1f1dSLionel Sambuc // ::= Q # __vectorcall
1691f4a2713aSLionel Sambuc // The 'export' calling conventions are from a bygone era
1692f4a2713aSLionel Sambuc // (*cough*Win16*cough*) when functions were declared for export with
1693f4a2713aSLionel Sambuc // that keyword. (It didn't actually export them, it just made them so
1694f4a2713aSLionel Sambuc // that they could be in a DLL and somebody from another module could call
1695f4a2713aSLionel Sambuc // them.)
1696f4a2713aSLionel Sambuc CallingConv CC = T->getCallConv();
1697f4a2713aSLionel Sambuc switch (CC) {
1698f4a2713aSLionel Sambuc default:
1699f4a2713aSLionel Sambuc llvm_unreachable("Unsupported CC for mangling");
1700f4a2713aSLionel Sambuc case CC_X86_64Win64:
1701f4a2713aSLionel Sambuc case CC_X86_64SysV:
1702f4a2713aSLionel Sambuc case CC_C: Out << 'A'; break;
1703f4a2713aSLionel Sambuc case CC_X86Pascal: Out << 'C'; break;
1704f4a2713aSLionel Sambuc case CC_X86ThisCall: Out << 'E'; break;
1705f4a2713aSLionel Sambuc case CC_X86StdCall: Out << 'G'; break;
1706f4a2713aSLionel Sambuc case CC_X86FastCall: Out << 'I'; break;
1707*0a6a1f1dSLionel Sambuc case CC_X86VectorCall: Out << 'Q'; break;
1708f4a2713aSLionel Sambuc }
1709f4a2713aSLionel Sambuc }
mangleThrowSpecification(const FunctionProtoType * FT)1710f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleThrowSpecification(
1711f4a2713aSLionel Sambuc const FunctionProtoType *FT) {
1712f4a2713aSLionel Sambuc // <throw-spec> ::= Z # throw(...) (default)
1713f4a2713aSLionel Sambuc // ::= @ # throw() or __declspec/__attribute__((nothrow))
1714f4a2713aSLionel Sambuc // ::= <type>+
1715f4a2713aSLionel Sambuc // NOTE: Since the Microsoft compiler ignores throw specifications, they are
1716f4a2713aSLionel Sambuc // all actually mangled as 'Z'. (They're ignored because their associated
1717f4a2713aSLionel Sambuc // functionality isn't implemented, and probably never will be.)
1718f4a2713aSLionel Sambuc Out << 'Z';
1719f4a2713aSLionel Sambuc }
1720f4a2713aSLionel Sambuc
mangleType(const UnresolvedUsingType * T,SourceRange Range)1721f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,
1722f4a2713aSLionel Sambuc SourceRange Range) {
1723f4a2713aSLionel Sambuc // Probably should be mangled as a template instantiation; need to see what
1724f4a2713aSLionel Sambuc // VC does first.
1725f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
1726f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1727f4a2713aSLionel Sambuc "cannot mangle this unresolved dependent type yet");
1728f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
1729f4a2713aSLionel Sambuc << Range;
1730f4a2713aSLionel Sambuc }
1731f4a2713aSLionel Sambuc
1732f4a2713aSLionel Sambuc // <type> ::= <union-type> | <struct-type> | <class-type> | <enum-type>
1733f4a2713aSLionel Sambuc // <union-type> ::= T <name>
1734f4a2713aSLionel Sambuc // <struct-type> ::= U <name>
1735f4a2713aSLionel Sambuc // <class-type> ::= V <name>
1736*0a6a1f1dSLionel Sambuc // <enum-type> ::= W4 <name>
mangleType(const EnumType * T,SourceRange)1737f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const EnumType *T, SourceRange) {
1738f4a2713aSLionel Sambuc mangleType(cast<TagType>(T)->getDecl());
1739f4a2713aSLionel Sambuc }
mangleType(const RecordType * T,SourceRange)1740f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const RecordType *T, SourceRange) {
1741f4a2713aSLionel Sambuc mangleType(cast<TagType>(T)->getDecl());
1742f4a2713aSLionel Sambuc }
mangleType(const TagDecl * TD)1743f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
1744f4a2713aSLionel Sambuc switch (TD->getTagKind()) {
1745f4a2713aSLionel Sambuc case TTK_Union:
1746f4a2713aSLionel Sambuc Out << 'T';
1747f4a2713aSLionel Sambuc break;
1748f4a2713aSLionel Sambuc case TTK_Struct:
1749f4a2713aSLionel Sambuc case TTK_Interface:
1750f4a2713aSLionel Sambuc Out << 'U';
1751f4a2713aSLionel Sambuc break;
1752f4a2713aSLionel Sambuc case TTK_Class:
1753f4a2713aSLionel Sambuc Out << 'V';
1754f4a2713aSLionel Sambuc break;
1755f4a2713aSLionel Sambuc case TTK_Enum:
1756*0a6a1f1dSLionel Sambuc Out << "W4";
1757f4a2713aSLionel Sambuc break;
1758f4a2713aSLionel Sambuc }
1759f4a2713aSLionel Sambuc mangleName(TD);
1760f4a2713aSLionel Sambuc }
1761f4a2713aSLionel Sambuc
1762f4a2713aSLionel Sambuc // <type> ::= <array-type>
1763f4a2713aSLionel Sambuc // <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
1764f4a2713aSLionel Sambuc // [Y <dimension-count> <dimension>+]
1765f4a2713aSLionel Sambuc // <element-type> # as global, E is never required
1766f4a2713aSLionel Sambuc // It's supposed to be the other way around, but for some strange reason, it
1767f4a2713aSLionel Sambuc // isn't. Today this behavior is retained for the sole purpose of backwards
1768f4a2713aSLionel Sambuc // compatibility.
mangleDecayedArrayType(const ArrayType * T)1769f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) {
1770f4a2713aSLionel Sambuc // This isn't a recursive mangling, so now we have to do it all in this
1771f4a2713aSLionel Sambuc // one call.
1772*0a6a1f1dSLionel Sambuc manglePointerCVQualifiers(T->getElementType().getQualifiers());
1773f4a2713aSLionel Sambuc mangleType(T->getElementType(), SourceRange());
1774f4a2713aSLionel Sambuc }
mangleType(const ConstantArrayType * T,SourceRange)1775f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T,
1776f4a2713aSLionel Sambuc SourceRange) {
1777f4a2713aSLionel Sambuc llvm_unreachable("Should have been special cased");
1778f4a2713aSLionel Sambuc }
mangleType(const VariableArrayType * T,SourceRange)1779f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T,
1780f4a2713aSLionel Sambuc SourceRange) {
1781f4a2713aSLionel Sambuc llvm_unreachable("Should have been special cased");
1782f4a2713aSLionel Sambuc }
mangleType(const DependentSizedArrayType * T,SourceRange)1783f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T,
1784f4a2713aSLionel Sambuc SourceRange) {
1785f4a2713aSLionel Sambuc llvm_unreachable("Should have been special cased");
1786f4a2713aSLionel Sambuc }
mangleType(const IncompleteArrayType * T,SourceRange)1787f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T,
1788f4a2713aSLionel Sambuc SourceRange) {
1789f4a2713aSLionel Sambuc llvm_unreachable("Should have been special cased");
1790f4a2713aSLionel Sambuc }
mangleArrayType(const ArrayType * T)1791f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) {
1792f4a2713aSLionel Sambuc QualType ElementTy(T, 0);
1793f4a2713aSLionel Sambuc SmallVector<llvm::APInt, 3> Dimensions;
1794f4a2713aSLionel Sambuc for (;;) {
1795f4a2713aSLionel Sambuc if (const ConstantArrayType *CAT =
1796f4a2713aSLionel Sambuc getASTContext().getAsConstantArrayType(ElementTy)) {
1797f4a2713aSLionel Sambuc Dimensions.push_back(CAT->getSize());
1798f4a2713aSLionel Sambuc ElementTy = CAT->getElementType();
1799f4a2713aSLionel Sambuc } else if (ElementTy->isVariableArrayType()) {
1800f4a2713aSLionel Sambuc const VariableArrayType *VAT =
1801f4a2713aSLionel Sambuc getASTContext().getAsVariableArrayType(ElementTy);
1802f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
1803f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1804f4a2713aSLionel Sambuc "cannot mangle this variable-length array yet");
1805f4a2713aSLionel Sambuc Diags.Report(VAT->getSizeExpr()->getExprLoc(), DiagID)
1806f4a2713aSLionel Sambuc << VAT->getBracketsRange();
1807f4a2713aSLionel Sambuc return;
1808f4a2713aSLionel Sambuc } else if (ElementTy->isDependentSizedArrayType()) {
1809f4a2713aSLionel Sambuc // The dependent expression has to be folded into a constant (TODO).
1810f4a2713aSLionel Sambuc const DependentSizedArrayType *DSAT =
1811f4a2713aSLionel Sambuc getASTContext().getAsDependentSizedArrayType(ElementTy);
1812f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
1813f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1814f4a2713aSLionel Sambuc "cannot mangle this dependent-length array yet");
1815f4a2713aSLionel Sambuc Diags.Report(DSAT->getSizeExpr()->getExprLoc(), DiagID)
1816f4a2713aSLionel Sambuc << DSAT->getBracketsRange();
1817f4a2713aSLionel Sambuc return;
1818f4a2713aSLionel Sambuc } else if (const IncompleteArrayType *IAT =
1819f4a2713aSLionel Sambuc getASTContext().getAsIncompleteArrayType(ElementTy)) {
1820f4a2713aSLionel Sambuc Dimensions.push_back(llvm::APInt(32, 0));
1821f4a2713aSLionel Sambuc ElementTy = IAT->getElementType();
1822f4a2713aSLionel Sambuc }
1823f4a2713aSLionel Sambuc else break;
1824f4a2713aSLionel Sambuc }
1825f4a2713aSLionel Sambuc Out << 'Y';
1826f4a2713aSLionel Sambuc // <dimension-count> ::= <number> # number of extra dimensions
1827f4a2713aSLionel Sambuc mangleNumber(Dimensions.size());
1828*0a6a1f1dSLionel Sambuc for (const llvm::APInt &Dimension : Dimensions)
1829*0a6a1f1dSLionel Sambuc mangleNumber(Dimension.getLimitedValue());
1830f4a2713aSLionel Sambuc mangleType(ElementTy, SourceRange(), QMM_Escape);
1831f4a2713aSLionel Sambuc }
1832f4a2713aSLionel Sambuc
1833f4a2713aSLionel Sambuc // <type> ::= <pointer-to-member-type>
1834f4a2713aSLionel Sambuc // <pointer-to-member-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
1835f4a2713aSLionel Sambuc // <class name> <type>
mangleType(const MemberPointerType * T,SourceRange Range)1836f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,
1837f4a2713aSLionel Sambuc SourceRange Range) {
1838f4a2713aSLionel Sambuc QualType PointeeType = T->getPointeeType();
1839f4a2713aSLionel Sambuc if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
1840f4a2713aSLionel Sambuc Out << '8';
1841f4a2713aSLionel Sambuc mangleName(T->getClass()->castAs<RecordType>()->getDecl());
1842*0a6a1f1dSLionel Sambuc mangleFunctionType(FPT, nullptr, true);
1843f4a2713aSLionel Sambuc } else {
1844f4a2713aSLionel Sambuc mangleQualifiers(PointeeType.getQualifiers(), true);
1845f4a2713aSLionel Sambuc mangleName(T->getClass()->castAs<RecordType>()->getDecl());
1846f4a2713aSLionel Sambuc mangleType(PointeeType, Range, QMM_Drop);
1847f4a2713aSLionel Sambuc }
1848f4a2713aSLionel Sambuc }
1849f4a2713aSLionel Sambuc
mangleType(const TemplateTypeParmType * T,SourceRange Range)1850f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T,
1851f4a2713aSLionel Sambuc SourceRange Range) {
1852f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
1853f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1854f4a2713aSLionel Sambuc "cannot mangle this template type parameter type yet");
1855f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
1856f4a2713aSLionel Sambuc << Range;
1857f4a2713aSLionel Sambuc }
1858f4a2713aSLionel Sambuc
mangleType(const SubstTemplateTypeParmPackType * T,SourceRange Range)1859f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(
1860f4a2713aSLionel Sambuc const SubstTemplateTypeParmPackType *T,
1861f4a2713aSLionel Sambuc SourceRange Range) {
1862f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
1863f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1864f4a2713aSLionel Sambuc "cannot mangle this substituted parameter pack yet");
1865f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
1866f4a2713aSLionel Sambuc << Range;
1867f4a2713aSLionel Sambuc }
1868f4a2713aSLionel Sambuc
1869f4a2713aSLionel Sambuc // <type> ::= <pointer-type>
1870f4a2713aSLionel Sambuc // <pointer-type> ::= E? <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
1871*0a6a1f1dSLionel Sambuc // # the E is required for 64-bit non-static pointers
mangleType(const PointerType * T,SourceRange Range)1872f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const PointerType *T,
1873f4a2713aSLionel Sambuc SourceRange Range) {
1874f4a2713aSLionel Sambuc QualType PointeeTy = T->getPointeeType();
1875f4a2713aSLionel Sambuc mangleType(PointeeTy, Range);
1876f4a2713aSLionel Sambuc }
mangleType(const ObjCObjectPointerType * T,SourceRange Range)1877f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
1878f4a2713aSLionel Sambuc SourceRange Range) {
1879f4a2713aSLionel Sambuc // Object pointers never have qualifiers.
1880f4a2713aSLionel Sambuc Out << 'A';
1881*0a6a1f1dSLionel Sambuc manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr());
1882f4a2713aSLionel Sambuc mangleType(T->getPointeeType(), Range);
1883f4a2713aSLionel Sambuc }
1884f4a2713aSLionel Sambuc
1885f4a2713aSLionel Sambuc // <type> ::= <reference-type>
1886f4a2713aSLionel Sambuc // <reference-type> ::= A E? <cvr-qualifiers> <type>
1887*0a6a1f1dSLionel Sambuc // # the E is required for 64-bit non-static lvalue references
mangleType(const LValueReferenceType * T,SourceRange Range)1888f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,
1889f4a2713aSLionel Sambuc SourceRange Range) {
1890f4a2713aSLionel Sambuc Out << 'A';
1891*0a6a1f1dSLionel Sambuc manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr());
1892f4a2713aSLionel Sambuc mangleType(T->getPointeeType(), Range);
1893f4a2713aSLionel Sambuc }
1894f4a2713aSLionel Sambuc
1895f4a2713aSLionel Sambuc // <type> ::= <r-value-reference-type>
1896f4a2713aSLionel Sambuc // <r-value-reference-type> ::= $$Q E? <cvr-qualifiers> <type>
1897*0a6a1f1dSLionel Sambuc // # the E is required for 64-bit non-static rvalue references
mangleType(const RValueReferenceType * T,SourceRange Range)1898f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,
1899f4a2713aSLionel Sambuc SourceRange Range) {
1900f4a2713aSLionel Sambuc Out << "$$Q";
1901*0a6a1f1dSLionel Sambuc manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr());
1902f4a2713aSLionel Sambuc mangleType(T->getPointeeType(), Range);
1903f4a2713aSLionel Sambuc }
1904f4a2713aSLionel Sambuc
mangleType(const ComplexType * T,SourceRange Range)1905f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const ComplexType *T,
1906f4a2713aSLionel Sambuc SourceRange Range) {
1907f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
1908f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1909f4a2713aSLionel Sambuc "cannot mangle this complex number type yet");
1910f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
1911f4a2713aSLionel Sambuc << Range;
1912f4a2713aSLionel Sambuc }
1913f4a2713aSLionel Sambuc
mangleType(const VectorType * T,SourceRange Range)1914f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const VectorType *T,
1915f4a2713aSLionel Sambuc SourceRange Range) {
1916f4a2713aSLionel Sambuc const BuiltinType *ET = T->getElementType()->getAs<BuiltinType>();
1917f4a2713aSLionel Sambuc assert(ET && "vectors with non-builtin elements are unsupported");
1918f4a2713aSLionel Sambuc uint64_t Width = getASTContext().getTypeSize(T);
1919f4a2713aSLionel Sambuc // Pattern match exactly the typedefs in our intrinsic headers. Anything that
1920f4a2713aSLionel Sambuc // doesn't match the Intel types uses a custom mangling below.
1921f4a2713aSLionel Sambuc bool IntelVector = true;
1922f4a2713aSLionel Sambuc if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {
1923f4a2713aSLionel Sambuc Out << "T__m64";
1924f4a2713aSLionel Sambuc } else if (Width == 128 || Width == 256) {
1925f4a2713aSLionel Sambuc if (ET->getKind() == BuiltinType::Float)
1926f4a2713aSLionel Sambuc Out << "T__m" << Width;
1927f4a2713aSLionel Sambuc else if (ET->getKind() == BuiltinType::LongLong)
1928f4a2713aSLionel Sambuc Out << "T__m" << Width << 'i';
1929f4a2713aSLionel Sambuc else if (ET->getKind() == BuiltinType::Double)
1930f4a2713aSLionel Sambuc Out << "U__m" << Width << 'd';
1931f4a2713aSLionel Sambuc else
1932f4a2713aSLionel Sambuc IntelVector = false;
1933f4a2713aSLionel Sambuc } else {
1934f4a2713aSLionel Sambuc IntelVector = false;
1935f4a2713aSLionel Sambuc }
1936f4a2713aSLionel Sambuc
1937f4a2713aSLionel Sambuc if (!IntelVector) {
1938f4a2713aSLionel Sambuc // The MS ABI doesn't have a special mangling for vector types, so we define
1939f4a2713aSLionel Sambuc // our own mangling to handle uses of __vector_size__ on user-specified
1940f4a2713aSLionel Sambuc // types, and for extensions like __v4sf.
1941f4a2713aSLionel Sambuc Out << "T__clang_vec" << T->getNumElements() << '_';
1942f4a2713aSLionel Sambuc mangleType(ET, Range);
1943f4a2713aSLionel Sambuc }
1944f4a2713aSLionel Sambuc
1945f4a2713aSLionel Sambuc Out << "@@";
1946f4a2713aSLionel Sambuc }
1947f4a2713aSLionel Sambuc
mangleType(const ExtVectorType * T,SourceRange Range)1948f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T,
1949f4a2713aSLionel Sambuc SourceRange Range) {
1950f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
1951f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1952f4a2713aSLionel Sambuc "cannot mangle this extended vector type yet");
1953f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
1954f4a2713aSLionel Sambuc << Range;
1955f4a2713aSLionel Sambuc }
mangleType(const DependentSizedExtVectorType * T,SourceRange Range)1956f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,
1957f4a2713aSLionel Sambuc SourceRange Range) {
1958f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
1959f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1960f4a2713aSLionel Sambuc "cannot mangle this dependent-sized extended vector type yet");
1961f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
1962f4a2713aSLionel Sambuc << Range;
1963f4a2713aSLionel Sambuc }
1964f4a2713aSLionel Sambuc
mangleType(const ObjCInterfaceType * T,SourceRange)1965f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T,
1966f4a2713aSLionel Sambuc SourceRange) {
1967f4a2713aSLionel Sambuc // ObjC interfaces have structs underlying them.
1968f4a2713aSLionel Sambuc Out << 'U';
1969f4a2713aSLionel Sambuc mangleName(T->getDecl());
1970f4a2713aSLionel Sambuc }
1971f4a2713aSLionel Sambuc
mangleType(const ObjCObjectType * T,SourceRange Range)1972f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,
1973f4a2713aSLionel Sambuc SourceRange Range) {
1974f4a2713aSLionel Sambuc // We don't allow overloading by different protocol qualification,
1975f4a2713aSLionel Sambuc // so mangling them isn't necessary.
1976f4a2713aSLionel Sambuc mangleType(T->getBaseType(), Range);
1977f4a2713aSLionel Sambuc }
1978f4a2713aSLionel Sambuc
mangleType(const BlockPointerType * T,SourceRange Range)1979f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T,
1980f4a2713aSLionel Sambuc SourceRange Range) {
1981f4a2713aSLionel Sambuc Out << "_E";
1982f4a2713aSLionel Sambuc
1983f4a2713aSLionel Sambuc QualType pointee = T->getPointeeType();
1984f4a2713aSLionel Sambuc mangleFunctionType(pointee->castAs<FunctionProtoType>());
1985f4a2713aSLionel Sambuc }
1986f4a2713aSLionel Sambuc
mangleType(const InjectedClassNameType *,SourceRange)1987f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *,
1988f4a2713aSLionel Sambuc SourceRange) {
1989f4a2713aSLionel Sambuc llvm_unreachable("Cannot mangle injected class name type.");
1990f4a2713aSLionel Sambuc }
1991f4a2713aSLionel Sambuc
mangleType(const TemplateSpecializationType * T,SourceRange Range)1992f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T,
1993f4a2713aSLionel Sambuc SourceRange Range) {
1994f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
1995f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1996f4a2713aSLionel Sambuc "cannot mangle this template specialization type yet");
1997f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
1998f4a2713aSLionel Sambuc << Range;
1999f4a2713aSLionel Sambuc }
2000f4a2713aSLionel Sambuc
mangleType(const DependentNameType * T,SourceRange Range)2001f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T,
2002f4a2713aSLionel Sambuc SourceRange Range) {
2003f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
2004f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
2005f4a2713aSLionel Sambuc "cannot mangle this dependent name type yet");
2006f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
2007f4a2713aSLionel Sambuc << Range;
2008f4a2713aSLionel Sambuc }
2009f4a2713aSLionel Sambuc
mangleType(const DependentTemplateSpecializationType * T,SourceRange Range)2010f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(
2011f4a2713aSLionel Sambuc const DependentTemplateSpecializationType *T,
2012f4a2713aSLionel Sambuc SourceRange Range) {
2013f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
2014f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
2015f4a2713aSLionel Sambuc "cannot mangle this dependent template specialization type yet");
2016f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
2017f4a2713aSLionel Sambuc << Range;
2018f4a2713aSLionel Sambuc }
2019f4a2713aSLionel Sambuc
mangleType(const PackExpansionType * T,SourceRange Range)2020f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T,
2021f4a2713aSLionel Sambuc SourceRange Range) {
2022f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
2023f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
2024f4a2713aSLionel Sambuc "cannot mangle this pack expansion yet");
2025f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
2026f4a2713aSLionel Sambuc << Range;
2027f4a2713aSLionel Sambuc }
2028f4a2713aSLionel Sambuc
mangleType(const TypeOfType * T,SourceRange Range)2029f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T,
2030f4a2713aSLionel Sambuc SourceRange Range) {
2031f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
2032f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
2033f4a2713aSLionel Sambuc "cannot mangle this typeof(type) yet");
2034f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
2035f4a2713aSLionel Sambuc << Range;
2036f4a2713aSLionel Sambuc }
2037f4a2713aSLionel Sambuc
mangleType(const TypeOfExprType * T,SourceRange Range)2038f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T,
2039f4a2713aSLionel Sambuc SourceRange Range) {
2040f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
2041f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
2042f4a2713aSLionel Sambuc "cannot mangle this typeof(expression) yet");
2043f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
2044f4a2713aSLionel Sambuc << Range;
2045f4a2713aSLionel Sambuc }
2046f4a2713aSLionel Sambuc
mangleType(const DecltypeType * T,SourceRange Range)2047f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T,
2048f4a2713aSLionel Sambuc SourceRange Range) {
2049f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
2050f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
2051f4a2713aSLionel Sambuc "cannot mangle this decltype() yet");
2052f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
2053f4a2713aSLionel Sambuc << Range;
2054f4a2713aSLionel Sambuc }
2055f4a2713aSLionel Sambuc
mangleType(const UnaryTransformType * T,SourceRange Range)2056f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T,
2057f4a2713aSLionel Sambuc SourceRange Range) {
2058f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
2059f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
2060f4a2713aSLionel Sambuc "cannot mangle this unary transform type yet");
2061f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
2062f4a2713aSLionel Sambuc << Range;
2063f4a2713aSLionel Sambuc }
2064f4a2713aSLionel Sambuc
mangleType(const AutoType * T,SourceRange Range)2065f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const AutoType *T, SourceRange Range) {
2066*0a6a1f1dSLionel Sambuc assert(T->getDeducedType().isNull() && "expecting a dependent type!");
2067*0a6a1f1dSLionel Sambuc
2068f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
2069f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
2070f4a2713aSLionel Sambuc "cannot mangle this 'auto' type yet");
2071f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
2072f4a2713aSLionel Sambuc << Range;
2073f4a2713aSLionel Sambuc }
2074f4a2713aSLionel Sambuc
mangleType(const AtomicType * T,SourceRange Range)2075f4a2713aSLionel Sambuc void MicrosoftCXXNameMangler::mangleType(const AtomicType *T,
2076f4a2713aSLionel Sambuc SourceRange Range) {
2077f4a2713aSLionel Sambuc DiagnosticsEngine &Diags = Context.getDiags();
2078f4a2713aSLionel Sambuc unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
2079f4a2713aSLionel Sambuc "cannot mangle this C11 atomic type yet");
2080f4a2713aSLionel Sambuc Diags.Report(Range.getBegin(), DiagID)
2081f4a2713aSLionel Sambuc << Range;
2082f4a2713aSLionel Sambuc }
2083f4a2713aSLionel Sambuc
mangleCXXName(const NamedDecl * D,raw_ostream & Out)2084f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXName(const NamedDecl *D,
2085f4a2713aSLionel Sambuc raw_ostream &Out) {
2086f4a2713aSLionel Sambuc assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
2087f4a2713aSLionel Sambuc "Invalid mangleName() call, argument is not a variable or function!");
2088f4a2713aSLionel Sambuc assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
2089f4a2713aSLionel Sambuc "Invalid mangleName() call on 'structor decl!");
2090f4a2713aSLionel Sambuc
2091f4a2713aSLionel Sambuc PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
2092f4a2713aSLionel Sambuc getASTContext().getSourceManager(),
2093f4a2713aSLionel Sambuc "Mangling declaration");
2094f4a2713aSLionel Sambuc
2095f4a2713aSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2096f4a2713aSLionel Sambuc return Mangler.mangle(D);
2097f4a2713aSLionel Sambuc }
2098f4a2713aSLionel Sambuc
2099f4a2713aSLionel Sambuc // <this-adjustment> ::= <no-adjustment> | <static-adjustment> |
2100f4a2713aSLionel Sambuc // <virtual-adjustment>
2101f4a2713aSLionel Sambuc // <no-adjustment> ::= A # private near
2102f4a2713aSLionel Sambuc // ::= B # private far
2103f4a2713aSLionel Sambuc // ::= I # protected near
2104f4a2713aSLionel Sambuc // ::= J # protected far
2105f4a2713aSLionel Sambuc // ::= Q # public near
2106f4a2713aSLionel Sambuc // ::= R # public far
2107f4a2713aSLionel Sambuc // <static-adjustment> ::= G <static-offset> # private near
2108f4a2713aSLionel Sambuc // ::= H <static-offset> # private far
2109f4a2713aSLionel Sambuc // ::= O <static-offset> # protected near
2110f4a2713aSLionel Sambuc // ::= P <static-offset> # protected far
2111f4a2713aSLionel Sambuc // ::= W <static-offset> # public near
2112f4a2713aSLionel Sambuc // ::= X <static-offset> # public far
2113f4a2713aSLionel Sambuc // <virtual-adjustment> ::= $0 <virtual-shift> <static-offset> # private near
2114f4a2713aSLionel Sambuc // ::= $1 <virtual-shift> <static-offset> # private far
2115f4a2713aSLionel Sambuc // ::= $2 <virtual-shift> <static-offset> # protected near
2116f4a2713aSLionel Sambuc // ::= $3 <virtual-shift> <static-offset> # protected far
2117f4a2713aSLionel Sambuc // ::= $4 <virtual-shift> <static-offset> # public near
2118f4a2713aSLionel Sambuc // ::= $5 <virtual-shift> <static-offset> # public far
2119f4a2713aSLionel Sambuc // <virtual-shift> ::= <vtordisp-shift> | <vtordispex-shift>
2120f4a2713aSLionel Sambuc // <vtordisp-shift> ::= <offset-to-vtordisp>
2121f4a2713aSLionel Sambuc // <vtordispex-shift> ::= <offset-to-vbptr> <vbase-offset-offset>
2122f4a2713aSLionel Sambuc // <offset-to-vtordisp>
mangleThunkThisAdjustment(const CXXMethodDecl * MD,const ThisAdjustment & Adjustment,MicrosoftCXXNameMangler & Mangler,raw_ostream & Out)2123f4a2713aSLionel Sambuc static void mangleThunkThisAdjustment(const CXXMethodDecl *MD,
2124f4a2713aSLionel Sambuc const ThisAdjustment &Adjustment,
2125f4a2713aSLionel Sambuc MicrosoftCXXNameMangler &Mangler,
2126f4a2713aSLionel Sambuc raw_ostream &Out) {
2127f4a2713aSLionel Sambuc if (!Adjustment.Virtual.isEmpty()) {
2128f4a2713aSLionel Sambuc Out << '$';
2129f4a2713aSLionel Sambuc char AccessSpec;
2130f4a2713aSLionel Sambuc switch (MD->getAccess()) {
2131f4a2713aSLionel Sambuc case AS_none:
2132f4a2713aSLionel Sambuc llvm_unreachable("Unsupported access specifier");
2133f4a2713aSLionel Sambuc case AS_private:
2134f4a2713aSLionel Sambuc AccessSpec = '0';
2135f4a2713aSLionel Sambuc break;
2136f4a2713aSLionel Sambuc case AS_protected:
2137f4a2713aSLionel Sambuc AccessSpec = '2';
2138f4a2713aSLionel Sambuc break;
2139f4a2713aSLionel Sambuc case AS_public:
2140f4a2713aSLionel Sambuc AccessSpec = '4';
2141f4a2713aSLionel Sambuc }
2142f4a2713aSLionel Sambuc if (Adjustment.Virtual.Microsoft.VBPtrOffset) {
2143f4a2713aSLionel Sambuc Out << 'R' << AccessSpec;
2144*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(
2145*0a6a1f1dSLionel Sambuc static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBPtrOffset));
2146*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(
2147*0a6a1f1dSLionel Sambuc static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBOffsetOffset));
2148*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(
2149*0a6a1f1dSLionel Sambuc static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));
2150*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(static_cast<uint32_t>(Adjustment.NonVirtual));
2151f4a2713aSLionel Sambuc } else {
2152f4a2713aSLionel Sambuc Out << AccessSpec;
2153*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(
2154*0a6a1f1dSLionel Sambuc static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));
2155*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
2156f4a2713aSLionel Sambuc }
2157f4a2713aSLionel Sambuc } else if (Adjustment.NonVirtual != 0) {
2158f4a2713aSLionel Sambuc switch (MD->getAccess()) {
2159f4a2713aSLionel Sambuc case AS_none:
2160f4a2713aSLionel Sambuc llvm_unreachable("Unsupported access specifier");
2161f4a2713aSLionel Sambuc case AS_private:
2162f4a2713aSLionel Sambuc Out << 'G';
2163f4a2713aSLionel Sambuc break;
2164f4a2713aSLionel Sambuc case AS_protected:
2165f4a2713aSLionel Sambuc Out << 'O';
2166f4a2713aSLionel Sambuc break;
2167f4a2713aSLionel Sambuc case AS_public:
2168f4a2713aSLionel Sambuc Out << 'W';
2169f4a2713aSLionel Sambuc }
2170*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
2171f4a2713aSLionel Sambuc } else {
2172f4a2713aSLionel Sambuc switch (MD->getAccess()) {
2173f4a2713aSLionel Sambuc case AS_none:
2174f4a2713aSLionel Sambuc llvm_unreachable("Unsupported access specifier");
2175f4a2713aSLionel Sambuc case AS_private:
2176f4a2713aSLionel Sambuc Out << 'A';
2177f4a2713aSLionel Sambuc break;
2178f4a2713aSLionel Sambuc case AS_protected:
2179f4a2713aSLionel Sambuc Out << 'I';
2180f4a2713aSLionel Sambuc break;
2181f4a2713aSLionel Sambuc case AS_public:
2182f4a2713aSLionel Sambuc Out << 'Q';
2183f4a2713aSLionel Sambuc }
2184f4a2713aSLionel Sambuc }
2185f4a2713aSLionel Sambuc }
2186f4a2713aSLionel Sambuc
2187*0a6a1f1dSLionel Sambuc void
mangleVirtualMemPtrThunk(const CXXMethodDecl * MD,raw_ostream & Out)2188*0a6a1f1dSLionel Sambuc MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
2189*0a6a1f1dSLionel Sambuc raw_ostream &Out) {
2190*0a6a1f1dSLionel Sambuc MicrosoftVTableContext *VTContext =
2191*0a6a1f1dSLionel Sambuc cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
2192*0a6a1f1dSLionel Sambuc const MicrosoftVTableContext::MethodVFTableLocation &ML =
2193*0a6a1f1dSLionel Sambuc VTContext->getMethodVFTableLocation(GlobalDecl(MD));
2194f4a2713aSLionel Sambuc
2195f4a2713aSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2196*0a6a1f1dSLionel Sambuc Mangler.getStream() << "\01?";
2197*0a6a1f1dSLionel Sambuc Mangler.mangleVirtualMemPtrThunk(MD, ML);
2198f4a2713aSLionel Sambuc }
2199f4a2713aSLionel Sambuc
mangleThunk(const CXXMethodDecl * MD,const ThunkInfo & Thunk,raw_ostream & Out)2200f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
2201f4a2713aSLionel Sambuc const ThunkInfo &Thunk,
2202f4a2713aSLionel Sambuc raw_ostream &Out) {
2203f4a2713aSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2204f4a2713aSLionel Sambuc Out << "\01?";
2205f4a2713aSLionel Sambuc Mangler.mangleName(MD);
2206f4a2713aSLionel Sambuc mangleThunkThisAdjustment(MD, Thunk.This, Mangler, Out);
2207f4a2713aSLionel Sambuc if (!Thunk.Return.isEmpty())
2208*0a6a1f1dSLionel Sambuc assert(Thunk.Method != nullptr &&
2209*0a6a1f1dSLionel Sambuc "Thunk info should hold the overridee decl");
2210f4a2713aSLionel Sambuc
2211f4a2713aSLionel Sambuc const CXXMethodDecl *DeclForFPT = Thunk.Method ? Thunk.Method : MD;
2212f4a2713aSLionel Sambuc Mangler.mangleFunctionType(
2213f4a2713aSLionel Sambuc DeclForFPT->getType()->castAs<FunctionProtoType>(), MD);
2214f4a2713aSLionel Sambuc }
2215f4a2713aSLionel Sambuc
mangleCXXDtorThunk(const CXXDestructorDecl * DD,CXXDtorType Type,const ThisAdjustment & Adjustment,raw_ostream & Out)2216f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXDtorThunk(
2217f4a2713aSLionel Sambuc const CXXDestructorDecl *DD, CXXDtorType Type,
2218f4a2713aSLionel Sambuc const ThisAdjustment &Adjustment, raw_ostream &Out) {
2219f4a2713aSLionel Sambuc // FIXME: Actually, the dtor thunk should be emitted for vector deleting
2220f4a2713aSLionel Sambuc // dtors rather than scalar deleting dtors. Just use the vector deleting dtor
2221f4a2713aSLionel Sambuc // mangling manually until we support both deleting dtor types.
2222f4a2713aSLionel Sambuc assert(Type == Dtor_Deleting);
2223f4a2713aSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out, DD, Type);
2224f4a2713aSLionel Sambuc Out << "\01??_E";
2225f4a2713aSLionel Sambuc Mangler.mangleName(DD->getParent());
2226f4a2713aSLionel Sambuc mangleThunkThisAdjustment(DD, Adjustment, Mangler, Out);
2227f4a2713aSLionel Sambuc Mangler.mangleFunctionType(DD->getType()->castAs<FunctionProtoType>(), DD);
2228f4a2713aSLionel Sambuc }
2229f4a2713aSLionel Sambuc
mangleCXXVFTable(const CXXRecordDecl * Derived,ArrayRef<const CXXRecordDecl * > BasePath,raw_ostream & Out)2230f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXVFTable(
2231f4a2713aSLionel Sambuc const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
2232f4a2713aSLionel Sambuc raw_ostream &Out) {
2233f4a2713aSLionel Sambuc // <mangled-name> ::= ?_7 <class-name> <storage-class>
2234f4a2713aSLionel Sambuc // <cvr-qualifiers> [<name>] @
2235f4a2713aSLionel Sambuc // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
2236f4a2713aSLionel Sambuc // is always '6' for vftables.
2237f4a2713aSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2238f4a2713aSLionel Sambuc Mangler.getStream() << "\01??_7";
2239f4a2713aSLionel Sambuc Mangler.mangleName(Derived);
2240f4a2713aSLionel Sambuc Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.
2241*0a6a1f1dSLionel Sambuc for (const CXXRecordDecl *RD : BasePath)
2242*0a6a1f1dSLionel Sambuc Mangler.mangleName(RD);
2243f4a2713aSLionel Sambuc Mangler.getStream() << '@';
2244f4a2713aSLionel Sambuc }
2245f4a2713aSLionel Sambuc
mangleCXXVBTable(const CXXRecordDecl * Derived,ArrayRef<const CXXRecordDecl * > BasePath,raw_ostream & Out)2246f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXVBTable(
2247f4a2713aSLionel Sambuc const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
2248f4a2713aSLionel Sambuc raw_ostream &Out) {
2249f4a2713aSLionel Sambuc // <mangled-name> ::= ?_8 <class-name> <storage-class>
2250f4a2713aSLionel Sambuc // <cvr-qualifiers> [<name>] @
2251f4a2713aSLionel Sambuc // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
2252f4a2713aSLionel Sambuc // is always '7' for vbtables.
2253f4a2713aSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2254f4a2713aSLionel Sambuc Mangler.getStream() << "\01??_8";
2255f4a2713aSLionel Sambuc Mangler.mangleName(Derived);
2256f4a2713aSLionel Sambuc Mangler.getStream() << "7B"; // '7' for vbtable, 'B' for const.
2257*0a6a1f1dSLionel Sambuc for (const CXXRecordDecl *RD : BasePath)
2258*0a6a1f1dSLionel Sambuc Mangler.mangleName(RD);
2259f4a2713aSLionel Sambuc Mangler.getStream() << '@';
2260f4a2713aSLionel Sambuc }
2261f4a2713aSLionel Sambuc
mangleCXXRTTI(QualType T,raw_ostream & Out)2262*0a6a1f1dSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
2263*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2264*0a6a1f1dSLionel Sambuc Mangler.getStream() << "\01??_R0";
2265*0a6a1f1dSLionel Sambuc Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
2266*0a6a1f1dSLionel Sambuc Mangler.getStream() << "@8";
2267f4a2713aSLionel Sambuc }
2268f4a2713aSLionel Sambuc
mangleCXXRTTIName(QualType T,raw_ostream & Out)2269*0a6a1f1dSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T,
2270*0a6a1f1dSLionel Sambuc raw_ostream &Out) {
2271*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2272*0a6a1f1dSLionel Sambuc Mangler.getStream() << '.';
2273*0a6a1f1dSLionel Sambuc Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
2274*0a6a1f1dSLionel Sambuc }
2275*0a6a1f1dSLionel Sambuc
mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl * Derived,uint32_t NVOffset,int32_t VBPtrOffset,uint32_t VBTableOffset,uint32_t Flags,raw_ostream & Out)2276*0a6a1f1dSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
2277*0a6a1f1dSLionel Sambuc const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
2278*0a6a1f1dSLionel Sambuc uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
2279*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2280*0a6a1f1dSLionel Sambuc Mangler.getStream() << "\01??_R1";
2281*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(NVOffset);
2282*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(VBPtrOffset);
2283*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(VBTableOffset);
2284*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(Flags);
2285*0a6a1f1dSLionel Sambuc Mangler.mangleName(Derived);
2286*0a6a1f1dSLionel Sambuc Mangler.getStream() << "8";
2287*0a6a1f1dSLionel Sambuc }
2288*0a6a1f1dSLionel Sambuc
mangleCXXRTTIBaseClassArray(const CXXRecordDecl * Derived,raw_ostream & Out)2289*0a6a1f1dSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
2290*0a6a1f1dSLionel Sambuc const CXXRecordDecl *Derived, raw_ostream &Out) {
2291*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2292*0a6a1f1dSLionel Sambuc Mangler.getStream() << "\01??_R2";
2293*0a6a1f1dSLionel Sambuc Mangler.mangleName(Derived);
2294*0a6a1f1dSLionel Sambuc Mangler.getStream() << "8";
2295*0a6a1f1dSLionel Sambuc }
2296*0a6a1f1dSLionel Sambuc
mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl * Derived,raw_ostream & Out)2297*0a6a1f1dSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
2298*0a6a1f1dSLionel Sambuc const CXXRecordDecl *Derived, raw_ostream &Out) {
2299*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2300*0a6a1f1dSLionel Sambuc Mangler.getStream() << "\01??_R3";
2301*0a6a1f1dSLionel Sambuc Mangler.mangleName(Derived);
2302*0a6a1f1dSLionel Sambuc Mangler.getStream() << "8";
2303*0a6a1f1dSLionel Sambuc }
2304*0a6a1f1dSLionel Sambuc
mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl * Derived,ArrayRef<const CXXRecordDecl * > BasePath,raw_ostream & Out)2305*0a6a1f1dSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
2306*0a6a1f1dSLionel Sambuc const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
2307*0a6a1f1dSLionel Sambuc raw_ostream &Out) {
2308*0a6a1f1dSLionel Sambuc // <mangled-name> ::= ?_R4 <class-name> <storage-class>
2309*0a6a1f1dSLionel Sambuc // <cvr-qualifiers> [<name>] @
2310*0a6a1f1dSLionel Sambuc // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
2311*0a6a1f1dSLionel Sambuc // is always '6' for vftables.
2312*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2313*0a6a1f1dSLionel Sambuc Mangler.getStream() << "\01??_R4";
2314*0a6a1f1dSLionel Sambuc Mangler.mangleName(Derived);
2315*0a6a1f1dSLionel Sambuc Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.
2316*0a6a1f1dSLionel Sambuc for (const CXXRecordDecl *RD : BasePath)
2317*0a6a1f1dSLionel Sambuc Mangler.mangleName(RD);
2318*0a6a1f1dSLionel Sambuc Mangler.getStream() << '@';
2319f4a2713aSLionel Sambuc }
2320f4a2713aSLionel Sambuc
mangleTypeName(QualType T,raw_ostream & Out)2321f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleTypeName(QualType T, raw_ostream &Out) {
2322f4a2713aSLionel Sambuc // This is just a made up unique string for the purposes of tbaa. undname
2323f4a2713aSLionel Sambuc // does *not* know how to demangle it.
2324f4a2713aSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2325f4a2713aSLionel Sambuc Mangler.getStream() << '?';
2326f4a2713aSLionel Sambuc Mangler.mangleType(T, SourceRange());
2327f4a2713aSLionel Sambuc }
2328f4a2713aSLionel Sambuc
mangleCXXCtor(const CXXConstructorDecl * D,CXXCtorType Type,raw_ostream & Out)2329f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXCtor(const CXXConstructorDecl *D,
2330f4a2713aSLionel Sambuc CXXCtorType Type,
2331f4a2713aSLionel Sambuc raw_ostream &Out) {
2332f4a2713aSLionel Sambuc MicrosoftCXXNameMangler mangler(*this, Out);
2333f4a2713aSLionel Sambuc mangler.mangle(D);
2334f4a2713aSLionel Sambuc }
2335f4a2713aSLionel Sambuc
mangleCXXDtor(const CXXDestructorDecl * D,CXXDtorType Type,raw_ostream & Out)2336f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleCXXDtor(const CXXDestructorDecl *D,
2337f4a2713aSLionel Sambuc CXXDtorType Type,
2338f4a2713aSLionel Sambuc raw_ostream &Out) {
2339f4a2713aSLionel Sambuc MicrosoftCXXNameMangler mangler(*this, Out, D, Type);
2340f4a2713aSLionel Sambuc mangler.mangle(D);
2341f4a2713aSLionel Sambuc }
2342f4a2713aSLionel Sambuc
mangleReferenceTemporary(const VarDecl * VD,unsigned,raw_ostream &)2343f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleReferenceTemporary(const VarDecl *VD,
2344*0a6a1f1dSLionel Sambuc unsigned,
2345f4a2713aSLionel Sambuc raw_ostream &) {
2346f4a2713aSLionel Sambuc unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
2347f4a2713aSLionel Sambuc "cannot mangle this reference temporary yet");
2348f4a2713aSLionel Sambuc getDiags().Report(VD->getLocation(), DiagID);
2349f4a2713aSLionel Sambuc }
2350f4a2713aSLionel Sambuc
mangleStaticGuardVariable(const VarDecl * VD,raw_ostream & Out)2351f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,
2352f4a2713aSLionel Sambuc raw_ostream &Out) {
2353*0a6a1f1dSLionel Sambuc // TODO: This is not correct, especially with respect to VS "14". VS "14"
2354*0a6a1f1dSLionel Sambuc // utilizes thread local variables to implement thread safe, re-entrant
2355*0a6a1f1dSLionel Sambuc // initialization for statics. They no longer differentiate between an
2356*0a6a1f1dSLionel Sambuc // externally visible and non-externally visible static with respect to
2357*0a6a1f1dSLionel Sambuc // mangling, they all get $TSS <number>.
2358*0a6a1f1dSLionel Sambuc //
2359*0a6a1f1dSLionel Sambuc // N.B. This means that they can get more than 32 static variable guards in a
2360*0a6a1f1dSLionel Sambuc // scope. It also means that they broke compatibility with their own ABI.
2361*0a6a1f1dSLionel Sambuc
2362*0a6a1f1dSLionel Sambuc // <guard-name> ::= ?_B <postfix> @5 <scope-depth>
2363f4a2713aSLionel Sambuc // ::= ?$S <guard-num> @ <postfix> @4IA
2364f4a2713aSLionel Sambuc
2365f4a2713aSLionel Sambuc // The first mangling is what MSVC uses to guard static locals in inline
2366f4a2713aSLionel Sambuc // functions. It uses a different mangling in external functions to support
2367f4a2713aSLionel Sambuc // guarding more than 32 variables. MSVC rejects inline functions with more
2368f4a2713aSLionel Sambuc // than 32 static locals. We don't fully implement the second mangling
2369f4a2713aSLionel Sambuc // because those guards are not externally visible, and instead use LLVM's
2370f4a2713aSLionel Sambuc // default renaming when creating a new guard variable.
2371f4a2713aSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2372f4a2713aSLionel Sambuc
2373f4a2713aSLionel Sambuc bool Visible = VD->isExternallyVisible();
2374f4a2713aSLionel Sambuc // <operator-name> ::= ?_B # local static guard
2375f4a2713aSLionel Sambuc Mangler.getStream() << (Visible ? "\01??_B" : "\01?$S1@");
2376*0a6a1f1dSLionel Sambuc unsigned ScopeDepth = 0;
2377*0a6a1f1dSLionel Sambuc if (Visible && !getNextDiscriminator(VD, ScopeDepth))
2378*0a6a1f1dSLionel Sambuc // If we do not have a discriminator and are emitting a guard variable for
2379*0a6a1f1dSLionel Sambuc // use at global scope, then mangling the nested name will not be enough to
2380*0a6a1f1dSLionel Sambuc // remove ambiguities.
2381*0a6a1f1dSLionel Sambuc Mangler.mangle(VD, "");
2382*0a6a1f1dSLionel Sambuc else
2383*0a6a1f1dSLionel Sambuc Mangler.mangleNestedName(VD);
2384*0a6a1f1dSLionel Sambuc Mangler.getStream() << (Visible ? "@5" : "@4IA");
2385*0a6a1f1dSLionel Sambuc if (ScopeDepth)
2386*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(ScopeDepth);
2387f4a2713aSLionel Sambuc }
2388f4a2713aSLionel Sambuc
mangleInitFiniStub(const VarDecl * D,raw_ostream & Out,char CharCode)2389f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D,
2390f4a2713aSLionel Sambuc raw_ostream &Out,
2391f4a2713aSLionel Sambuc char CharCode) {
2392f4a2713aSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2393f4a2713aSLionel Sambuc Mangler.getStream() << "\01??__" << CharCode;
2394f4a2713aSLionel Sambuc Mangler.mangleName(D);
2395*0a6a1f1dSLionel Sambuc if (D->isStaticDataMember()) {
2396*0a6a1f1dSLionel Sambuc Mangler.mangleVariableEncoding(D);
2397*0a6a1f1dSLionel Sambuc Mangler.getStream() << '@';
2398*0a6a1f1dSLionel Sambuc }
2399f4a2713aSLionel Sambuc // This is the function class mangling. These stubs are global, non-variadic,
2400f4a2713aSLionel Sambuc // cdecl functions that return void and take no args.
2401f4a2713aSLionel Sambuc Mangler.getStream() << "YAXXZ";
2402f4a2713aSLionel Sambuc }
2403f4a2713aSLionel Sambuc
mangleDynamicInitializer(const VarDecl * D,raw_ostream & Out)2404f4a2713aSLionel Sambuc void MicrosoftMangleContextImpl::mangleDynamicInitializer(const VarDecl *D,
2405f4a2713aSLionel Sambuc raw_ostream &Out) {
2406f4a2713aSLionel Sambuc // <initializer-name> ::= ?__E <name> YAXXZ
2407f4a2713aSLionel Sambuc mangleInitFiniStub(D, Out, 'E');
2408f4a2713aSLionel Sambuc }
2409f4a2713aSLionel Sambuc
2410f4a2713aSLionel Sambuc void
mangleDynamicAtExitDestructor(const VarDecl * D,raw_ostream & Out)2411f4a2713aSLionel Sambuc MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D,
2412f4a2713aSLionel Sambuc raw_ostream &Out) {
2413f4a2713aSLionel Sambuc // <destructor-name> ::= ?__F <name> YAXXZ
2414f4a2713aSLionel Sambuc mangleInitFiniStub(D, Out, 'F');
2415f4a2713aSLionel Sambuc }
2416f4a2713aSLionel Sambuc
mangleStringLiteral(const StringLiteral * SL,raw_ostream & Out)2417*0a6a1f1dSLionel Sambuc void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
2418*0a6a1f1dSLionel Sambuc raw_ostream &Out) {
2419*0a6a1f1dSLionel Sambuc // <char-type> ::= 0 # char
2420*0a6a1f1dSLionel Sambuc // ::= 1 # wchar_t
2421*0a6a1f1dSLionel Sambuc // ::= ??? # char16_t/char32_t will need a mangling too...
2422*0a6a1f1dSLionel Sambuc //
2423*0a6a1f1dSLionel Sambuc // <literal-length> ::= <non-negative integer> # the length of the literal
2424*0a6a1f1dSLionel Sambuc //
2425*0a6a1f1dSLionel Sambuc // <encoded-crc> ::= <hex digit>+ @ # crc of the literal including
2426*0a6a1f1dSLionel Sambuc // # null-terminator
2427*0a6a1f1dSLionel Sambuc //
2428*0a6a1f1dSLionel Sambuc // <encoded-string> ::= <simple character> # uninteresting character
2429*0a6a1f1dSLionel Sambuc // ::= '?$' <hex digit> <hex digit> # these two nibbles
2430*0a6a1f1dSLionel Sambuc // # encode the byte for the
2431*0a6a1f1dSLionel Sambuc // # character
2432*0a6a1f1dSLionel Sambuc // ::= '?' [a-z] # \xe1 - \xfa
2433*0a6a1f1dSLionel Sambuc // ::= '?' [A-Z] # \xc1 - \xda
2434*0a6a1f1dSLionel Sambuc // ::= '?' [0-9] # [,/\:. \n\t'-]
2435*0a6a1f1dSLionel Sambuc //
2436*0a6a1f1dSLionel Sambuc // <literal> ::= '??_C@_' <char-type> <literal-length> <encoded-crc>
2437*0a6a1f1dSLionel Sambuc // <encoded-string> '@'
2438*0a6a1f1dSLionel Sambuc MicrosoftCXXNameMangler Mangler(*this, Out);
2439*0a6a1f1dSLionel Sambuc Mangler.getStream() << "\01??_C@_";
2440*0a6a1f1dSLionel Sambuc
2441*0a6a1f1dSLionel Sambuc // <char-type>: The "kind" of string literal is encoded into the mangled name.
2442*0a6a1f1dSLionel Sambuc if (SL->isWide())
2443*0a6a1f1dSLionel Sambuc Mangler.getStream() << '1';
2444*0a6a1f1dSLionel Sambuc else
2445*0a6a1f1dSLionel Sambuc Mangler.getStream() << '0';
2446*0a6a1f1dSLionel Sambuc
2447*0a6a1f1dSLionel Sambuc // <literal-length>: The next part of the mangled name consists of the length
2448*0a6a1f1dSLionel Sambuc // of the string.
2449*0a6a1f1dSLionel Sambuc // The StringLiteral does not consider the NUL terminator byte(s) but the
2450*0a6a1f1dSLionel Sambuc // mangling does.
2451*0a6a1f1dSLionel Sambuc // N.B. The length is in terms of bytes, not characters.
2452*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(SL->getByteLength() + SL->getCharByteWidth());
2453*0a6a1f1dSLionel Sambuc
2454*0a6a1f1dSLionel Sambuc // We will use the "Rocksoft^tm Model CRC Algorithm" to describe the
2455*0a6a1f1dSLionel Sambuc // properties of our CRC:
2456*0a6a1f1dSLionel Sambuc // Width : 32
2457*0a6a1f1dSLionel Sambuc // Poly : 04C11DB7
2458*0a6a1f1dSLionel Sambuc // Init : FFFFFFFF
2459*0a6a1f1dSLionel Sambuc // RefIn : True
2460*0a6a1f1dSLionel Sambuc // RefOut : True
2461*0a6a1f1dSLionel Sambuc // XorOut : 00000000
2462*0a6a1f1dSLionel Sambuc // Check : 340BC6D9
2463*0a6a1f1dSLionel Sambuc uint32_t CRC = 0xFFFFFFFFU;
2464*0a6a1f1dSLionel Sambuc
2465*0a6a1f1dSLionel Sambuc auto UpdateCRC = [&CRC](char Byte) {
2466*0a6a1f1dSLionel Sambuc for (unsigned i = 0; i < 8; ++i) {
2467*0a6a1f1dSLionel Sambuc bool Bit = CRC & 0x80000000U;
2468*0a6a1f1dSLionel Sambuc if (Byte & (1U << i))
2469*0a6a1f1dSLionel Sambuc Bit = !Bit;
2470*0a6a1f1dSLionel Sambuc CRC <<= 1;
2471*0a6a1f1dSLionel Sambuc if (Bit)
2472*0a6a1f1dSLionel Sambuc CRC ^= 0x04C11DB7U;
2473*0a6a1f1dSLionel Sambuc }
2474*0a6a1f1dSLionel Sambuc };
2475*0a6a1f1dSLionel Sambuc
2476*0a6a1f1dSLionel Sambuc auto GetLittleEndianByte = [&Mangler, &SL](unsigned Index) {
2477*0a6a1f1dSLionel Sambuc unsigned CharByteWidth = SL->getCharByteWidth();
2478*0a6a1f1dSLionel Sambuc uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
2479*0a6a1f1dSLionel Sambuc unsigned OffsetInCodeUnit = Index % CharByteWidth;
2480*0a6a1f1dSLionel Sambuc return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
2481*0a6a1f1dSLionel Sambuc };
2482*0a6a1f1dSLionel Sambuc
2483*0a6a1f1dSLionel Sambuc auto GetBigEndianByte = [&Mangler, &SL](unsigned Index) {
2484*0a6a1f1dSLionel Sambuc unsigned CharByteWidth = SL->getCharByteWidth();
2485*0a6a1f1dSLionel Sambuc uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
2486*0a6a1f1dSLionel Sambuc unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
2487*0a6a1f1dSLionel Sambuc return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
2488*0a6a1f1dSLionel Sambuc };
2489*0a6a1f1dSLionel Sambuc
2490*0a6a1f1dSLionel Sambuc // CRC all the bytes of the StringLiteral.
2491*0a6a1f1dSLionel Sambuc for (unsigned I = 0, E = SL->getByteLength(); I != E; ++I)
2492*0a6a1f1dSLionel Sambuc UpdateCRC(GetLittleEndianByte(I));
2493*0a6a1f1dSLionel Sambuc
2494*0a6a1f1dSLionel Sambuc // The NUL terminator byte(s) were not present earlier,
2495*0a6a1f1dSLionel Sambuc // we need to manually process those bytes into the CRC.
2496*0a6a1f1dSLionel Sambuc for (unsigned NullTerminator = 0; NullTerminator < SL->getCharByteWidth();
2497*0a6a1f1dSLionel Sambuc ++NullTerminator)
2498*0a6a1f1dSLionel Sambuc UpdateCRC('\x00');
2499*0a6a1f1dSLionel Sambuc
2500*0a6a1f1dSLionel Sambuc // The literature refers to the process of reversing the bits in the final CRC
2501*0a6a1f1dSLionel Sambuc // output as "reflection".
2502*0a6a1f1dSLionel Sambuc CRC = llvm::reverseBits(CRC);
2503*0a6a1f1dSLionel Sambuc
2504*0a6a1f1dSLionel Sambuc // <encoded-crc>: The CRC is encoded utilizing the standard number mangling
2505*0a6a1f1dSLionel Sambuc // scheme.
2506*0a6a1f1dSLionel Sambuc Mangler.mangleNumber(CRC);
2507*0a6a1f1dSLionel Sambuc
2508*0a6a1f1dSLionel Sambuc // <encoded-string>: The mangled name also contains the first 32 _characters_
2509*0a6a1f1dSLionel Sambuc // (including null-terminator bytes) of the StringLiteral.
2510*0a6a1f1dSLionel Sambuc // Each character is encoded by splitting them into bytes and then encoding
2511*0a6a1f1dSLionel Sambuc // the constituent bytes.
2512*0a6a1f1dSLionel Sambuc auto MangleByte = [&Mangler](char Byte) {
2513*0a6a1f1dSLionel Sambuc // There are five different manglings for characters:
2514*0a6a1f1dSLionel Sambuc // - [a-zA-Z0-9_$]: A one-to-one mapping.
2515*0a6a1f1dSLionel Sambuc // - ?[a-z]: The range from \xe1 to \xfa.
2516*0a6a1f1dSLionel Sambuc // - ?[A-Z]: The range from \xc1 to \xda.
2517*0a6a1f1dSLionel Sambuc // - ?[0-9]: The set of [,/\:. \n\t'-].
2518*0a6a1f1dSLionel Sambuc // - ?$XX: A fallback which maps nibbles.
2519*0a6a1f1dSLionel Sambuc if (isIdentifierBody(Byte, /*AllowDollar=*/true)) {
2520*0a6a1f1dSLionel Sambuc Mangler.getStream() << Byte;
2521*0a6a1f1dSLionel Sambuc } else if (isLetter(Byte & 0x7f)) {
2522*0a6a1f1dSLionel Sambuc Mangler.getStream() << '?' << static_cast<char>(Byte & 0x7f);
2523*0a6a1f1dSLionel Sambuc } else {
2524*0a6a1f1dSLionel Sambuc const char SpecialChars[] = {',', '/', '\\', ':', '.',
2525*0a6a1f1dSLionel Sambuc ' ', '\n', '\t', '\'', '-'};
2526*0a6a1f1dSLionel Sambuc const char *Pos =
2527*0a6a1f1dSLionel Sambuc std::find(std::begin(SpecialChars), std::end(SpecialChars), Byte);
2528*0a6a1f1dSLionel Sambuc if (Pos != std::end(SpecialChars)) {
2529*0a6a1f1dSLionel Sambuc Mangler.getStream() << '?' << (Pos - std::begin(SpecialChars));
2530*0a6a1f1dSLionel Sambuc } else {
2531*0a6a1f1dSLionel Sambuc Mangler.getStream() << "?$";
2532*0a6a1f1dSLionel Sambuc Mangler.getStream() << static_cast<char>('A' + ((Byte >> 4) & 0xf));
2533*0a6a1f1dSLionel Sambuc Mangler.getStream() << static_cast<char>('A' + (Byte & 0xf));
2534*0a6a1f1dSLionel Sambuc }
2535*0a6a1f1dSLionel Sambuc }
2536*0a6a1f1dSLionel Sambuc };
2537*0a6a1f1dSLionel Sambuc
2538*0a6a1f1dSLionel Sambuc // Enforce our 32 character max.
2539*0a6a1f1dSLionel Sambuc unsigned NumCharsToMangle = std::min(32U, SL->getLength());
2540*0a6a1f1dSLionel Sambuc for (unsigned I = 0, E = NumCharsToMangle * SL->getCharByteWidth(); I != E;
2541*0a6a1f1dSLionel Sambuc ++I)
2542*0a6a1f1dSLionel Sambuc if (SL->isWide())
2543*0a6a1f1dSLionel Sambuc MangleByte(GetBigEndianByte(I));
2544*0a6a1f1dSLionel Sambuc else
2545*0a6a1f1dSLionel Sambuc MangleByte(GetLittleEndianByte(I));
2546*0a6a1f1dSLionel Sambuc
2547*0a6a1f1dSLionel Sambuc // Encode the NUL terminator if there is room.
2548*0a6a1f1dSLionel Sambuc if (NumCharsToMangle < 32)
2549*0a6a1f1dSLionel Sambuc for (unsigned NullTerminator = 0; NullTerminator < SL->getCharByteWidth();
2550*0a6a1f1dSLionel Sambuc ++NullTerminator)
2551*0a6a1f1dSLionel Sambuc MangleByte(0);
2552*0a6a1f1dSLionel Sambuc
2553*0a6a1f1dSLionel Sambuc Mangler.getStream() << '@';
2554*0a6a1f1dSLionel Sambuc }
2555*0a6a1f1dSLionel Sambuc
2556f4a2713aSLionel Sambuc MicrosoftMangleContext *
create(ASTContext & Context,DiagnosticsEngine & Diags)2557f4a2713aSLionel Sambuc MicrosoftMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
2558f4a2713aSLionel Sambuc return new MicrosoftMangleContextImpl(Context, Diags);
2559f4a2713aSLionel Sambuc }
2560