Skip to content

Commit b83b094

Browse files
committed
[SILDeclRef] RuntimeMetadata: Add a special kind for runtime attribute generator
A new `RuntimeAttributeGenerator` is used to reference runtime attribute generator functions synthesized by SILGen. `#function` magic literal points to the declaration that declaration attribute is attached to.
1 parent 91042d7 commit b83b094

File tree

11 files changed

+106
-20
lines changed

11 files changed

+106
-20
lines changed

include/swift/SIL/SILDeclRef.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ namespace swift {
5353
enum class SILLinkage : uint8_t;
5454
class AnyFunctionRef;
5555
class GenericSignature;
56+
class CustomAttr;
5657

5758
/// How a method is dispatched.
5859
enum class MethodDispatch {
@@ -162,6 +163,10 @@ struct SILDeclRef {
162163

163164
/// The asynchronous main entry-point function.
164165
AsyncEntryPoint,
166+
167+
/// This constant references the generator function used to instantiate
168+
/// attribute value associated with a particular declaration.
169+
RuntimeAttributeGenerator,
165170
};
166171

167172
/// Represents the variants of a back deployable function.
@@ -198,7 +203,7 @@ struct SILDeclRef {
198203
unsigned defaultArgIndex : 10;
199204

200205
PointerUnion<AutoDiffDerivativeFunctionIdentifier *,
201-
const GenericSignatureImpl *>
206+
const GenericSignatureImpl *, CustomAttr *>
202207
pointer;
203208

204209
/// Returns the type of AST node location being stored by the SILDeclRef.
@@ -277,6 +282,9 @@ struct SILDeclRef {
277282
/// Produces a SILDeclRef for the entry-point of an async main FileUnit.
278283
static SILDeclRef getAsyncMainFileEntryPoint(FileUnit *file);
279284

285+
static SILDeclRef getRuntimeAttributeGenerator(CustomAttr *attr,
286+
ValueDecl *decl);
287+
280288
bool isNull() const { return loc.isNull(); }
281289
explicit operator bool() const { return !isNull(); }
282290

lib/IRGen/GenDecl.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4414,9 +4414,7 @@ void IRGenModule::emitRuntimeDiscoverableAttributes(
44144414

44154415
// Map attribute type to each declaration it's attached to
44164416
// and a corresponding generator function.
4417-
llvm::DenseMap<NominalTypeDecl *,
4418-
SmallVector<std::pair<ValueDecl *, SILFunction *>, 2>>
4419-
attributes;
4417+
llvm::MapVector<NominalTypeDecl *, SmallVector<SILDeclRef, 2>> attributes;
44204418
{
44214419
for (auto *fileUnit : filesToEmit) {
44224420
auto *SF = dyn_cast<SourceFile>(fileUnit);
@@ -4426,15 +4424,16 @@ void IRGenModule::emitRuntimeDiscoverableAttributes(
44264424
for (auto *decl : SF->getDeclsWithRuntimeDiscoverableAttrs()) {
44274425
for (auto *attr : decl->getRuntimeDiscoverableAttrs()) {
44284426
auto *attrType = decl->getRuntimeDiscoverableAttrTypeDecl(attr);
4429-
auto *generator = getSILModule().lookUpFunction(
4430-
SILDeclRef(decl->getRuntimeDiscoverableAttributeGenerator(attr)));
4431-
4432-
attributes[attrType].push_back({decl, generator});
4427+
attributes[attrType].push_back(
4428+
SILDeclRef::getRuntimeAttributeGenerator(attr, decl)
4429+
.asRuntimeAccessible());
44334430
}
44344431
}
44354432
}
44364433
}
44374434

4435+
auto &SM = getSILModule();
4436+
44384437
for (auto &attr : attributes) {
44394438
auto *attrType = attr.first;
44404439
const auto &attachedTo = attr.second;
@@ -4457,9 +4456,9 @@ void IRGenModule::emitRuntimeDiscoverableAttributes(
44574456
B.addInt32(attachedTo.size());
44584457

44594458
// Emit all of the trailing objects
4460-
for (auto &e : attachedTo) {
4461-
auto type = e.first->getInterfaceType()->getCanonicalType();
4462-
auto *generator = e.second;
4459+
for (auto &ref : attachedTo) {
4460+
auto type = ref.getDecl()->getInterfaceType()->getCanonicalType();
4461+
auto *generator = SM.lookUpFunction(ref);
44634462

44644463
B.addRelativeAddress(
44654464
getTypeRef(type, /*genericSig=*/nullptr, MangledTypeRefRole::Metadata)

lib/IRGen/GenObjC.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ namespace {
628628
case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue:
629629
case SILDeclRef::Kind::EntryPoint:
630630
case SILDeclRef::Kind::AsyncEntryPoint:
631+
case SILDeclRef::Kind::RuntimeAttributeGenerator:
631632
llvm_unreachable("Method does not have a selector");
632633

633634
case SILDeclRef::Kind::Destroyer:

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ bool SILDeclRef::hasUserWrittenCode() const {
369369
case Kind::PropertyWrapperInitFromProjectedValue:
370370
case Kind::EntryPoint:
371371
case Kind::AsyncEntryPoint:
372+
case Kind::RuntimeAttributeGenerator:
372373
// Implicit decls for these don't splice in user-written code.
373374
return false;
374375
}
@@ -510,6 +511,9 @@ static LinkageLimit getLinkageLimit(SILDeclRef constant) {
510511
// class from which they come, and never get seen externally.
511512
return Limit::NeverPublic;
512513

514+
case Kind::RuntimeAttributeGenerator:
515+
return Limit::NeverPublic;
516+
513517
case Kind::EntryPoint:
514518
case Kind::AsyncEntryPoint:
515519
llvm_unreachable("Already handled");
@@ -671,6 +675,16 @@ SILDeclRef SILDeclRef::getMainFileEntryPoint(FileUnit *file) {
671675
return result;
672676
}
673677

678+
SILDeclRef SILDeclRef::getRuntimeAttributeGenerator(CustomAttr *attr,
679+
ValueDecl *decl) {
680+
SILDeclRef result;
681+
result.loc = decl;
682+
result.kind = Kind::RuntimeAttributeGenerator;
683+
result.isRuntimeAccessible = true;
684+
result.pointer = attr;
685+
return result;
686+
}
687+
674688
bool SILDeclRef::hasClosureExpr() const {
675689
return loc.is<AbstractClosureExpr *>()
676690
&& isa<ClosureExpr>(getAbstractClosureExpr());
@@ -1009,7 +1023,8 @@ bool SILDeclRef::isBackDeploymentThunk() const {
10091023
}
10101024

10111025
bool SILDeclRef::isRuntimeAccessibleFunction() const {
1012-
return isRuntimeAccessible && kind == Kind::Func;
1026+
return isRuntimeAccessible &&
1027+
(kind == Kind::Func || kind == Kind::RuntimeAttributeGenerator);
10131028
}
10141029

10151030
/// Use the Clang importer to mangle a Clang declaration.
@@ -1188,6 +1203,10 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
11881203
case SILDeclRef::Kind::EntryPoint: {
11891204
return getASTContext().getEntryPointFunctionName();
11901205
}
1206+
1207+
case SILDeclRef::Kind::RuntimeAttributeGenerator:
1208+
return mangler.mangleRuntimeAttributeGeneratorEntity(
1209+
loc.get<ValueDecl *>(), pointer.get<CustomAttr *>(), SKind);
11911210
}
11921211

11931212
llvm_unreachable("bad entity kind!");
@@ -1556,7 +1575,7 @@ unsigned SILDeclRef::getParameterListCount() const {
15561575

15571576
// Always uncurried even if the underlying function is curried.
15581577
if (kind == Kind::DefaultArgGenerator || kind == Kind::EntryPoint ||
1559-
kind == Kind::AsyncEntryPoint)
1578+
kind == Kind::AsyncEntryPoint || kind == Kind::RuntimeAttributeGenerator)
15601579
return 1;
15611580

15621581
auto *vd = getDecl();

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,6 +2396,7 @@ static CanSILFunctionType getNativeSILFunctionType(
23962396
case SILDeclRef::Kind::Destroyer:
23972397
case SILDeclRef::Kind::GlobalAccessor:
23982398
case SILDeclRef::Kind::DefaultArgGenerator:
2399+
case SILDeclRef::Kind::RuntimeAttributeGenerator:
23992400
case SILDeclRef::Kind::StoredPropertyInitializer:
24002401
case SILDeclRef::Kind::PropertyWrapperBackingInitializer:
24012402
case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue:
@@ -3238,6 +3239,7 @@ static ObjCSelectorFamily getObjCSelectorFamily(SILDeclRef c) {
32383239
case SILDeclRef::Kind::EnumElement:
32393240
case SILDeclRef::Kind::GlobalAccessor:
32403241
case SILDeclRef::Kind::DefaultArgGenerator:
3242+
case SILDeclRef::Kind::RuntimeAttributeGenerator:
32413243
case SILDeclRef::Kind::StoredPropertyInitializer:
32423244
case SILDeclRef::Kind::PropertyWrapperBackingInitializer:
32433245
case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue:
@@ -3508,6 +3510,7 @@ TypeConverter::getDeclRefRepresentation(SILDeclRef c) {
35083510
switch (c.kind) {
35093511
case SILDeclRef::Kind::GlobalAccessor:
35103512
case SILDeclRef::Kind::DefaultArgGenerator:
3513+
case SILDeclRef::Kind::RuntimeAttributeGenerator:
35113514
case SILDeclRef::Kind::StoredPropertyInitializer:
35123515
case SILDeclRef::Kind::PropertyWrapperBackingInitializer:
35133516
case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue:
@@ -4370,6 +4373,7 @@ static AbstractFunctionDecl *getBridgedFunction(SILDeclRef declRef) {
43704373
case SILDeclRef::Kind::Deallocator:
43714374
case SILDeclRef::Kind::GlobalAccessor:
43724375
case SILDeclRef::Kind::DefaultArgGenerator:
4376+
case SILDeclRef::Kind::RuntimeAttributeGenerator:
43734377
case SILDeclRef::Kind::StoredPropertyInitializer:
43744378
case SILDeclRef::Kind::PropertyWrapperBackingInitializer:
43754379
case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue:

lib/SIL/IR/SILPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,9 @@ void SILDeclRef::print(raw_ostream &OS) const {
376376
case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue:
377377
OS << "!projectedvalueinit";
378378
break;
379+
case SILDeclRef::Kind::RuntimeAttributeGenerator:
380+
OS << "!attrgenerator";
381+
break;
379382
}
380383

381384
if (isForeign)

lib/SIL/IR/SILSymbolVisitor.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,8 @@ class SILSymbolVisitorImpl : public ASTVisitor<SILSymbolVisitorImpl> {
367367

368368
void addRuntimeDiscoverableAttrGenerators(ValueDecl *D) {
369369
for (auto *attr : D->getRuntimeDiscoverableAttrs()) {
370-
auto *generator = D->getRuntimeDiscoverableAttributeGenerator(attr);
371-
assert(generator);
372-
addFunction(SILDeclRef(generator), /*ignoreLinkage=*/true);
370+
addFunction(SILDeclRef::getRuntimeAttributeGenerator(attr, D),
371+
/*ignoreLinkage=*/true);
373372
}
374373
}
375374

lib/SIL/IR/TypeLowering.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3229,6 +3229,31 @@ static CanAnyFunctionType getStoredPropertyInitializerInterfaceType(
32293229
info);
32303230
}
32313231

3232+
/// Type of runtime discoverable attribute generator is () -> <#AttrType#>
3233+
static CanAnyFunctionType
3234+
getRuntimeAttributeGeneratorInterfaceType(TypeConverter &TC, SILDeclRef c) {
3235+
auto *attachedToDecl = c.getDecl();
3236+
auto *attr = c.pointer.get<CustomAttr *>();
3237+
auto *attrType = attachedToDecl->getRuntimeDiscoverableAttrTypeDecl(attr);
3238+
auto *generator =
3239+
attachedToDecl->getRuntimeDiscoverableAttributeGenerator(attr);
3240+
3241+
auto resultTy =
3242+
generator->getType()->mapTypeOutOfContext()->getCanonicalType();
3243+
3244+
CanType canResultTy = resultTy->getReducedType(
3245+
attrType->getInnermostDeclContext()->getGenericSignatureOfContext());
3246+
3247+
// Remove @noescape from function return types. A @noescape
3248+
// function return type is a contradiction.
3249+
canResultTy = removeNoEscape(canResultTy);
3250+
3251+
// FIXME: Verify ExtInfo state is correct, not working by accident.
3252+
CanAnyFunctionType::ExtInfo info;
3253+
return CanAnyFunctionType::get(/*genericSignature=*/nullptr,
3254+
/*params=*/{}, canResultTy, info);
3255+
}
3256+
32323257
/// Get the type of a property wrapper backing initializer,
32333258
/// (property-type) -> backing-type.
32343259
static CanAnyFunctionType getPropertyWrapperBackingInitializerInterfaceType(
@@ -3489,6 +3514,8 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
34893514
return getAsyncEntryPoint(Context);
34903515
case SILDeclRef::Kind::EntryPoint:
34913516
return getEntryPointInterfaceType(Context);
3517+
case SILDeclRef::Kind::RuntimeAttributeGenerator:
3518+
return getRuntimeAttributeGeneratorInterfaceType(*this, c);
34923519
}
34933520

34943521
llvm_unreachable("Unhandled SILDeclRefKind in switch.");
@@ -3542,6 +3569,7 @@ TypeConverter::getConstantGenericSignature(SILDeclRef c) {
35423569
return vd->getDeclContext()->getGenericSignatureOfContext();
35433570
case SILDeclRef::Kind::EntryPoint:
35443571
case SILDeclRef::Kind::AsyncEntryPoint:
3572+
case SILDeclRef::Kind::RuntimeAttributeGenerator:
35453573
llvm_unreachable("Doesn't have generic signature");
35463574
}
35473575

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,9 @@ bool SILParser::parseSILDeclRef(SILDeclRef &Result,
16161616
} else if (!ParseState && Id.str() == "defaultarg") {
16171617
Kind = SILDeclRef::Kind::IVarInitializer;
16181618
ParseState = 1;
1619+
} else if (!ParseState && Id.str() == "attrgenerator") {
1620+
Kind = SILDeclRef::Kind::RuntimeAttributeGenerator;
1621+
ParseState = 1;
16191622
} else if (!ParseState && Id.str() == "propertyinit") {
16201623
Kind = SILDeclRef::Kind::StoredPropertyInitializer;
16211624
ParseState = 1;

lib/SILGen/SILGen.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,21 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
11351135
postEmitFunction(constant, f);
11361136
return;
11371137
}
1138+
1139+
case SILDeclRef::Kind::RuntimeAttributeGenerator: {
1140+
auto *decl = constant.getDecl();
1141+
auto *attr = constant.pointer.get<CustomAttr *>();
1142+
auto *DC = decl->getDeclContext()->getParentSourceFile();
1143+
1144+
Expr *generator = decl->getRuntimeDiscoverableAttributeGenerator(attr);
1145+
auto loc = RegularLocation::getAutoGeneratedLocation(generator);
1146+
preEmitFunction(constant, f, loc);
1147+
PrettyStackTraceSILFunction X("silgen emitRuntimeAttributeGenerator ", f);
1148+
SILGenFunction SGF(*this, *f, DC);
1149+
SGF.emitGeneratorFunction(constant, generator);
1150+
postEmitFunction(constant, f);
1151+
break;
1152+
}
11381153
}
11391154
}
11401155

@@ -2210,9 +2225,9 @@ class SILGenModuleRAII {
22102225

22112226
for (auto *D : sf->getDeclsWithRuntimeDiscoverableAttrs()) {
22122227
for (auto *attr : D->getRuntimeDiscoverableAttrs()) {
2213-
auto *generator = D->getRuntimeDiscoverableAttributeGenerator(attr);
2214-
assert(generator);
2215-
emitSILFunctionDefinition(SILDeclRef(generator).asRuntimeAccessible());
2228+
emitSILFunctionDefinition(
2229+
SILDeclRef::getRuntimeAttributeGenerator(attr, D)
2230+
.asRuntimeAccessible());
22162231
}
22172232
}
22182233

0 commit comments

Comments
 (0)