Mangle.cpp revision 1.1 1 1.1 joerg //===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===//
2 1.1 joerg //
3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information.
5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 1.1 joerg //
7 1.1 joerg //===----------------------------------------------------------------------===//
8 1.1 joerg //
9 1.1 joerg // Implements generic name mangling support for blocks and Objective-C.
10 1.1 joerg //
11 1.1 joerg //===----------------------------------------------------------------------===//
12 1.1 joerg #include "clang/AST/Attr.h"
13 1.1 joerg #include "clang/AST/ASTContext.h"
14 1.1 joerg #include "clang/AST/Decl.h"
15 1.1 joerg #include "clang/AST/DeclCXX.h"
16 1.1 joerg #include "clang/AST/DeclObjC.h"
17 1.1 joerg #include "clang/AST/DeclTemplate.h"
18 1.1 joerg #include "clang/AST/ExprCXX.h"
19 1.1 joerg #include "clang/AST/Mangle.h"
20 1.1 joerg #include "clang/AST/VTableBuilder.h"
21 1.1 joerg #include "clang/Basic/ABI.h"
22 1.1 joerg #include "clang/Basic/SourceManager.h"
23 1.1 joerg #include "clang/Basic/TargetInfo.h"
24 1.1 joerg #include "llvm/ADT/StringExtras.h"
25 1.1 joerg #include "llvm/IR/DataLayout.h"
26 1.1 joerg #include "llvm/IR/Mangler.h"
27 1.1 joerg #include "llvm/Support/ErrorHandling.h"
28 1.1 joerg #include "llvm/Support/raw_ostream.h"
29 1.1 joerg
30 1.1 joerg using namespace clang;
31 1.1 joerg
32 1.1 joerg // FIXME: For blocks we currently mimic GCC's mangling scheme, which leaves
33 1.1 joerg // much to be desired. Come up with a better mangling scheme.
34 1.1 joerg
35 1.1 joerg static void mangleFunctionBlock(MangleContext &Context,
36 1.1 joerg StringRef Outer,
37 1.1 joerg const BlockDecl *BD,
38 1.1 joerg raw_ostream &Out) {
39 1.1 joerg unsigned discriminator = Context.getBlockId(BD, true);
40 1.1 joerg if (discriminator == 0)
41 1.1 joerg Out << "__" << Outer << "_block_invoke";
42 1.1 joerg else
43 1.1 joerg Out << "__" << Outer << "_block_invoke_" << discriminator+1;
44 1.1 joerg }
45 1.1 joerg
46 1.1 joerg void MangleContext::anchor() { }
47 1.1 joerg
48 1.1 joerg enum CCMangling {
49 1.1 joerg CCM_Other,
50 1.1 joerg CCM_Fast,
51 1.1 joerg CCM_RegCall,
52 1.1 joerg CCM_Vector,
53 1.1 joerg CCM_Std
54 1.1 joerg };
55 1.1 joerg
56 1.1 joerg static bool isExternC(const NamedDecl *ND) {
57 1.1 joerg if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
58 1.1 joerg return FD->isExternC();
59 1.1 joerg return cast<VarDecl>(ND)->isExternC();
60 1.1 joerg }
61 1.1 joerg
62 1.1 joerg static CCMangling getCallingConvMangling(const ASTContext &Context,
63 1.1 joerg const NamedDecl *ND) {
64 1.1 joerg const TargetInfo &TI = Context.getTargetInfo();
65 1.1 joerg const llvm::Triple &Triple = TI.getTriple();
66 1.1 joerg if (!Triple.isOSWindows() ||
67 1.1 joerg !(Triple.getArch() == llvm::Triple::x86 ||
68 1.1 joerg Triple.getArch() == llvm::Triple::x86_64))
69 1.1 joerg return CCM_Other;
70 1.1 joerg
71 1.1 joerg if (Context.getLangOpts().CPlusPlus && !isExternC(ND) &&
72 1.1 joerg TI.getCXXABI() == TargetCXXABI::Microsoft)
73 1.1 joerg return CCM_Other;
74 1.1 joerg
75 1.1 joerg const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
76 1.1 joerg if (!FD)
77 1.1 joerg return CCM_Other;
78 1.1 joerg QualType T = FD->getType();
79 1.1 joerg
80 1.1 joerg const FunctionType *FT = T->castAs<FunctionType>();
81 1.1 joerg
82 1.1 joerg CallingConv CC = FT->getCallConv();
83 1.1 joerg switch (CC) {
84 1.1 joerg default:
85 1.1 joerg return CCM_Other;
86 1.1 joerg case CC_X86FastCall:
87 1.1 joerg return CCM_Fast;
88 1.1 joerg case CC_X86StdCall:
89 1.1 joerg return CCM_Std;
90 1.1 joerg case CC_X86VectorCall:
91 1.1 joerg return CCM_Vector;
92 1.1 joerg }
93 1.1 joerg }
94 1.1 joerg
95 1.1 joerg bool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
96 1.1 joerg const ASTContext &ASTContext = getASTContext();
97 1.1 joerg
98 1.1 joerg CCMangling CC = getCallingConvMangling(ASTContext, D);
99 1.1 joerg if (CC != CCM_Other)
100 1.1 joerg return true;
101 1.1 joerg
102 1.1 joerg // If the declaration has an owning module for linkage purposes that needs to
103 1.1 joerg // be mangled, we must mangle its name.
104 1.1 joerg if (!D->hasExternalFormalLinkage() && D->getOwningModuleForLinkage())
105 1.1 joerg return true;
106 1.1 joerg
107 1.1 joerg // In C, functions with no attributes never need to be mangled. Fastpath them.
108 1.1 joerg if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
109 1.1 joerg return false;
110 1.1 joerg
111 1.1 joerg // Any decl can be declared with __asm("foo") on it, and this takes precedence
112 1.1 joerg // over all other naming in the .o file.
113 1.1 joerg if (D->hasAttr<AsmLabelAttr>())
114 1.1 joerg return true;
115 1.1 joerg
116 1.1 joerg return shouldMangleCXXName(D);
117 1.1 joerg }
118 1.1 joerg
119 1.1 joerg void MangleContext::mangleName(const NamedDecl *D, raw_ostream &Out) {
120 1.1 joerg // Any decl can be declared with __asm("foo") on it, and this takes precedence
121 1.1 joerg // over all other naming in the .o file.
122 1.1 joerg if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
123 1.1 joerg // If we have an asm name, then we use it as the mangling.
124 1.1 joerg
125 1.1 joerg // If the label isn't literal, or if this is an alias for an LLVM intrinsic,
126 1.1 joerg // do not add a "\01" prefix.
127 1.1 joerg if (!ALA->getIsLiteralLabel() || ALA->getLabel().startswith("llvm.")) {
128 1.1 joerg Out << ALA->getLabel();
129 1.1 joerg return;
130 1.1 joerg }
131 1.1 joerg
132 1.1 joerg // Adding the prefix can cause problems when one file has a "foo" and
133 1.1 joerg // another has a "\01foo". That is known to happen on ELF with the
134 1.1 joerg // tricks normally used for producing aliases (PR9177). Fortunately the
135 1.1 joerg // llvm mangler on ELF is a nop, so we can just avoid adding the \01
136 1.1 joerg // marker.
137 1.1 joerg char GlobalPrefix =
138 1.1 joerg getASTContext().getTargetInfo().getDataLayout().getGlobalPrefix();
139 1.1 joerg if (GlobalPrefix)
140 1.1 joerg Out << '\01'; // LLVM IR Marker for __asm("foo")
141 1.1 joerg
142 1.1 joerg Out << ALA->getLabel();
143 1.1 joerg return;
144 1.1 joerg }
145 1.1 joerg
146 1.1 joerg const ASTContext &ASTContext = getASTContext();
147 1.1 joerg CCMangling CC = getCallingConvMangling(ASTContext, D);
148 1.1 joerg bool MCXX = shouldMangleCXXName(D);
149 1.1 joerg const TargetInfo &TI = Context.getTargetInfo();
150 1.1 joerg if (CC == CCM_Other || (MCXX && TI.getCXXABI() == TargetCXXABI::Microsoft)) {
151 1.1 joerg if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
152 1.1 joerg mangleObjCMethodName(OMD, Out);
153 1.1 joerg else
154 1.1 joerg mangleCXXName(D, Out);
155 1.1 joerg return;
156 1.1 joerg }
157 1.1 joerg
158 1.1 joerg Out << '\01';
159 1.1 joerg if (CC == CCM_Std)
160 1.1 joerg Out << '_';
161 1.1 joerg else if (CC == CCM_Fast)
162 1.1 joerg Out << '@';
163 1.1 joerg else if (CC == CCM_RegCall)
164 1.1 joerg Out << "__regcall3__";
165 1.1 joerg
166 1.1 joerg if (!MCXX)
167 1.1 joerg Out << D->getIdentifier()->getName();
168 1.1 joerg else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
169 1.1 joerg mangleObjCMethodName(OMD, Out);
170 1.1 joerg else
171 1.1 joerg mangleCXXName(D, Out);
172 1.1 joerg
173 1.1 joerg const FunctionDecl *FD = cast<FunctionDecl>(D);
174 1.1 joerg const FunctionType *FT = FD->getType()->castAs<FunctionType>();
175 1.1 joerg const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT);
176 1.1 joerg if (CC == CCM_Vector)
177 1.1 joerg Out << '@';
178 1.1 joerg Out << '@';
179 1.1 joerg if (!Proto) {
180 1.1 joerg Out << '0';
181 1.1 joerg return;
182 1.1 joerg }
183 1.1 joerg assert(!Proto->isVariadic());
184 1.1 joerg unsigned ArgWords = 0;
185 1.1 joerg if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
186 1.1 joerg if (!MD->isStatic())
187 1.1 joerg ++ArgWords;
188 1.1 joerg for (const auto &AT : Proto->param_types())
189 1.1 joerg // Size should be aligned to pointer size.
190 1.1 joerg ArgWords +=
191 1.1 joerg llvm::alignTo(ASTContext.getTypeSize(AT), TI.getPointerWidth(0)) /
192 1.1 joerg TI.getPointerWidth(0);
193 1.1 joerg Out << ((TI.getPointerWidth(0) / 8) * ArgWords);
194 1.1 joerg }
195 1.1 joerg
196 1.1 joerg void MangleContext::mangleGlobalBlock(const BlockDecl *BD,
197 1.1 joerg const NamedDecl *ID,
198 1.1 joerg raw_ostream &Out) {
199 1.1 joerg unsigned discriminator = getBlockId(BD, false);
200 1.1 joerg if (ID) {
201 1.1 joerg if (shouldMangleDeclName(ID))
202 1.1 joerg mangleName(ID, Out);
203 1.1 joerg else {
204 1.1 joerg Out << ID->getIdentifier()->getName();
205 1.1 joerg }
206 1.1 joerg }
207 1.1 joerg if (discriminator == 0)
208 1.1 joerg Out << "_block_invoke";
209 1.1 joerg else
210 1.1 joerg Out << "_block_invoke_" << discriminator+1;
211 1.1 joerg }
212 1.1 joerg
213 1.1 joerg void MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD,
214 1.1 joerg CXXCtorType CT, const BlockDecl *BD,
215 1.1 joerg raw_ostream &ResStream) {
216 1.1 joerg SmallString<64> Buffer;
217 1.1 joerg llvm::raw_svector_ostream Out(Buffer);
218 1.1 joerg mangleCXXCtor(CD, CT, Out);
219 1.1 joerg mangleFunctionBlock(*this, Buffer, BD, ResStream);
220 1.1 joerg }
221 1.1 joerg
222 1.1 joerg void MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD,
223 1.1 joerg CXXDtorType DT, const BlockDecl *BD,
224 1.1 joerg raw_ostream &ResStream) {
225 1.1 joerg SmallString<64> Buffer;
226 1.1 joerg llvm::raw_svector_ostream Out(Buffer);
227 1.1 joerg mangleCXXDtor(DD, DT, Out);
228 1.1 joerg mangleFunctionBlock(*this, Buffer, BD, ResStream);
229 1.1 joerg }
230 1.1 joerg
231 1.1 joerg void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD,
232 1.1 joerg raw_ostream &Out) {
233 1.1 joerg assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC));
234 1.1 joerg
235 1.1 joerg SmallString<64> Buffer;
236 1.1 joerg llvm::raw_svector_ostream Stream(Buffer);
237 1.1 joerg if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
238 1.1 joerg mangleObjCMethodName(Method, Stream);
239 1.1 joerg } else {
240 1.1 joerg assert((isa<NamedDecl>(DC) || isa<BlockDecl>(DC)) &&
241 1.1 joerg "expected a NamedDecl or BlockDecl");
242 1.1 joerg if (isa<BlockDecl>(DC))
243 1.1 joerg for (; DC && isa<BlockDecl>(DC); DC = DC->getParent())
244 1.1 joerg (void) getBlockId(cast<BlockDecl>(DC), true);
245 1.1 joerg assert((isa<TranslationUnitDecl>(DC) || isa<NamedDecl>(DC)) &&
246 1.1 joerg "expected a TranslationUnitDecl or a NamedDecl");
247 1.1 joerg if (const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
248 1.1 joerg mangleCtorBlock(CD, /*CT*/ Ctor_Complete, BD, Out);
249 1.1 joerg else if (const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
250 1.1 joerg mangleDtorBlock(DD, /*DT*/ Dtor_Complete, BD, Out);
251 1.1 joerg else if (auto ND = dyn_cast<NamedDecl>(DC)) {
252 1.1 joerg if (!shouldMangleDeclName(ND) && ND->getIdentifier())
253 1.1 joerg Stream << ND->getIdentifier()->getName();
254 1.1 joerg else {
255 1.1 joerg // FIXME: We were doing a mangleUnqualifiedName() before, but that's
256 1.1 joerg // a private member of a class that will soon itself be private to the
257 1.1 joerg // Itanium C++ ABI object. What should we do now? Right now, I'm just
258 1.1 joerg // calling the mangleName() method on the MangleContext; is there a
259 1.1 joerg // better way?
260 1.1 joerg mangleName(ND, Stream);
261 1.1 joerg }
262 1.1 joerg }
263 1.1 joerg }
264 1.1 joerg mangleFunctionBlock(*this, Buffer, BD, Out);
265 1.1 joerg }
266 1.1 joerg
267 1.1 joerg void MangleContext::mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD,
268 1.1 joerg raw_ostream &OS) {
269 1.1 joerg const ObjCContainerDecl *CD =
270 1.1 joerg dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
271 1.1 joerg assert (CD && "Missing container decl in GetNameForMethod");
272 1.1 joerg OS << (MD->isInstanceMethod() ? '-' : '+') << '[';
273 1.1 joerg if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD)) {
274 1.1 joerg OS << CID->getClassInterface()->getName();
275 1.1 joerg OS << '(' << *CID << ')';
276 1.1 joerg } else {
277 1.1 joerg OS << CD->getName();
278 1.1 joerg }
279 1.1 joerg OS << ' ';
280 1.1 joerg MD->getSelector().print(OS);
281 1.1 joerg OS << ']';
282 1.1 joerg }
283 1.1 joerg
284 1.1 joerg void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD,
285 1.1 joerg raw_ostream &Out) {
286 1.1 joerg SmallString<64> Name;
287 1.1 joerg llvm::raw_svector_ostream OS(Name);
288 1.1 joerg
289 1.1 joerg mangleObjCMethodNameWithoutSize(MD, OS);
290 1.1 joerg Out << OS.str().size() << OS.str();
291 1.1 joerg }
292 1.1 joerg
293 1.1 joerg class ASTNameGenerator::Implementation {
294 1.1 joerg std::unique_ptr<MangleContext> MC;
295 1.1 joerg llvm::DataLayout DL;
296 1.1 joerg
297 1.1 joerg public:
298 1.1 joerg explicit Implementation(ASTContext &Ctx)
299 1.1 joerg : MC(Ctx.createMangleContext()), DL(Ctx.getTargetInfo().getDataLayout()) {
300 1.1 joerg }
301 1.1 joerg
302 1.1 joerg bool writeName(const Decl *D, raw_ostream &OS) {
303 1.1 joerg // First apply frontend mangling.
304 1.1 joerg SmallString<128> FrontendBuf;
305 1.1 joerg llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
306 1.1 joerg if (auto *FD = dyn_cast<FunctionDecl>(D)) {
307 1.1 joerg if (FD->isDependentContext())
308 1.1 joerg return true;
309 1.1 joerg if (writeFuncOrVarName(FD, FrontendBufOS))
310 1.1 joerg return true;
311 1.1 joerg } else if (auto *VD = dyn_cast<VarDecl>(D)) {
312 1.1 joerg if (writeFuncOrVarName(VD, FrontendBufOS))
313 1.1 joerg return true;
314 1.1 joerg } else if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
315 1.1 joerg MC->mangleObjCMethodNameWithoutSize(MD, OS);
316 1.1 joerg return false;
317 1.1 joerg } else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
318 1.1 joerg writeObjCClassName(ID, FrontendBufOS);
319 1.1 joerg } else {
320 1.1 joerg return true;
321 1.1 joerg }
322 1.1 joerg
323 1.1 joerg // Now apply backend mangling.
324 1.1 joerg llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
325 1.1 joerg return false;
326 1.1 joerg }
327 1.1 joerg
328 1.1 joerg std::string getName(const Decl *D) {
329 1.1 joerg std::string Name;
330 1.1 joerg {
331 1.1 joerg llvm::raw_string_ostream OS(Name);
332 1.1 joerg writeName(D, OS);
333 1.1 joerg }
334 1.1 joerg return Name;
335 1.1 joerg }
336 1.1 joerg
337 1.1 joerg enum ObjCKind {
338 1.1 joerg ObjCClass,
339 1.1 joerg ObjCMetaclass,
340 1.1 joerg };
341 1.1 joerg
342 1.1 joerg static StringRef getClassSymbolPrefix(ObjCKind Kind,
343 1.1 joerg const ASTContext &Context) {
344 1.1 joerg if (Context.getLangOpts().ObjCRuntime.isGNUFamily())
345 1.1 joerg return Kind == ObjCMetaclass ? "_OBJC_METACLASS_" : "_OBJC_CLASS_";
346 1.1 joerg return Kind == ObjCMetaclass ? "OBJC_METACLASS_$_" : "OBJC_CLASS_$_";
347 1.1 joerg }
348 1.1 joerg
349 1.1 joerg std::vector<std::string> getAllManglings(const ObjCContainerDecl *OCD) {
350 1.1 joerg StringRef ClassName;
351 1.1 joerg if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
352 1.1 joerg ClassName = OID->getObjCRuntimeNameAsString();
353 1.1 joerg else if (const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
354 1.1 joerg ClassName = OID->getObjCRuntimeNameAsString();
355 1.1 joerg
356 1.1 joerg if (ClassName.empty())
357 1.1 joerg return {};
358 1.1 joerg
359 1.1 joerg auto Mangle = [&](ObjCKind Kind, StringRef ClassName) -> std::string {
360 1.1 joerg SmallString<40> Mangled;
361 1.1 joerg auto Prefix = getClassSymbolPrefix(Kind, OCD->getASTContext());
362 1.1 joerg llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
363 1.1 joerg return Mangled.str();
364 1.1 joerg };
365 1.1 joerg
366 1.1 joerg return {
367 1.1 joerg Mangle(ObjCClass, ClassName),
368 1.1 joerg Mangle(ObjCMetaclass, ClassName),
369 1.1 joerg };
370 1.1 joerg }
371 1.1 joerg
372 1.1 joerg std::vector<std::string> getAllManglings(const Decl *D) {
373 1.1 joerg if (const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
374 1.1 joerg return getAllManglings(OCD);
375 1.1 joerg
376 1.1 joerg if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
377 1.1 joerg return {};
378 1.1 joerg
379 1.1 joerg const NamedDecl *ND = cast<NamedDecl>(D);
380 1.1 joerg
381 1.1 joerg ASTContext &Ctx = ND->getASTContext();
382 1.1 joerg std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
383 1.1 joerg
384 1.1 joerg std::vector<std::string> Manglings;
385 1.1 joerg
386 1.1 joerg auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
387 1.1 joerg auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
388 1.1 joerg /*IsCXXMethod=*/true);
389 1.1 joerg auto CC = MD->getType()->castAs<FunctionProtoType>()->getCallConv();
390 1.1 joerg return CC == DefaultCC;
391 1.1 joerg };
392 1.1 joerg
393 1.1 joerg if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
394 1.1 joerg Manglings.emplace_back(getMangledStructor(CD, Ctor_Base));
395 1.1 joerg
396 1.1 joerg if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
397 1.1 joerg if (!CD->getParent()->isAbstract())
398 1.1 joerg Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete));
399 1.1 joerg
400 1.1 joerg if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
401 1.1 joerg if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
402 1.1 joerg if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
403 1.1 joerg Manglings.emplace_back(getMangledStructor(CD, Ctor_DefaultClosure));
404 1.1 joerg } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
405 1.1 joerg Manglings.emplace_back(getMangledStructor(DD, Dtor_Base));
406 1.1 joerg if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
407 1.1 joerg Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete));
408 1.1 joerg if (DD->isVirtual())
409 1.1 joerg Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting));
410 1.1 joerg }
411 1.1 joerg } else if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
412 1.1 joerg Manglings.emplace_back(getName(ND));
413 1.1 joerg if (MD->isVirtual())
414 1.1 joerg if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD))
415 1.1 joerg for (const auto &T : *TIV)
416 1.1 joerg Manglings.emplace_back(getMangledThunk(MD, T));
417 1.1 joerg }
418 1.1 joerg
419 1.1 joerg return Manglings;
420 1.1 joerg }
421 1.1 joerg
422 1.1 joerg private:
423 1.1 joerg bool writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) {
424 1.1 joerg if (MC->shouldMangleDeclName(D)) {
425 1.1 joerg if (const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
426 1.1 joerg MC->mangleCXXCtor(CtorD, Ctor_Complete, OS);
427 1.1 joerg else if (const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
428 1.1 joerg MC->mangleCXXDtor(DtorD, Dtor_Complete, OS);
429 1.1 joerg else
430 1.1 joerg MC->mangleName(D, OS);
431 1.1 joerg return false;
432 1.1 joerg } else {
433 1.1 joerg IdentifierInfo *II = D->getIdentifier();
434 1.1 joerg if (!II)
435 1.1 joerg return true;
436 1.1 joerg OS << II->getName();
437 1.1 joerg return false;
438 1.1 joerg }
439 1.1 joerg }
440 1.1 joerg
441 1.1 joerg void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) {
442 1.1 joerg OS << getClassSymbolPrefix(ObjCClass, D->getASTContext());
443 1.1 joerg OS << D->getObjCRuntimeNameAsString();
444 1.1 joerg }
445 1.1 joerg
446 1.1 joerg std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) {
447 1.1 joerg std::string FrontendBuf;
448 1.1 joerg llvm::raw_string_ostream FOS(FrontendBuf);
449 1.1 joerg
450 1.1 joerg if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
451 1.1 joerg MC->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
452 1.1 joerg else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
453 1.1 joerg MC->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
454 1.1 joerg
455 1.1 joerg std::string BackendBuf;
456 1.1 joerg llvm::raw_string_ostream BOS(BackendBuf);
457 1.1 joerg
458 1.1 joerg llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
459 1.1 joerg
460 1.1 joerg return BOS.str();
461 1.1 joerg }
462 1.1 joerg
463 1.1 joerg std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T) {
464 1.1 joerg std::string FrontendBuf;
465 1.1 joerg llvm::raw_string_ostream FOS(FrontendBuf);
466 1.1 joerg
467 1.1 joerg MC->mangleThunk(MD, T, FOS);
468 1.1 joerg
469 1.1 joerg std::string BackendBuf;
470 1.1 joerg llvm::raw_string_ostream BOS(BackendBuf);
471 1.1 joerg
472 1.1 joerg llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
473 1.1 joerg
474 1.1 joerg return BOS.str();
475 1.1 joerg }
476 1.1 joerg };
477 1.1 joerg
478 1.1 joerg ASTNameGenerator::ASTNameGenerator(ASTContext &Ctx)
479 1.1 joerg : Impl(std::make_unique<Implementation>(Ctx)) {}
480 1.1 joerg
481 1.1 joerg ASTNameGenerator::~ASTNameGenerator() {}
482 1.1 joerg
483 1.1 joerg bool ASTNameGenerator::writeName(const Decl *D, raw_ostream &OS) {
484 1.1 joerg return Impl->writeName(D, OS);
485 1.1 joerg }
486 1.1 joerg
487 1.1 joerg std::string ASTNameGenerator::getName(const Decl *D) {
488 1.1 joerg return Impl->getName(D);
489 1.1 joerg }
490 1.1 joerg
491 1.1 joerg std::vector<std::string> ASTNameGenerator::getAllManglings(const Decl *D) {
492 1.1 joerg return Impl->getAllManglings(D);
493 1.1 joerg }
494