Skip to content

Commit dad1557

Browse files
committed
[SE-0111] Store argument labels directly on object literal expressions.
1 parent 5ca9f88 commit dad1557

File tree

5 files changed

+254
-164
lines changed

5 files changed

+254
-164
lines changed

include/swift/AST/Expr.h

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,22 @@ class alignas(8) Expr {
273273
enum { NumMagicIdentifierLiteralExprBits = NumLiteralExprBits + 4 };
274274
static_assert(NumMagicIdentifierLiteralExprBits <= 32, "fits in an unsigned");
275275

276+
class ObjectLiteralExprBitfields {
277+
friend class ObjectLiteralExpr;
278+
unsigned : NumLiteralExprBits;
279+
280+
unsigned LitKind : 3;
281+
/// # of argument labels stored after the ObjectLiteralExpr.
282+
unsigned NumArgLabels : 16;
283+
/// Whether the ObjectLiteralExpr also has source locations for the argument
284+
/// label.
285+
unsigned HasArgLabelLocs : 1;
286+
/// Whether the last argument is a trailing closure.
287+
unsigned HasTrailingClosure : 1;
288+
};
289+
enum { NumObjectLiteralExprBits = NumLiteralExprBits + 21 };
290+
static_assert(NumObjectLiteralExprBits <= 32, "fits in an unsigned");
291+
276292
class AbstractClosureExprBitfields {
277293
friend class AbstractClosureExpr;
278294
unsigned : NumExprBits;
@@ -399,6 +415,7 @@ class alignas(8) Expr {
399415
OverloadedMemberRefExprBitfields OverloadedMemberRefExprBits;
400416
BooleanLiteralExprBitfields BooleanLiteralExprBits;
401417
MagicIdentifierLiteralExprBitfields MagicIdentifierLiteralExprBits;
418+
ObjectLiteralExprBitfields ObjectLiteralExprBits;
402419
AbstractClosureExprBitfields AbstractClosureExprBits;
403420
ClosureExprBitfields ClosureExprBits;
404421
BindOptionalExprBitfields BindOptionalExprBits;
@@ -1004,7 +1021,9 @@ class MagicIdentifierLiteralExpr : public LiteralExpr {
10041021
// '#colorLiteral(red: 1, blue: 0, green: 0, alpha: 1)' with a name and a list
10051022
// argument. The components of the list argument are meant to be themselves
10061023
// constant.
1007-
class ObjectLiteralExpr : public LiteralExpr {
1024+
class ObjectLiteralExpr final
1025+
: public LiteralExpr,
1026+
public TrailingCallArguments<ObjectLiteralExpr> {
10081027
public:
10091028
/// The kind of object literal.
10101029
enum LiteralKind : unsigned {
@@ -1013,29 +1032,54 @@ class ObjectLiteralExpr : public LiteralExpr {
10131032
};
10141033

10151034
private:
1016-
LiteralKind LitKind;
10171035
Expr *Arg;
10181036
Expr *SemanticExpr;
10191037
SourceLoc PoundLoc;
10201038

1021-
public:
10221039
ObjectLiteralExpr(SourceLoc PoundLoc, LiteralKind LitKind,
1023-
Expr *Arg, bool implicit = false)
1024-
: LiteralExpr(ExprKind::ObjectLiteral, implicit),
1025-
LitKind(LitKind), Arg(Arg), SemanticExpr(nullptr),
1026-
PoundLoc(PoundLoc) {}
1040+
Expr *Arg,
1041+
ArrayRef<Identifier> argLabels,
1042+
ArrayRef<SourceLoc> argLabelLocs,
1043+
bool hasTrailingClosure,
1044+
bool implicit);
1045+
1046+
public:
1047+
/// Create a new object literal expression.
1048+
///
1049+
/// Note: prefer to use the second entry point, which separates out
1050+
/// arguments/labels/etc.
1051+
static ObjectLiteralExpr *create(ASTContext &ctx, SourceLoc poundLoc,
1052+
LiteralKind kind, Expr *arg, bool implicit);
10271053

1028-
LiteralKind getLiteralKind() const { return LitKind; }
1054+
/// Create a new object literal expression.
1055+
static ObjectLiteralExpr *create(ASTContext &ctx, SourceLoc poundLoc,
1056+
LiteralKind kind,
1057+
SourceLoc lParenLoc,
1058+
ArrayRef<Expr *> args,
1059+
ArrayRef<Identifier> argLabels,
1060+
ArrayRef<SourceLoc> argLabelLocs,
1061+
SourceLoc rParenLoc,
1062+
Expr *trailingClosure,
1063+
bool implicit);
1064+
1065+
LiteralKind getLiteralKind() const {
1066+
return static_cast<LiteralKind>(ObjectLiteralExprBits.LitKind);
1067+
}
10291068

10301069
Expr *getArg() const { return Arg; }
10311070
void setArg(Expr *arg) { Arg = arg; }
10321071

1033-
/// Retrieve the argument labels for the argument.
1034-
///
1035-
/// \param scratch Scratch space that will be used when the argument labels
1036-
/// aren't already stored in the AST context.
1037-
ArrayRef<Identifier>
1038-
getArgumentLabels(SmallVectorImpl<Identifier> &scratch) const;
1072+
unsigned getNumArguments() const {
1073+
return ObjectLiteralExprBits.NumArgLabels;
1074+
}
1075+
bool hasArgumentLabelLocs() const {
1076+
return ObjectLiteralExprBits.HasArgLabelLocs;
1077+
}
1078+
1079+
/// Whether this call with written with a trailing closure.
1080+
bool hasTrailingClosure() const {
1081+
return ObjectLiteralExprBits.HasTrailingClosure;
1082+
}
10391083

10401084
Expr *getSemanticExpr() const { return SemanticExpr; }
10411085
void setSemanticExpr(Expr *expr) { SemanticExpr = expr; }
@@ -3466,6 +3510,9 @@ class ApplyExpr : public Expr {
34663510
ArrayRef<Identifier>
34673511
getArgumentLabels(SmallVectorImpl<Identifier> &scratch) const;
34683512

3513+
/// Whether this application was written using a trailing closure.
3514+
bool hasTrailingClosure() const;
3515+
34693516
static bool classof(const Expr *E) {
34703517
return E->getKind() >= ExprKind::First_ApplyExpr &&
34713518
E->getKind() <= ExprKind::Last_ApplyExpr;

0 commit comments

Comments
 (0)