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)
153 if (D->
hasAttr<AsmLabelAttr>())
167struct FunctionIsDirectlyRecursive
169 const StringRef Name;
174 bool VisitCallExpr(
const CallExpr *E) {
179 if (
Attr && Name ==
Attr->getLabel())
184 std::string BuiltinNameStr = BI.
getName(BuiltinID);
185 StringRef BuiltinName = BuiltinNameStr;
186 return BuiltinName.consume_front(
"__builtin_") && Name == BuiltinName;
189 bool VisitStmt(
const Stmt *S) {
190 for (
const Stmt *Child : S->
children())
191 if (Child && this->Visit(Child))
206 Name =
Attr->getLabel();
213 return Body ? Walker.Visit(Body) :
false;
228 llvm::raw_ostream &Out) {
233 if (
auto *Ctor = llvm::dyn_cast<clang::CXXConstructorDecl>(GD.
getDecl())) {
235 if (Ctor->getInheritedConstructor().getConstructor())
238 }
else if (llvm::isa<clang::CXXDestructorDecl>(GD.
getDecl())) {
251 if (
const AsmLabelAttr *ALA = D->
getAttr<AsmLabelAttr>()) {
256 if (ALA->getLabel().starts_with(
"llvm.")) {
257 Out << ALA->getLabel();
266 StringRef UserLabelPrefix =
270 llvm::DataLayout(
getASTContext().getTargetInfo().getDataLayoutString())
272 assert((UserLabelPrefix.empty() && !GlobalPrefix) ||
273 (UserLabelPrefix.size() == 1 && UserLabelPrefix[0] == GlobalPrefix));
275 if (!UserLabelPrefix.empty())
281 Out << ALA->getLabel();
286 if (
auto *GD = dyn_cast<MSGuidDecl>(D))
292 Out <<
"__main_argc_argv";
297 const TargetInfo &TI = Context.getTargetInfo();
313 Out <<
"__regcall4__";
315 Out <<
"__regcall3__";
335 assert(!Proto->isVariadic());
336 unsigned ArgWords = 0;
338 if (MD->isImplicitObjectMemberFunction())
341 for (
const auto &AT : Proto->param_types()) {
345 if (AT->isIncompleteType())
351 Out << ((DefaultPtrWidth / 8) * ArgWords);
355 raw_ostream &Out)
const {
359 Out << llvm::format(
"_GUID_%08" PRIx32
"_%04" PRIx32
"_%04" PRIx32
"_",
363 Out << llvm::format(
"%02" PRIx8,
C);
372 unsigned discriminator =
getBlockId(BD,
false);
377 Out << ID->getIdentifier()->getName();
380 if (discriminator == 0)
381 Out <<
"_block_invoke";
383 Out <<
"_block_invoke_" << discriminator+1;
388 raw_ostream &ResStream) {
390 llvm::raw_svector_ostream Out(Buffer);
397 raw_ostream &ResStream) {
399 llvm::raw_svector_ostream Out(Buffer);
409 llvm::raw_svector_ostream Stream(Buffer);
414 "expected a NamedDecl or BlockDecl");
415 for (; isa_and_nonnull<BlockDecl>(DC); DC = DC->
getParent())
418 "expected a TranslationUnitDecl or a NamedDecl");
419 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
421 else if (
const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
423 else if (
auto ND = dyn_cast<NamedDecl>(DC)) {
425 Stream << ND->getIdentifier()->getName();
441 bool includePrefixByte,
442 bool includeCategoryNamespace,
443 bool useDirectABI)
const {
452 if (includeCategoryNamespace) {
454 OS << category->getName();
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();
477 auto CategoryName = std::optional<StringRef>();
478 StringRef ClassName =
"";
480 if (
const auto *CI = CID->getClassInterface()) {
481 ClassName = CI->getName();
482 if (includeCategoryNamespace) {
483 CategoryName = CID->getName();
486 }
else if (
const auto *CD =
488 ClassName = CD->getName();
490 llvm_unreachable(
"Unexpected ObjC method decl context");
492 std::string MethodName;
493 llvm::raw_string_ostream MethodNameOS(MethodName);
504 MethodName, useDirectABI);
508 raw_ostream &Out)
const {
510 llvm::raw_svector_ostream OS(Name);
514 Out << OS.str().size() << OS.str();
518 std::unique_ptr<MangleContext> MC;
523 : MC(Ctx.createMangleContext()),
524 DL(Ctx.getTargetInfo().getDataLayoutString()) {}
529 llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
530 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
533 if (writeFuncOrVarName(FD, FrontendBufOS))
535 }
else if (
auto *VD = dyn_cast<VarDecl>(D)) {
536 if (writeFuncOrVarName(VD, FrontendBufOS))
538 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
539 MC->mangleObjCMethodName(MD, OS,
false,
542 }
else if (
auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
543 writeObjCClassName(ID, FrontendBufOS);
549 llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
556 llvm::raw_string_ostream OS(Name);
569 if (Context.getLangOpts().ObjCRuntime.isGNUFamily())
570 return Kind ==
ObjCMetaclass ?
"_OBJC_METACLASS_" :
"_OBJC_CLASS_";
571 return Kind ==
ObjCMetaclass ?
"OBJC_METACLASS_$_" :
"OBJC_CLASS_$_";
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();
581 if (ClassName.empty())
584 auto Mangle = [&](
ObjCKind Kind, StringRef ClassName) -> std::string {
587 llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
588 return std::string(Mangled);
598 if (
const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
609 std::vector<std::string> Manglings;
612 auto DefaultCC =
C.getDefaultCallingConvention(
false,
615 return CC == DefaultCC;
618 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
619 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Base));
622 if (!CD->getParent()->isAbstract())
623 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Complete));
626 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
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));
634 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Deleting));
636 }
else if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
637 Manglings.emplace_back(
getName(ND));
638 if (MD->isVirtual()) {
640 for (
const auto &T : *TIV) {
641 std::string ThunkName;
642 std::string ContextualizedName =
643 getMangledThunk(MD, T,
false);
645 ThunkName = getMangledThunk(MD, T,
true);
647 ThunkName = ContextualizedName;
648 Manglings.emplace_back(ThunkName);
658 bool writeFuncOrVarName(
const NamedDecl *D, raw_ostream &OS) {
659 if (MC->shouldMangleDeclName(D)) {
661 if (
const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
663 else if (
const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
665 else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
669 MC->mangleName(GD, OS);
680 void writeObjCClassName(
const ObjCInterfaceDecl *D, raw_ostream &OS) {
685 std::string getMangledStructor(
const NamedDecl *ND,
unsigned StructorType) {
686 std::string FrontendBuf;
687 llvm::raw_string_ostream FOS(FrontendBuf);
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);
696 std::string BackendBuf;
697 llvm::raw_string_ostream BOS(BackendBuf);
699 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);
704 std::string getMangledThunk(
const CXXMethodDecl *MD,
const ThunkInfo &T,
705 bool ElideOverrideInfo) {
706 std::string FrontendBuf;
707 llvm::raw_string_ostream FOS(FrontendBuf);
709 MC->mangleThunk(MD, T, ElideOverrideInfo, FOS);
711 std::string BackendBuf;
712 llvm::raw_string_ostream BOS(BackendBuf);
714 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);
726 return Impl->writeName(D, OS);
730 return Impl->getName(D);
734 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 &)
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:").
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,...
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}