Bug Summary

File:build/source/clang/lib/AST/MicrosoftMangle.cpp
Warning:line 972, column 7
Forming reference to null pointer

Annotated Source Code

Press '?' to see keyboard shortcuts

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