Skip to content

Commit 40d1adc

Browse files
authored
Merge pull request #3949 from slavapestov/fix-store-generic-member-from-extension
2 parents c1c1fe6 + 75bd889 commit 40d1adc

22 files changed

+284
-64
lines changed

include/swift/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,6 +1852,9 @@ class PatternBindingEntry {
18521852
InitCheckedAndRemoved.setInt(
18531853
InitCheckedAndRemoved.getInt() | Flags::Checked);
18541854
}
1855+
1856+
// Return the first variable initialized by this pattern.
1857+
VarDecl *getAnchoringVarDecl() const;
18551858
};
18561859

18571860
/// \brief This decl contains a pattern and optional initializer for a set

include/swift/SIL/SILDeclRef.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ struct SILDeclRef {
117117
/// References the generator for a default argument of a function.
118118
DefaultArgGenerator,
119119

120+
/// References the initializer expression for a stored property
121+
/// of a nominal type.
122+
StoredPropertyInitializer,
123+
120124
/// References the ivar initializer for the ClassDecl in loc.
121125
///
122126
/// Only classes that are allocated using Objective-C's allocation
@@ -261,6 +265,11 @@ struct SILDeclRef {
261265
bool isDefaultArgGenerator() const {
262266
return kind == Kind::DefaultArgGenerator;
263267
}
268+
/// True if the SILDeclRef references the initializer for a stored property
269+
/// of a nominal type.
270+
bool isStoredPropertyInitializer() const {
271+
return kind == Kind::StoredPropertyInitializer;
272+
}
264273

265274
/// \brief True if the function should be treated as transparent.
266275
bool isTransparent() const;

lib/AST/Decl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,13 @@ void PatternBindingEntry::setInit(Expr *E) {
949949
}
950950
}
951951

952+
VarDecl *PatternBindingEntry::getAnchoringVarDecl() const {
953+
SmallVector<VarDecl *, 8> variables;
954+
getPattern()->collectVariables(variables);
955+
assert(variables.size() > 0);
956+
return variables[0];
957+
}
958+
952959
SourceRange PatternBindingDecl::getSourceRange() const {
953960
SourceLoc startLoc = getStartLoc();
954961

lib/IRGen/GenObjC.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ namespace {
512512
Selector(SILDeclRef ref) {
513513
switch (ref.kind) {
514514
case SILDeclRef::Kind::DefaultArgGenerator:
515+
case SILDeclRef::Kind::StoredPropertyInitializer:
515516
case SILDeclRef::Kind::EnumElement:
516517
case SILDeclRef::Kind::GlobalAccessor:
517518
case SILDeclRef::Kind::GlobalGetter:

lib/Parse/ParseSIL.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,12 @@ bool SILParser::parseSILDeclRef(SILDeclRef &Result,
10531053
} else if (!ParseState && Id.str() == "ivarinitializer") {
10541054
Kind = SILDeclRef::Kind::IVarInitializer;
10551055
ParseState = 1;
1056+
} else if (!ParseState && Id.str() == "defaultarg") {
1057+
Kind = SILDeclRef::Kind::IVarInitializer;
1058+
ParseState = 1;
1059+
} else if (!ParseState && Id.str() == "propertyinit") {
1060+
Kind = SILDeclRef::Kind::StoredPropertyInitializer;
1061+
ParseState = 1;
10561062
} else if (Id.str() == "foreign") {
10571063
IsObjC = true;
10581064
break;

lib/SIL/SILDeclRef.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,11 @@ SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind,
152152
"can only create ivar initializer/destroyer SILDeclRef for class");
153153
naturalUncurryLevel = 1;
154154
} else if (auto *var = dyn_cast<VarDecl>(vd)) {
155-
assert((kind == Kind::GlobalAccessor || kind == Kind::GlobalGetter) &&
156-
"can only create GlobalAccessor or GlobalGetter SILDeclRef for var");
155+
assert((kind == Kind::GlobalAccessor ||
156+
kind == Kind::GlobalGetter ||
157+
kind == Kind::StoredPropertyInitializer) &&
158+
"can only create GlobalAccessor, GlobalGetter or "
159+
"StoredPropertyInitializer SILDeclRef for var");
157160

158161
naturalUncurryLevel = 0;
159162
assert(!var->getDeclContext()->isLocalContext() &&
@@ -316,9 +319,14 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
316319

317320
// Enum constructors are essentially the same as thunks, they are
318321
// emitted by need and have shared linkage.
319-
if (kind == Kind::EnumElement)
322+
if (isEnumElement())
320323
return SILLinkage::Shared;
321324

325+
// Stored property initializers have hidden linkage, since they are
326+
// not meant to be used from outside of their module.
327+
if (isStoredPropertyInitializer())
328+
return SILLinkage::Hidden;
329+
322330
// Declarations imported from Clang modules have shared linkage.
323331
const SILLinkage ClangLinkage = SILLinkage::Shared;
324332

@@ -353,6 +361,9 @@ bool SILDeclRef::isTransparent() const {
353361
if (isEnumElement())
354362
return true;
355363

364+
if (isStoredPropertyInitializer())
365+
return true;
366+
356367
if (hasAutoClosureExpr())
357368
return true;
358369

@@ -576,12 +587,18 @@ static std::string mangleConstant(SILDeclRef c, StringRef prefix) {
576587
mangler.mangleGlobalGetterEntity(c.getDecl());
577588
return mangler.finalize();
578589

579-
// entity ::= context 'e' index // default arg generator
590+
// entity ::= context 'e' index // default arg generator
580591
case SILDeclRef::Kind::DefaultArgGenerator:
581592
mangler.append(introducer);
582593
mangler.mangleDefaultArgumentEntity(cast<AbstractFunctionDecl>(c.getDecl()),
583594
c.defaultArgIndex);
584595
return mangler.finalize();
596+
597+
// entity ::= 'I' declaration 'i' // stored property initializer
598+
case SILDeclRef::Kind::StoredPropertyInitializer:
599+
mangler.append(introducer);
600+
mangler.mangleInitializerEntity(cast<VarDecl>(c.getDecl()));
601+
return mangler.finalize();
585602
}
586603

587604
llvm_unreachable("bad entity kind!");

lib/SIL/SILFunctionType.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,7 @@ static CanSILFunctionType getNativeSILFunctionType(SILModule &M,
10031003
case SILDeclRef::Kind::GlobalAccessor:
10041004
case SILDeclRef::Kind::GlobalGetter:
10051005
case SILDeclRef::Kind::DefaultArgGenerator:
1006+
case SILDeclRef::Kind::StoredPropertyInitializer:
10061007
case SILDeclRef::Kind::IVarInitializer:
10071008
case SILDeclRef::Kind::IVarDestroyer:
10081009
case SILDeclRef::Kind::EnumElement:
@@ -1472,6 +1473,7 @@ static SelectorFamily getSelectorFamily(SILDeclRef c) {
14721473
case SILDeclRef::Kind::GlobalGetter:
14731474
case SILDeclRef::Kind::IVarDestroyer:
14741475
case SILDeclRef::Kind::DefaultArgGenerator:
1476+
case SILDeclRef::Kind::StoredPropertyInitializer:
14751477
return SelectorFamily::None;
14761478
}
14771479
}
@@ -1653,6 +1655,7 @@ TypeConverter::getDeclRefRepresentation(SILDeclRef c) {
16531655
case SILDeclRef::Kind::GlobalAccessor:
16541656
case SILDeclRef::Kind::GlobalGetter:
16551657
case SILDeclRef::Kind::DefaultArgGenerator:
1658+
case SILDeclRef::Kind::StoredPropertyInitializer:
16561659
return SILFunctionTypeRepresentation::Thin;
16571660

16581661
case SILDeclRef::Kind::Func:
@@ -2319,6 +2322,7 @@ static AbstractFunctionDecl *getBridgedFunction(SILDeclRef declRef) {
23192322
case SILDeclRef::Kind::GlobalAccessor:
23202323
case SILDeclRef::Kind::GlobalGetter:
23212324
case SILDeclRef::Kind::DefaultArgGenerator:
2325+
case SILDeclRef::Kind::StoredPropertyInitializer:
23222326
case SILDeclRef::Kind::IVarInitializer:
23232327
case SILDeclRef::Kind::IVarDestroyer:
23242328
return nullptr;

lib/SIL/SILPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,9 @@ void SILDeclRef::print(raw_ostream &OS) const {
322322
case SILDeclRef::Kind::DefaultArgGenerator:
323323
OS << "!defaultarg" << "." << defaultArgIndex;
324324
break;
325+
case SILDeclRef::Kind::StoredPropertyInitializer:
326+
OS << "!propertyinit";
327+
break;
325328
}
326329
if (uncurryLevel != 0)
327330
OS << (isDot ? '.' : '!') << uncurryLevel;

lib/SIL/TypeLowering.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,6 +1671,27 @@ static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
16711671
return CanFunctionType::get(TupleType::getEmpty(context), resultTy);
16721672
}
16731673

1674+
/// Get the type of a stored property initializer, () -> T.
1675+
static CanAnyFunctionType getStoredPropertyInitializerInterfaceType(
1676+
TypeConverter &TC,
1677+
VarDecl *VD,
1678+
ASTContext &context) {
1679+
auto *DC = VD->getDeclContext();
1680+
CanType resultTy =
1681+
ArchetypeBuilder::mapTypeOutOfContext(
1682+
DC, VD->getParentInitializer()->getType())
1683+
->getCanonicalType();
1684+
GenericSignature *sig = DC->getGenericSignatureOfContext();
1685+
1686+
if (sig)
1687+
return CanGenericFunctionType::get(sig->getCanonicalSignature(),
1688+
TupleType::getEmpty(context),
1689+
resultTy,
1690+
GenericFunctionType::ExtInfo());
1691+
1692+
return CanFunctionType::get(TupleType::getEmpty(context), resultTy);
1693+
}
1694+
16741695
/// Get the type of a destructor function.
16751696
static CanAnyFunctionType getDestructorInterfaceType(DestructorDecl *dd,
16761697
bool isDeallocating,
@@ -1868,8 +1889,12 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
18681889
}
18691890
case SILDeclRef::Kind::DefaultArgGenerator:
18701891
return getDefaultArgGeneratorInterfaceType(*this,
1871-
cast<AbstractFunctionDecl>(vd),
1872-
c.defaultArgIndex, Context);
1892+
cast<AbstractFunctionDecl>(vd),
1893+
c.defaultArgIndex, Context);
1894+
case SILDeclRef::Kind::StoredPropertyInitializer:
1895+
return getStoredPropertyInitializerInterfaceType(*this,
1896+
cast<VarDecl>(vd),
1897+
Context);
18731898
case SILDeclRef::Kind::IVarInitializer:
18741899
return getIVarInitDestroyerInterfaceType(cast<ClassDecl>(vd),
18751900
c.isForeign, Context, false);
@@ -1926,6 +1951,12 @@ TypeConverter::getConstantContextGenericParams(SILDeclRef c) {
19261951
case SILDeclRef::Kind::DefaultArgGenerator:
19271952
// Use the context generic parameters of the original declaration.
19281953
return getConstantContextGenericParams(SILDeclRef(c.getDecl()));
1954+
case SILDeclRef::Kind::StoredPropertyInitializer:
1955+
// Use the context generic parameters of the containing type.
1956+
return {
1957+
c.getDecl()->getDeclContext()->getGenericParamsOfContext(),
1958+
nullptr,
1959+
};
19291960
}
19301961
}
19311962

lib/SILGen/SILGen.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,21 @@ void SILGenModule::emitDefaultArgGenerator(SILDeclRef constant, Expr *arg) {
877877
});
878878
}
879879

880+
void SILGenModule::
881+
emitStoredPropertyInitialization(PatternBindingDecl *pbd, unsigned i) {
882+
const PatternBindingEntry &pbdEntry = pbd->getPatternList()[i];
883+
auto *var = pbdEntry.getAnchoringVarDecl();
884+
auto *init = pbdEntry.getInit();
885+
886+
SILDeclRef constant(var, SILDeclRef::Kind::StoredPropertyInitializer);
887+
emitOrDelayFunction(*this, constant, [this,constant,init](SILFunction *f) {
888+
preEmitFunction(constant, init, f, init);
889+
PrettyStackTraceSILFunction X("silgen emitStoredPropertyInitialization", f);
890+
SILGenFunction(*this, *f).emitGeneratorFunction(constant, init);
891+
postEmitFunction(constant, f);
892+
});
893+
}
894+
880895
SILFunction *SILGenModule::emitLazyGlobalInitializer(StringRef funcName,
881896
PatternBindingDecl *binding,
882897
unsigned pbdEntry) {

0 commit comments

Comments
 (0)