Skip to content

Commit 3843d39

Browse files
authored
Merge pull request #16741 from davezarzycki/nfc_create_abstract_LookupExpr
[AST] NFC: Create abstract class for MemberRefExpr/SubscriptExpr
2 parents 7f042a7 + 6d52f43 commit 3843d39

File tree

5 files changed

+80
-115
lines changed

5 files changed

+80
-115
lines changed

include/swift/AST/Expr.h

Lines changed: 64 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ class alignas(8) Expr {
156156

157157
SWIFT_INLINE_BITFIELD_EMPTY(LiteralExpr, Expr);
158158
SWIFT_INLINE_BITFIELD_EMPTY(IdentityExpr, Expr);
159+
SWIFT_INLINE_BITFIELD(LookupExpr, Expr, 1,
160+
IsSuper : 1
161+
);
162+
SWIFT_INLINE_BITFIELD_EMPTY(DynamicLookupExpr, LookupExpr);
159163

160164
SWIFT_INLINE_BITFIELD(ParenExpr, IdentityExpr, 1,
161165
/// \brief Whether we're wrapping a trailing closure expression.
@@ -182,9 +186,8 @@ class alignas(8) Expr {
182186
FunctionRefKind : 2
183187
);
184188

185-
SWIFT_INLINE_BITFIELD(MemberRefExpr, Expr, 2+1,
186-
Semantics : 2, // an AccessSemantics
187-
IsSuper : 1
189+
SWIFT_INLINE_BITFIELD(MemberRefExpr, LookupExpr, 2,
190+
Semantics : 2 // an AccessSemantics
188191
);
189192

190193
SWIFT_INLINE_BITFIELD_FULL(TupleElementExpr, Expr, 32,
@@ -210,9 +213,8 @@ class alignas(8) Expr {
210213
FunctionRefKind : 2
211214
);
212215

213-
SWIFT_INLINE_BITFIELD_FULL(SubscriptExpr, Expr, 2+1+16+1+1,
216+
SWIFT_INLINE_BITFIELD_FULL(SubscriptExpr, LookupExpr, 2+1+1+16,
214217
Semantics : 2, // an AccessSemantics
215-
IsSuper : 1,
216218
/// Whether the SubscriptExpr also has source locations for the argument
217219
/// label.
218220
HasArgLabelLocs : 1,
@@ -223,7 +225,7 @@ class alignas(8) Expr {
223225
NumArgLabels : 16
224226
);
225227

226-
SWIFT_INLINE_BITFIELD_FULL(DynamicSubscriptExpr, Expr, 1+1+16,
228+
SWIFT_INLINE_BITFIELD_FULL(DynamicSubscriptExpr, DynamicLookupExpr, 1+1+16,
227229
/// Whether the DynamicSubscriptExpr also has source locations for the
228230
/// argument label.
229231
HasArgLabelLocs : 1,
@@ -1489,47 +1491,79 @@ class UnresolvedDeclRefExpr : public Expr {
14891491
return E->getKind() == ExprKind::UnresolvedDeclRef;
14901492
}
14911493
};
1494+
1495+
/// LookupExpr - This abstract class represents 'a.b', 'a[]', etc where we
1496+
/// are referring to a member of a type, such as a property, variable, etc.
1497+
class LookupExpr : public Expr {
1498+
Expr *Base;
1499+
ConcreteDeclRef Member;
1500+
1501+
protected:
1502+
explicit LookupExpr(ExprKind Kind, Expr *base, ConcreteDeclRef member,
1503+
bool Implicit)
1504+
: Expr(Kind, Implicit), Base(base), Member(member) {
1505+
Bits.LookupExpr.IsSuper = false;
1506+
assert(Base);
1507+
}
1508+
1509+
public:
1510+
/// Retrieve the base of the expression.
1511+
Expr *getBase() const { return Base; }
1512+
1513+
/// Replace the base of the expression.
1514+
void setBase(Expr *E) { Base = E; }
1515+
1516+
/// Retrieve the member to which this access refers.
1517+
ConcreteDeclRef getMember() const { return Member; }
1518+
1519+
/// Determine whether the operation has a known underlying declaration or not.
1520+
bool hasDecl() const { return static_cast<bool>(Member); }
14921521

1522+
/// Retrieve the declaration that this /// operation refers to.
1523+
/// Only valid when \c hasDecl() is true.
1524+
ConcreteDeclRef getDecl() const {
1525+
assert(hasDecl() && "No subscript declaration known!");
1526+
return getMember();
1527+
}
1528+
1529+
/// Determine whether this reference refers to the superclass's property.
1530+
bool isSuper() const { return Bits.LookupExpr.IsSuper; }
1531+
1532+
/// Set whether this reference refers to the superclass's property.
1533+
void setIsSuper(bool isSuper) { Bits.LookupExpr.IsSuper = isSuper; }
1534+
1535+
static bool classof(const Expr *E) {
1536+
return E->getKind() >= ExprKind::First_LookupExpr &&
1537+
E->getKind() <= ExprKind::Last_LookupExpr;
1538+
}
1539+
};
1540+
14931541
/// MemberRefExpr - This represents 'a.b' where we are referring to a member
14941542
/// of a type, such as a property or variable.
14951543
///
14961544
/// Note that methods found via 'dot' syntax are expressed as DotSyntaxCallExpr
14971545
/// nodes, because 'a.f' is actually an application of 'a' (the implicit object
14981546
/// argument) to the function 'f'.
1499-
class MemberRefExpr : public Expr {
1500-
Expr *Base;
1501-
ConcreteDeclRef Member;
1547+
class MemberRefExpr : public LookupExpr {
15021548
SourceLoc DotLoc;
15031549
DeclNameLoc NameLoc;
15041550

15051551
public:
15061552
MemberRefExpr(Expr *base, SourceLoc dotLoc, ConcreteDeclRef member,
15071553
DeclNameLoc loc, bool Implicit,
15081554
AccessSemantics semantics = AccessSemantics::Ordinary);
1509-
Expr *getBase() const { return Base; }
1510-
ConcreteDeclRef getMember() const { return Member; }
1511-
DeclNameLoc getNameLoc() const { return NameLoc; }
15121555
SourceLoc getDotLoc() const { return DotLoc; }
1513-
1514-
void setBase(Expr *E) { Base = E; }
1556+
DeclNameLoc getNameLoc() const { return NameLoc; }
15151557

15161558
/// Return true if this member access is direct, meaning that it
15171559
/// does not call the getter or setter.
15181560
AccessSemantics getAccessSemantics() const {
15191561
return (AccessSemantics) Bits.MemberRefExpr.Semantics;
15201562
}
15211563

1522-
/// Determine whether this member reference refers to the
1523-
/// superclass's property.
1524-
bool isSuper() const { return Bits.MemberRefExpr.IsSuper; }
1525-
1526-
/// Set whether this member reference refers to the superclass's
1527-
/// property.
1528-
void setIsSuper(bool isSuper) { Bits.MemberRefExpr.IsSuper = isSuper; }
1529-
15301564
SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
15311565
SourceLoc getStartLoc() const {
1532-
SourceLoc BaseStartLoc = Base->getStartLoc();
1566+
SourceLoc BaseStartLoc = getBase()->getStartLoc();
15331567
if (BaseStartLoc.isInvalid() || NameLoc.isInvalid()) {
15341568
return NameLoc.getBaseNameLoc();
15351569
} else {
@@ -1548,24 +1582,12 @@ class MemberRefExpr : public Expr {
15481582
/// Common base for expressions that involve dynamic lookup, which
15491583
/// determines at runtime whether a particular method, property, or
15501584
/// subscript is available.
1551-
class DynamicLookupExpr : public Expr {
1585+
class DynamicLookupExpr : public LookupExpr {
15521586
protected:
1553-
Expr *Base;
1554-
ConcreteDeclRef Member;
1555-
15561587
explicit DynamicLookupExpr(ExprKind kind, ConcreteDeclRef member, Expr *base)
1557-
: Expr(kind, /*Implicit=*/false), Base(base), Member(member) { }
1588+
: LookupExpr(kind, base, member, /*Implicit=*/false) { }
15581589

15591590
public:
1560-
/// Retrieve the member to which this access refers.
1561-
ConcreteDeclRef getMember() const { return Member; }
1562-
1563-
/// Retrieve the base of the expression.
1564-
Expr *getBase() const { return Base; }
1565-
1566-
/// Replace the base of the expression.
1567-
void setBase(Expr *base) { Base = base; }
1568-
15691591
static bool classof(const Expr *E) {
15701592
return E->getKind() >= ExprKind::First_DynamicLookupExpr &&
15711593
E->getKind() <= ExprKind::Last_DynamicLookupExpr;
@@ -1608,7 +1630,7 @@ class DynamicMemberRefExpr : public DynamicLookupExpr {
16081630
SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
16091631

16101632
SourceLoc getStartLoc() const {
1611-
SourceLoc BaseStartLoc = Base->getStartLoc();
1633+
SourceLoc BaseStartLoc = getBase()->getStartLoc();
16121634
if (BaseStartLoc.isInvalid() || NameLoc.isInvalid()) {
16131635
return NameLoc.getBaseNameLoc();
16141636
} else {
@@ -1676,12 +1698,6 @@ class DynamicSubscriptExpr final
16761698
ConcreteDeclRef decl,
16771699
bool implicit);
16781700

1679-
/// Retrieve the base of the expression.
1680-
Expr *getBase() const { return Base; }
1681-
1682-
/// Replace the base of the expression.
1683-
void setBase(Expr *base) { Base = base; }
1684-
16851701
/// getIndex - Retrieve the index of the subscript expression, i.e., the
16861702
/// "offset" into the base value.
16871703
Expr *getIndex() const { return Index; }
@@ -1702,7 +1718,7 @@ class DynamicSubscriptExpr final
17021718

17031719
SourceLoc getLoc() const { return Index->getStartLoc(); }
17041720

1705-
SourceLoc getStartLoc() const { return Base->getStartLoc(); }
1721+
SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
17061722
SourceLoc getEndLoc() const { return Index->getEndLoc(); }
17071723

17081724
static bool classof(const Expr *E) {
@@ -2230,12 +2246,10 @@ class DictionaryExpr final : public CollectionExpr,
22302246
/// type-checked and well-formed subscript expression refers to a subscript
22312247
/// declaration, which provides a getter and (optionally) a setter that will
22322248
/// be used to perform reads/writes.
2233-
class SubscriptExpr final : public Expr,
2249+
class SubscriptExpr final : public LookupExpr,
22342250
public TrailingCallArguments<SubscriptExpr> {
22352251
friend TrailingCallArguments;
22362252

2237-
ConcreteDeclRef TheDecl;
2238-
Expr *Base;
22392253
Expr *Index;
22402254

22412255
SubscriptExpr(Expr *base, Expr *index, ArrayRef<Identifier> argLabels,
@@ -2267,11 +2281,6 @@ class SubscriptExpr final : public Expr,
22672281
AccessSemantics semantics
22682282
= AccessSemantics::Ordinary);
22692283

2270-
/// getBase - Retrieve the base of the subscript expression, i.e., the
2271-
/// value being indexed.
2272-
Expr *getBase() const { return Base; }
2273-
void setBase(Expr *E) { Base = E; }
2274-
22752284
/// getIndex - Retrieve the index of the subscript expression, i.e., the
22762285
/// "offset" into the base value.
22772286
Expr *getIndex() const { return Index; }
@@ -2296,30 +2305,11 @@ class SubscriptExpr final : public Expr,
22962305
return (AccessSemantics) Bits.SubscriptExpr.Semantics;
22972306
}
22982307

2299-
/// Determine whether this member reference refers to the
2300-
/// superclass's property.
2301-
bool isSuper() const { return Bits.SubscriptExpr.IsSuper; }
2302-
2303-
/// Set whether this member reference refers to the superclass's
2304-
/// property.
2305-
void setIsSuper(bool isSuper) { Bits.SubscriptExpr.IsSuper = isSuper; }
2306-
2307-
/// Determine whether subscript operation has a known underlying
2308-
/// subscript declaration or not.
2309-
bool hasDecl() const { return static_cast<bool>(TheDecl); }
2310-
2311-
/// Retrieve the subscript declaration that this subscripting
2312-
/// operation refers to. Only valid when \c hasDecl() is true.
2313-
ConcreteDeclRef getDecl() const {
2314-
assert(hasDecl() && "No subscript declaration known!");
2315-
return TheDecl;
2316-
}
2317-
23182308
SourceLoc getLoc() const { return Index->getStartLoc(); }
2319-
SourceLoc getStartLoc() const { return Base->getStartLoc(); }
2309+
SourceLoc getStartLoc() const { return getBase()->getStartLoc(); }
23202310
SourceLoc getEndLoc() const {
23212311
auto end = Index->getEndLoc();
2322-
return end.isValid() ? end : Base->getEndLoc();
2312+
return end.isValid() ? end : getBase()->getEndLoc();
23232313
}
23242314

23252315
static bool classof(const Expr *E) {

include/swift/AST/ExprNodes.def

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,14 @@ ABSTRACT_EXPR(OverloadSetRef, Expr)
8888
UNCHECKED_EXPR(OverloadedDeclRef, OverloadSetRefExpr)
8989
EXPR_RANGE(OverloadSetRef, OverloadedDeclRef, OverloadedDeclRef)
9090
UNCHECKED_EXPR(UnresolvedDeclRef, Expr)
91-
EXPR(MemberRef, Expr)
92-
ABSTRACT_EXPR(DynamicLookup, Expr)
93-
EXPR(DynamicMemberRef, DynamicLookupExpr)
94-
EXPR(DynamicSubscript, DynamicLookupExpr)
95-
EXPR_RANGE(DynamicLookup, DynamicMemberRef, DynamicSubscript)
91+
ABSTRACT_EXPR(Lookup, Expr)
92+
EXPR(MemberRef, LookupExpr)
93+
EXPR(Subscript, LookupExpr)
94+
ABSTRACT_EXPR(DynamicLookup, LookupExpr)
95+
EXPR(DynamicMemberRef, DynamicLookupExpr)
96+
EXPR(DynamicSubscript, DynamicLookupExpr)
97+
EXPR_RANGE(DynamicLookup, DynamicMemberRef, DynamicSubscript)
98+
EXPR_RANGE(Lookup, MemberRef, DynamicSubscript)
9699
UNCHECKED_EXPR(UnresolvedSpecialize, Expr)
97100
UNCHECKED_EXPR(UnresolvedMember, Expr)
98101
UNCHECKED_EXPR(UnresolvedDot, Expr)
@@ -111,7 +114,6 @@ ABSTRACT_EXPR(Collection, Expr)
111114
EXPR(Array, CollectionExpr)
112115
EXPR(Dictionary, CollectionExpr)
113116
EXPR_RANGE(Collection, Array, Dictionary)
114-
EXPR(Subscript, Expr)
115117
EXPR(KeyPathApplication, Expr)
116118
EXPR(TupleElement, Expr)
117119
EXPR(CaptureList, Expr)

lib/AST/Expr.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,12 +1342,10 @@ ConstructorDecl *OtherConstructorDeclRefExpr::getDecl() const {
13421342
MemberRefExpr::MemberRefExpr(Expr *base, SourceLoc dotLoc,
13431343
ConcreteDeclRef member, DeclNameLoc nameLoc,
13441344
bool Implicit, AccessSemantics semantics)
1345-
: Expr(ExprKind::MemberRef, Implicit), Base(base),
1346-
Member(member), DotLoc(dotLoc), NameLoc(nameLoc) {
1345+
: LookupExpr(ExprKind::MemberRef, base, member, Implicit),
1346+
DotLoc(dotLoc), NameLoc(nameLoc) {
13471347

13481348
Bits.MemberRefExpr.Semantics = (unsigned) semantics;
1349-
Bits.MemberRefExpr.IsSuper = false;
1350-
assert(Member);
13511349
}
13521350

13531351
Type OverloadSetRefExpr::getBaseType() const {
@@ -1588,10 +1586,9 @@ SubscriptExpr::SubscriptExpr(Expr *base, Expr *index,
15881586
bool hasTrailingClosure,
15891587
ConcreteDeclRef decl,
15901588
bool implicit, AccessSemantics semantics)
1591-
: Expr(ExprKind::Subscript, implicit, Type()),
1592-
TheDecl(decl), Base(base), Index(index) {
1589+
: LookupExpr(ExprKind::Subscript, base, decl, implicit),
1590+
Index(index) {
15931591
Bits.SubscriptExpr.Semantics = (unsigned) semantics;
1594-
Bits.SubscriptExpr.IsSuper = false;
15951592
Bits.SubscriptExpr.NumArgLabels = argLabels.size();
15961593
Bits.SubscriptExpr.HasArgLabelLocs = !argLabelLocs.empty();
15971594
Bits.SubscriptExpr.HasTrailingClosure = hasTrailingClosure;

lib/SILGen/SILGenExpr.cpp

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4567,30 +4567,12 @@ static bool mayLieAboutNonOptionalReturn(SILModule &M, Expr *expr) {
45674567
return mayLieAboutNonOptionalReturn(M, load->getSubExpr());
45684568
}
45694569

4570-
// A reference to a member property.
4571-
if (auto member = dyn_cast<MemberRefExpr>(expr)) {
4570+
// A reference to a potentially dynamic member/subscript property.
4571+
if (auto member = dyn_cast<LookupExpr>(expr)) {
45724572
return isVerbatimNullableTypeInC(M, member->getType()) &&
45734573
mayLieAboutNonOptionalReturn(M, member->getMember().getDecl());
45744574
}
45754575

4576-
// A reference to a subscript.
4577-
if (auto subscript = dyn_cast<SubscriptExpr>(expr)) {
4578-
return isVerbatimNullableTypeInC(M, subscript->getType()) &&
4579-
mayLieAboutNonOptionalReturn(M, subscript->getDecl().getDecl());
4580-
}
4581-
4582-
// A reference to a member property found via dynamic lookup.
4583-
if (auto member = dyn_cast<DynamicMemberRefExpr>(expr)) {
4584-
return isVerbatimNullableTypeInC(M, member->getType()) &&
4585-
mayLieAboutNonOptionalReturn(M, member->getMember().getDecl());
4586-
}
4587-
4588-
// A reference to a subscript found via dynamic lookup.
4589-
if (auto subscript = dyn_cast<DynamicSubscriptExpr>(expr)) {
4590-
return isVerbatimNullableTypeInC(M, subscript->getType()) &&
4591-
mayLieAboutNonOptionalReturn(M, subscript->getMember().getDecl());
4592-
}
4593-
45944576
return false;
45954577
}
45964578

lib/Sema/CSApply.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -758,14 +758,8 @@ namespace {
758758
return ctorRef->getArg();
759759
} else if (auto apply = dyn_cast<ApplyExpr>(expr)) {
760760
return apply->getFn();
761-
} else if (auto memberRef = dyn_cast<MemberRefExpr>(expr)) {
762-
return memberRef->getBase();
763-
} else if (auto dynMemberRef = dyn_cast<DynamicMemberRefExpr>(expr)) {
764-
return dynMemberRef->getBase();
765-
} else if (auto subscriptRef = dyn_cast<SubscriptExpr>(expr)) {
766-
return subscriptRef->getBase();
767-
} else if (auto dynSubscriptRef = dyn_cast<DynamicSubscriptExpr>(expr)) {
768-
return dynSubscriptRef->getBase();
761+
} else if (auto lookupRef = dyn_cast<LookupExpr>(expr)) {
762+
return lookupRef->getBase();
769763
} else if (auto load = dyn_cast<LoadExpr>(expr)) {
770764
return load->getSubExpr();
771765
} else if (auto inout = dyn_cast<InOutExpr>(expr)) {

0 commit comments

Comments
 (0)