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"
36 std::optional<StringRef> CategoryName,
37 StringRef MethodName,
bool useDirectABI) {
39 !(includePrefixByte && useDirectABI) &&
40 "includePrefixByte and useDirectABI shouldn't be set at the same time");
43 if (includePrefixByte)
49 OS <<
"(" << *CategoryName <<
")";
64 unsigned discriminator = Context.getBlockId(BD,
true);
65 if (discriminator == 0)
66 Out <<
"__" << Outer <<
"_block_invoke";
68 Out <<
"__" << Outer <<
"_block_invoke_" << discriminator+1;
71void MangleContext::anchor() { }
84 return FD->isExternC();
85 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND))
86 return VD->isExternC();
92 const TargetInfo &TI = Context.getTargetInfo();
93 const llvm::Triple &Triple = TI.
getTriple();
99 if (FD->isMain() && FD->getNumParams() == 2)
105 if (Context.getLangOpts().CPlusPlus && !
isExternC(ND) &&
106 TI.
getCXXABI() == TargetCXXABI::Microsoft)
132 if (D->
hasAttr<AsmLabelAttr>())
171struct FunctionIsDirectlyRecursive
173 const StringRef Name;
178 bool VisitCallExpr(
const CallExpr *E) {
183 if (
Attr && Name ==
Attr->getLabel())
188 std::string BuiltinNameStr = BI.
getName(BuiltinID);
189 StringRef BuiltinName = BuiltinNameStr;
190 return BuiltinName.consume_front(
"__builtin_") && Name == BuiltinName;
193 bool VisitStmt(
const Stmt *S) {
194 for (
const Stmt *Child : S->
children())
195 if (Child && this->Visit(Child))
210 Name =
Attr->getLabel();
217 return Body ? Walker.Visit(Body) :
false;
232 llvm::raw_ostream &Out) {
237 if (
auto *Ctor = llvm::dyn_cast<clang::CXXConstructorDecl>(GD.
getDecl())) {
239 if (Ctor->getInheritedConstructor().getConstructor())
242 }
else if (llvm::isa<clang::CXXDestructorDecl>(GD.
getDecl())) {
254 if (
const AsmLabelAttr *ALA = D->
getAttr<AsmLabelAttr>()) {
259 if (ALA->getLabel().starts_with(
"llvm.")) {
260 Out << ALA->getLabel();
269 StringRef UserLabelPrefix =
273 llvm::DataLayout(
getASTContext().getTargetInfo().getDataLayoutString())
275 assert((UserLabelPrefix.empty() && !GlobalPrefix) ||
276 (UserLabelPrefix.size() == 1 && UserLabelPrefix[0] == GlobalPrefix));
278 if (!UserLabelPrefix.empty())
284 Out << ALA->getLabel();
297 if (
auto *GD = dyn_cast<MSGuidDecl>(D))
303 Out <<
"__main_argc_argv";
308 const TargetInfo &TI = Context.getTargetInfo();
324 Out <<
"__regcall4__";
326 Out <<
"__regcall3__";
346 assert(!Proto->isVariadic());
347 unsigned ArgWords = 0;
349 if (MD->isImplicitObjectMemberFunction())
352 for (
const auto &AT : Proto->param_types()) {
356 if (AT->isIncompleteType())
362 Out << ((DefaultPtrWidth / 8) * ArgWords);
366 raw_ostream &Out)
const {
370 Out << llvm::format(
"_GUID_%08" PRIx32
"_%04" PRIx32
"_%04" PRIx32
"_",
374 Out << llvm::format(
"%02" PRIx8,
C);
383 unsigned discriminator =
getBlockId(BD,
false);
388 Out << ID->getIdentifier()->getName();
391 if (discriminator == 0)
392 Out <<
"_block_invoke";
394 Out <<
"_block_invoke_" << discriminator+1;
399 raw_ostream &ResStream) {
401 llvm::raw_svector_ostream Out(Buffer);
408 raw_ostream &ResStream) {
410 llvm::raw_svector_ostream Out(Buffer);
420 llvm::raw_svector_ostream Stream(Buffer);
425 "expected a NamedDecl or BlockDecl");
426 for (; isa_and_nonnull<BlockDecl>(DC); DC = DC->
getParent())
429 "expected a TranslationUnitDecl or a NamedDecl");
430 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
432 else if (
const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
434 else if (
auto ND = dyn_cast<NamedDecl>(DC)) {
436 Stream << ND->getIdentifier()->getName();
452 bool includePrefixByte,
453 bool includeCategoryNamespace,
454 bool useDirectABI)
const {
463 if (includeCategoryNamespace) {
465 OS << category->getName();
470 for (
unsigned slotIndex = 0,
471 numArgs = selector.getNumArgs(),
472 slotEnd = std::max(numArgs, 1U);
473 slotIndex != slotEnd; ++slotIndex) {
474 if (
auto name = selector.getIdentifierInfoForSlot(slotIndex))
475 OS << name->getName();
488 auto CategoryName = std::optional<StringRef>();
489 StringRef ClassName =
"";
491 if (
const auto *CI = CID->getClassInterface()) {
492 ClassName = CI->getName();
493 if (includeCategoryNamespace) {
494 CategoryName = CID->getName();
497 }
else if (
const auto *CD =
499 ClassName = CD->getName();
501 llvm_unreachable(
"Unexpected ObjC method decl context");
503 std::string MethodName;
504 llvm::raw_string_ostream MethodNameOS(MethodName);
515 MethodName, useDirectABI);
519 raw_ostream &Out)
const {
521 llvm::raw_svector_ostream OS(Name);
525 Out << OS.str().size() << OS.str();
529 std::unique_ptr<MangleContext> MC;
534 : MC(Ctx.createMangleContext()),
535 DL(Ctx.getTargetInfo().getDataLayoutString()) {}
540 llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
541 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
544 if (writeFuncOrVarName(FD, FrontendBufOS))
546 }
else if (
auto *VD = dyn_cast<VarDecl>(D)) {
547 if (writeFuncOrVarName(VD, FrontendBufOS))
549 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
550 MC->mangleObjCMethodName(MD, OS,
false,
553 }
else if (
auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
554 writeObjCClassName(ID, FrontendBufOS);
560 llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
567 llvm::raw_string_ostream OS(Name);
580 if (Context.getLangOpts().ObjCRuntime.isGNUFamily())
581 return Kind ==
ObjCMetaclass ?
"_OBJC_METACLASS_" :
"_OBJC_CLASS_";
582 return Kind ==
ObjCMetaclass ?
"OBJC_METACLASS_$_" :
"OBJC_CLASS_$_";
587 if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
588 ClassName = OID->getObjCRuntimeNameAsString();
589 else if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
590 ClassName = OID->getObjCRuntimeNameAsString();
592 if (ClassName.empty())
595 auto Mangle = [&](
ObjCKind Kind, StringRef ClassName) -> std::string {
598 llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
599 return std::string(Mangled);
609 if (
const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
620 std::vector<std::string> Manglings;
623 auto DefaultCC =
C.getDefaultCallingConvention(
false,
626 return CC == DefaultCC;
629 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
630 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Base));
633 if (!CD->getParent()->isAbstract())
634 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Complete));
637 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
640 }
else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
641 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Base));
643 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Complete));
645 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Deleting));
647 }
else if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
648 Manglings.emplace_back(
getName(ND));
649 if (MD->isVirtual()) {
651 for (
const auto &
T : *TIV) {
652 std::string ThunkName;
653 std::string ContextualizedName =
654 getMangledThunk(MD,
T,
false);
656 ThunkName = getMangledThunk(MD,
T,
true);
658 ThunkName = ContextualizedName;
659 Manglings.emplace_back(ThunkName);
669 bool writeFuncOrVarName(
const NamedDecl *D, raw_ostream &OS) {
670 if (MC->shouldMangleDeclName(D)) {
672 if (
const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
674 else if (
const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
676 else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
680 MC->mangleName(GD, OS);
691 void writeObjCClassName(
const ObjCInterfaceDecl *D, raw_ostream &OS) {
696 std::string getMangledStructor(
const NamedDecl *ND,
unsigned StructorType) {
697 std::string FrontendBuf;
698 llvm::raw_string_ostream FOS(FrontendBuf);
701 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
702 GD = GlobalDecl(CD,
static_cast<CXXCtorType>(StructorType));
703 else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
704 GD = GlobalDecl(DD,
static_cast<CXXDtorType>(StructorType));
705 MC->mangleName(GD, FOS);
707 std::string BackendBuf;
708 llvm::raw_string_ostream BOS(BackendBuf);
710 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);
715 std::string getMangledThunk(
const CXXMethodDecl *MD,
const ThunkInfo &
T,
716 bool ElideOverrideInfo) {
717 std::string FrontendBuf;
718 llvm::raw_string_ostream FOS(FrontendBuf);
720 MC->mangleThunk(MD,
T, ElideOverrideInfo, FOS);
722 std::string BackendBuf;
723 llvm::raw_string_ostream BOS(BackendBuf);
725 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);
737 return Impl->writeName(D, OS);
741 return Impl->getName(D);
745 return Impl->getAllManglings(D);
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.
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.
Builtin::Context & BuiltinInfo
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)
Attr - This represents one attribute.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Holds information about both target-independent and target-specific builtins, allowing easy queries b...
bool isLibFunction(unsigned ID) const
Return true if this is a builtin for a libc/libm function, with a "__builtin_" prefix (e....
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
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.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
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...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
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.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
bool isReferenceableKernel() const
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 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 ...
bool shouldMangleDeclName(const NamedDecl *D)
virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream &) const
void mangleName(GlobalDecl GD, raw_ostream &)
void mangleNameIgnoringAsmLabel(GlobalDecl GD, raw_ostream &)
virtual void mangleCXXName(GlobalDecl GD, raw_ostream &)=0
bool shouldMangleDeclNameIgnoringAsmLabel(const NamedDecl *D)
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:").
Stmt - This represents one statement.
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,...
Top level wrappers for InstallAPI frontend operations.
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...
const FunctionProtoType * T
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}