Bug Summary

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