23#include "llvm/ADT/StringExtras.h"
24#include "llvm/IR/DataLayout.h"
25#include "llvm/IR/Mangler.h"
26#include "llvm/Support/ErrorHandling.h"
27#include "llvm/Support/Format.h"
28#include "llvm/Support/raw_ostream.h"
34 std::optional<StringRef> CategoryName,
35 StringRef MethodName,
bool useDirectABI) {
37 !(includePrefixByte && useDirectABI) &&
38 "includePrefixByte and useDirectABI shouldn't be set at the same time");
41 if (includePrefixByte)
47 OS <<
"(" << *CategoryName <<
")";
62 unsigned discriminator = Context.getBlockId(BD,
true);
63 if (discriminator == 0)
64 Out <<
"__" << Outer <<
"_block_invoke";
66 Out <<
"__" << Outer <<
"_block_invoke_" << discriminator+1;
69void MangleContext::anchor() { }
82 return FD->isExternC();
83 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND))
84 return VD->isExternC();
90 const TargetInfo &TI = Context.getTargetInfo();
91 const llvm::Triple &Triple = TI.
getTriple();
97 if (FD->isMain() && FD->getNumParams() == 2)
103 if (Context.getLangOpts().CPlusPlus && !
isExternC(ND) &&
104 TI.
getCXXABI() == TargetCXXABI::Microsoft)
151 if (D->
hasAttr<AsmLabelAttr>())
173 llvm::raw_ostream &Out) {
178 if (
auto *Ctor = llvm::dyn_cast<clang::CXXConstructorDecl>(GD.
getDecl())) {
180 if (Ctor->getInheritedConstructor().getConstructor())
183 }
else if (llvm::isa<clang::CXXDestructorDecl>(GD.
getDecl())) {
196 if (
const AsmLabelAttr *ALA = D->
getAttr<AsmLabelAttr>()) {
201 if (ALA->getLabel().starts_with(
"llvm.")) {
202 Out << ALA->getLabel();
211 StringRef UserLabelPrefix =
215 llvm::DataLayout(
getASTContext().getTargetInfo().getDataLayoutString())
217 assert((UserLabelPrefix.empty() && !GlobalPrefix) ||
218 (UserLabelPrefix.size() == 1 && UserLabelPrefix[0] == GlobalPrefix));
220 if (!UserLabelPrefix.empty())
226 Out << ALA->getLabel();
231 if (
auto *GD = dyn_cast<MSGuidDecl>(D))
237 Out <<
"__main_argc_argv";
242 const TargetInfo &TI = Context.getTargetInfo();
258 Out <<
"__regcall4__";
260 Out <<
"__regcall3__";
280 assert(!Proto->isVariadic());
281 unsigned ArgWords = 0;
283 if (MD->isImplicitObjectMemberFunction())
286 for (
const auto &AT : Proto->param_types()) {
290 if (AT->isIncompleteType())
296 Out << ((DefaultPtrWidth / 8) * ArgWords);
300 raw_ostream &Out)
const {
304 Out << llvm::format(
"_GUID_%08" PRIx32
"_%04" PRIx32
"_%04" PRIx32
"_",
308 Out << llvm::format(
"%02" PRIx8,
C);
317 unsigned discriminator =
getBlockId(BD,
false);
322 Out << ID->getIdentifier()->getName();
325 if (discriminator == 0)
326 Out <<
"_block_invoke";
328 Out <<
"_block_invoke_" << discriminator+1;
333 raw_ostream &ResStream) {
335 llvm::raw_svector_ostream Out(Buffer);
342 raw_ostream &ResStream) {
344 llvm::raw_svector_ostream Out(Buffer);
354 llvm::raw_svector_ostream Stream(Buffer);
359 "expected a NamedDecl or BlockDecl");
360 for (; isa_and_nonnull<BlockDecl>(DC); DC = DC->
getParent())
363 "expected a TranslationUnitDecl or a NamedDecl");
364 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
366 else if (
const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
368 else if (
auto ND = dyn_cast<NamedDecl>(DC)) {
370 Stream << ND->getIdentifier()->getName();
386 bool includePrefixByte,
387 bool includeCategoryNamespace,
388 bool useDirectABI)
const {
397 if (includeCategoryNamespace) {
399 OS << category->getName();
404 for (
unsigned slotIndex = 0,
405 numArgs = selector.getNumArgs(),
406 slotEnd = std::max(numArgs, 1U);
407 slotIndex != slotEnd; ++slotIndex) {
408 if (
auto name = selector.getIdentifierInfoForSlot(slotIndex))
409 OS << name->getName();
422 auto CategoryName = std::optional<StringRef>();
423 StringRef ClassName =
"";
425 if (
const auto *CI = CID->getClassInterface()) {
426 ClassName = CI->getName();
427 if (includeCategoryNamespace) {
428 CategoryName = CID->getName();
431 }
else if (
const auto *CD =
433 ClassName = CD->getName();
435 llvm_unreachable(
"Unexpected ObjC method decl context");
437 std::string MethodName;
438 llvm::raw_string_ostream MethodNameOS(MethodName);
449 MethodName, useDirectABI);
453 raw_ostream &Out)
const {
455 llvm::raw_svector_ostream OS(Name);
459 Out << OS.str().size() << OS.str();
463 std::unique_ptr<MangleContext> MC;
468 : MC(Ctx.createMangleContext()),
469 DL(Ctx.getTargetInfo().getDataLayoutString()) {}
474 llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
475 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
476 if (FD->isDependentContext())
478 if (writeFuncOrVarName(FD, FrontendBufOS))
480 }
else if (
auto *VD = dyn_cast<VarDecl>(D)) {
481 if (writeFuncOrVarName(VD, FrontendBufOS))
483 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
484 MC->mangleObjCMethodName(MD, OS,
false,
487 }
else if (
auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
488 writeObjCClassName(ID, FrontendBufOS);
494 llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
501 llvm::raw_string_ostream OS(Name);
514 if (Context.getLangOpts().ObjCRuntime.isGNUFamily())
515 return Kind ==
ObjCMetaclass ?
"_OBJC_METACLASS_" :
"_OBJC_CLASS_";
516 return Kind ==
ObjCMetaclass ?
"OBJC_METACLASS_$_" :
"OBJC_CLASS_$_";
521 if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
522 ClassName = OID->getObjCRuntimeNameAsString();
523 else if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
524 ClassName = OID->getObjCRuntimeNameAsString();
526 if (ClassName.empty())
529 auto Mangle = [&](
ObjCKind Kind, StringRef ClassName) -> std::string {
532 llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
533 return std::string(Mangled);
543 if (
const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
554 std::vector<std::string> Manglings;
557 auto DefaultCC =
C.getDefaultCallingConvention(
false,
560 return CC == DefaultCC;
563 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
564 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Base));
567 if (!CD->getParent()->isAbstract())
568 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Complete));
571 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
574 }
else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
575 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Base));
577 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Complete));
579 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Deleting));
581 }
else if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
582 Manglings.emplace_back(
getName(ND));
583 if (MD->isVirtual()) {
585 for (
const auto &T : *TIV) {
586 std::string ThunkName;
587 std::string ContextualizedName =
588 getMangledThunk(MD, T,
false);
590 ThunkName = getMangledThunk(MD, T,
true);
592 ThunkName = ContextualizedName;
593 Manglings.emplace_back(ThunkName);
603 bool writeFuncOrVarName(
const NamedDecl *D, raw_ostream &OS) {
604 if (MC->shouldMangleDeclName(D)) {
606 if (
const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
608 else if (
const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
610 else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
614 MC->mangleName(GD, OS);
625 void writeObjCClassName(
const ObjCInterfaceDecl *D, raw_ostream &OS) {
630 std::string getMangledStructor(
const NamedDecl *ND,
unsigned StructorType) {
631 std::string FrontendBuf;
632 llvm::raw_string_ostream FOS(FrontendBuf);
635 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
636 GD = GlobalDecl(CD,
static_cast<CXXCtorType>(StructorType));
637 else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
638 GD = GlobalDecl(DD,
static_cast<CXXDtorType>(StructorType));
639 MC->mangleName(GD, FOS);
641 std::string BackendBuf;
642 llvm::raw_string_ostream BOS(BackendBuf);
644 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);
649 std::string getMangledThunk(
const CXXMethodDecl *MD,
const ThunkInfo &T,
650 bool ElideOverrideInfo) {
651 std::string FrontendBuf;
652 llvm::raw_string_ostream FOS(FrontendBuf);
654 MC->mangleThunk(MD, T, ElideOverrideInfo, FOS);
656 std::string BackendBuf;
657 llvm::raw_string_ostream BOS(BackendBuf);
659 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);
671 return Impl->writeName(D, OS);
675 return Impl->getName(D);
679 return Impl->getAllManglings(D);
Enums/classes describing ABI related information about constructors, destructors and thunks.
Defines the clang::ASTContext interface.
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.
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...
static void mangleFunctionBlock(MangleContext &Context, StringRef Outer, const BlockDecl *BD, raw_ostream &Out)
static bool isExternC(const NamedDecl *ND)
static CCMangling getCallingConvMangling(const ASTContext &Context, const NamedDecl *ND)
std::string getName(const Decl *D)
std::vector< std::string > getAllManglings(const Decl *D)
static StringRef getClassSymbolPrefix(ObjCKind Kind, const ASTContext &Context)
bool writeName(const Decl *D, raw_ostream &OS)
Implementation(ASTContext &Ctx)
std::vector< std::string > getAllManglings(const ObjCContainerDecl *OCD)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
MangleContext * createMangleContext(const TargetInfo *T=nullptr)
If T is null pointer, assume the target in ASTContext.
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
std::string getName(const Decl *D)
ASTNameGenerator(ASTContext &Ctx)
bool writeName(const Decl *D, raw_ostream &OS)
Writes name for D to OS.
std::vector< std::string > getAllManglings(const Decl *D)
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Represents a C++ constructor within a class.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
DeclContext * getDeclContext()
Module * getOwningModuleForLinkage() const
Get the module that owns this declaration for linkage purposes.
Represents a function declaration or definition.
Represents a prototype with parameter type info, e.g.
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Parts getParts() const
Get the decomposed parts of this declaration.
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out)
unsigned getBlockId(const BlockDecl *BD, bool Local)
void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, const BlockDecl *BD, raw_ostream &Out)
ASTContext & getASTContext() const
void mangleGlobalBlock(const BlockDecl *BD, const NamedDecl *ID, raw_ostream &Out)
void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS, bool includePrefixByte=true, bool includeCategoryNamespace=true, bool useDirectABI=false) const
virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND)
bool shouldMangleDeclName(const NamedDecl *D)
virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream &) const
void mangleName(GlobalDecl GD, raw_ostream &)
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)
void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD, raw_ostream &) const
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
bool hasExternalFormalLinkage() const
True if this decl has external linkage.
ObjCContainerDecl - Represents a container for method declarations.
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
ObjCMethodDecl - Represents an instance or class method declaration.
Selector getSelector() const
bool isInstanceMethod() const
ObjCCategoryDecl * getCategory()
If this method is declared or implemented in a category, return that category.
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
The basic abstraction for the target Objective-C runtime.
bool isGNUFamily() const
Is this runtime basically of the GNU family of runtimes?
A (possibly-)qualified type.
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
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.
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.
const char * getUserLabelPrefix() const
Returns the default value of the USER_LABEL_PREFIX macro, which is the prefix given to user symbols b...
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>.
virtual const ThunkInfoVectorTy * getThunkInfo(GlobalDecl GD)
Represents a variable declaration or definition.
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.
@ Ctor_Base
Base object ctor.
@ Ctor_DefaultClosure
Default closure variant of a ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
bool isInstanceMethod(const Decl *D)
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...
CXXDtorType
C++ destructor types.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
static constexpr llvm::StringLiteral FunctionLabelPrefix
uint16_t Part2
...-89ab-...
uint32_t Part1
{01234567-...
uint16_t Part3
...-cdef-...
uint8_t Part4And5[8]
...-0123-456789abcdef}