mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SILGen: Allow extensions to define designated initializers of generic types
Previously, if a generic type had a stored property with a generic type and an initializer expression, we would emit the expression directly in the body of each designated initializer. This is a problem if the designated initializer is defined within an extension (even in the same source file), because extensions have a different set of generic parameters and archetypes. Also, we've had bugs in the past where emitting an expression multiple times didn't work properly. While these might currently all be fixed, this is a tricky case to test and it would be best to avoid it. Fix both problems by emitting the initializer expression inside its own function at the SIL level, and call the initializer function from each designated initializer. I'm using the existing 'variable initializer' mangling for this; it doesn't seem to be used for anything else right now. Currently, the default memberwise initializer does not use this, because the machinery for emitting it is somewhat duplicated and separate from the initializer expressions in user-defined constructors. I'll clean this up in an upcoming patch. Fixes <https://bugs.swift.org/browse/SR-488>.
This commit is contained in:
@@ -152,8 +152,11 @@ SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind,
|
||||
"can only create ivar initializer/destroyer SILDeclRef for class");
|
||||
naturalUncurryLevel = 1;
|
||||
} else if (auto *var = dyn_cast<VarDecl>(vd)) {
|
||||
assert((kind == Kind::GlobalAccessor || kind == Kind::GlobalGetter) &&
|
||||
"can only create GlobalAccessor or GlobalGetter SILDeclRef for var");
|
||||
assert((kind == Kind::GlobalAccessor ||
|
||||
kind == Kind::GlobalGetter ||
|
||||
kind == Kind::StoredPropertyInitializer) &&
|
||||
"can only create GlobalAccessor, GlobalGetter or "
|
||||
"StoredPropertyInitializer SILDeclRef for var");
|
||||
|
||||
naturalUncurryLevel = 0;
|
||||
assert(!var->getDeclContext()->isLocalContext() &&
|
||||
@@ -316,9 +319,14 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
|
||||
|
||||
// Enum constructors are essentially the same as thunks, they are
|
||||
// emitted by need and have shared linkage.
|
||||
if (kind == Kind::EnumElement)
|
||||
if (isEnumElement())
|
||||
return SILLinkage::Shared;
|
||||
|
||||
// Stored property initializers have hidden linkage, since they are
|
||||
// not meant to be used from outside of their module.
|
||||
if (isStoredPropertyInitializer())
|
||||
return SILLinkage::Hidden;
|
||||
|
||||
// Declarations imported from Clang modules have shared linkage.
|
||||
const SILLinkage ClangLinkage = SILLinkage::Shared;
|
||||
|
||||
@@ -353,6 +361,9 @@ bool SILDeclRef::isTransparent() const {
|
||||
if (isEnumElement())
|
||||
return true;
|
||||
|
||||
if (isStoredPropertyInitializer())
|
||||
return true;
|
||||
|
||||
if (hasAutoClosureExpr())
|
||||
return true;
|
||||
|
||||
@@ -576,12 +587,18 @@ static std::string mangleConstant(SILDeclRef c, StringRef prefix) {
|
||||
mangler.mangleGlobalGetterEntity(c.getDecl());
|
||||
return mangler.finalize();
|
||||
|
||||
// entity ::= context 'e' index // default arg generator
|
||||
// entity ::= context 'e' index // default arg generator
|
||||
case SILDeclRef::Kind::DefaultArgGenerator:
|
||||
mangler.append(introducer);
|
||||
mangler.mangleDefaultArgumentEntity(cast<AbstractFunctionDecl>(c.getDecl()),
|
||||
c.defaultArgIndex);
|
||||
return mangler.finalize();
|
||||
|
||||
// entity ::= 'I' declaration 'i' // stored property initializer
|
||||
case SILDeclRef::Kind::StoredPropertyInitializer:
|
||||
mangler.append(introducer);
|
||||
mangler.mangleInitializerEntity(cast<VarDecl>(c.getDecl()));
|
||||
return mangler.finalize();
|
||||
}
|
||||
|
||||
llvm_unreachable("bad entity kind!");
|
||||
|
||||
Reference in New Issue
Block a user