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) {
37 if (includePrefixByte)
43 OS <<
"(" << *CategoryName <<
")";
56 unsigned discriminator = Context.getBlockId(BD,
true);
57 if (discriminator == 0)
58 Out <<
"__" << Outer <<
"_block_invoke";
60 Out <<
"__" << Outer <<
"_block_invoke_" << discriminator+1;
63void MangleContext::anchor() { }
76 return FD->isExternC();
77 if (
const VarDecl *VD = dyn_cast<VarDecl>(ND))
78 return VD->isExternC();
84 const TargetInfo &TI = Context.getTargetInfo();
85 const llvm::Triple &Triple = TI.
getTriple();
91 if (FD->isMain() && FD->getNumParams() == 2)
97 if (Context.getLangOpts().CPlusPlus && !
isExternC(ND) &&
98 TI.
getCXXABI() == TargetCXXABI::Microsoft)
145 if (D->
hasAttr<AsmLabelAttr>())
169 llvm::raw_ostream &Out) {
174 if (
auto *Ctor = llvm::dyn_cast<clang::CXXConstructorDecl>(GD.
getDecl())) {
176 if (Ctor->getInheritedConstructor().getConstructor())
179 }
else if (llvm::isa<clang::CXXDestructorDecl>(GD.
getDecl())) {
192 if (
const AsmLabelAttr *ALA = D->
getAttr<AsmLabelAttr>()) {
197 if (ALA->getLabel().starts_with(
"llvm.")) {
198 Out << ALA->getLabel();
207 StringRef UserLabelPrefix =
211 llvm::DataLayout(
getASTContext().getTargetInfo().getDataLayoutString())
213 assert((UserLabelPrefix.empty() && !GlobalPrefix) ||
214 (UserLabelPrefix.size() == 1 && UserLabelPrefix[0] == GlobalPrefix));
216 if (!UserLabelPrefix.empty())
222 Out << ALA->getLabel();
227 if (
auto *GD = dyn_cast<MSGuidDecl>(D))
233 Out <<
"__main_argc_argv";
238 const TargetInfo &TI = Context.getTargetInfo();
254 Out <<
"__regcall4__";
256 Out <<
"__regcall3__";
276 assert(!Proto->isVariadic());
277 unsigned ArgWords = 0;
279 if (MD->isImplicitObjectMemberFunction())
282 for (
const auto &AT : Proto->param_types()) {
286 if (AT->isIncompleteType())
292 Out << ((DefaultPtrWidth / 8) * ArgWords);
296 raw_ostream &Out)
const {
300 Out << llvm::format(
"_GUID_%08" PRIx32
"_%04" PRIx32
"_%04" PRIx32
"_",
304 Out << llvm::format(
"%02" PRIx8,
C);
313 unsigned discriminator =
getBlockId(BD,
false);
318 Out << ID->getIdentifier()->getName();
321 if (discriminator == 0)
322 Out <<
"_block_invoke";
324 Out <<
"_block_invoke_" << discriminator+1;
329 raw_ostream &ResStream) {
331 llvm::raw_svector_ostream Out(Buffer);
338 raw_ostream &ResStream) {
340 llvm::raw_svector_ostream Out(Buffer);
350 llvm::raw_svector_ostream Stream(Buffer);
355 "expected a NamedDecl or BlockDecl");
356 for (; isa_and_nonnull<BlockDecl>(DC); DC = DC->
getParent())
359 "expected a TranslationUnitDecl or a NamedDecl");
360 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
362 else if (
const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
364 else if (
auto ND = dyn_cast<NamedDecl>(DC)) {
366 Stream << ND->getIdentifier()->getName();
382 bool includePrefixByte,
383 bool includeCategoryNamespace)
const {
392 if (includeCategoryNamespace) {
394 OS << category->getName();
399 for (
unsigned slotIndex = 0,
400 numArgs = selector.getNumArgs(),
401 slotEnd = std::max(numArgs, 1U);
402 slotIndex != slotEnd; ++slotIndex) {
403 if (
auto name = selector.getIdentifierInfoForSlot(slotIndex))
404 OS << name->getName();
417 auto CategoryName = std::optional<StringRef>();
418 StringRef ClassName =
"";
420 if (
const auto *CI = CID->getClassInterface()) {
421 ClassName = CI->getName();
422 if (includeCategoryNamespace) {
423 CategoryName = CID->getName();
426 }
else if (
const auto *CD =
428 ClassName = CD->getName();
430 llvm_unreachable(
"Unexpected ObjC method decl context");
432 std::string MethodName;
433 llvm::raw_string_ostream MethodNameOS(MethodName);
436 ClassName, CategoryName, MethodName);
440 raw_ostream &Out)
const {
442 llvm::raw_svector_ostream OS(Name);
446 Out << OS.str().size() << OS.str();
450 std::unique_ptr<MangleContext> MC;
455 : MC(Ctx.createMangleContext()),
456 DL(Ctx.getTargetInfo().getDataLayoutString()) {}
461 llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
462 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
463 if (FD->isDependentContext())
465 if (writeFuncOrVarName(FD, FrontendBufOS))
467 }
else if (
auto *VD = dyn_cast<VarDecl>(D)) {
468 if (writeFuncOrVarName(VD, FrontendBufOS))
470 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
471 MC->mangleObjCMethodName(MD, OS,
false,
474 }
else if (
auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
475 writeObjCClassName(ID, FrontendBufOS);
481 llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
488 llvm::raw_string_ostream OS(Name);
501 if (Context.getLangOpts().ObjCRuntime.isGNUFamily())
502 return Kind ==
ObjCMetaclass ?
"_OBJC_METACLASS_" :
"_OBJC_CLASS_";
503 return Kind ==
ObjCMetaclass ?
"OBJC_METACLASS_$_" :
"OBJC_CLASS_$_";
508 if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
509 ClassName = OID->getObjCRuntimeNameAsString();
510 else if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
511 ClassName = OID->getObjCRuntimeNameAsString();
513 if (ClassName.empty())
516 auto Mangle = [&](
ObjCKind Kind, StringRef ClassName) -> std::string {
519 llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
520 return std::string(Mangled);
530 if (
const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
541 std::vector<std::string> Manglings;
544 auto DefaultCC =
C.getDefaultCallingConvention(
false,
547 return CC == DefaultCC;
550 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
551 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Base));
554 if (!CD->getParent()->isAbstract())
555 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Complete));
558 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
561 }
else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
562 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Base));
564 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Complete));
566 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Deleting));
568 }
else if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
569 Manglings.emplace_back(
getName(ND));
570 if (MD->isVirtual()) {
572 for (
const auto &
T : *TIV) {
573 std::string ThunkName;
574 std::string ContextualizedName =
575 getMangledThunk(MD,
T,
false);
577 ThunkName = getMangledThunk(MD,
T,
true);
579 ThunkName = ContextualizedName;
580 Manglings.emplace_back(ThunkName);
590 bool writeFuncOrVarName(
const NamedDecl *D, raw_ostream &OS) {
591 if (MC->shouldMangleDeclName(D)) {
593 if (
const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
595 else if (
const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
597 else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
601 MC->mangleName(GD, OS);
612 void writeObjCClassName(
const ObjCInterfaceDecl *D, raw_ostream &OS) {
617 std::string getMangledStructor(
const NamedDecl *ND,
unsigned StructorType) {
618 std::string FrontendBuf;
619 llvm::raw_string_ostream FOS(FrontendBuf);
622 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
623 GD = GlobalDecl(CD,
static_cast<CXXCtorType>(StructorType));
624 else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
625 GD = GlobalDecl(DD,
static_cast<CXXDtorType>(StructorType));
626 MC->mangleName(GD, FOS);
628 std::string BackendBuf;
629 llvm::raw_string_ostream BOS(BackendBuf);
631 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);
636 std::string getMangledThunk(
const CXXMethodDecl *MD,
const ThunkInfo &
T,
637 bool ElideOverrideInfo) {
638 std::string FrontendBuf;
639 llvm::raw_string_ostream FOS(FrontendBuf);
641 MC->mangleThunk(MD,
T, ElideOverrideInfo, FOS);
643 std::string BackendBuf;
644 llvm::raw_string_ostream BOS(BackendBuf);
646 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);
658 return Impl->writeName(D, OS);
662 return Impl->getName(D);
666 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 llvm::StringRef g_lldb_func_call_label_prefix
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)
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 mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS, bool includePrefixByte=true, bool includeCategoryNamespace=true) const
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)
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)
void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName)
Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...
uint16_t Part2
...-89ab-...
uint32_t Part1
{01234567-...
uint16_t Part3
...-cdef-...
uint8_t Part4And5[8]
...-0123-456789abcdef}