16#include "llvm/ADT/StringRef.h"
17#include "llvm/IR/DataLayout.h"
18#include "llvm/IR/Mangler.h"
24enum class CXXLinkage {
43 bool HasInlineAttribute =
false;
50 for (
const auto *RD : D->
redecls()) {
53 HasInlineAttribute =
true;
54 if (!(NoCXXAttr || RD->hasAttr<GNUInlineAttr>()))
56 if (RD->doesThisDeclarationHaveABody() &&
57 RD->isInlineDefinitionExternallyVisible())
61 if (!HasInlineAttribute)
70 Result |= SymbolFlags::WeakDefined;
72 Result |= SymbolFlags::ThreadLocalValue;
85std::string InstallAPIVisitor::getMangledName(
const NamedDecl *D)
const {
87 if (MC->shouldMangleDeclName(D)) {
88 raw_svector_ostream NStream(Name);
89 MC->mangleName(D, NStream);
93 return getBackendMangledName(Name);
96std::string InstallAPIVisitor::getBackendMangledName(Twine Name)
const {
98 Mangler::getNameWithPrefix(FinalName, Name, DataLayout(Layout));
99 return std::string(FinalName);
102std::optional<HeaderType>
103InstallAPIVisitor::getAccessForDecl(
const NamedDecl *D)
const {
104 SourceLocation Loc = D->getLocation();
110 auto FileLoc = SrcMgr.getFileLoc(Loc);
111 FileID
ID = SrcMgr.getFileID(FileLoc);
115 const FileEntry *FE = SrcMgr.getFileEntryForID(ID);
119 auto Header = Ctx.findAndRecordFile(FE, PP);
120 if (!Header.has_value())
134 if (D->
hasAttr<ObjCExceptionAttr>())
139void InstallAPIVisitor::recordObjCInstanceVariables(
141 const llvm::iterator_range<
148 Linkage = RecordLinkage::Unknown;
150 else if (ContainerLinkage != RecordLinkage::Unknown)
152 for (
const auto *IV : Ivars) {
153 auto Access = getAccessForDecl(IV);
156 StringRef Name = IV->getName();
158 auto AC = IV->getCanonicalAccessControl();
161 Ctx.
Verifier->verify(ObjCIVR, FA, SuperClass);
171 auto Access = getAccessForDecl(D);
177 isExported(D) ? RecordLinkage::Exported : RecordLinkage::Internal;
179 const bool IsEHType =
184 Ctx.Slice->addObjCInterface(Name,
Linkage, Avail, D, *Access, IsEHType);
185 Ctx.Verifier->verify(
Class, FA);
188 StringRef SuperClassName;
190 SuperClassName = SuperClass->getObjCRuntimeNameAsString();
198 StringRef CategoryName = D->
getName();
200 auto Access = getAccessForDecl(D);
205 const StringRef InterfaceName = InterfaceD->
getName();
208 Ctx.Slice->addObjCCategory(InterfaceName, CategoryName, Avail, D, *Access)
210 recordObjCInstanceVariables(D->
getASTContext(), CategoryRecord, InterfaceName,
234 auto Access = getAccessForDecl(D);
239 isExported(D) ? RecordLinkage::Exported : RecordLinkage::Internal;
240 const bool WeakDef = D->
hasAttr<WeakAttr>();
243 auto [GR, FA] = Ctx.Slice->addGlobal(getMangledName(D),
Linkage,
244 GlobalRecord::Kind::Variable, Avail, D,
245 *Access,
getFlags(WeakDef, ThreadLocal));
246 Ctx.Verifier->verify(GR, FA);
253 if (M->getParent()->getDescribedClassTemplate() !=
nullptr)
275 if (!TempInfo->isExplicitInstantiationOrSpecialization())
284 auto Access = getAccessForDecl(D);
287 auto Name = getMangledName(D);
294 ? RecordLinkage::Internal
295 : RecordLinkage::Exported;
297 Ctx.Slice->addGlobal(Name,
Linkage, GlobalRecord::Kind::Function, Avail,
298 D, *Access,
getFlags(WeakDef), Inlined);
299 Ctx.Verifier->verify(GR, FA);
325 "Unexpected TemplateSpecializationKind for key function");
344 llvm_unreachable(
"Invalid TemplateSpecializationKind!");
351 return CXXLinkage::PrivateLinkage;
362 return CXXLinkage::LinkOnceODRLinkage;
363 return CXXLinkage::ExternalLinkage;
365 llvm_unreachable(
"No external vtable for implicit instantiations");
367 return CXXLinkage::WeakODRLinkage;
370 "Unexpected TemplateSpecializationKind for key function");
378 return CXXLinkage::LinkOnceODRLinkage;
381 return CXXLinkage::WeakODRLinkage;
384 llvm_unreachable(
"Invalid TemplateSpecializationKind!");
424InstallAPIVisitor::getMangledCXXRTTIName(
const CXXRecordDecl *D)
const {
426 raw_svector_ostream NameStream(Name);
427 MC->mangleCXXRTTIName(MC->getASTContext().getCanonicalTagType(D), NameStream);
429 return getBackendMangledName(Name);
432std::string InstallAPIVisitor::getMangledCXXRTTI(
const CXXRecordDecl *D)
const {
434 raw_svector_ostream NameStream(Name);
435 MC->mangleCXXRTTI(MC->getASTContext().getCanonicalTagType(D), NameStream);
437 return getBackendMangledName(Name);
441InstallAPIVisitor::getMangledCXXVTableName(
const CXXRecordDecl *D)
const {
442 SmallString<256> Name;
443 raw_svector_ostream NameStream(Name);
444 MC->mangleCXXVTable(D, NameStream);
446 return getBackendMangledName(Name);
449std::string InstallAPIVisitor::getMangledCXXThunk(
450 const GlobalDecl &D,
const ThunkInfo &Thunk,
bool ElideOverrideInfo)
const {
451 SmallString<256> Name;
452 raw_svector_ostream NameStream(Name);
454 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(
Method))
455 MC->mangleCXXDtorThunk(Dtor, D.getDtorType(), Thunk, ElideOverrideInfo,
458 MC->mangleThunk(
Method, Thunk, ElideOverrideInfo, NameStream);
460 return getBackendMangledName(Name);
463std::string InstallAPIVisitor::getMangledCtorDtor(
const CXXMethodDecl *D,
465 SmallString<256> Name;
466 raw_svector_ostream NameStream(Name);
468 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(D))
474 MC->mangleName(GD, NameStream);
475 return getBackendMangledName(Name);
478void InstallAPIVisitor::emitVTableSymbols(
const CXXRecordDecl *D,
479 const AvailabilityInfo &Avail,
481 bool EmittedVTable) {
483 EmittedVTable =
true;
485 if (VTableLinkage == CXXLinkage::ExternalLinkage ||
486 VTableLinkage == CXXLinkage::WeakODRLinkage) {
487 const std::string Name = getMangledCXXVTableName(D);
488 const bool WeakDef = VTableLinkage == CXXLinkage::WeakODRLinkage;
489 auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported,
490 GlobalRecord::Kind::Variable, Avail,
492 Ctx.Verifier->verify(GR, FA);
493 if (!D->getDescribedClassTemplate() && !D->isInvalidDecl()) {
494 VTableContextBase *VTable = D->getASTContext().getVTableContext();
495 auto AddThunk = [&](GlobalDecl GD) {
497 VTable->getThunkInfo(GD);
501 for (
const auto &Thunk : *Thunks) {
502 const std::string Name =
503 getMangledCXXThunk(GD, Thunk,
true);
504 auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported,
505 GlobalRecord::Kind::Function,
506 Avail, GD.getDecl(), Access);
507 Ctx.Verifier->verify(GR, FA);
511 for (
const auto *
Method : D->methods()) {
515 if (
auto Dtor = dyn_cast<CXXDestructorDecl>(
Method)) {
517 if (Dtor->isDefaulted())
532 std::string Name = getMangledCXXRTTI(D);
534 Ctx.Slice->addGlobal(Name, RecordLinkage::Exported,
535 GlobalRecord::Kind::Variable, Avail, D, Access);
536 Ctx.Verifier->verify(GR, FA);
538 Name = getMangledCXXRTTIName(D);
539 auto [NamedGR, NamedFA] =
540 Ctx.Slice->addGlobal(Name, RecordLinkage::Exported,
541 GlobalRecord::Kind::Variable, Avail, D, Access);
542 Ctx.Verifier->verify(NamedGR, NamedFA);
545 for (
const auto &It : D->bases()) {
547 It.getType()->castAs<RecordType>()->getOriginalDecl());
548 const auto BaseAccess = getAccessForDecl(Base);
552 emitVTableSymbols(Base, BaseAvail, *BaseAccess,
true);
568 auto Access = getAccessForDecl(D);
575 emitVTableSymbols(D, Avail, *Access);
578 bool KeepInlineAsWeak =
false;
579 if (
auto *Templ = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
580 ClassSK = Templ->getTemplateSpecializationKind();
582 KeepInlineAsWeak =
true;
586 for (
const auto *M : D->
methods()) {
589 bool WeakDef =
false;
591 if (!KeepInlineAsWeak)
600 switch (M->getTemplateSpecializationKind()) {
615 if (!M->isUserProvided())
622 const auto Access = getAccessForDecl(M);
627 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(M)) {
629 if (Ctor->isDefaulted())
632 std::string Name = getMangledCtorDtor(M,
Ctor_Base);
633 auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported,
634 GlobalRecord::Kind::Function, Avail,
636 Ctx.Verifier->verify(GR, FA);
640 auto [GR, FA] = Ctx.Slice->addGlobal(
641 Name, RecordLinkage::Exported, GlobalRecord::Kind::Function, Avail,
643 Ctx.Verifier->verify(GR, FA);
649 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(M)) {
651 if (Dtor->isDefaulted())
654 std::string Name = getMangledCtorDtor(M,
Dtor_Base);
655 auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported,
656 GlobalRecord::Kind::Function, Avail,
658 Ctx.Verifier->verify(GR, FA);
661 auto [CompleteGR, CompleteFA] = Ctx.Slice->addGlobal(
662 Name, RecordLinkage::Exported, GlobalRecord::Kind::Function, Avail, D,
664 Ctx.Verifier->verify(CompleteGR, CompleteFA);
666 if (Dtor->isVirtual()) {
668 auto [VirtualGR, VirtualFA] = Ctx.Slice->addGlobal(
669 Name, RecordLinkage::Exported, GlobalRecord::Kind::Function, Avail,
671 Ctx.Verifier->verify(VirtualGR, VirtualFA);
680 if (M->isPureVirtual())
683 std::string Name = getMangledName(M);
684 auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported,
685 GlobalRecord::Kind::Function, Avail, M,
687 Ctx.Verifier->verify(GR, FA);
690 if (
auto *Templ = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
691 if (!Templ->isExplicitInstantiationOrSpecialization())
696 using var_range = iterator_range<var_iter>;
697 for (
const auto *Var : var_range(D->
decls())) {
704 if (Var->isStaticDataMember() && Var->hasInit())
711 const std::string Name = getMangledName(Var);
712 const auto Access = getAccessForDecl(Var);
716 const bool WeakDef = Var->hasAttr<WeakAttr>() || KeepInlineAsWeak;
718 auto [GR, FA] = Ctx.Slice->addGlobal(Name, RecordLinkage::Exported,
719 GlobalRecord::Kind::Variable, Avail, D,
721 Ctx.Verifier->verify(GR, FA);
llvm::MachO::SymbolFlags SymbolFlags
llvm::MachO::ObjCCategoryRecord ObjCCategoryRecord
llvm::MachO::RecordLinkage RecordLinkage
llvm::MachO::Record Record
llvm::MachO::ObjCContainerRecord ObjCContainerRecord
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var)
DynTypedNodeList getParents(const NodeT &Node)
Forwards to get node parents from the ParentMapContext.
const CXXMethodDecl * getCurrentKeyFunction(const CXXRecordDecl *RD)
Get our current best idea for the key function of the given record decl, or nullptr if there isn't on...
const LangOptions & getLangOpts() const
DiagnosticsEngine & getDiagnostics() const
const TargetInfo & getTargetInfo() const
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
method_range methods() const
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
ASTContext & getASTContext() const LLVM_READONLY
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
DeclContext * getDeclContext()
bool hasErrorOccurred() const
A dynamically typed AST node container.
Represents a function declaration or definition.
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
@ TK_MemberSpecialization
@ TK_DependentNonTemplate
@ TK_FunctionTemplateSpecialization
@ TK_DependentFunctionTemplateSpecialization
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template instantiation this function represents.
clang::ObjCRuntime ObjCRuntime
This represents a decl that may have a name.
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Visibility getVisibility() const
Determines the visibility of this entity.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
bool isExternallyVisible() const
ObjCCategoryDecl - Represents a category declaration.
ObjCInterfaceDecl * getClassInterface()
Represents an ObjC class declaration.
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
ObjCInterfaceDecl * getSuperClass() const
The basic abstraction for the target Objective-C runtime.
bool isFragile() const
The inverse of isNonFragile(): does this runtime follow the set of implied behaviors for a "fragile" ...
bool TraverseDecl(Decl *D)
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
SmallVector< ThunkInfo, 1 > ThunkInfoVectorTy
Represents a variable declaration or definition.
TLSKind getTLSKind() const
@ TLS_None
Not a TLS variable.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
void HandleTranslationUnit(ASTContext &ASTCtx) override
HandleTranslationUnit - This method is called when the ASTs for entire translation unit have been par...
bool VisitCXXRecordDecl(const CXXRecordDecl *D)
Collect global c++ declarations.
bool VisitFunctionDecl(const FunctionDecl *D)
Collect global functions.
bool VisitVarDecl(const VarDecl *D)
Collect global variables.
bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D)
Collect Objective-C Category/Extension declarations.
bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D)
Collect Objective-C Interface declarations.
Defines the Linkage enumeration and various utility functions.
The DirectoryScanner for collecting library files on the file system.
static bool isInlined(const FunctionDecl *D)
static CXXLinkage getVTableLinkage(const CXXRecordDecl *D)
@ Unknown
Unset or unknown type.
static bool hasObjCExceptionAttribute(const ObjCInterfaceDecl *D)
Check if the interface itself or any of its super classes have an exception attribute.
static bool hasVTable(const CXXRecordDecl *D)
static bool isRTTIWeakDef(const CXXRecordDecl *D)
static bool hasRTTI(const CXXRecordDecl *D)
static SymbolFlags getFlags(bool WeakDef, bool ThreadLocal=false)
static bool isExported(const NamedDecl *D)
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ Result
The result type of a method or function.
@ ExplicitInstantiation
We are parsing an explicit instantiation.
CXXDtorType
C++ destructor types.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
@ Type
The name was classified as a type.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
bool isExternallyVisible(Linkage L)
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
Diagnostic wrappers for TextAPI types for error reporting.
Storage of availability attributes for a declaration.
static AvailabilityInfo createFromDecl(const Decl *Decl)
std::shared_ptr< FrontendRecordsSlice > Slice
Active TargetSlice for symbol record collection.
std::unique_ptr< DylibVerifier > Verifier
Verifier when binary dylib is passed as input.