Skip to content

TBDGen: Refactor symbol enumeration into SIL and IRGen utilities #61685

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions include/swift/IRGen/IRSymbolVisitor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//===--- IRSymbolVisitor.h - Symbol Visitor for IR --------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_IRGEN_IRSYMBOLVISITOR_H
#define SWIFT_IRGEN_IRSYMBOLVISITOR_H

#include "swift/IRGen/Linking.h"

namespace swift {

class SILSymbolVisitorContext;

namespace irgen {

/// Context for symbol enumeration using `IRSymbolVisitor`.
class IRSymbolVisitorContext {
const UniversalLinkageInfo &LinkInfo;
const SILSymbolVisitorContext &SILCtx;

public:
IRSymbolVisitorContext(const UniversalLinkageInfo &LinkInfo,
const SILSymbolVisitorContext &SILCtx)
: LinkInfo{LinkInfo}, SILCtx{SILCtx} {}

const UniversalLinkageInfo &getLinkInfo() const { return LinkInfo; }
const SILSymbolVisitorContext &getSILCtx() const { return SILCtx; }
};

/// A visitor class which may be used to enumerate the entities representing
/// linker symbols associated with a Swift declaration, file, or module. This
/// class is a refinement of `SILSymbolVisitor` for the IRGen layer. Most of the
/// enumerated linker symbols can be represented as either a `SILDeclRef` or a
/// `LinkEntity`, but a few aren't supported by those abstractions and are
/// handled ad-hoc. Additionally, there are some Obj-C entities (like methods)
/// that don't actually have associated linker symbols but are enumerated for
/// the convenience of clients using this utility for API surface discovery.
class IRSymbolVisitor {
public:
virtual ~IRSymbolVisitor() {}

/// Enumerate the symbols associated with the given decl.
void visit(Decl *D, const IRSymbolVisitorContext &ctx);

/// Enumerate the symbols associated with the given file.
void visitFile(FileUnit *file, const IRSymbolVisitorContext &ctx);

/// Enumerate the symbols associated with the given modules.
void visitModules(llvm::SmallVector<ModuleDecl *, 4> &modules,
const IRSymbolVisitorContext &ctx);

/// Override to prepare for enumeration of the symbols for a specific decl.
virtual void willVisitDecl(Decl *D) {}

/// Override to clean up after enumeration of the symbols for a specific decl.
virtual void didVisitDecl(Decl *D) {}

virtual void addFunction(SILDeclRef declRef) {}
virtual void addFunction(StringRef name, SILDeclRef declRef) {}
virtual void addGlobalVar(VarDecl *VD) {}
virtual void addLinkEntity(LinkEntity entity) {}
virtual void addObjCInterface(ClassDecl *CD) {}
virtual void addObjCMethod(AbstractFunctionDecl *AFD) {}
virtual void addProtocolWitnessThunk(RootProtocolConformance *C,
ValueDecl *requirementDecl) {}
};

} // end namespace irgen
} // end namespace swift

#endif
131 changes: 131 additions & 0 deletions include/swift/SIL/SILSymbolVisitor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
//===--- SILSymbolVisitor.h - Symbol Visitor for SIL ------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SIL_SILSYMBOLVISITOR_H
#define SWIFT_SIL_SILSYMBOLVISITOR_H

#include "swift/AST/Decl.h"
#include "swift/AST/ProtocolAssociations.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/SIL/SILDeclRef.h"

namespace swift {

/// Options dictating which symbols are enumerated by `SILSymbolVisitor`.
struct SILSymbolVisitorOptions {
/// Whether to visit the members of declarations like structs, classes, and
/// protocols.
bool VisitMembers = true;

/// Whether to only visit declarations for which linker directive symbols
/// are needed (e.g. decls with `@_originallyDefinedIn`.
bool LinkerDirectivesOnly = false;

/// Whether to only visit symbols with public linkage.
bool PublicSymbolsOnly = true;

/// Whether LLVM IR Virtual Function Elimination is enabled.
bool VirtualFunctionElimination = false;

/// Whether LLVM IR Witness Method Elimination is enabled.
bool WitnessMethodElimination = false;
};

/// Context for `SILSymbolVisitor` symbol enumeration.
class SILSymbolVisitorContext {
ModuleDecl *Module;
const SILSymbolVisitorOptions Opts;

public:
SILSymbolVisitorContext(ModuleDecl *M, const SILSymbolVisitorOptions Opts)
: Module{M}, Opts{Opts} {
assert(M);
};

ModuleDecl *getModule() const { return Module; }
const SILSymbolVisitorOptions &getOpts() const { return Opts; }
};

/// A visitor class which may be used to enumerate the entities representing
/// linker symbols associated with a Swift declaration, file, or module. Some
/// enumerated linker symbols can be represented as a `SILDeclRef`. The rest are
/// enumerated ad-hoc. Additionally, there a some Obj-C entities (like methods)
/// that don't actually have associated linker symbols but are enumerated for
/// the convenience of clients using this utility for API surface discovery.
class SILSymbolVisitor {
public:
virtual ~SILSymbolVisitor() {}

/// Enumerate the symbols associated with the given decl.
void visitDecl(Decl *D, const SILSymbolVisitorContext &ctx);

/// Enumerate the symbols associated with the given file.
void visitFile(FileUnit *file, const SILSymbolVisitorContext &ctx);

/// Enumerate the symbols associated with the given modules.
void visitModules(llvm::SmallVector<ModuleDecl *, 4> &modules,
const SILSymbolVisitorContext &ctx);

/// Override to prepare for enumeration of the symbols for a specific decl.
virtual void willVisitDecl(Decl *D) {}

/// Override to clean up after enumeration of the symbols for a specific decl.
virtual void didVisitDecl(Decl *D) {}

/// A classification for the dynamic dispatch metadata of a decl.
enum class DynamicKind {
/// May be replaced at runtime (e.g.`dynamic`).
Replaceable,

/// May replace another decl at runtime (e.g. `@_dynamicReplacement(for:)`).
Replacement,
};

virtual void addAssociatedConformanceDescriptor(AssociatedConformance AC) {}
virtual void addAssociatedTypeDescriptor(AssociatedTypeDecl *ATD) {}
virtual void addAsyncFunctionPointer(SILDeclRef declRef) {}
virtual void addBaseConformanceDescriptor(BaseConformance BC) {}
virtual void addClassMetadataBaseOffset(ClassDecl *CD) {}
virtual void addDispatchThunk(SILDeclRef declRef) {}
virtual void addDynamicFunction(AbstractFunctionDecl *AFD,
DynamicKind dynKind) {}
virtual void addEnumCase(EnumElementDecl *EED) {}
virtual void addFieldOffset(VarDecl *VD) {}
virtual void addFunction(SILDeclRef declRef) {}
virtual void addFunction(StringRef name, SILDeclRef declRef) {}
virtual void addGlobalVar(VarDecl *VD) {}
virtual void addMethodDescriptor(SILDeclRef declRef) {}
virtual void addMethodLookupFunction(ClassDecl *CD) {}
virtual void addNominalTypeDescriptor(NominalTypeDecl *NTD) {}
virtual void addObjCClass(ClassDecl *CD) {}
virtual void addObjCInterface(ClassDecl *CD) {}
virtual void addObjCMetaclass(ClassDecl *CD) {}
virtual void addObjCMethod(AbstractFunctionDecl *AFD) {}
virtual void addObjCResilientClassStub(ClassDecl *CD) {}
virtual void addOpaqueTypeDescriptor(OpaqueTypeDecl *OTD) {}
virtual void addOpaqueTypeDescriptorAccessor(OpaqueTypeDecl *OTD,
DynamicKind dynKind) {}
virtual void addPropertyDescriptor(AbstractStorageDecl *ASD) {}
virtual void addProtocolConformanceDescriptor(RootProtocolConformance *C) {}
virtual void addProtocolDescriptor(ProtocolDecl *PD) {}
virtual void addProtocolRequirementsBaseDescriptor(ProtocolDecl *PD) {}
virtual void addProtocolWitnessTable(RootProtocolConformance *C) {}
virtual void addProtocolWitnessThunk(RootProtocolConformance *C,
ValueDecl *requirementDecl) {}
virtual void addSwiftMetaclassStub(ClassDecl *CD) {}
virtual void addTypeMetadataAccessFunction(CanType T) {}
virtual void addTypeMetadataAddress(CanType T) {}
};

} // end namespace swift

#endif
1 change: 1 addition & 0 deletions lib/IRGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ add_swift_host_library(swiftIRGen STATIC
IRGenSILPasses.cpp
IRGenRequests.cpp
IRGenSIL.cpp
IRSymbolVisitor.cpp
Linking.cpp
LoadableByAddress.cpp
LocalTypeData.cpp
Expand Down
Loading