mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Centralize the definition of isMemberwiseInitialized()
This utility was defined in Sema, used in Sema and Index, declared in two headers, and semi- copy-pasted into SILGen. Pull it into VarDecl::isMemberwiseInitialized() and use it consistently.
This commit is contained in:
@@ -5142,7 +5142,11 @@ public:
|
|||||||
|
|
||||||
/// Returns true if the name is the self identifier and is implicit.
|
/// Returns true if the name is the self identifier and is implicit.
|
||||||
bool isSelfParameter() const;
|
bool isSelfParameter() const;
|
||||||
|
|
||||||
|
/// Determine whether this property will be part of the implicit memberwise
|
||||||
|
/// initializer.
|
||||||
|
bool isMemberwiseInitialized() const;
|
||||||
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
// Implement isa/cast/dyncast/etc.
|
||||||
static bool classof(const Decl *D) {
|
static bool classof(const Decl *D) {
|
||||||
return D->getKind() == DeclKind::Var || D->getKind() == DeclKind::Param;
|
return D->getKind() == DeclKind::Var || D->getKind() == DeclKind::Param;
|
||||||
|
|||||||
@@ -239,10 +239,6 @@ namespace swift {
|
|||||||
/// \param DC The DeclContext from which the subscript is being referenced.
|
/// \param DC The DeclContext from which the subscript is being referenced.
|
||||||
Optional<Type> getRootTypeOfKeypathDynamicMember(SubscriptDecl *subscript,
|
Optional<Type> getRootTypeOfKeypathDynamicMember(SubscriptDecl *subscript,
|
||||||
const DeclContext *DC);
|
const DeclContext *DC);
|
||||||
|
|
||||||
/// Determine whether the given property is part of the memberwise initializer
|
|
||||||
/// for a struct.
|
|
||||||
bool isMemberwiseInitialized(VarDecl *var);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -5254,6 +5254,30 @@ bool VarDecl::isSelfParameter() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VarDecl::isMemberwiseInitialized() const {
|
||||||
|
if (!getDeclContext()->isTypeContext())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Implicit, computed, and static properties are not initialized.
|
||||||
|
// The exception is lazy properties, which due to batch mode we may or
|
||||||
|
// may not have yet finalized, so they may currently be "stored" or
|
||||||
|
// "computed" in the current AST state.
|
||||||
|
if (isImplicit() || isStatic())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!hasStorage() && !getAttrs().hasAttribute<LazyAttr>() &&
|
||||||
|
!getAttachedPropertyDelegate())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Initialized 'let' properties have storage, but don't get an argument
|
||||||
|
// to the memberwise initializer since they already have an initial
|
||||||
|
// value that cannot be overridden.
|
||||||
|
if (isLet() && isParentInitialized())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void VarDecl::setSpecifier(Specifier specifier) {
|
void VarDecl::setSpecifier(Specifier specifier) {
|
||||||
Bits.VarDecl.Specifier = static_cast<unsigned>(specifier);
|
Bits.VarDecl.Specifier = static_cast<unsigned>(specifier);
|
||||||
setSupportsMutationIfStillStored(
|
setSupportsMutationIfStillStored(
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ private:
|
|||||||
if (auto Original = Prop->getOriginalDelegatedProperty())
|
if (auto Original = Prop->getOriginalDelegatedProperty())
|
||||||
Prop = Original;
|
Prop = Original;
|
||||||
|
|
||||||
if (!isMemberwiseInitialized(Prop))
|
if (!Prop->isMemberwiseInitialized())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (CurLabel == LabelLocs.size())
|
if (CurLabel == LabelLocs.size())
|
||||||
|
|||||||
@@ -217,14 +217,8 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
|
|||||||
auto fieldTy = selfTy.getFieldType(field, SGF.SGM.M);
|
auto fieldTy = selfTy.getFieldType(field, SGF.SGM.M);
|
||||||
SILValue v;
|
SILValue v;
|
||||||
|
|
||||||
// An initialized 'let' property has a single value specified by the
|
// If it's memberwise initialized, do so now.
|
||||||
// initializer - it doesn't come from an argument.
|
if (field->isMemberwiseInitialized()) {
|
||||||
if (!field->isStatic() && field->isLet() && field->getParentInitializer()) {
|
|
||||||
// Cleanup after this initialization.
|
|
||||||
FullExpr scope(SGF.Cleanups, field->getParentPatternBinding());
|
|
||||||
v = SGF.emitRValue(field->getParentInitializer())
|
|
||||||
.forwardAsSingleStorageValue(SGF, fieldTy, Loc);
|
|
||||||
} else {
|
|
||||||
FullExpr scope(SGF.Cleanups, field->getParentPatternBinding());
|
FullExpr scope(SGF.Cleanups, field->getParentPatternBinding());
|
||||||
assert(elti != eltEnd && "number of args does not match number of fields");
|
assert(elti != eltEnd && "number of args does not match number of fields");
|
||||||
(void)eltEnd;
|
(void)eltEnd;
|
||||||
@@ -237,6 +231,14 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
|
|||||||
v = std::move(*elti).forwardAsSingleStorageValue(SGF, fieldTy, Loc);
|
v = std::move(*elti).forwardAsSingleStorageValue(SGF, fieldTy, Loc);
|
||||||
}
|
}
|
||||||
++elti;
|
++elti;
|
||||||
|
} else {
|
||||||
|
// Otherwise, use its initializer.
|
||||||
|
assert(field->isParentInitialized());
|
||||||
|
|
||||||
|
// Cleanup after this initialization.
|
||||||
|
FullExpr scope(SGF.Cleanups, field->getParentPatternBinding());
|
||||||
|
v = SGF.emitRValue(field->getParentInitializer())
|
||||||
|
.forwardAsSingleStorageValue(SGF, fieldTy, Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
eltValues.push_back(v);
|
eltValues.push_back(v);
|
||||||
|
|||||||
@@ -2050,26 +2050,6 @@ static void maybeAddMemberwiseDefaultArg(ParamDecl *arg, VarDecl *var,
|
|||||||
arg->setDefaultArgumentKind(DefaultArgumentKind::StoredProperty);
|
arg->setDefaultArgumentKind(DefaultArgumentKind::StoredProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool swift::isMemberwiseInitialized(VarDecl *var) {
|
|
||||||
// Implicit, computed, and static properties are not initialized.
|
|
||||||
// The exception is lazy properties, which due to batch mode we may or
|
|
||||||
// may not have yet finalized, so they may currently be "stored" or
|
|
||||||
// "computed" in the current AST state.
|
|
||||||
if (var->isImplicit() || var->isStatic())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!var->hasStorage() && !var->getAttrs().hasAttribute<LazyAttr>() &&
|
|
||||||
!var->getAttachedPropertyDelegate())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Initialized 'let' properties have storage, but don't get an argument
|
|
||||||
// to the memberwise initializer since they already have an initial
|
|
||||||
// value that cannot be overridden.
|
|
||||||
if (var->isLet() && var->isParentInitialized())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/// Create an implicit struct or class constructor.
|
/// Create an implicit struct or class constructor.
|
||||||
///
|
///
|
||||||
/// \param decl The struct or class for which a constructor will be created.
|
/// \param decl The struct or class for which a constructor will be created.
|
||||||
@@ -2097,7 +2077,7 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc,
|
|||||||
if (!var)
|
if (!var)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!isMemberwiseInitialized(var))
|
if (!var->isMemberwiseInitialized())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
accessLevel = std::min(accessLevel, var->getFormalAccess());
|
accessLevel = std::min(accessLevel, var->getFormalAccess());
|
||||||
|
|||||||
@@ -69,8 +69,6 @@ enum class ImplicitConstructorKind {
|
|||||||
Memberwise
|
Memberwise
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isMemberwiseInitialized(VarDecl *var);
|
|
||||||
|
|
||||||
/// Create an implicit struct or class constructor.
|
/// Create an implicit struct or class constructor.
|
||||||
///
|
///
|
||||||
/// \param decl The struct or class for which a constructor will be created.
|
/// \param decl The struct or class for which a constructor will be created.
|
||||||
|
|||||||
@@ -5230,7 +5230,7 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
|
|||||||
if (isa<StructDecl>(decl)) {
|
if (isa<StructDecl>(decl)) {
|
||||||
for (auto member : decl->getMembers()) {
|
for (auto member : decl->getMembers()) {
|
||||||
if (auto var = dyn_cast<VarDecl>(member)) {
|
if (auto var = dyn_cast<VarDecl>(member)) {
|
||||||
if (!isMemberwiseInitialized(var))
|
if (!var->isMemberwiseInitialized())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
validateDecl(var);
|
validateDecl(var);
|
||||||
@@ -5303,7 +5303,7 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
|
|||||||
if (backingStorageVars.count(var) > 0)
|
if (backingStorageVars.count(var) > 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (isMemberwiseInitialized(var)) {
|
if (var->isMemberwiseInitialized()) {
|
||||||
// Initialized 'let' properties have storage, but don't get an argument
|
// Initialized 'let' properties have storage, but don't get an argument
|
||||||
// to the memberwise initializer since they already have an initial
|
// to the memberwise initializer since they already have an initial
|
||||||
// value that cannot be overridden.
|
// value that cannot be overridden.
|
||||||
|
|||||||
Reference in New Issue
Block a user