Skip to content

Commit ab5d161

Browse files
committed
[SILGen] Separate the initialization of a wrapped property from a wrapped value
Teach SILGen to emit a separate SIL function to capture the initialization of the backing storage type for a wrapped property based on the wrapped value. This eliminates manual code expansion at every use site.
1 parent 3e48f71 commit ab5d161

26 files changed

+228
-50
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ Entities
290290
entity-spec ::= type 'fu' INDEX // implicit anonymous closure
291291
entity-spec ::= 'fA' INDEX // default argument N+1 generator
292292
entity-spec ::= 'fi' // non-local variable initializer
293+
entity-spec ::= 'fP' // property wrapper backing initializer
293294
entity-spec ::= 'fD' // deallocating destructor; untyped
294295
entity-spec ::= 'fd' // non-deallocating destructor; untyped
295296
entity-spec ::= 'fE' // ivar destroyer; untyped

include/swift/AST/ASTMangler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ class ASTMangler : public Mangler {
124124
SymbolKind SKind);
125125

126126
std::string mangleInitializerEntity(const VarDecl *var, SymbolKind SKind);
127+
std::string mangleBackingInitializerEntity(const VarDecl *var,
128+
SymbolKind SKind);
127129

128130
std::string mangleNominalType(const NominalTypeDecl *decl);
129131

@@ -311,6 +313,7 @@ class ASTMangler : public Mangler {
311313
void appendDefaultArgumentEntity(const DeclContext *ctx, unsigned index);
312314

313315
void appendInitializerEntity(const VarDecl *var);
316+
void appendBackingInitializerEntity(const VarDecl *var);
314317

315318
CanType getDeclTypeForMangling(const ValueDecl *decl,
316319
GenericSignature *&genericSig,

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ NODE(PostfixOperator)
157157
NODE(PrefixOperator)
158158
NODE(PrivateDeclName)
159159
NODE(PropertyDescriptor)
160+
CONTEXT_NODE(PropertyWrapperBackingInitializer)
160161
CONTEXT_NODE(Protocol)
161162
CONTEXT_NODE(ProtocolSymbolicReference)
162163
NODE(ProtocolConformance)

include/swift/SIL/SILDeclRef.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ struct SILDeclRef {
133133
/// routines have an ivar destroyer, which is emitted as
134134
/// .cxx_destruct.
135135
IVarDestroyer,
136+
137+
/// References the wrapped value injection function used to initialize
138+
/// the backing storage property from a wrapped value.
139+
PropertyWrapperBackingInitializer,
136140
};
137141

138142
/// The ValueDecl or AbstractClosureExpr represented by this SILDeclRef.

lib/AST/ASTMangler.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ std::string ASTMangler::mangleInitializerEntity(const VarDecl *var,
155155
return finalize();
156156
}
157157

158+
std::string ASTMangler::mangleBackingInitializerEntity(const VarDecl *var,
159+
SymbolKind SKind) {
160+
beginMangling();
161+
appendBackingInitializerEntity(var);
162+
appendSymbolKind(SKind);
163+
return finalize();
164+
}
165+
158166
std::string ASTMangler::mangleNominalType(const NominalTypeDecl *decl) {
159167
beginMangling();
160168
appendAnyGenericType(decl);
@@ -2328,6 +2336,11 @@ void ASTMangler::appendInitializerEntity(const VarDecl *var) {
23282336
appendOperator("fi");
23292337
}
23302338

2339+
void ASTMangler::appendBackingInitializerEntity(const VarDecl *var) {
2340+
appendEntity(var, "vp", var->isStatic());
2341+
appendOperator("fP");
2342+
}
2343+
23312344
/// Is this declaration a method for mangling purposes? If so, we'll leave the
23322345
/// Self type out of its mangling.
23332346
static bool isMethodDecl(const Decl *decl) {

lib/AST/Decl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5482,7 +5482,8 @@ bool VarDecl::hasAttachedPropertyWrapper() const {
54825482
return !getAttachedPropertyWrappers().empty();
54835483
}
54845484

5485-
/// Whether all of the attached property wrappers have an init(initialValue:) initializer.
5485+
/// Whether all of the attached property wrappers have an init(wrappedValue:)
5486+
/// initializer.
54865487
bool VarDecl::allAttachedPropertyWrappersHaveInitialValueInit() const {
54875488
for (unsigned i : indices(getAttachedPropertyWrappers())) {
54885489
if (!getAttachedPropertyWrapperTypeInfo(i).wrappedValueInit)

lib/Demangling/Demangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,6 +1577,7 @@ bool Demangle::nodeConsumesGenericArgs(Node *node) {
15771577
case Node::Kind::ExplicitClosure:
15781578
case Node::Kind::DefaultArgumentInitializer:
15791579
case Node::Kind::Initializer:
1580+
case Node::Kind::PropertyWrapperBackingInitializer:
15801581
return false;
15811582
default:
15821583
return true;
@@ -2934,6 +2935,10 @@ NodePointer Demangler::demangleFunctionEntity() {
29342935
case 'u': Args = TypeAndIndex; Kind = Node::Kind::ImplicitClosure; break;
29352936
case 'A': Args = Index; Kind = Node::Kind::DefaultArgumentInitializer; break;
29362937
case 'p': return demangleEntity(Node::Kind::GenericTypeParamDecl);
2938+
case 'P':
2939+
Args = None;
2940+
Kind = Node::Kind::PropertyWrapperBackingInitializer;
2941+
break;
29372942
default: return nullptr;
29382943
}
29392944

lib/Demangling/NodePrinter.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ class NodePrinter {
398398
case Node::Kind::InOut:
399399
case Node::Kind::InfixOperator:
400400
case Node::Kind::Initializer:
401+
case Node::Kind::PropertyWrapperBackingInitializer:
401402
case Node::Kind::KeyPathGetterThunkHelper:
402403
case Node::Kind::KeyPathSetterThunkHelper:
403404
case Node::Kind::KeyPathEqualsThunkHelper:
@@ -1125,6 +1126,10 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
11251126
case Node::Kind::Initializer:
11261127
return printEntity(Node, asPrefixContext, TypePrinting::NoType,
11271128
/*hasName*/false, "variable initialization expression");
1129+
case Node::Kind::PropertyWrapperBackingInitializer:
1130+
return printEntity(
1131+
Node, asPrefixContext, TypePrinting::NoType,
1132+
/*hasName*/false, "property wrapper backing initializer");
11281133
case Node::Kind::DefaultArgumentInitializer:
11291134
return printEntity(Node, asPrefixContext, TypePrinting::NoType,
11301135
/*hasName*/false, "default argument ",
@@ -2447,7 +2452,8 @@ printEntity(NodePointer Entity, bool asPrefixContext, TypePrinting TypePr,
24472452
if (!asPrefixContext && PostfixContext) {
24482453
// Print any left over context which couldn't be printed in prefix form.
24492454
if (Entity->getKind() == Node::Kind::DefaultArgumentInitializer ||
2450-
Entity->getKind() == Node::Kind::Initializer) {
2455+
Entity->getKind() == Node::Kind::Initializer ||
2456+
Entity->getKind() == Node::Kind::PropertyWrapperBackingInitializer) {
24512457
Printer << " of ";
24522458
} else {
24532459
Printer << " in ";

lib/Demangling/OldRemangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,11 @@ void Remangler::mangleInitializer(Node *node, EntityContext &ctx) {
796796
mangleSimpleEntity(node, 'I', "i", ctx);
797797
}
798798

799+
void Remangler::manglePropertyWrapperBackingInitializer(Node *node,
800+
EntityContext &ctx) {
801+
mangleSimpleEntity(node, 'I', "P", ctx);
802+
}
803+
799804
void Remangler::mangleDefaultArgumentInitializer(Node *node,
800805
EntityContext &ctx) {
801806
mangleNamedEntity(node, 'I', "A", ctx);

lib/Demangling/Remangler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ void Remangler::mangleGenericArgs(Node *node, char &Separator,
518518
case Node::Kind::ImplicitClosure:
519519
case Node::Kind::DefaultArgumentInitializer:
520520
case Node::Kind::Initializer:
521+
case Node::Kind::PropertyWrapperBackingInitializer:
521522
if (!fullSubstitutionMap)
522523
break;
523524

@@ -1525,6 +1526,11 @@ void Remangler::mangleInitializer(Node *node) {
15251526
Buffer << "fi";
15261527
}
15271528

1529+
void Remangler::manglePropertyWrapperBackingInitializer(Node *node) {
1530+
mangleChildNodes(node);
1531+
Buffer << "fP";
1532+
}
1533+
15281534
void Remangler::mangleLazyProtocolWitnessTableAccessor(Node *node) {
15291535
mangleChildNodes(node);
15301536
Buffer << "Wl";
@@ -2482,6 +2488,7 @@ bool Demangle::isSpecialized(Node *node) {
24822488
case Node::Kind::ExplicitClosure:
24832489
case Node::Kind::ImplicitClosure:
24842490
case Node::Kind::Initializer:
2491+
case Node::Kind::PropertyWrapperBackingInitializer:
24852492
case Node::Kind::DefaultArgumentInitializer:
24862493
case Node::Kind::Getter:
24872494
case Node::Kind::Setter:
@@ -2521,6 +2528,7 @@ NodePointer Demangle::getUnspecialized(Node *node, NodeFactory &Factory) {
25212528
case Node::Kind::ExplicitClosure:
25222529
case Node::Kind::ImplicitClosure:
25232530
case Node::Kind::Initializer:
2531+
case Node::Kind::PropertyWrapperBackingInitializer:
25242532
case Node::Kind::DefaultArgumentInitializer:
25252533
NumToCopy = node->getNumChildren();
25262534
LLVM_FALLTHROUGH;

0 commit comments

Comments
 (0)