Skip to content

Commit c4cacd1

Browse files
authored
Merge pull request #62426 from xedin/runtime-discoverable-attrs
[Sema/SILGen/IRGen] Implement runtime discoverable attributes (under flag)
2 parents 3d36113 + 7a593ce commit c4cacd1

File tree

95 files changed

+1919
-118
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+1919
-118
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ Globals
149149
#endif
150150
global ::= protocol-conformance 'Hc' // protocol conformance runtime record
151151
global ::= global 'HF' // accessible function runtime record
152+
global ::= global 'Ha' // runtime discoverable attribute record
152153

153154
global ::= nominal-type 'Mo' // class metadata immediate member base offset
154155

@@ -346,6 +347,7 @@ Entities
346347
entity-spec ::= type 'fU' INDEX // explicit anonymous closure expression
347348
entity-spec ::= type 'fu' INDEX // implicit anonymous closure
348349
entity-spec ::= 'fA' INDEX // default argument N+1 generator
350+
entity-spec ::= 'fa' // runtime discoverable attribute generator
349351
entity-spec ::= 'fi' // non-local variable initializer
350352
entity-spec ::= 'fP' // property wrapper backing initializer
351353
entity-spec ::= 'fW' // property wrapper init from projected value

include/swift/ABI/Metadata.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4736,6 +4736,45 @@ struct TargetAccessibleFunctionRecord final {
47364736

47374737
using AccessibleFunctionRecord = TargetAccessibleFunctionRecord<InProcess>;
47384738

4739+
/// A single entry in an runtine discoverable attribute record
4740+
/// that relates a type attribute is attached to a generator function.
4741+
template <typename Runtime>
4742+
struct TargetRuntimeDiscoverableAttributeEntry {
4743+
ConstTargetMetadataPointer<Runtime, TargetMetadata> Type;
4744+
RelativeDirectPointer<TargetAccessibleFunctionRecord<Runtime>> Generator;
4745+
};
4746+
4747+
/// A record that relates a runtime discoverable attribute to all of the
4748+
/// types (i.e. a nominal type, method, property etc.) it's attached to.
4749+
template <typename Runtime>
4750+
class RuntimeDiscoverableAttributeRecord
4751+
: private swift::ABI::TrailingObjects<
4752+
RuntimeDiscoverableAttributeRecord<Runtime>,
4753+
TargetRuntimeDiscoverableAttributeEntry<Runtime>> {
4754+
using TrailingObjects = swift::ABI::TrailingObjects<
4755+
RuntimeDiscoverableAttributeRecord<Runtime>,
4756+
ConstTargetMetadataPointer<Runtime, TargetMetadata>>;
4757+
friend TrailingObjects;
4758+
4759+
uint32_t flags;
4760+
4761+
/// The nominal type that describes the attribute.
4762+
TargetSignedContextPointer<Runtime, TargetTypeContextDescriptor> Attribute;
4763+
4764+
/// The number of types this attribute is associated with.
4765+
uint32_t numEntries;
4766+
4767+
public:
4768+
uint32_t getFlags() { return flags; }
4769+
4770+
llvm::ArrayRef<TargetRuntimeDiscoverableAttributeEntry<Runtime>>
4771+
getEntries() const {
4772+
return {this->template getTrailingObjects<
4773+
TargetRuntimeDiscoverableAttributeEntry<Runtime>>(),
4774+
numEntries};
4775+
}
4776+
};
4777+
47394778
} // end namespace swift
47404779

47414780
#pragma clang diagnostic pop

include/swift/AST/ASTMangler.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ class ASTMangler : public Mangler {
158158
BackDeploymentThunk,
159159
BackDeploymentFallback,
160160
HasSymbolQuery,
161+
RuntimeDiscoverableAttributeRecord,
161162
};
162163

163164
/// lldb overrides the defaulted argument to 'true'.
@@ -360,6 +361,10 @@ class ASTMangler : public Mangler {
360361

361362
std::string mangleHasSymbolQuery(const ValueDecl *decl);
362363

364+
std::string
365+
mangleRuntimeAttributeGeneratorEntity(const ValueDecl *decl, CustomAttr *attr,
366+
SymbolKind SKind = SymbolKind::Default);
367+
363368
enum SpecialContext {
364369
ObjCContext,
365370
ClangImporterContext,
@@ -584,6 +589,9 @@ class ASTMangler : public Mangler {
584589

585590
void appendConstrainedExistential(Type base, GenericSignature sig,
586591
const ValueDecl *forDecl);
592+
593+
void appendRuntimeAttributeGeneratorEntity(const ValueDecl *decl,
594+
CustomAttr *attr);
587595
};
588596

589597
} // end namespace Mangle

include/swift/AST/Decl.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2794,6 +2794,22 @@ class ValueDecl : public Decl {
27942794
/// 'func foo(Int) -> () -> Self?'.
27952795
GenericParameterReferenceInfo findExistentialSelfReferences(
27962796
Type baseTy, bool treatNonResultCovariantSelfAsInvariant) const;
2797+
2798+
/// Retrieve runtime discoverable attributes (if any) associated
2799+
/// with this declaration.
2800+
ArrayRef<CustomAttr *> getRuntimeDiscoverableAttrs() const;
2801+
/// Retrieve a nominal type declaration backing given runtime discoverable
2802+
/// attribute.
2803+
///
2804+
/// FIXME: This should be a more general facility but its unclear where
2805+
/// to place it for maximum impact.
2806+
NominalTypeDecl *getRuntimeDiscoverableAttrTypeDecl(CustomAttr *attr) const;
2807+
2808+
/// Given a runtime discoverable attribute, return a generator
2809+
/// which could be used to instantiate it for this declaration
2810+
/// together with its result type.
2811+
std::pair<BraceStmt *, Type>
2812+
getRuntimeDiscoverableAttributeGenerator(CustomAttr *) const;
27972813
};
27982814

27992815
/// This is a common base class for declarations which declare a type.

include/swift/AST/DiagnosticsSema.def

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6803,6 +6803,28 @@ ERROR(moveonly_cannot_conform_to_protocol_with_name, none,
68036803
ERROR(runtime_discoverable_attrs_are_experimental,none,
68046804
"runtime discoverable attributes are an experimental feature", ())
68056805

6806+
ERROR(invalid_decl_for_runtime_discoverable_attr,none,
6807+
"@%0 can only be applied to non-generic types, methods, "
6808+
"instance properties, and global functions", (StringRef))
6809+
6810+
ERROR(duplicate_runtime_discoverable_attr,none,
6811+
"duplicate runtime discoverable attribute", ())
6812+
6813+
ERROR(runtime_attribute_requires_init,none,
6814+
"runtime attribute type %0 does not contain a required initializer"
6815+
" - init(attachedTo:)",
6816+
(DeclName))
6817+
6818+
ERROR(runtime_attribute_type_failable_init,none,
6819+
"runtime attribute type initializer %0 cannot be failable", (DeclName))
6820+
6821+
ERROR(runtime_attribute_type_requirement_not_accessible,none,
6822+
"%select{private|fileprivate|internal|public|open}0 %1 %2 cannot have "
6823+
"more restrictive access than its enclosing runtime attribute type %3 "
6824+
"(which is %select{private|fileprivate|internal|public|open}4)",
6825+
(AccessLevel, DescriptiveDeclKind, DeclName, Type, AccessLevel))
6826+
6827+
68066828
#define UNDEFINE_DIAGNOSTIC_MACROS
68076829
#include "DefineDiagnosticMacros.h"
68086830

include/swift/AST/Initializer.h

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ enum class InitializerKind : uint8_t {
3636

3737
/// A property wrapper initialization expression.
3838
PropertyWrapper,
39+
40+
/// A runtime discoverable attribute initialization expression.
41+
RuntimeAttribute,
3942
};
4043

4144
/// An Initializer is a kind of DeclContext used for expressions that
@@ -232,7 +235,36 @@ class PropertyWrapperInitializer : public Initializer {
232235
return I->getInitializerKind() == InitializerKind::PropertyWrapper;
233236
}
234237
};
235-
238+
239+
/// A runtime discoverable attribute initialization expression context.
240+
///
241+
/// The parent context is context of the file/module this generator is
242+
/// synthesized in.
243+
class RuntimeAttributeInitializer : public Initializer {
244+
CustomAttr *Attr;
245+
ValueDecl *AttachedTo;
246+
247+
public:
248+
explicit RuntimeAttributeInitializer(CustomAttr *attr, ValueDecl *attachedTo)
249+
: Initializer(InitializerKind::RuntimeAttribute,
250+
attachedTo->getDeclContext()->getModuleScopeContext()),
251+
Attr(attr), AttachedTo(attachedTo) {}
252+
253+
CustomAttr *getAttr() const { return Attr; }
254+
255+
ValueDecl *getAttachedToDecl() const { return AttachedTo; }
256+
257+
static bool classof(const DeclContext *DC) {
258+
if (auto init = dyn_cast<Initializer>(DC))
259+
return classof(init);
260+
return false;
261+
}
262+
263+
static bool classof(const Initializer *I) {
264+
return I->getInitializerKind() == InitializerKind::RuntimeAttribute;
265+
}
266+
};
267+
236268
} // end namespace swift
237269

238270
#endif

include/swift/AST/KnownIdentifiers.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ IDENTIFIER(unsafe)
333333
// The singleton instance of TupleTypeDecl in the Builtin module
334334
IDENTIFIER(TheTupleType)
335335

336+
// Runtime attributes
337+
IDENTIFIER(attachedTo)
338+
336339
#undef IDENTIFIER
337340
#undef IDENTIFIER_
338341
#undef IDENTIFIER_WITH_NAME

include/swift/AST/SourceFile.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ class SourceFile final : public FileUnit {
150150
/// been validated.
151151
llvm::SetVector<ValueDecl *> UnvalidatedDeclsWithOpaqueReturnTypes;
152152

153+
/// The set of declarations with valid runtime discoverable attributes
154+
/// located in the source file.
155+
llvm::SetVector<ValueDecl *> DeclsWithRuntimeDiscoverableAttrs;
156+
153157
/// The list of top-level items in the source file. This is \c None if
154158
/// they have not yet been parsed.
155159
/// FIXME: Once addTopLevelDecl/prependTopLevelDecl
@@ -209,6 +213,10 @@ class SourceFile final : public FileUnit {
209213
/// Add a hoisted declaration. See Decl::isHoisted().
210214
void addHoistedDecl(Decl *d);
211215

216+
/// Add a declaration with any number of runtime disoverable attributes
217+
/// associated with it.
218+
void addDeclWithRuntimeDiscoverableAttrs(ValueDecl *);
219+
212220
/// Retrieves an immutable view of the list of top-level items in this file.
213221
ArrayRef<ASTNode> getTopLevelItems() const;
214222

@@ -221,6 +229,10 @@ class SourceFile final : public FileUnit {
221229
/// See Decl::isHoisted().
222230
ArrayRef<Decl *> getHoistedDecls() const;
223231

232+
/// Retrieves an immutable view of the set of all declaration with runtime
233+
/// discoverable attributes located in this file.
234+
ArrayRef<ValueDecl *> getDeclsWithRuntimeDiscoverableAttrs() const;
235+
224236
/// Retrieves an immutable view of the top-level items if they have already
225237
/// been parsed, or \c None if they haven't. Should only be used for dumping.
226238
Optional<ArrayRef<ASTNode>> getCachedTopLevelItems() const {

include/swift/AST/TypeCheckRequests.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3374,6 +3374,10 @@ enum class CustomAttrTypeKind {
33743374
/// Global actors are represented as custom type attributes. They don't
33753375
/// have any particularly interesting semantics.
33763376
GlobalActor,
3377+
3378+
/// Attributes that are discoverable/constructable at runtime given a name.
3379+
/// They allow unbound generic types.
3380+
RuntimeMetadata,
33773381
};
33783382

33793383
void simple_display(llvm::raw_ostream &out, CustomAttrTypeKind value);
@@ -3792,6 +3796,57 @@ class MacroDefinitionRequest
37923796
bool isCached() const { return true; }
37933797
};
37943798

3799+
class GetRuntimeDiscoverableAttributes
3800+
: public SimpleRequest<GetRuntimeDiscoverableAttributes,
3801+
ArrayRef<CustomAttr *>(ValueDecl *),
3802+
RequestFlags::Cached> {
3803+
public:
3804+
using SimpleRequest::SimpleRequest;
3805+
3806+
private:
3807+
friend SimpleRequest;
3808+
3809+
ArrayRef<CustomAttr *> evaluate(Evaluator &evaluator, ValueDecl *decl) const;
3810+
3811+
public:
3812+
bool isCached() const { return true; }
3813+
};
3814+
3815+
class SynthesizeRuntimeMetadataAttrGenerator
3816+
: public SimpleRequest<SynthesizeRuntimeMetadataAttrGenerator,
3817+
Expr *(CustomAttr *, ValueDecl *),
3818+
RequestFlags::Cached> {
3819+
3820+
public:
3821+
using SimpleRequest::SimpleRequest;
3822+
3823+
private:
3824+
friend SimpleRequest;
3825+
3826+
Expr *evaluate(Evaluator &evaluator, CustomAttr *attr,
3827+
ValueDecl *attachedTo) const;
3828+
3829+
public:
3830+
bool isCached() const { return true; }
3831+
};
3832+
3833+
class SynthesizeRuntimeMetadataAttrGeneratorBody
3834+
: public SimpleRequest<SynthesizeRuntimeMetadataAttrGeneratorBody,
3835+
BraceStmt *(CustomAttr *, ValueDecl *),
3836+
RequestFlags::Cached> {
3837+
public:
3838+
using SimpleRequest::SimpleRequest;
3839+
3840+
private:
3841+
friend SimpleRequest;
3842+
3843+
BraceStmt *evaluate(Evaluator &evaluator, CustomAttr *attr,
3844+
ValueDecl *attachedTo) const;
3845+
3846+
public:
3847+
bool isCached() const { return true; }
3848+
};
3849+
37953850
/// Compute the local discriminators for the given declaration context.
37963851
///
37973852
/// This is a state-changing operation for closures within the context, which

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,15 @@ SWIFT_REQUEST(TypeChecker, UsesTypeWrapperFeature,
449449
SWIFT_REQUEST(TypeChecker, MacroDefinitionRequest,
450450
MacroDefinition(MacroDecl *),
451451
Cached, NoLocationInfo)
452+
SWIFT_REQUEST(TypeChecker, SynthesizeRuntimeMetadataAttrGenerator,
453+
Expr *(CustomAttr *, ValueDecl *),
454+
Cached, NoLocationInfo)
455+
SWIFT_REQUEST(TypeChecker, SynthesizeRuntimeMetadataAttrGeneratorBody,
456+
BraceStmt *(CustomAttr *, ValueDecl *),
457+
Cached, NoLocationInfo)
458+
SWIFT_REQUEST(TypeChecker, GetRuntimeDiscoverableAttributes,
459+
ArrayRef<CustomAttr *>(ValueDecl *),
460+
Cached, NoLocationInfo)
452461
SWIFT_REQUEST(TypeChecker, LocalDiscriminatorsRequest,
453462
unsigned(DeclContext *),
454463
Cached, NoLocationInfo)

include/swift/Demangling/DemangleNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,8 @@ NODE(SymbolicExtendedExistentialType)
351351
// Added in Swift 5.8
352352
NODE(MetatypeParamsRemoved)
353353
NODE(HasSymbolQuery)
354+
NODE(RuntimeDiscoverableAttributeRecord)
355+
CONTEXT_NODE(RuntimeAttributeGenerator)
354356

355357
#undef CONTEXT_NODE
356358
#undef NODE

include/swift/IRGen/Linking.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,11 @@ class LinkEntity {
341341
/// the metadata cache once.
342342
CanonicalPrespecializedGenericTypeCachingOnceToken,
343343

344+
/// The record that describes an attribute that could be looked
345+
/// up at runtime together with all types it's attached to and
346+
/// generator functions.
347+
RuntimeDiscoverableAttributeRecord,
348+
344349
/// The same as AsyncFunctionPointer but with a different stored value, for
345350
/// use by TBDGen.
346351
/// The pointer is an AbstractFunctionDecl*.
@@ -1380,6 +1385,12 @@ class LinkEntity {
13801385
return entity;
13811386
}
13821387

1388+
static LinkEntity forRuntimeDiscoverableAttributeRecord(NominalTypeDecl *attr) {
1389+
LinkEntity entity;
1390+
entity.setForDecl(Kind::RuntimeDiscoverableAttributeRecord, attr);
1391+
return entity;
1392+
}
1393+
13831394
void mangle(llvm::raw_ostream &out) const;
13841395
void mangle(SmallVectorImpl<char> &buffer) const;
13851396
std::string mangleAsString() const;

0 commit comments

Comments
 (0)