mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Implement super mesage sends for @objc property and subscript getters/setters.
Fixes <rdar://problem/15933008>. Swift SVN r13100
This commit is contained in:
@@ -102,10 +102,19 @@ class alignas(8) Expr {
|
|||||||
friend class MemberRefExpr;
|
friend class MemberRefExpr;
|
||||||
unsigned : NumExprBits;
|
unsigned : NumExprBits;
|
||||||
unsigned IsDirectPropertyAccess : 1;
|
unsigned IsDirectPropertyAccess : 1;
|
||||||
|
unsigned IsSuper : 1;
|
||||||
};
|
};
|
||||||
enum { NumMemberRefExprBits = NumExprBits + 1 };
|
enum { NumMemberRefExprBits = NumExprBits + 2 };
|
||||||
static_assert(NumMemberRefExprBits <= 32, "fits in an unsigned");
|
static_assert(NumMemberRefExprBits <= 32, "fits in an unsigned");
|
||||||
|
|
||||||
|
class SubscriptExprBitfields {
|
||||||
|
friend class SubscriptExpr;
|
||||||
|
unsigned : NumExprBits;
|
||||||
|
unsigned IsSuper : 1;
|
||||||
|
};
|
||||||
|
enum { NumSubscriptExprBits = NumExprBits + 1 };
|
||||||
|
static_assert(NumSubscriptExprBits <= 32, "fits in an unsigned");
|
||||||
|
|
||||||
class MagicIdentifierLiteralExprBitfields {
|
class MagicIdentifierLiteralExprBitfields {
|
||||||
friend class MagicIdentifierLiteralExpr;
|
friend class MagicIdentifierLiteralExpr;
|
||||||
unsigned : NumLiteralExprBits;
|
unsigned : NumLiteralExprBits;
|
||||||
@@ -146,6 +155,7 @@ protected:
|
|||||||
IntegerLiteralExprBitfields IntegerLiteralExprBits;
|
IntegerLiteralExprBitfields IntegerLiteralExprBits;
|
||||||
StringLiteralExprBitfields StringLiteralExprBits;
|
StringLiteralExprBitfields StringLiteralExprBits;
|
||||||
MemberRefExprBitfields MemberRefExprBits;
|
MemberRefExprBitfields MemberRefExprBits;
|
||||||
|
SubscriptExprBitfields SubscriptExprBits;
|
||||||
MagicIdentifierLiteralExprBitfields MagicIdentifierLiteralExprBits;
|
MagicIdentifierLiteralExprBitfields MagicIdentifierLiteralExprBits;
|
||||||
AbstractClosureExprBitfields AbstractClosureExprBits;
|
AbstractClosureExprBitfields AbstractClosureExprBits;
|
||||||
ClosureExprBitfields ClosureExprBits;
|
ClosureExprBitfields ClosureExprBits;
|
||||||
@@ -783,11 +793,20 @@ public:
|
|||||||
|
|
||||||
void setBase(Expr *E) { Base = E; }
|
void setBase(Expr *E) { Base = E; }
|
||||||
|
|
||||||
/// Return true if this member access is
|
/// Return true if this member access is direct, meaning that it
|
||||||
|
/// does not call the getter or setter.
|
||||||
bool isDirectPropertyAccess() const {
|
bool isDirectPropertyAccess() const {
|
||||||
return MemberRefExprBits.IsDirectPropertyAccess;
|
return MemberRefExprBits.IsDirectPropertyAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Determine whether this member reference refers to the
|
||||||
|
/// superclass's property.
|
||||||
|
bool isSuper() const { return MemberRefExprBits.IsSuper; }
|
||||||
|
|
||||||
|
/// Set whether this member reference refers to the superclass's
|
||||||
|
/// property.
|
||||||
|
void setIsSuper(bool isSuper) { MemberRefExprBits.IsSuper = isSuper; }
|
||||||
|
|
||||||
SourceLoc getLoc() const { return NameLoc; }
|
SourceLoc getLoc() const { return NameLoc; }
|
||||||
SourceRange getSourceRange() const {
|
SourceRange getSourceRange() const {
|
||||||
if (Base->isImplicit())
|
if (Base->isImplicit())
|
||||||
@@ -1252,7 +1271,9 @@ public:
|
|||||||
SubscriptExpr(Expr *base, Expr *index,
|
SubscriptExpr(Expr *base, Expr *index,
|
||||||
ConcreteDeclRef decl = ConcreteDeclRef())
|
ConcreteDeclRef decl = ConcreteDeclRef())
|
||||||
: Expr(ExprKind::Subscript, /*Implicit=*/false, Type()),
|
: Expr(ExprKind::Subscript, /*Implicit=*/false, Type()),
|
||||||
TheDecl(decl), Base(base), Index(index) { }
|
TheDecl(decl), Base(base), Index(index) {
|
||||||
|
SubscriptExprBits.IsSuper = false;
|
||||||
|
}
|
||||||
|
|
||||||
/// getBase - Retrieve the base of the subscript expression, i.e., the
|
/// getBase - Retrieve the base of the subscript expression, i.e., the
|
||||||
/// value being indexed.
|
/// value being indexed.
|
||||||
@@ -1264,6 +1285,14 @@ public:
|
|||||||
Expr *getIndex() const { return Index; }
|
Expr *getIndex() const { return Index; }
|
||||||
void setIndex(Expr *E) { Index = E; }
|
void setIndex(Expr *E) { Index = E; }
|
||||||
|
|
||||||
|
/// Determine whether this member reference refers to the
|
||||||
|
/// superclass's property.
|
||||||
|
bool isSuper() const { return SubscriptExprBits.IsSuper; }
|
||||||
|
|
||||||
|
/// Set whether this member reference refers to the superclass's
|
||||||
|
/// property.
|
||||||
|
void setIsSuper(bool isSuper) { SubscriptExprBits.IsSuper = isSuper; }
|
||||||
|
|
||||||
/// Determine whether subscript operation has a known underlying
|
/// Determine whether subscript operation has a known underlying
|
||||||
/// subscript declaration or not.
|
/// subscript declaration or not.
|
||||||
bool hasDecl() const { return static_cast<bool>(TheDecl); }
|
bool hasDecl() const { return static_cast<bool>(TheDecl); }
|
||||||
|
|||||||
@@ -1090,6 +1090,8 @@ public:
|
|||||||
|
|
||||||
if (E->isDirectPropertyAccess())
|
if (E->isDirectPropertyAccess())
|
||||||
OS << " direct_property_access";
|
OS << " direct_property_access";
|
||||||
|
if (E->isSuper())
|
||||||
|
OS << " super";
|
||||||
|
|
||||||
OS << '\n';
|
OS << '\n';
|
||||||
printRec(E->getBase());
|
printRec(E->getBase());
|
||||||
@@ -1162,6 +1164,8 @@ public:
|
|||||||
}
|
}
|
||||||
void visitSubscriptExpr(SubscriptExpr *E) {
|
void visitSubscriptExpr(SubscriptExpr *E) {
|
||||||
printCommon(E, "subscript_expr");
|
printCommon(E, "subscript_expr");
|
||||||
|
if (E->isSuper())
|
||||||
|
OS << " super";
|
||||||
OS << '\n';
|
OS << '\n';
|
||||||
printRec(E->getBase());
|
printRec(E->getBase());
|
||||||
OS << '\n';
|
OS << '\n';
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ MemberRefExpr::MemberRefExpr(Expr *base, SourceLoc dotLoc,
|
|||||||
Member(member), DotLoc(dotLoc), NameLoc(nameLoc) {
|
Member(member), DotLoc(dotLoc), NameLoc(nameLoc) {
|
||||||
|
|
||||||
MemberRefExprBits.IsDirectPropertyAccess = UsesDirectPropertyAccess;
|
MemberRefExprBits.IsDirectPropertyAccess = UsesDirectPropertyAccess;
|
||||||
|
MemberRefExprBits.IsSuper = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExistentialMemberRefExpr::ExistentialMemberRefExpr(Expr *Base, SourceLoc DotLoc,
|
ExistentialMemberRefExpr::ExistentialMemberRefExpr(Expr *Base, SourceLoc DotLoc,
|
||||||
|
|||||||
@@ -2410,6 +2410,7 @@ static Callee getBaseAccessorFunctionRef(SILGenFunction &gen,
|
|||||||
SILLocation loc,
|
SILLocation loc,
|
||||||
SILDeclRef constant,
|
SILDeclRef constant,
|
||||||
RValueSource &selfValue,
|
RValueSource &selfValue,
|
||||||
|
bool isSuper,
|
||||||
CanAnyFunctionType substAccessorType) {
|
CanAnyFunctionType substAccessorType) {
|
||||||
ValueDecl *decl = constant.getDecl();
|
ValueDecl *decl = constant.getDecl();
|
||||||
|
|
||||||
@@ -2420,6 +2421,10 @@ static Callee getBaseAccessorFunctionRef(SILGenFunction &gen,
|
|||||||
// getters and setters.
|
// getters and setters.
|
||||||
if (gen.SGM.requiresObjCDispatch(decl)) {
|
if (gen.SGM.requiresObjCDispatch(decl)) {
|
||||||
auto self = selfValue.forceAndPeekRValue(gen).peekScalarValue();
|
auto self = selfValue.forceAndPeekRValue(gen).peekScalarValue();
|
||||||
|
|
||||||
|
if (isSuper)
|
||||||
|
return Callee::forSuperMethod(gen, self, constant, substAccessorType, loc);
|
||||||
|
|
||||||
return Callee::forClassMethod(gen, self, constant, substAccessorType, loc);
|
return Callee::forClassMethod(gen, self, constant, substAccessorType, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2431,7 +2436,8 @@ emitSpecializedAccessorFunctionRef(SILGenFunction &gen,
|
|||||||
SILLocation loc,
|
SILLocation loc,
|
||||||
SILDeclRef constant,
|
SILDeclRef constant,
|
||||||
ArrayRef<Substitution> substitutions,
|
ArrayRef<Substitution> substitutions,
|
||||||
RValueSource &selfValue)
|
RValueSource &selfValue,
|
||||||
|
bool isSuper)
|
||||||
{
|
{
|
||||||
// If the accessor is a local constant, use it.
|
// If the accessor is a local constant, use it.
|
||||||
// FIXME: Can local properties ever be generic?
|
// FIXME: Can local properties ever be generic?
|
||||||
@@ -2457,7 +2463,7 @@ emitSpecializedAccessorFunctionRef(SILGenFunction &gen,
|
|||||||
// the Self type is generic.
|
// the Self type is generic.
|
||||||
// FIXME: Dynamic dispatch for archetype/existential methods.
|
// FIXME: Dynamic dispatch for archetype/existential methods.
|
||||||
Callee callee = getBaseAccessorFunctionRef(gen, loc, constant, selfValue,
|
Callee callee = getBaseAccessorFunctionRef(gen, loc, constant, selfValue,
|
||||||
substAccessorType);
|
isSuper, substAccessorType);
|
||||||
|
|
||||||
// If there are substitutions, specialize the generic accessor.
|
// If there are substitutions, specialize the generic accessor.
|
||||||
// FIXME: Generic subscript operator could add another layer of
|
// FIXME: Generic subscript operator could add another layer of
|
||||||
@@ -2501,6 +2507,7 @@ ManagedValue SILGenFunction::
|
|||||||
emitGetAccessor(SILLocation loc, AbstractStorageDecl *decl,
|
emitGetAccessor(SILLocation loc, AbstractStorageDecl *decl,
|
||||||
ArrayRef<Substitution> substitutions,
|
ArrayRef<Substitution> substitutions,
|
||||||
RValueSource &&selfValue,
|
RValueSource &&selfValue,
|
||||||
|
bool isSuper,
|
||||||
RValueSource &&subscripts,
|
RValueSource &&subscripts,
|
||||||
SGFContext c) {
|
SGFContext c) {
|
||||||
|
|
||||||
@@ -2509,7 +2516,8 @@ emitGetAccessor(SILLocation loc, AbstractStorageDecl *decl,
|
|||||||
decl->usesObjCGetterAndSetter());
|
decl->usesObjCGetterAndSetter());
|
||||||
|
|
||||||
Callee getter = emitSpecializedAccessorFunctionRef(*this, loc, get,
|
Callee getter = emitSpecializedAccessorFunctionRef(*this, loc, get,
|
||||||
substitutions, selfValue);
|
substitutions, selfValue,
|
||||||
|
isSuper);
|
||||||
CanAnyFunctionType accessType = getter.getSubstFormalType();
|
CanAnyFunctionType accessType = getter.getSubstFormalType();
|
||||||
|
|
||||||
CallEmission emission(*this, std::move(getter));
|
CallEmission emission(*this, std::move(getter));
|
||||||
@@ -2533,6 +2541,7 @@ emitGetAccessor(SILLocation loc, AbstractStorageDecl *decl,
|
|||||||
void SILGenFunction::emitSetAccessor(SILLocation loc, AbstractStorageDecl *decl,
|
void SILGenFunction::emitSetAccessor(SILLocation loc, AbstractStorageDecl *decl,
|
||||||
ArrayRef<Substitution> substitutions,
|
ArrayRef<Substitution> substitutions,
|
||||||
RValueSource &&selfValue,
|
RValueSource &&selfValue,
|
||||||
|
bool isSuper,
|
||||||
RValueSource &&subscripts,
|
RValueSource &&subscripts,
|
||||||
RValueSource &&setValue) {
|
RValueSource &&setValue) {
|
||||||
SILDeclRef set(decl, SILDeclRef::Kind::Setter,
|
SILDeclRef set(decl, SILDeclRef::Kind::Setter,
|
||||||
@@ -2540,7 +2549,8 @@ void SILGenFunction::emitSetAccessor(SILLocation loc, AbstractStorageDecl *decl,
|
|||||||
decl->usesObjCGetterAndSetter());
|
decl->usesObjCGetterAndSetter());
|
||||||
|
|
||||||
Callee setter = emitSpecializedAccessorFunctionRef(*this, loc, set,
|
Callee setter = emitSpecializedAccessorFunctionRef(*this, loc, set,
|
||||||
substitutions, selfValue);
|
substitutions, selfValue,
|
||||||
|
isSuper);
|
||||||
CanAnyFunctionType accessType = setter.getSubstFormalType();
|
CanAnyFunctionType accessType = setter.getSubstFormalType();
|
||||||
|
|
||||||
CallEmission emission(*this, std::move(setter));
|
CallEmission emission(*this, std::move(setter));
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ emitRValueForDecl(SILLocation loc, ConcreteDeclRef declRef, Type ncRefType,
|
|||||||
// Global properties have no base or subscript.
|
// Global properties have no base or subscript.
|
||||||
return emitGetAccessor(loc, var,
|
return emitGetAccessor(loc, var,
|
||||||
ArrayRef<Substitution>(), RValueSource(),
|
ArrayRef<Substitution>(), RValueSource(),
|
||||||
RValueSource(), C);
|
/*isSuper=*/false, RValueSource(), C);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the referenced decl isn't a VarDecl, it should be a constant of some
|
// If the referenced decl isn't a VarDecl, it should be a constant of some
|
||||||
@@ -533,6 +533,7 @@ static AbstractionPattern getOrigFormalRValueType(Type formalStorageType) {
|
|||||||
/// is designed to work with RValue ManagedValue bases that are either +0 or +1.
|
/// is designed to work with RValue ManagedValue bases that are either +0 or +1.
|
||||||
ManagedValue SILGenFunction::
|
ManagedValue SILGenFunction::
|
||||||
emitRValueForPropertyLoad(SILLocation loc, ManagedValue base,
|
emitRValueForPropertyLoad(SILLocation loc, ManagedValue base,
|
||||||
|
bool isSuper,
|
||||||
VarDecl *FieldDecl,
|
VarDecl *FieldDecl,
|
||||||
ArrayRef<Substitution> substitutions,
|
ArrayRef<Substitution> substitutions,
|
||||||
bool isDirectPropertyAccess,
|
bool isDirectPropertyAccess,
|
||||||
@@ -548,7 +549,7 @@ emitRValueForPropertyLoad(SILLocation loc, ManagedValue base,
|
|||||||
RValueSource baseRV = prepareAccessorBaseArg(loc, base,
|
RValueSource baseRV = prepareAccessorBaseArg(loc, base,
|
||||||
FieldDecl->getGetter());
|
FieldDecl->getGetter());
|
||||||
return emitGetAccessor(loc, FieldDecl, substitutions,
|
return emitGetAccessor(loc, FieldDecl, substitutions,
|
||||||
std::move(baseRV), RValueSource(), C);
|
std::move(baseRV), isSuper, RValueSource(), C);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(FieldDecl->hasStorage() &&
|
assert(FieldDecl->hasStorage() &&
|
||||||
@@ -1272,7 +1273,8 @@ RValue RValueEmitter::visitMemberRefExpr(MemberRefExpr *E, SGFContext C) {
|
|||||||
// works with +0 bases correctly, we ask for them to come back.
|
// works with +0 bases correctly, we ask for them to come back.
|
||||||
ManagedValue base = SGF.emitRValueAsSingleValue(E->getBase(),
|
ManagedValue base = SGF.emitRValueAsSingleValue(E->getBase(),
|
||||||
SGFContext::AllowPlusZero);
|
SGFContext::AllowPlusZero);
|
||||||
ManagedValue res = SGF.emitRValueForPropertyLoad(E, base, FieldDecl,
|
ManagedValue res = SGF.emitRValueForPropertyLoad(E, base, E->isSuper(),
|
||||||
|
FieldDecl,
|
||||||
E->getMember().getSubstitutions(),
|
E->getMember().getSubstitutions(),
|
||||||
E->isDirectPropertyAccess(),
|
E->isDirectPropertyAccess(),
|
||||||
E->getType(), C);
|
E->getType(), C);
|
||||||
@@ -1330,7 +1332,8 @@ RValue RValueEmitter::visitSubscriptExpr(SubscriptExpr *E, SGFContext C) {
|
|||||||
|
|
||||||
ManagedValue MV =
|
ManagedValue MV =
|
||||||
SGF.emitGetAccessor(E, decl, E->getDecl().getSubstitutions(),
|
SGF.emitGetAccessor(E, decl, E->getDecl().getSubstitutions(),
|
||||||
std::move(baseRV), std::move(subscriptRV), C);
|
std::move(baseRV), E->isSuper(),
|
||||||
|
std::move(subscriptRV), C);
|
||||||
return RValue(SGF, E, MV);
|
return RValue(SGF, E, MV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -582,7 +582,7 @@ public:
|
|||||||
|
|
||||||
/// Produce a singular RValue for a load from the specified property.
|
/// Produce a singular RValue for a load from the specified property.
|
||||||
ManagedValue emitRValueForPropertyLoad(SILLocation loc, ManagedValue base,
|
ManagedValue emitRValueForPropertyLoad(SILLocation loc, ManagedValue base,
|
||||||
VarDecl *property,
|
bool isSuper, VarDecl *property,
|
||||||
ArrayRef<Substitution> substitutions,
|
ArrayRef<Substitution> substitutions,
|
||||||
bool isDirectPropertyAccess,
|
bool isDirectPropertyAccess,
|
||||||
Type propTy, SGFContext C);
|
Type propTy, SGFContext C);
|
||||||
@@ -601,11 +601,13 @@ public:
|
|||||||
ManagedValue emitGetAccessor(SILLocation loc, AbstractStorageDecl *decl,
|
ManagedValue emitGetAccessor(SILLocation loc, AbstractStorageDecl *decl,
|
||||||
ArrayRef<Substitution> substitutions,
|
ArrayRef<Substitution> substitutions,
|
||||||
RValueSource &&optionalSelfValue,
|
RValueSource &&optionalSelfValue,
|
||||||
|
bool isSuper,
|
||||||
RValueSource &&optionalSubscripts,
|
RValueSource &&optionalSubscripts,
|
||||||
SGFContext C);
|
SGFContext C);
|
||||||
void emitSetAccessor(SILLocation loc, AbstractStorageDecl *decl,
|
void emitSetAccessor(SILLocation loc, AbstractStorageDecl *decl,
|
||||||
ArrayRef<Substitution> substitutions,
|
ArrayRef<Substitution> substitutions,
|
||||||
RValueSource &&optionalSelfValue,
|
RValueSource &&optionalSelfValue,
|
||||||
|
bool isSuper,
|
||||||
RValueSource &&optionalSubscripts,
|
RValueSource &&optionalSubscripts,
|
||||||
RValueSource &&value);
|
RValueSource &&value);
|
||||||
|
|
||||||
|
|||||||
@@ -341,6 +341,7 @@ namespace {
|
|||||||
class GetterSetterComponent : public LogicalPathComponent {
|
class GetterSetterComponent : public LogicalPathComponent {
|
||||||
// The VarDecl or SubscriptDecl being get/set.
|
// The VarDecl or SubscriptDecl being get/set.
|
||||||
AbstractStorageDecl *decl;
|
AbstractStorageDecl *decl;
|
||||||
|
bool IsSuper;
|
||||||
std::vector<Substitution> substitutions;
|
std::vector<Substitution> substitutions;
|
||||||
Expr *subscriptIndexExpr;
|
Expr *subscriptIndexExpr;
|
||||||
mutable RValue origSubscripts;
|
mutable RValue origSubscripts;
|
||||||
@@ -373,11 +374,13 @@ namespace {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
GetterSetterComponent(AbstractStorageDecl *decl,
|
GetterSetterComponent(AbstractStorageDecl *decl,
|
||||||
|
bool isSuper,
|
||||||
ArrayRef<Substitution> substitutions,
|
ArrayRef<Substitution> substitutions,
|
||||||
LValueTypeData typeData,
|
LValueTypeData typeData,
|
||||||
Expr *subscriptIndexExpr = nullptr)
|
Expr *subscriptIndexExpr = nullptr)
|
||||||
: LogicalPathComponent(typeData),
|
: LogicalPathComponent(typeData),
|
||||||
decl(decl),
|
decl(decl),
|
||||||
|
IsSuper(isSuper),
|
||||||
substitutions(substitutions.begin(), substitutions.end()),
|
substitutions(substitutions.begin(), substitutions.end()),
|
||||||
subscriptIndexExpr(subscriptIndexExpr)
|
subscriptIndexExpr(subscriptIndexExpr)
|
||||||
{
|
{
|
||||||
@@ -388,6 +391,7 @@ namespace {
|
|||||||
SILLocation loc)
|
SILLocation loc)
|
||||||
: LogicalPathComponent(copied.getTypeData()),
|
: LogicalPathComponent(copied.getTypeData()),
|
||||||
decl(copied.decl),
|
decl(copied.decl),
|
||||||
|
IsSuper(copied.IsSuper),
|
||||||
substitutions(copied.substitutions),
|
substitutions(copied.substitutions),
|
||||||
subscriptIndexExpr(copied.subscriptIndexExpr),
|
subscriptIndexExpr(copied.subscriptIndexExpr),
|
||||||
origSubscripts(copied.origSubscripts.copy(gen, loc))
|
origSubscripts(copied.origSubscripts.copy(gen, loc))
|
||||||
@@ -400,7 +404,7 @@ namespace {
|
|||||||
auto args = prepareAccessorArgs(gen, loc, base, decl->getSetter());
|
auto args = prepareAccessorArgs(gen, loc, base, decl->getSetter());
|
||||||
|
|
||||||
return gen.emitSetAccessor(loc, decl, substitutions,
|
return gen.emitSetAccessor(loc, decl, substitutions,
|
||||||
std::move(args.base),
|
std::move(args.base), IsSuper,
|
||||||
std::move(args.subscripts),
|
std::move(args.subscripts),
|
||||||
std::move(rvalue));
|
std::move(rvalue));
|
||||||
}
|
}
|
||||||
@@ -410,7 +414,7 @@ namespace {
|
|||||||
auto args = prepareAccessorArgs(gen, loc, base, decl->getGetter());
|
auto args = prepareAccessorArgs(gen, loc, base, decl->getGetter());
|
||||||
|
|
||||||
return gen.emitGetAccessor(loc, decl, substitutions,
|
return gen.emitGetAccessor(loc, decl, substitutions,
|
||||||
std::move(args.base),
|
std::move(args.base), IsSuper,
|
||||||
std::move(args.subscripts), c);
|
std::move(args.subscripts), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,7 +527,8 @@ static LValue emitLValueForNonMemberVarDecl(SILGenFunction &gen,
|
|||||||
substitutions = gen.buildForwardingSubstitutions(genericParams);
|
substitutions = gen.buildForwardingSubstitutions(genericParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
lv.add<GetterSetterComponent>(var, substitutions, typeData);
|
lv.add<GetterSetterComponent>(var, /*isSuper=*/false, substitutions,
|
||||||
|
typeData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::move(lv);
|
return std::move(lv);
|
||||||
@@ -553,8 +558,8 @@ LValue SILGenLValue::visitMemberRefExpr(MemberRefExpr *e) {
|
|||||||
// Use the property accessors if the variable has accessors and this isn't a
|
// Use the property accessors if the variable has accessors and this isn't a
|
||||||
// direct access to underlying storage.
|
// direct access to underlying storage.
|
||||||
if (var->hasAccessorFunctions() && !e->isDirectPropertyAccess()) {
|
if (var->hasAccessorFunctions() && !e->isDirectPropertyAccess()) {
|
||||||
lv.add<GetterSetterComponent>(var, e->getMember().getSubstitutions(),
|
lv.add<GetterSetterComponent>(var, e->isSuper(),
|
||||||
typeData);
|
e->getMember().getSubstitutions(), typeData);
|
||||||
return std::move(lv);
|
return std::move(lv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,7 +602,8 @@ LValue SILGenLValue::visitSubscriptExpr(SubscriptExpr *e) {
|
|||||||
auto typeData = getMemberTypeData(gen, decl->getElementType(), e);
|
auto typeData = getMemberTypeData(gen, decl->getElementType(), e);
|
||||||
|
|
||||||
LValue lv = visitRec(e->getBase());
|
LValue lv = visitRec(e->getBase());
|
||||||
lv.add<GetterSetterComponent>(decl, e->getDecl().getSubstitutions(),
|
lv.add<GetterSetterComponent>(decl, e->isSuper(),
|
||||||
|
e->getDecl().getSubstitutions(),
|
||||||
typeData, e->getIndex());
|
typeData, e->getIndex());
|
||||||
return std::move(lv);
|
return std::move(lv);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -382,7 +382,7 @@ static SILBasicBlock *emitDispatchAndDestructure(SILGenFunction &gen,
|
|||||||
|
|
||||||
for (auto &elt : np->getElements()) {
|
for (auto &elt : np->getElements()) {
|
||||||
ManagedValue MV = ManagedValue::forUnmanaged(v);
|
ManagedValue MV = ManagedValue::forUnmanaged(v);
|
||||||
auto Val = gen.emitRValueForPropertyLoad(loc, MV, elt.getProperty(),
|
auto Val = gen.emitRValueForPropertyLoad(loc, MV, false, elt.getProperty(),
|
||||||
// FIXME: No generic substitions.
|
// FIXME: No generic substitions.
|
||||||
{}, false,
|
{}, false,
|
||||||
elt.getSubPattern()->getType(),
|
elt.getSubPattern()->getType(),
|
||||||
|
|||||||
@@ -401,6 +401,8 @@ namespace {
|
|||||||
auto &tc = cs.getTypeChecker();
|
auto &tc = cs.getTypeChecker();
|
||||||
auto &context = tc.Context;
|
auto &context = tc.Context;
|
||||||
|
|
||||||
|
bool isSuper = isa<SuperRefExpr>(base->getSemanticsProvidingExpr());
|
||||||
|
|
||||||
Type baseTy = base->getType()->getRValueType();
|
Type baseTy = base->getType()->getRValueType();
|
||||||
|
|
||||||
// Explicit member accesses are permitted to implicitly look
|
// Explicit member accesses are permitted to implicitly look
|
||||||
@@ -547,6 +549,7 @@ namespace {
|
|||||||
= new (context) MemberRefExpr(base, dotLoc, memberRef,
|
= new (context) MemberRefExpr(base, dotLoc, memberRef,
|
||||||
memberLoc, Implicit,
|
memberLoc, Implicit,
|
||||||
IsDirectPropertyAccess);
|
IsDirectPropertyAccess);
|
||||||
|
result->setIsSuper(isSuper);
|
||||||
|
|
||||||
// Skip the synthesized 'self' input type of the opened type.
|
// Skip the synthesized 'self' input type of the opened type.
|
||||||
result->setType(simplifyType(openedType));
|
result->setType(simplifyType(openedType));
|
||||||
@@ -752,6 +755,9 @@ namespace {
|
|||||||
auto &tc = cs.getTypeChecker();
|
auto &tc = cs.getTypeChecker();
|
||||||
auto baseTy = base->getType()->getRValueType();
|
auto baseTy = base->getType()->getRValueType();
|
||||||
|
|
||||||
|
// Check whether the base is 'super'.
|
||||||
|
bool isSuper = isa<SuperRefExpr>(base->getSemanticsProvidingExpr());
|
||||||
|
|
||||||
// Handle accesses that implicitly look through UncheckedOptional<T>.
|
// Handle accesses that implicitly look through UncheckedOptional<T>.
|
||||||
if (auto objTy = cs.lookThroughUncheckedOptionalType(baseTy)) {
|
if (auto objTy = cs.lookThroughUncheckedOptionalType(baseTy)) {
|
||||||
base = coerceUncheckedOptionalToValue(base, objTy, locator);
|
base = coerceUncheckedOptionalToValue(base, objTy, locator);
|
||||||
@@ -844,6 +850,7 @@ namespace {
|
|||||||
subscript,
|
subscript,
|
||||||
substitutions));
|
substitutions));
|
||||||
subscriptExpr->setType(resultTy);
|
subscriptExpr->setType(resultTy);
|
||||||
|
subscriptExpr->setIsSuper(isSuper);
|
||||||
return subscriptExpr;
|
return subscriptExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -876,6 +883,7 @@ namespace {
|
|||||||
auto *subscriptExpr
|
auto *subscriptExpr
|
||||||
= new (tc.Context) SubscriptExpr(base, index, subscript);
|
= new (tc.Context) SubscriptExpr(base, index, subscript);
|
||||||
subscriptExpr->setType(resultTy);
|
subscriptExpr->setType(resultTy);
|
||||||
|
subscriptExpr->setIsSuper(isSuper);
|
||||||
return subscriptExpr;
|
return subscriptExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user