16#include "llvm/ADT/SmallString.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/IR/DataLayout.h"
19#include "llvm/IR/Mangler.h"
25enum class CXXLinkage {
44 bool HasInlineAttribute =
false;
51 for (
const auto *RD : D->
redecls()) {
54 HasInlineAttribute =
true;
55 if (!(NoCXXAttr || RD->hasAttr<GNUInlineAttr>()))
57 if (RD->doesThisDeclarationHaveABody() &&
58 RD->isInlineDefinitionExternallyVisible())
62 if (!HasInlineAttribute)
71 Result |= SymbolFlags::WeakDefined;
73 Result |= SymbolFlags::ThreadLocalValue;
86std::string InstallAPIVisitor::getMangledName(
const NamedDecl *D)
const {
88 if (MC->shouldMangleDeclName(D)) {
89 raw_svector_ostream NStream(Name);
90 MC->mangleName(D, NStream);
94 return getBackendMangledName(Name);
97std::string InstallAPIVisitor::getBackendMangledName(Twine Name)
const {
99 Mangler::getNameWithPrefix(FinalName, Name, DataLayout(Layout));
100 return std::string(FinalName);
103std::optional<HeaderType>
104InstallAPIVisitor::getAccessForDecl(
const NamedDecl *D)
const {
105 SourceLocation Loc = D->getLocation();
121 if (!Header.has_value())
135 if (D->
hasAttr<ObjCExceptionAttr>())
140void InstallAPIVisitor::recordObjCInstanceVariables(
142 const llvm::iterator_range<
149 Linkage = RecordLinkage::Unknown;
151 else if (ContainerLinkage != RecordLinkage::Unknown)
153 for (
const auto *IV : Ivars) {
154 auto Access = getAccessForDecl(IV);
157 StringRef Name = IV->getName();
159 auto AC = IV->getCanonicalAccessControl();
162 Ctx.
Verifier->verify(ObjCIVR, FA, SuperClass);
172 auto Access = getAccessForDecl(D);
178 isExported(D) ? RecordLinkage::Exported : RecordLinkage::Internal;
180 const bool IsEHType =
185 Ctx.
Slice->addObjCInterface(Name,
Linkage, Avail, D, *Access, IsEHType);
189 StringRef SuperClassName;
191 SuperClassName = SuperClass->getObjCRuntimeNameAsString();
199 StringRef CategoryName = D->
getName();
201 auto Access = getAccessForDecl(D);
206 const StringRef InterfaceName = InterfaceD->
getName();
209 Ctx.
Slice->addObjCCategory(InterfaceName, CategoryName, Avail, D, *Access)
211 recordObjCInstanceVariables(D->
getASTContext(), CategoryRecord, InterfaceName,
218 if (isa<ParmVarDecl>(D))
235 auto Access = getAccessForDecl(D);
240 isExported(D) ? RecordLinkage::Exported : RecordLinkage::Internal;
241 const bool WeakDef = D->
hasAttr<WeakAttr>();
244 auto [GR, FA] = Ctx.
Slice->addGlobal(getMangledName(D),
Linkage,
245 GlobalRecord::Kind::Variable, Avail, D,
246 *Access,
getFlags(WeakDef, ThreadLocal));
254 if (M->getParent()->getDescribedClassTemplate() !=
nullptr)
264 if (isa<CXXConstructorDecl>(M) || isa<CXXDestructorDecl>(M))
276 if (!TempInfo->isExplicitInstantiationOrSpecialization())
285 auto Access = getAccessForDecl(D);
288 auto Name = getMangledName(D);
292 const bool WeakDef = ExplicitInstantiation || D->
hasAttr<WeakAttr>();
295 ? RecordLinkage::Internal
296 : RecordLinkage::Exported;
298 Ctx.
Slice->addGlobal(Name,
Linkage, GlobalRecord::Kind::Function, Avail,
299 D, *Access,
getFlags(WeakDef), Inlined);
326 "Unexpected TemplateSpecializationKind for key function");
345 llvm_unreachable(
"Invalid TemplateSpecializationKind!");
352 return CXXLinkage::PrivateLinkage;
363 return CXXLinkage::LinkOnceODRLinkage;
364 return CXXLinkage::ExternalLinkage;
366 llvm_unreachable(
"No external vtable for implicit instantiations");
368 return CXXLinkage::WeakODRLinkage;
371 "Unexpected TemplateSpecializationKind for key function");
379 return CXXLinkage::LinkOnceODRLinkage;
382 return CXXLinkage::WeakODRLinkage;
385 llvm_unreachable(
"Invalid TemplateSpecializationKind!");
425InstallAPIVisitor::getMangledCXXRTTIName(
const CXXRecordDecl *D)
const {
427 raw_svector_ostream NameStream(Name);
430 return getBackendMangledName(Name);
433std::string InstallAPIVisitor::getMangledCXXRTTI(
const CXXRecordDecl *D)
const {
435 raw_svector_ostream NameStream(Name);
436 MC->mangleCXXRTTI(QualType(D->getTypeForDecl(), 0), NameStream);
438 return getBackendMangledName(Name);
442InstallAPIVisitor::getMangledCXXVTableName(
const CXXRecordDecl *D)
const {
444 raw_svector_ostream NameStream(Name);
445 MC->mangleCXXVTable(D, NameStream);
447 return getBackendMangledName(Name);
451InstallAPIVisitor::getMangledCXXThunk(
const GlobalDecl &D,
452 const ThunkInfo &Thunk)
const {
454 raw_svector_ostream NameStream(Name);
455 const auto *Method = cast<CXXMethodDecl>(D.getDecl());
456 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(Method))
457 MC->mangleCXXDtorThunk(Dtor, D.getDtorType(), Thunk.This, NameStream);
459 MC->mangleThunk(Method, Thunk, NameStream);
461 return getBackendMangledName(Name);
464std::string InstallAPIVisitor::getMangledCtorDtor(
const CXXMethodDecl *D,
467 raw_svector_ostream NameStream(Name);
469 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(D))
472 const auto *Dtor = cast<CXXDestructorDecl>(D);
475 MC->mangleName(GD, NameStream);
476 return getBackendMangledName(Name);
479void InstallAPIVisitor::emitVTableSymbols(
const CXXRecordDecl *D,
480 const AvailabilityInfo &Avail,
482 bool EmittedVTable) {
484 EmittedVTable =
true;
486 if (VTableLinkage == CXXLinkage::ExternalLinkage ||
487 VTableLinkage == CXXLinkage::WeakODRLinkage) {
488 const std::string Name = getMangledCXXVTableName(D);
489 const bool WeakDef = VTableLinkage == CXXLinkage::WeakODRLinkage;
490 auto [GR, FA] = Ctx.
Slice->addGlobal(Name, RecordLinkage::Exported,
491 GlobalRecord::Kind::Variable, Avail,
494 if (!D->getDescribedClassTemplate() && !D->isInvalidDecl()) {
495 VTableContextBase *VTable = D->getASTContext().getVTableContext();
496 auto AddThunk = [&](GlobalDecl GD) {
498 VTable->getThunkInfo(GD);
502 for (
const auto &Thunk : *Thunks) {
503 const std::string Name = getMangledCXXThunk(GD, Thunk);
504 auto [GR, FA] = Ctx.
Slice->addGlobal(Name, RecordLinkage::Exported,
505 GlobalRecord::Kind::Function,
506 Avail, GD.getDecl(), Access);
511 for (
const auto *Method : D->methods()) {
512 if (isa<CXXConstructorDecl>(Method) || !Method->isVirtual())
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);
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()) {
546 const CXXRecordDecl *
Base =
547 cast<CXXRecordDecl>(It.getType()->castAs<RecordType>()->getDecl());
548 const auto BaseAccess = getAccessForDecl(
Base);
552 emitVTableSymbols(
Base, BaseAvail, *BaseAccess,
true);
565 if (isa<ClassTemplatePartialSpecializationDecl>(D))
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,
640 auto [GR, FA] = Ctx.
Slice->addGlobal(
641 Name, RecordLinkage::Exported, GlobalRecord::Kind::Function, Avail,
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,
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,
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,
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.
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
bool isFragile() const
The inverse of isNonFragile(): does this runtime follow the set of implied behaviors for a "fragile" ...
A (possibly-)qualified type.
bool TraverseDecl(Decl *D)
Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument's dynamic ty...
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getFileLoc(SourceLocation Loc) const
Given Loc, if it is a macro location return the expansion location or the spelling location,...
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
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.
const Type * getTypeForDecl() const
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.
Representations of a library's headers for InstallAPI.
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.
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.
CXXDtorType
C++ destructor types.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
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,...
@ 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::optional< HeaderType > findAndRecordFile(const FileEntry *FE, const Preprocessor &PP)
Record visited files during frontend actions to determine whether to include their declarations for T...
std::shared_ptr< FrontendRecordsSlice > Slice
Active TargetSlice for symbol record collection.
std::unique_ptr< DylibVerifier > Verifier
Verifier when binary dylib is passed as input.