Skip to content

NFC: Refactor conveniences for filtering out unavailable decls #67785

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 2 commits into from
Aug 8, 2023
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
15 changes: 13 additions & 2 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1236,12 +1236,12 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {

/// Returns true if this declaration should be considered available during
/// SIL/IR lowering. A declaration would not be available during lowering if,
/// for example, it is annotated as unavailable with \c @available and
/// for example, it is annotated as unavailable with `@available` and
/// optimization settings require that it be omitted.
bool isAvailableDuringLowering() const;

/// Returns true if ABI compatibility stubs must be emitted for the given
/// declaration. Decls marked unavailable with \c @available require these
/// declaration. Decls marked unavailable with `@available` require these
/// stubs if the compiler flags have enabled unavailable declaration ABI
/// compatibility mode.
bool requiresUnavailableDeclABICompatibilityStubs() const;
Expand Down Expand Up @@ -1288,6 +1288,17 @@ void *allocateMemoryForDecl(AllocatorTy &allocator, size_t baseSize,
return mem;
}

/// A convenience function object for filtering out decls that are not available
/// during lowering.
template <typename T>
struct AvailableDuringLoweringDeclFilter {
llvm::Optional<T *> operator()(T *decl) const {
if (decl->isAvailableDuringLowering())
return decl;
return llvm::None;
}
};

// A private class for forcing exact field layout.
class alignas(8) _GenericContext {
// Not really public. See GenericContext.
Expand Down
19 changes: 15 additions & 4 deletions include/swift/AST/DeclContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ namespace swift {
class StructDecl;
class AccessorDecl;

template <typename T>
struct AvailableDuringLoweringDeclFilter;

namespace serialization {
using DeclID = llvm::PointerEmbeddedInt<unsigned, 31>;
}
Expand Down Expand Up @@ -865,12 +868,11 @@ class IterableDeclContext {
/// on.
DeclRange getMembers() const;

/// Retrieve the current set of members in this context, without triggering the
/// creation of new members via code synthesis, macro expansion, etc.
/// Retrieve the current set of members in this context, without triggering
/// the creation of new members via code synthesis, macro expansion, etc.
///
/// This operation should only be used in narrow places where any side-effect
/// producing operations have been done earlier. For the most part, this means that
/// it should only be used in the implementation of
/// producing operations have been done earlier.
DeclRange getCurrentMembers() const;

/// Get the members that were syntactically present in the source code,
Expand All @@ -884,6 +886,15 @@ class IterableDeclContext {
/// The resulting list of members will be stable across translation units.
ArrayRef<Decl *> getABIMembers() const;

using DeclsForLowering =
OptionalTransformRange<ArrayRef<Decl *>,
AvailableDuringLoweringDeclFilter<Decl>>;

/// Get all of the members within this context that should be included when
/// lowering to SIL/IR, including any implicitly-synthesized members. The
/// decls returned by \c getABIMembers() are a superset of these decls.
DeclsForLowering getMembersForLowering() const;

/// Get all of the members within this context, including any
/// implicitly-synthesized members.
///
Expand Down
10 changes: 0 additions & 10 deletions include/swift/SIL/SILModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -1079,16 +1079,6 @@ namespace Lowering {
/// Objective-C runtime, i.e., +alloc and -dealloc.
LLVM_LIBRARY_VISIBILITY bool usesObjCAllocator(ClassDecl *theClass);
} // namespace Lowering

/// Apply the given function to each ABI member of \c D skipping the members
/// that should be skipped according to \c shouldSkipLowering()
template <typename F>
void forEachMemberToLower(IterableDeclContext *D, F &&f) {
for (auto *member : D->getABIMembers()) {
if (member->isAvailableDuringLowering())
f(member);
}
}
} // namespace swift

#endif
4 changes: 2 additions & 2 deletions include/swift/SIL/SILVTableVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ template <class T> class SILVTableVisitor {
if (!theClass->hasKnownSwiftImplementation())
return;

forEachMemberToLower(theClass, [&](Decl *member) {
for (Decl *member : theClass->getMembersForLowering()) {
maybeAddMember(member);
});
}
}
};

Expand Down
6 changes: 6 additions & 0 deletions lib/AST/DeclContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,12 @@ ArrayRef<Decl *> IterableDeclContext::getABIMembers() const {
ArrayRef<Decl *>());
}

IterableDeclContext::DeclsForLowering
IterableDeclContext::getMembersForLowering() const {
return DeclsForLowering(getABIMembers(),
AvailableDuringLoweringDeclFilter<Decl>());
}

ArrayRef<Decl *> IterableDeclContext::getAllMembers() const {
ASTContext &ctx = getASTContext();
return evaluateOrDefault(
Expand Down
8 changes: 4 additions & 4 deletions lib/SILGen/SILGenType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1098,9 +1098,9 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
void emitType() {
SGM.emitLazyConformancesForType(theType);

forEachMemberToLower(theType, [&](Decl *member) {
for (Decl *member : theType->getMembersForLowering()) {
visit(member);
});
}

// Build a vtable if this is a class.
if (auto theClass = dyn_cast<ClassDecl>(theType)) {
Expand Down Expand Up @@ -1276,9 +1276,9 @@ class SILGenExtension : public TypeMemberVisitor<SILGenExtension> {
// @_objcImplementation extension, but we don't actually need to do any of
// the stuff that it currently does.

forEachMemberToLower(e, [&](Decl *member) {
for (Decl *member : e->getMembersForLowering()) {
visit(member);
});
}

// If this is a main-interface @_objcImplementation extension and the class
// has a synthesized destructor, emit it now.
Expand Down