clang 23.0.0git
Mangle.cpp
Go to the documentation of this file.
1//===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===//
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// Implements generic name mangling support for blocks and Objective-C.
10//
11//===----------------------------------------------------------------------===//
12#include "clang/AST/Mangle.h"
14#include "clang/AST/Attr.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclCXX.h"
17#include "clang/AST/DeclObjC.h"
19#include "clang/AST/ExprCXX.h"
22#include "clang/Basic/ABI.h"
25#include "llvm/ADT/StringExtras.h"
26#include "llvm/IR/DataLayout.h"
27#include "llvm/IR/Mangler.h"
28#include "llvm/Support/ErrorHandling.h"
29#include "llvm/Support/Format.h"
30#include "llvm/Support/raw_ostream.h"
31
32using namespace clang;
33
34void clang::mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte,
35 bool isInstanceMethod, StringRef ClassName,
36 std::optional<StringRef> CategoryName,
37 StringRef MethodName, bool useDirectABI) {
38 assert(
39 !(includePrefixByte && useDirectABI) &&
40 "includePrefixByte and useDirectABI shouldn't be set at the same time");
41 // \01+[ContainerName(CategoryName) SelectorName]
42 // Or for direct ABI: +[ContainerName(CategoryName) SelectorName]D
43 if (includePrefixByte)
44 OS << "\01";
45 OS << (isInstanceMethod ? '-' : '+');
46 OS << '[';
47 OS << ClassName;
48 if (CategoryName)
49 OS << "(" << *CategoryName << ")";
50 OS << " ";
51 OS << MethodName;
52 OS << ']';
53 if (useDirectABI)
54 OS << 'D';
55}
56
57// FIXME: For blocks we currently mimic GCC's mangling scheme, which leaves
58// much to be desired. Come up with a better mangling scheme.
59
61 StringRef Outer,
62 const BlockDecl *BD,
63 raw_ostream &Out) {
64 unsigned discriminator = Context.getBlockId(BD, true);
65 if (discriminator == 0)
66 Out << "__" << Outer << "_block_invoke";
67 else
68 Out << "__" << Outer << "_block_invoke_" << discriminator+1;
69}
70
71void MangleContext::anchor() { }
72
81
82static bool isExternC(const NamedDecl *ND) {
83 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
84 return FD->isExternC();
85 if (const VarDecl *VD = dyn_cast<VarDecl>(ND))
86 return VD->isExternC();
87 return false;
88}
89
91 const NamedDecl *ND) {
92 const TargetInfo &TI = Context.getTargetInfo();
93 const llvm::Triple &Triple = TI.getTriple();
94
95 // On wasm, the argc/argv form of "main" is renamed so that the startup code
96 // can call it with the correct function signature.
97 if (Triple.isWasm())
98 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
99 if (FD->isMain() && FD->getNumParams() == 2)
101
103 return CCM_Other;
104
105 if (Context.getLangOpts().CPlusPlus && !isExternC(ND) &&
106 TI.getCXXABI() == TargetCXXABI::Microsoft)
107 return CCM_Other;
108
109 const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
110 if (!FD)
111 return CCM_Other;
112 QualType T = FD->getType();
113
114 const FunctionType *FT = T->castAs<FunctionType>();
115
116 CallingConv CC = FT->getCallConv();
117 switch (CC) {
118 default:
119 return CCM_Other;
120 case CC_X86FastCall:
121 return CCM_Fast;
122 case CC_X86StdCall:
123 return CCM_Std;
124 case CC_X86VectorCall:
125 return CCM_Vector;
126 }
127}
128
131
133 if (CC != CCM_Other)
134 return true;
135
136 // If the declaration has an owning module for linkage purposes that needs to
137 // be mangled, we must mangle its name.
139 return true;
140
141 // C functions with internal linkage have to be mangled with option
142 // -funique-internal-linkage-names.
143 if (!getASTContext().getLangOpts().CPlusPlus &&
145 return true;
146
147 // In C, functions with no attributes never need to be mangled. Fastpath them.
148 if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
149 return false;
150
151 // Any decl can be declared with __asm("foo") on it, and this takes precedence
152 // over all other naming in the .o file.
153 if (D->hasAttr<AsmLabelAttr>())
154 return true;
155
156 // Declarations that don't have identifier names always need to be mangled.
157 if (isa<MSGuidDecl>(D))
158 return true;
159
160 return shouldMangleCXXName(D);
161}
162
163namespace {
164// Visits a function body looking for a direct call back to the symbol the
165// function will link as. Detects both asm-label aliases and __builtin_*
166// wrappers (PR9614 / glibc btowc pattern).
167struct FunctionIsDirectlyRecursive
168 : public ConstStmtVisitor<FunctionIsDirectlyRecursive, bool> {
169 const StringRef Name;
170 const Builtin::Context &BI;
171 FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C)
172 : Name(N), BI(C) {}
173
174 bool VisitCallExpr(const CallExpr *E) {
175 const FunctionDecl *FD = E->getDirectCallee();
176 if (!FD)
177 return false;
178 AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
179 if (Attr && Name == Attr->getLabel())
180 return true;
181 unsigned BuiltinID = FD->getBuiltinID();
182 if (!BuiltinID || !BI.isLibFunction(BuiltinID))
183 return false;
184 std::string BuiltinNameStr = BI.getName(BuiltinID);
185 StringRef BuiltinName = BuiltinNameStr;
186 return BuiltinName.consume_front("__builtin_") && Name == BuiltinName;
187 }
188
189 bool VisitStmt(const Stmt *S) {
190 for (const Stmt *Child : S->children())
191 if (Child && this->Visit(Child))
192 return true;
193 return false;
194 }
195};
196} // namespace
197
199 StringRef Name;
200 if (shouldMangleDeclName(FD)) {
201 // C++-mangled functions can only recurse into themselves through an
202 // asm label that bypasses the mangled name.
203 AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
204 if (!Attr)
205 return false;
206 Name = Attr->getLabel();
207 } else {
208 Name = FD->getName();
209 }
210
211 FunctionIsDirectlyRecursive Walker(Name, FD->getASTContext().BuiltinInfo);
212 const Stmt *Body = FD->getBody();
213 return Body ? Walker.Visit(Body) : false;
214}
215
216/// Given an LLDB function call label, this function prints the label
217/// into \c Out, together with the structor type of \c GD (if the
218/// decl is a constructor/destructor). LLDB knows how to handle mangled
219/// names with this encoding.
220///
221/// Example input label:
222/// $__lldb_func::123:456:~Foo
223///
224/// Example output:
225/// $__lldb_func:D1:123:456:~Foo
226///
227static void emitLLDBAsmLabel(llvm::StringRef label, GlobalDecl GD,
228 llvm::raw_ostream &Out) {
229 assert(label.starts_with(LLDBManglingABI::FunctionLabelPrefix));
230
232
233 if (auto *Ctor = llvm::dyn_cast<clang::CXXConstructorDecl>(GD.getDecl())) {
234 Out << "C";
235 if (Ctor->getInheritedConstructor().getConstructor())
236 Out << "I";
237 Out << GD.getCtorType();
238 } else if (llvm::isa<clang::CXXDestructorDecl>(GD.getDecl())) {
239 Out << "D" << GD.getDtorType();
240 }
241
242 Out << label.substr(LLDBManglingABI::FunctionLabelPrefix.size());
243}
244
245void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {
247 const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
248
249 // Any decl can be declared with __asm("foo") on it, and this takes precedence
250 // over all other naming in the .o file.
251 if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
252 // If we have an asm name, then we use it as the mangling.
253
254 // If the label is an alias for an LLVM intrinsic,
255 // do not add a "\01" prefix.
256 if (ALA->getLabel().starts_with("llvm.")) {
257 Out << ALA->getLabel();
258 return;
259 }
260
261 // Adding the prefix can cause problems when one file has a "foo" and
262 // another has a "\01foo". That is known to happen on ELF with the
263 // tricks normally used for producing aliases (PR9177). Fortunately the
264 // llvm mangler on ELF is a nop, so we can just avoid adding the \01
265 // marker.
266 StringRef UserLabelPrefix =
268#ifndef NDEBUG
269 char GlobalPrefix =
270 llvm::DataLayout(getASTContext().getTargetInfo().getDataLayoutString())
271 .getGlobalPrefix();
272 assert((UserLabelPrefix.empty() && !GlobalPrefix) ||
273 (UserLabelPrefix.size() == 1 && UserLabelPrefix[0] == GlobalPrefix));
274#endif
275 if (!UserLabelPrefix.empty())
276 Out << '\01'; // LLVM IR Marker for __asm("foo")
277
278 if (ALA->getLabel().starts_with(LLDBManglingABI::FunctionLabelPrefix))
279 emitLLDBAsmLabel(ALA->getLabel(), GD, Out);
280 else
281 Out << ALA->getLabel();
282
283 return;
284 }
285
286 if (auto *GD = dyn_cast<MSGuidDecl>(D))
287 return mangleMSGuidDecl(GD, Out);
288
290
291 if (CC == CCM_WasmMainArgcArgv) {
292 Out << "__main_argc_argv";
293 return;
294 }
295
296 bool MCXX = shouldMangleCXXName(D);
297 const TargetInfo &TI = Context.getTargetInfo();
298 if (CC == CCM_Other || (MCXX && TI.getCXXABI() == TargetCXXABI::Microsoft)) {
299 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
301 else
302 mangleCXXName(GD, Out);
303 return;
304 }
305
306 Out << '\01';
307 if (CC == CCM_Std)
308 Out << '_';
309 else if (CC == CCM_Fast)
310 Out << '@';
311 else if (CC == CCM_RegCall) {
312 if (getASTContext().getLangOpts().RegCall4)
313 Out << "__regcall4__";
314 else
315 Out << "__regcall3__";
316 }
317
318 if (!MCXX)
319 Out << D->getIdentifier()->getName();
320 else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
322 else
323 mangleCXXName(GD, Out);
324
325 const FunctionDecl *FD = cast<FunctionDecl>(D);
326 const FunctionType *FT = FD->getType()->castAs<FunctionType>();
327 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT);
328 if (CC == CCM_Vector)
329 Out << '@';
330 Out << '@';
331 if (!Proto) {
332 Out << '0';
333 return;
334 }
335 assert(!Proto->isVariadic());
336 unsigned ArgWords = 0;
337 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
338 if (MD->isImplicitObjectMemberFunction())
339 ++ArgWords;
340 uint64_t DefaultPtrWidth = TI.getPointerWidth(LangAS::Default);
341 for (const auto &AT : Proto->param_types()) {
342 // If an argument type is incomplete there is no way to get its size to
343 // correctly encode into the mangling scheme.
344 // Follow GCCs behaviour by simply breaking out of the loop.
345 if (AT->isIncompleteType())
346 break;
347 // Size should be aligned to pointer size.
348 ArgWords += llvm::alignTo(ASTContext.getTypeSize(AT), DefaultPtrWidth) /
349 DefaultPtrWidth;
350 }
351 Out << ((DefaultPtrWidth / 8) * ArgWords);
352}
353
355 raw_ostream &Out) const {
356 // For now, follow the MSVC naming convention for GUID objects on all
357 // targets.
358 MSGuidDecl::Parts P = GD->getParts();
359 Out << llvm::format("_GUID_%08" PRIx32 "_%04" PRIx32 "_%04" PRIx32 "_",
360 P.Part1, P.Part2, P.Part3);
361 unsigned I = 0;
362 for (uint8_t C : P.Part4And5) {
363 Out << llvm::format("%02" PRIx8, C);
364 if (++I == 2)
365 Out << "_";
366 }
367}
368
370 const NamedDecl *ID,
371 raw_ostream &Out) {
372 unsigned discriminator = getBlockId(BD, false);
373 if (ID) {
374 if (shouldMangleDeclName(ID))
375 mangleName(ID, Out);
376 else {
377 Out << ID->getIdentifier()->getName();
378 }
379 }
380 if (discriminator == 0)
381 Out << "_block_invoke";
382 else
383 Out << "_block_invoke_" << discriminator+1;
384}
385
387 CXXCtorType CT, const BlockDecl *BD,
388 raw_ostream &ResStream) {
389 SmallString<64> Buffer;
390 llvm::raw_svector_ostream Out(Buffer);
391 mangleName(GlobalDecl(CD, CT), Out);
392 mangleFunctionBlock(*this, Buffer, BD, ResStream);
393}
394
396 CXXDtorType DT, const BlockDecl *BD,
397 raw_ostream &ResStream) {
398 SmallString<64> Buffer;
399 llvm::raw_svector_ostream Out(Buffer);
400 mangleName(GlobalDecl(DD, DT), Out);
401 mangleFunctionBlock(*this, Buffer, BD, ResStream);
402}
403
405 raw_ostream &Out) {
407
408 SmallString<64> Buffer;
409 llvm::raw_svector_ostream Stream(Buffer);
410 if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
412 } else {
413 assert((isa<NamedDecl>(DC) || isa<BlockDecl>(DC)) &&
414 "expected a NamedDecl or BlockDecl");
415 for (; isa_and_nonnull<BlockDecl>(DC); DC = DC->getParent())
416 (void)getBlockId(cast<BlockDecl>(DC), true);
417 assert((isa<TranslationUnitDecl>(DC) || isa<NamedDecl>(DC)) &&
418 "expected a TranslationUnitDecl or a NamedDecl");
419 if (const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
420 mangleCtorBlock(CD, /*CT*/ Ctor_Complete, BD, Out);
421 else if (const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
422 mangleDtorBlock(DD, /*DT*/ Dtor_Complete, BD, Out);
423 else if (auto ND = dyn_cast<NamedDecl>(DC)) {
424 if (!shouldMangleDeclName(ND) && ND->getIdentifier())
425 Stream << ND->getIdentifier()->getName();
426 else {
427 // FIXME: We were doing a mangleUnqualifiedName() before, but that's
428 // a private member of a class that will soon itself be private to the
429 // Itanium C++ ABI object. What should we do now? Right now, I'm just
430 // calling the mangleName() method on the MangleContext; is there a
431 // better way?
432 mangleName(ND, Stream);
433 }
434 }
435 }
436 mangleFunctionBlock(*this, Buffer, BD, Out);
437}
438
440 raw_ostream &OS,
441 bool includePrefixByte,
442 bool includeCategoryNamespace,
443 bool useDirectABI) const {
444 if (getASTContext().getLangOpts().ObjCRuntime.isGNUFamily()) {
445 // This is the mangling we've always used on the GNU runtimes, but it
446 // has obvious collisions in the face of underscores within class
447 // names, category names, and selectors; maybe we should improve it.
448
449 OS << (MD->isClassMethod() ? "_c_" : "_i_")
450 << MD->getClassInterface()->getName() << '_';
451
452 if (includeCategoryNamespace) {
453 if (auto category = MD->getCategory())
454 OS << category->getName();
455 }
456 OS << '_';
457
458 auto selector = MD->getSelector();
459 for (unsigned slotIndex = 0,
460 numArgs = selector.getNumArgs(),
461 slotEnd = std::max(numArgs, 1U);
462 slotIndex != slotEnd; ++slotIndex) {
463 if (auto name = selector.getIdentifierInfoForSlot(slotIndex))
464 OS << name->getName();
465
466 // Replace all the positions that would've been ':' with '_'.
467 // That's after each slot except that a unary selector doesn't
468 // end in ':'.
469 if (numArgs)
470 OS << '_';
471 }
472
473 return;
474 }
475
476 // \01+[ContainerName(CategoryName) SelectorName]
477 auto CategoryName = std::optional<StringRef>();
478 StringRef ClassName = "";
479 if (const auto *CID = MD->getCategory()) {
480 if (const auto *CI = CID->getClassInterface()) {
481 ClassName = CI->getName();
482 if (includeCategoryNamespace) {
483 CategoryName = CID->getName();
484 }
485 }
486 } else if (const auto *CD =
487 dyn_cast<ObjCContainerDecl>(MD->getDeclContext())) {
488 ClassName = CD->getName();
489 } else {
490 llvm_unreachable("Unexpected ObjC method decl context");
491 }
492 std::string MethodName;
493 llvm::raw_string_ostream MethodNameOS(MethodName);
494 MD->getSelector().print(MethodNameOS);
495 // Normal methods always have internal linkage, and we prefix them with '\01'
496 // for reasons that are somewhat lost to time. We suppress this for direct
497 // methods because they have non-internal linkage and we don't want to make it
498 // unnecessarily difficult to refer to them, e.g. in things like export lists.
499 // Direct methods also have a distinct ABI, so we add a suffix to make them
500 // obvious to tools like debuggers and to elevate incompatible uses into
501 // linker errors.
502 clang::mangleObjCMethodName(OS, includePrefixByte && !useDirectABI,
503 MD->isInstanceMethod(), ClassName, CategoryName,
504 MethodName, useDirectABI);
505}
506
508 raw_ostream &Out) const {
509 SmallString<64> Name;
510 llvm::raw_svector_ostream OS(Name);
511
512 mangleObjCMethodName(MD, OS, /*includePrefixByte=*/false,
513 /*includeCategoryNamespace=*/true);
514 Out << OS.str().size() << OS.str();
515}
516
518 std::unique_ptr<MangleContext> MC;
519 llvm::DataLayout DL;
520
521public:
523 : MC(Ctx.createMangleContext()),
524 DL(Ctx.getTargetInfo().getDataLayoutString()) {}
525
526 bool writeName(const Decl *D, raw_ostream &OS) {
527 // First apply frontend mangling.
528 SmallString<128> FrontendBuf;
529 llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
530 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
531 if (FD->isDependentContext())
532 return true;
533 if (writeFuncOrVarName(FD, FrontendBufOS))
534 return true;
535 } else if (auto *VD = dyn_cast<VarDecl>(D)) {
536 if (writeFuncOrVarName(VD, FrontendBufOS))
537 return true;
538 } else if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
539 MC->mangleObjCMethodName(MD, OS, /*includePrefixByte=*/false,
540 /*includeCategoryNamespace=*/true);
541 return false;
542 } else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
543 writeObjCClassName(ID, FrontendBufOS);
544 } else {
545 return true;
546 }
547
548 // Now apply backend mangling.
549 llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
550 return false;
551 }
552
553 std::string getName(const Decl *D) {
554 std::string Name;
555 {
556 llvm::raw_string_ostream OS(Name);
557 writeName(D, OS);
558 }
559 return Name;
560 }
561
566
567 static StringRef getClassSymbolPrefix(ObjCKind Kind,
568 const ASTContext &Context) {
569 if (Context.getLangOpts().ObjCRuntime.isGNUFamily())
570 return Kind == ObjCMetaclass ? "_OBJC_METACLASS_" : "_OBJC_CLASS_";
571 return Kind == ObjCMetaclass ? "OBJC_METACLASS_$_" : "OBJC_CLASS_$_";
572 }
573
574 std::vector<std::string> getAllManglings(const ObjCContainerDecl *OCD) {
575 StringRef ClassName;
576 if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
577 ClassName = OID->getObjCRuntimeNameAsString();
578 else if (const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
579 ClassName = OID->getObjCRuntimeNameAsString();
580
581 if (ClassName.empty())
582 return {};
583
584 auto Mangle = [&](ObjCKind Kind, StringRef ClassName) -> std::string {
585 SmallString<40> Mangled;
586 auto Prefix = getClassSymbolPrefix(Kind, OCD->getASTContext());
587 llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
588 return std::string(Mangled);
589 };
590
591 return {
592 Mangle(ObjCClass, ClassName),
593 Mangle(ObjCMetaclass, ClassName),
594 };
595 }
596
597 std::vector<std::string> getAllManglings(const Decl *D) {
598 if (const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
599 return getAllManglings(OCD);
600
602 return {};
603
604 const NamedDecl *ND = cast<NamedDecl>(D);
605
606 ASTContext &Ctx = ND->getASTContext();
607 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
608
609 std::vector<std::string> Manglings;
610
611 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
612 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
613 /*IsCXXMethod=*/true);
614 auto CC = MD->getType()->castAs<FunctionProtoType>()->getCallConv();
615 return CC == DefaultCC;
616 };
617
618 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
619 Manglings.emplace_back(getMangledStructor(CD, Ctor_Base));
620
622 if (!CD->getParent()->isAbstract())
623 Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete));
624
625 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
626 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
627 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
628 Manglings.emplace_back(getMangledStructor(CD, Ctor_DefaultClosure));
629 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
630 Manglings.emplace_back(getMangledStructor(DD, Dtor_Base));
632 Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete));
633 if (DD->isVirtual())
634 Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting));
635 }
636 } else if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
637 Manglings.emplace_back(getName(ND));
638 if (MD->isVirtual()) {
639 if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD)) {
640 for (const auto &T : *TIV) {
641 std::string ThunkName;
642 std::string ContextualizedName =
643 getMangledThunk(MD, T, /* ElideOverrideInfo */ false);
644 if (Ctx.useAbbreviatedThunkName(MD, ContextualizedName))
645 ThunkName = getMangledThunk(MD, T, /* ElideOverrideInfo */ true);
646 else
647 ThunkName = ContextualizedName;
648 Manglings.emplace_back(ThunkName);
649 }
650 }
651 }
652 }
653
654 return Manglings;
655 }
656
657private:
658 bool writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) {
659 if (MC->shouldMangleDeclName(D)) {
660 GlobalDecl GD;
661 if (const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
662 GD = GlobalDecl(CtorD, Ctor_Complete);
663 else if (const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
664 GD = GlobalDecl(DtorD, Dtor_Complete);
665 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
666 GD = FD->isReferenceableKernel() ? GlobalDecl(FD) : GlobalDecl(D);
667 } else
668 GD = GlobalDecl(D);
669 MC->mangleName(GD, OS);
670 return false;
671 } else {
672 IdentifierInfo *II = D->getIdentifier();
673 if (!II)
674 return true;
675 OS << II->getName();
676 return false;
677 }
678 }
679
680 void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) {
683 }
684
685 std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) {
686 std::string FrontendBuf;
687 llvm::raw_string_ostream FOS(FrontendBuf);
688
689 GlobalDecl GD;
690 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
691 GD = GlobalDecl(CD, static_cast<CXXCtorType>(StructorType));
692 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
693 GD = GlobalDecl(DD, static_cast<CXXDtorType>(StructorType));
694 MC->mangleName(GD, FOS);
695
696 std::string BackendBuf;
697 llvm::raw_string_ostream BOS(BackendBuf);
698
699 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);
700
701 return BackendBuf;
702 }
703
704 std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T,
705 bool ElideOverrideInfo) {
706 std::string FrontendBuf;
707 llvm::raw_string_ostream FOS(FrontendBuf);
708
709 MC->mangleThunk(MD, T, ElideOverrideInfo, FOS);
710
711 std::string BackendBuf;
712 llvm::raw_string_ostream BOS(BackendBuf);
713
714 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);
715
716 return BackendBuf;
717 }
718};
719
721 : Impl(std::make_unique<Implementation>(Ctx)) {}
722
724
725bool ASTNameGenerator::writeName(const Decl *D, raw_ostream &OS) {
726 return Impl->writeName(D, OS);
727}
728
729std::string ASTNameGenerator::getName(const Decl *D) {
730 return Impl->getName(D);
731}
732
733std::vector<std::string> ASTNameGenerator::getAllManglings(const Decl *D) {
734 return Impl->getAllManglings(D);
735}
Enums/classes describing ABI related information about constructors, destructors and thunks.
Defines the clang::ASTContext interface.
Defines enum values for all the target-independent builtin functions.
static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
CCMangling
Definition Mangle.cpp:73
@ CCM_Fast
Definition Mangle.cpp:75
@ CCM_Vector
Definition Mangle.cpp:77
@ CCM_Std
Definition Mangle.cpp:78
@ CCM_WasmMainArgcArgv
Definition Mangle.cpp:79
@ CCM_RegCall
Definition Mangle.cpp:76
@ CCM_Other
Definition Mangle.cpp:74
static void emitLLDBAsmLabel(llvm::StringRef label, GlobalDecl GD, llvm::raw_ostream &Out)
Given an LLDB function call label, this function prints the label into Out, together with the structo...
Definition Mangle.cpp:227
static void mangleFunctionBlock(MangleContext &Context, StringRef Outer, const BlockDecl *BD, raw_ostream &Out)
Definition Mangle.cpp:60
static bool isExternC(const NamedDecl *ND)
Definition Mangle.cpp:82
static CCMangling getCallingConvMangling(const ASTContext &Context, const NamedDecl *ND)
Definition Mangle.cpp:90
std::string getName(const Decl *D)
Definition Mangle.cpp:553
std::vector< std::string > getAllManglings(const Decl *D)
Definition Mangle.cpp:597
static StringRef getClassSymbolPrefix(ObjCKind Kind, const ASTContext &Context)
Definition Mangle.cpp:567
bool writeName(const Decl *D, raw_ostream &OS)
Definition Mangle.cpp:526
std::vector< std::string > getAllManglings(const ObjCContainerDecl *OCD)
Definition Mangle.cpp:574
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
MangleContext * createMangleContext(const TargetInfo *T=nullptr)
If T is null pointer, assume the target in ASTContext.
Builtin::Context & BuiltinInfo
Definition ASTContext.h:810
bool useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl, StringRef MangledName)
VTableContextBase * getVTableContext()
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:927
std::string getName(const Decl *D)
Definition Mangle.cpp:729
ASTNameGenerator(ASTContext &Ctx)
Definition Mangle.cpp:720
bool writeName(const Decl *D, raw_ostream &OS)
Writes name for D to OS.
Definition Mangle.cpp:725
std::vector< std::string > getAllManglings(const Decl *D)
Definition Mangle.cpp:733
Attr - This represents one attribute.
Definition Attr.h:46
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4716
Holds information about both target-independent and target-specific builtins, allowing easy queries b...
Definition Builtins.h:236
bool isLibFunction(unsigned ID) const
Return true if this is a builtin for a libc/libm function, with a "__builtin_" prefix (e....
Definition Builtins.h:310
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
Definition Builtins.cpp:94
Represents a C++ constructor within a class.
Definition DeclCXX.h:2633
Represents a C++ destructor within a class.
Definition DeclCXX.h:2898
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2145
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2949
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3132
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
T * getAttr() const
Definition DeclBase.h:581
bool hasAttrs() const
Definition DeclBase.h:526
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:550
DeclContext * getDeclContext()
Definition DeclBase.h:456
Module * getOwningModuleForLinkage() const
Get the module that owns this declaration for linkage purposes.
Definition Decl.cpp:1637
bool hasAttr() const
Definition DeclBase.h:585
Represents a function declaration or definition.
Definition Decl.h:2029
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition Decl.cpp:3257
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3740
bool isReferenceableKernel() const
Definition Decl.cpp:5643
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5371
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4567
CallingConv getCallConv() const
Definition TypeBase.h:4922
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:57
CXXCtorType getCtorType() const
Definition GlobalDecl.h:108
CXXDtorType getDtorType() const
Definition GlobalDecl.h:113
const Decl * getDecl() const
Definition GlobalDecl.h:106
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
A global _GUID constant.
Definition DeclCXX.h:4424
Parts getParts() const
Get the decomposed parts of this declaration.
Definition DeclCXX.h:4454
MSGuidDeclParts Parts
Definition DeclCXX.h:4426
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
Definition Mangle.h:56
void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out)
Definition Mangle.cpp:404
unsigned getBlockId(const BlockDecl *BD, bool Local)
Definition Mangle.h:92
void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, const BlockDecl *BD, raw_ostream &Out)
Definition Mangle.cpp:386
ASTContext & getASTContext() const
Definition Mangle.h:86
void mangleGlobalBlock(const BlockDecl *BD, const NamedDecl *ID, raw_ostream &Out)
Definition Mangle.cpp:369
void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS, bool includePrefixByte=true, bool includeCategoryNamespace=true, bool useDirectABI=false) const
Definition Mangle.cpp:439
virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND)
Definition Mangle.h:140
bool isTriviallyRecursive(const FunctionDecl *FD)
Return true if FD's body contains a direct call back to the symbol it links as, through an asm label ...
Definition Mangle.cpp:198
bool shouldMangleDeclName(const NamedDecl *D)
Definition Mangle.cpp:129
virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream &) const
Definition Mangle.cpp:354
void mangleName(GlobalDecl GD, raw_ostream &)
Definition Mangle.cpp:245
virtual void mangleCXXName(GlobalDecl GD, raw_ostream &)=0
virtual bool shouldMangleCXXName(const NamedDecl *D)=0
void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT, const BlockDecl *BD, raw_ostream &Out)
Definition Mangle.cpp:395
void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD, raw_ostream &) const
Definition Mangle.cpp:507
This represents a decl that may have a name.
Definition Decl.h:274
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
bool hasExternalFormalLinkage() const
True if this decl has external linkage.
Definition Decl.h:429
ObjCContainerDecl - Represents a container for method declarations.
Definition DeclObjC.h:948
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
Selector getSelector() const
Definition DeclObjC.h:327
bool isInstanceMethod() const
Definition DeclObjC.h:426
ObjCCategoryDecl * getCategory()
If this method is declared or implemented in a category, return that category.
bool isClassMethod() const
Definition DeclObjC.h:434
ObjCInterfaceDecl * getClassInterface()
The basic abstraction for the target Objective-C runtime.
Definition ObjCRuntime.h:28
bool isGNUFamily() const
Is this runtime basically of the GNU family of runtimes?
A (possibly-)qualified type.
Definition TypeBase.h:937
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
Stmt - This represents one statement.
Definition Stmt.h:86
child_range children()
Definition Stmt.cpp:304
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
bool isItaniumFamily() const
Does this ABI generally fall into the Itanium family of ABIs?
Exposes information about the current target.
Definition TargetInfo.h:227
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
Definition TargetInfo.h:493
const char * getUserLabelPrefix() const
Returns the default value of the USER_LABEL_PREFIX macro, which is the prefix given to user symbols b...
Definition TargetInfo.h:933
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
bool shouldUseMicrosoftCCforMangling() const
Should the Microsoft mangling scheme be used for C Calling Convention.
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9344
virtual const ThunkInfoVectorTy * getThunkInfo(GlobalDecl GD)
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:932
Defines the clang::TargetInfo interface.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
CXXCtorType
C++ constructor types.
Definition ABI.h:24
@ Ctor_Base
Base object ctor.
Definition ABI.h:26
@ Ctor_DefaultClosure
Default closure variant of a ctor.
Definition ABI.h:29
@ Ctor_Complete
Complete object ctor.
Definition ABI.h:25
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus
bool isInstanceMethod(const Decl *D)
Definition Attr.h:120
void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName, bool useDirectABI)
Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...
Definition Mangle.cpp:34
CXXDtorType
C++ destructor types.
Definition ABI.h:34
@ Dtor_Base
Base object dtor.
Definition ABI.h:37
@ Dtor_Complete
Complete object dtor.
Definition ABI.h:36
@ Dtor_Deleting
Deleting dtor.
Definition ABI.h:35
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition Specifiers.h:279
@ CC_X86VectorCall
Definition Specifiers.h:284
@ CC_X86StdCall
Definition Specifiers.h:281
@ CC_X86FastCall
Definition Specifiers.h:282
U cast(CodeGen::Address addr)
Definition Address.h:327
static constexpr llvm::StringLiteral FunctionLabelPrefix
Definition Mangle.h:336
uint16_t Part2
...-89ab-...
Definition DeclCXX.h:4403
uint32_t Part1
{01234567-...
Definition DeclCXX.h:4401
uint16_t Part3
...-cdef-...
Definition DeclCXX.h:4405
uint8_t Part4And5[8]
...-0123-456789abcdef}
Definition DeclCXX.h:4407