Skip to content

Commit 64d4465

Browse files
authored
Merge pull request #34132 from Interfere/SR-12022-LiteralExpr-refactoring
SR-12022: refactor LiteralExpr to combine common initializer code
2 parents 04606d5 + 4fa17bf commit 64d4465

File tree

7 files changed

+233
-311
lines changed

7 files changed

+233
-311
lines changed

include/swift/AST/Expr.h

Lines changed: 62 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -613,20 +613,65 @@ class CodeCompletionExpr : public Expr {
613613

614614
/// LiteralExpr - Common base class between the literals.
615615
class LiteralExpr : public Expr {
616+
// Set by Sema:
617+
ConcreteDeclRef Initializer;
618+
616619
public:
617620
LiteralExpr(ExprKind Kind, bool Implicit) : Expr(Kind, Implicit) {}
618621

619622
static bool classof(const Expr *E) {
620623
return E->getKind() >= ExprKind::First_LiteralExpr &&
621624
E->getKind() <= ExprKind::Last_LiteralExpr;
622625
}
626+
627+
/// Retrieve the initializer that will be used to construct the
628+
/// literal from the result of the initializer.
629+
///
630+
/// Only literals that have no builtin literal conformance will have
631+
/// this initializer, which will be called on the result of the builtin
632+
/// initializer.
633+
ConcreteDeclRef getInitializer() const { return Initializer; }
634+
635+
/// Set the initializer that will be used to construct the literal.
636+
void setInitializer(ConcreteDeclRef initializer) {
637+
Initializer = initializer;
638+
}
639+
};
640+
641+
/// BuiltinLiteralExpr - Common base class between all literals
642+
/// that provides BuiltinInitializer
643+
class BuiltinLiteralExpr : public LiteralExpr {
644+
// Set by Seam:
645+
ConcreteDeclRef BuiltinInitializer;
646+
647+
public:
648+
BuiltinLiteralExpr(ExprKind Kind, bool Implicit)
649+
: LiteralExpr(Kind, Implicit) {}
650+
651+
static bool classof(const Expr *E) {
652+
return E->getKind() >= ExprKind::First_BuiltinLiteralExpr &&
653+
E->getKind() <= ExprKind::Last_BuiltinLiteralExpr;
654+
}
655+
656+
/// Retrieve the builtin initializer that will be used to construct the
657+
/// literal.
658+
///
659+
/// Any type-checked literal will have a builtin initializer, which is
660+
/// called first to form a concrete Swift type.
661+
ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }
662+
663+
/// Set the builtin initializer that will be used to construct the
664+
/// literal.
665+
void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
666+
BuiltinInitializer = builtinInitializer;
667+
}
623668
};
624669

625670
/// The 'nil' literal.
626671
///
627672
class NilLiteralExpr : public LiteralExpr {
628673
SourceLoc Loc;
629-
ConcreteDeclRef Initializer;
674+
630675
public:
631676
NilLiteralExpr(SourceLoc Loc, bool Implicit = false)
632677
: LiteralExpr(ExprKind::NilLiteral, Implicit), Loc(Loc) {
@@ -635,42 +680,30 @@ class NilLiteralExpr : public LiteralExpr {
635680
SourceRange getSourceRange() const {
636681
return Loc;
637682
}
638-
639-
/// Retrieve the initializer that will be used to construct the 'nil'
640-
/// literal from the result of the initializer.
641-
ConcreteDeclRef getInitializer() const { return Initializer; }
642-
643-
/// Set the initializer that will be used to construct the 'nil' literal.
644-
void setInitializer(ConcreteDeclRef initializer) {
645-
Initializer = initializer;
646-
}
647683

648684
static bool classof(const Expr *E) {
649685
return E->getKind() == ExprKind::NilLiteral;
650686
}
651687
};
652688

653689
/// Abstract base class for numeric literals, potentially with a sign.
654-
class NumberLiteralExpr : public LiteralExpr {
690+
class NumberLiteralExpr : public BuiltinLiteralExpr {
655691
/// The value of the literal as an ASTContext-owned string. Underscores must
656692
/// be stripped.
657693
StringRef Val; // Use StringRef instead of APInt or APFloat, which leak.
658-
ConcreteDeclRef BuiltinInitializer;
659-
ConcreteDeclRef Initializer;
660694

661695
protected:
662696
SourceLoc MinusLoc;
663697
SourceLoc DigitsLoc;
664698

665699
public:
666-
NumberLiteralExpr(ExprKind Kind,
667-
StringRef Val, SourceLoc DigitsLoc, bool Implicit)
668-
: LiteralExpr(Kind, Implicit), Val(Val), DigitsLoc(DigitsLoc)
669-
{
670-
Bits.NumberLiteralExpr.IsNegative = false;
671-
Bits.NumberLiteralExpr.IsExplicitConversion = false;
672-
}
673-
700+
NumberLiteralExpr(ExprKind Kind, StringRef Val, SourceLoc DigitsLoc,
701+
bool Implicit)
702+
: BuiltinLiteralExpr(Kind, Implicit), Val(Val), DigitsLoc(DigitsLoc) {
703+
Bits.NumberLiteralExpr.IsNegative = false;
704+
Bits.NumberLiteralExpr.IsExplicitConversion = false;
705+
}
706+
674707
bool isNegative() const { return Bits.NumberLiteralExpr.IsNegative; }
675708
void setNegative(SourceLoc Loc) {
676709
MinusLoc = Loc;
@@ -701,32 +734,6 @@ class NumberLiteralExpr : public LiteralExpr {
701734
return DigitsLoc;
702735
}
703736

704-
/// Retrieve the builtin initializer that will be used to construct the
705-
/// boolean literal.
706-
///
707-
/// Any type-checked boolean literal will have a builtin initializer, which is
708-
/// called first to form a concrete Swift type.
709-
ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }
710-
711-
/// Set the builtin initializer that will be used to construct the boolean
712-
/// literal.
713-
void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
714-
BuiltinInitializer = builtinInitializer;
715-
}
716-
717-
/// Retrieve the initializer that will be used to construct the boolean
718-
/// literal from the result of the initializer.
719-
///
720-
/// Only boolean literals that have no builtin literal conformance will have
721-
/// this initializer, which will be called on the result of the builtin
722-
/// initializer.
723-
ConcreteDeclRef getInitializer() const { return Initializer; }
724-
725-
/// Set the initializer that will be used to construct the boolean literal.
726-
void setInitializer(ConcreteDeclRef initializer) {
727-
Initializer = initializer;
728-
}
729-
730737
static bool classof(const Expr *E) {
731738
return E->getKind() >= ExprKind::First_NumberLiteralExpr
732739
&& E->getKind() <= ExprKind::Last_NumberLiteralExpr;
@@ -790,14 +797,12 @@ class FloatLiteralExpr : public NumberLiteralExpr {
790797

791798
/// A Boolean literal ('true' or 'false')
792799
///
793-
class BooleanLiteralExpr : public LiteralExpr {
800+
class BooleanLiteralExpr : public BuiltinLiteralExpr {
794801
SourceLoc Loc;
795-
ConcreteDeclRef BuiltinInitializer;
796-
ConcreteDeclRef Initializer;
797802

798803
public:
799804
BooleanLiteralExpr(bool Value, SourceLoc Loc, bool Implicit = false)
800-
: LiteralExpr(ExprKind::BooleanLiteral, Implicit), Loc(Loc) {
805+
: BuiltinLiteralExpr(ExprKind::BooleanLiteral, Implicit), Loc(Loc) {
801806
Bits.BooleanLiteralExpr.Value = Value;
802807
}
803808

@@ -808,43 +813,15 @@ class BooleanLiteralExpr : public LiteralExpr {
808813
return Loc;
809814
}
810815

811-
/// Retrieve the builtin initializer that will be used to construct the
812-
/// boolean literal.
813-
///
814-
/// Any type-checked boolean literal will have a builtin initializer, which is
815-
/// called first to form a concrete Swift type.
816-
ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }
817-
818-
/// Set the builtin initializer that will be used to construct the boolean
819-
/// literal.
820-
void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
821-
BuiltinInitializer = builtinInitializer;
822-
}
823-
824-
/// Retrieve the initializer that will be used to construct the boolean
825-
/// literal from the result of the initializer.
826-
///
827-
/// Only boolean literals that have no builtin literal conformance will have
828-
/// this initializer, which will be called on the result of the builtin
829-
/// initializer.
830-
ConcreteDeclRef getInitializer() const { return Initializer; }
831-
832-
/// Set the initializer that will be used to construct the boolean literal.
833-
void setInitializer(ConcreteDeclRef initializer) {
834-
Initializer = initializer;
835-
}
836-
837816
static bool classof(const Expr *E) {
838817
return E->getKind() == ExprKind::BooleanLiteral;
839818
}
840819
};
841-
820+
842821
/// StringLiteralExpr - String literal, like '"foo"'.
843-
class StringLiteralExpr : public LiteralExpr {
822+
class StringLiteralExpr : public BuiltinLiteralExpr {
844823
StringRef Val;
845824
SourceRange Range;
846-
ConcreteDeclRef BuiltinInitializer;
847-
ConcreteDeclRef Initializer;
848825

849826
public:
850827
/// The encoding that should be used for the string literal.
@@ -879,32 +856,6 @@ class StringLiteralExpr : public LiteralExpr {
879856
return Bits.StringLiteralExpr.IsSingleExtendedGraphemeCluster;
880857
}
881858

882-
/// Retrieve the builtin initializer that will be used to construct the string
883-
/// literal.
884-
///
885-
/// Any type-checked string literal will have a builtin initializer, which is
886-
/// called first to form a concrete Swift type.
887-
ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }
888-
889-
/// Set the builtin initializer that will be used to construct the string
890-
/// literal.
891-
void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
892-
BuiltinInitializer = builtinInitializer;
893-
}
894-
895-
/// Retrieve the initializer that will be used to construct the string
896-
/// literal from the result of the initializer.
897-
///
898-
/// Only string literals that have no builtin literal conformance will have
899-
/// this initializer, which will be called on the result of the builtin
900-
/// initializer.
901-
ConcreteDeclRef getInitializer() const { return Initializer; }
902-
903-
/// Set the initializer that will be used to construct the string literal.
904-
void setInitializer(ConcreteDeclRef initializer) {
905-
Initializer = initializer;
906-
}
907-
908859
static bool classof(const Expr *E) {
909860
return E->getKind() == ExprKind::StringLiteral;
910861
}
@@ -973,7 +924,6 @@ class InterpolatedStringLiteralExpr : public LiteralExpr {
973924
// Set by Sema:
974925
OpaqueValueExpr *interpolationExpr = nullptr;
975926
ConcreteDeclRef builderInit;
976-
ConcreteDeclRef resultInit;
977927
Expr *interpolationCountExpr = nullptr;
978928
Expr *literalCapacityExpr = nullptr;
979929

@@ -995,11 +945,6 @@ class InterpolatedStringLiteralExpr : public LiteralExpr {
995945
void setBuilderInit(ConcreteDeclRef decl) { builderInit = decl; }
996946
ConcreteDeclRef getBuilderInit() const { return builderInit; }
997947

998-
/// Sets the decl that constructs the final result type after the
999-
/// AppendingExpr has been evaluated.
1000-
void setResultInit(ConcreteDeclRef decl) { resultInit = decl; }
1001-
ConcreteDeclRef getResultInit() const { return resultInit; }
1002-
1003948
/// Sets the OpaqueValueExpr that is passed into AppendingExpr as the SubExpr
1004949
/// that the tap operates on.
1005950
void setInterpolationExpr(OpaqueValueExpr *expr) { interpolationExpr = expr; }
@@ -1059,7 +1004,7 @@ class InterpolatedStringLiteralExpr : public LiteralExpr {
10591004

10601005
/// MagicIdentifierLiteralExpr - A magic identifier like #file which expands
10611006
/// out to a literal at SILGen time.
1062-
class MagicIdentifierLiteralExpr : public LiteralExpr {
1007+
class MagicIdentifierLiteralExpr : public BuiltinLiteralExpr {
10631008
public:
10641009
enum Kind : unsigned {
10651010
#define MAGIC_IDENTIFIER(NAME, STRING, SYNTAX_KIND) NAME,
@@ -1077,17 +1022,16 @@ class MagicIdentifierLiteralExpr : public LiteralExpr {
10771022

10781023
private:
10791024
SourceLoc Loc;
1080-
ConcreteDeclRef BuiltinInitializer;
1081-
ConcreteDeclRef Initializer;
10821025

10831026
public:
10841027
MagicIdentifierLiteralExpr(Kind kind, SourceLoc loc, bool implicit = false)
1085-
: LiteralExpr(ExprKind::MagicIdentifierLiteral, implicit), Loc(loc) {
1028+
: BuiltinLiteralExpr(ExprKind::MagicIdentifierLiteral, implicit),
1029+
Loc(loc) {
10861030
Bits.MagicIdentifierLiteralExpr.Kind = static_cast<unsigned>(kind);
10871031
Bits.MagicIdentifierLiteralExpr.StringEncoding
10881032
= static_cast<unsigned>(StringLiteralExpr::UTF8);
10891033
}
1090-
1034+
10911035
Kind getKind() const {
10921036
return static_cast<Kind>(Bits.MagicIdentifierLiteralExpr.Kind);
10931037
}
@@ -1123,35 +1067,6 @@ class MagicIdentifierLiteralExpr : public LiteralExpr {
11231067
= static_cast<unsigned>(encoding);
11241068
}
11251069

1126-
/// Retrieve the builtin initializer that will be used to construct the
1127-
/// literal.
1128-
///
1129-
/// Any type-checked literal will have a builtin initializer, which is
1130-
/// called first to form a concrete Swift type.
1131-
ConcreteDeclRef getBuiltinInitializer() const {
1132-
return BuiltinInitializer;
1133-
}
1134-
1135-
/// Set the builtin initializer that will be used to construct the literal.
1136-
void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
1137-
BuiltinInitializer = builtinInitializer;
1138-
}
1139-
1140-
/// Retrieve the initializer that will be used to construct the literal from
1141-
/// the result of the initializer.
1142-
///
1143-
/// Only literals that have no builtin literal conformance will have
1144-
/// this initializer, which will be called on the result of the builtin
1145-
/// initializer.
1146-
ConcreteDeclRef getInitializer() const {
1147-
return Initializer;
1148-
}
1149-
1150-
/// Set the initializer that will be used to construct the literal.
1151-
void setInitializer(ConcreteDeclRef initializer) {
1152-
Initializer = initializer;
1153-
}
1154-
11551070
static bool classof(const Expr *E) {
11561071
return E->getKind() == ExprKind::MagicIdentifierLiteral;
11571072
}
@@ -1174,7 +1089,6 @@ class ObjectLiteralExpr final
11741089
private:
11751090
Expr *Arg;
11761091
SourceLoc PoundLoc;
1177-
ConcreteDeclRef Initializer;
11781092

11791093
ObjectLiteralExpr(SourceLoc PoundLoc, LiteralKind LitKind,
11801094
Expr *Arg,
@@ -1237,15 +1151,6 @@ class ObjectLiteralExpr final
12371151

12381152
StringRef getLiteralKindPlainName() const;
12391153

1240-
/// Retrieve the initializer that will be used to construct the 'object'
1241-
/// literal from the result of the initializer.
1242-
ConcreteDeclRef getInitializer() const { return Initializer; }
1243-
1244-
/// Set the initializer that will be used to construct the 'object' literal.
1245-
void setInitializer(ConcreteDeclRef initializer) {
1246-
Initializer = initializer;
1247-
}
1248-
12491154
static bool classof(const Expr *E) {
12501155
return E->getKind() == ExprKind::ObjectLiteral;
12511156
}

include/swift/AST/ExprNodes.def

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,18 @@
6868
EXPR(Error, Expr)
6969
ABSTRACT_EXPR(Literal, Expr)
7070
LITERAL_EXPR(NilLiteral, LiteralExpr)
71-
ABSTRACT_EXPR(NumberLiteral, LiteralExpr)
72-
LITERAL_EXPR(IntegerLiteral, NumberLiteralExpr)
73-
LITERAL_EXPR(FloatLiteral, NumberLiteralExpr)
74-
EXPR_RANGE(NumberLiteral, IntegerLiteral, FloatLiteral)
75-
LITERAL_EXPR(BooleanLiteral, LiteralExpr)
76-
LITERAL_EXPR(StringLiteral, LiteralExpr)
71+
ABSTRACT_EXPR(BuiltinLiteral, LiteralExpr)
72+
LITERAL_EXPR(BooleanLiteral, BuiltinLiteralExpr)
73+
ABSTRACT_EXPR(NumberLiteral, BuiltinLiteralExpr)
74+
LITERAL_EXPR(IntegerLiteral, NumberLiteralExpr)
75+
LITERAL_EXPR(FloatLiteral, NumberLiteralExpr)
76+
EXPR_RANGE(NumberLiteral, IntegerLiteral, FloatLiteral)
77+
LITERAL_EXPR(StringLiteral, BuiltinLiteralExpr)
78+
LITERAL_EXPR(MagicIdentifierLiteral, BuiltinLiteralExpr)
79+
EXPR_RANGE(BuiltinLiteral, BooleanLiteral, MagicIdentifierLiteral)
7780
LITERAL_EXPR(InterpolatedStringLiteral, LiteralExpr)
7881
LITERAL_EXPR(ObjectLiteral, LiteralExpr)
79-
LITERAL_EXPR(MagicIdentifierLiteral, LiteralExpr)
80-
EXPR_RANGE(Literal, NilLiteral, MagicIdentifierLiteral)
82+
EXPR_RANGE(Literal, NilLiteral, ObjectLiteral)
8183
EXPR(DiscardAssignment, Expr)
8284
EXPR(DeclRef, Expr)
8385
EXPR(SuperRef, Expr)

lib/AST/ASTDumper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1994,7 +1994,7 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
19941994
PrintWithColorRAII(OS, LiteralValueColor) << " builder_init=";
19951995
E->getBuilderInit().dump(PrintWithColorRAII(OS, LiteralValueColor).getOS());
19961996
PrintWithColorRAII(OS, LiteralValueColor) << " result_init=";
1997-
E->getResultInit().dump(PrintWithColorRAII(OS, LiteralValueColor).getOS());
1997+
E->getInitializer().dump(PrintWithColorRAII(OS, LiteralValueColor).getOS());
19981998
OS << "\n";
19991999
printRec(E->getAppendingExpr());
20002000
PrintWithColorRAII(OS, ParenthesisColor) << ')';

0 commit comments

Comments
 (0)