Skip to content

Commit e7e8b66

Browse files
authored
Merge pull request #3801 from DougGregor/string-literal-ast
Simplify AST for string literals to not depend on implicit tuple splat.
2 parents dfc3933 + e4d8f48 commit e7e8b66

File tree

11 files changed

+646
-238
lines changed

11 files changed

+646
-238
lines changed

include/swift/AST/Expr.h

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -883,13 +883,13 @@ class BooleanLiteralExpr : public LiteralExpr {
883883
}
884884
};
885885

886-
/// StringLiteralExpr - String literal, like '"foo"'. After semantic
887-
/// analysis assigns types, this is guaranteed to only have a
888-
/// BuiltinRawPointerType.
886+
/// StringLiteralExpr - String literal, like '"foo"'.
889887
class StringLiteralExpr : public LiteralExpr {
890888
StringRef Val;
891889
SourceRange Range;
892-
890+
ConcreteDeclRef BuiltinInitializer;
891+
ConcreteDeclRef Initializer;
892+
893893
public:
894894
/// The encoding that should be used for the string literal.
895895
enum Encoding : unsigned {
@@ -926,6 +926,32 @@ class StringLiteralExpr : public LiteralExpr {
926926
return StringLiteralExprBits.IsSingleExtendedGraphemeCluster;
927927
}
928928

929+
/// Retrieve the builtin initializer that will be used to construct the string
930+
/// literal.
931+
///
932+
/// Any type-checked string literal will have a builtin initializer, which is
933+
/// called first to form a concrete Swift type.
934+
ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }
935+
936+
/// Set the builtin initializer that will be used to construct the string
937+
/// literal.
938+
void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
939+
BuiltinInitializer = builtinInitializer;
940+
}
941+
942+
/// Retrieve the initializer that will be used to construct the string
943+
/// literal from the result of the initializer.
944+
///
945+
/// Only string literals that have no builtin literal conformance will have
946+
/// this initializer, which will be called on the result of the builtin
947+
/// initializer.
948+
ConcreteDeclRef getInitializer() const { return Initializer; }
949+
950+
/// Set the initializer that will be used to construct the string literal.
951+
void setInitializer(ConcreteDeclRef initializer) {
952+
Initializer = initializer;
953+
}
954+
929955
static bool classof(const Expr *E) {
930956
return E->getKind() == ExprKind::StringLiteral;
931957
}
@@ -978,7 +1004,9 @@ class MagicIdentifierLiteralExpr : public LiteralExpr {
9781004
};
9791005
private:
9801006
SourceLoc Loc;
981-
1007+
ConcreteDeclRef BuiltinInitializer;
1008+
ConcreteDeclRef Initializer;
1009+
9821010
public:
9831011
MagicIdentifierLiteralExpr(Kind kind, SourceLoc loc, bool implicit = false)
9841012
: LiteralExpr(ExprKind::MagicIdentifierLiteral, implicit), Loc(loc) {
@@ -1031,6 +1059,40 @@ class MagicIdentifierLiteralExpr : public LiteralExpr {
10311059
= static_cast<unsigned>(encoding);
10321060
}
10331061

1062+
/// Retrieve the builtin initializer that will be used to construct the string
1063+
/// literal.
1064+
///
1065+
/// Any type-checked string literal will have a builtin initializer, which is
1066+
/// called first to form a concrete Swift type.
1067+
ConcreteDeclRef getBuiltinInitializer() const {
1068+
assert(isString() && "Magic identifier literal is not a string");
1069+
return BuiltinInitializer;
1070+
}
1071+
1072+
/// Set the builtin initializer that will be used to construct the string
1073+
/// literal.
1074+
void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
1075+
assert(isString() && "Magic identifier literal is not a string");
1076+
BuiltinInitializer = builtinInitializer;
1077+
}
1078+
1079+
/// Retrieve the initializer that will be used to construct the string
1080+
/// literal from the result of the initializer.
1081+
///
1082+
/// Only string literals that have no builtin literal conformance will have
1083+
/// this initializer, which will be called on the result of the builtin
1084+
/// initializer.
1085+
ConcreteDeclRef getInitializer() const {
1086+
assert(isString() && "Magic identifier literal is not a string");
1087+
return Initializer;
1088+
}
1089+
1090+
/// Set the initializer that will be used to construct the string literal.
1091+
void setInitializer(ConcreteDeclRef initializer) {
1092+
assert(isString() && "Magic identifier literal is not a string");
1093+
Initializer = initializer;
1094+
}
1095+
10341096
static bool classof(const Expr *E) {
10351097
return E->getKind() == ExprKind::MagicIdentifierLiteral;
10361098
}

lib/AST/ASTDumper.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1630,7 +1630,12 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
16301630
printCommon(E, "string_literal_expr")
16311631
<< " encoding=";
16321632
printStringEncoding(E->getEncoding());
1633-
OS << " value=" << QuotedString(E->getValue()) << ')';
1633+
OS << " value=" << QuotedString(E->getValue())
1634+
<< " builtin_initializer=";
1635+
E->getBuiltinInitializer().dump(OS);
1636+
OS << " initializer=";
1637+
E->getInitializer().dump(OS);
1638+
OS << ')';
16341639
}
16351640
void visitInterpolatedStringLiteralExpr(InterpolatedStringLiteralExpr *E) {
16361641
printCommon(E, "interpolated_string_literal_expr");
@@ -1657,6 +1662,13 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
16571662
case MagicIdentifierLiteralExpr::Column: OS << "#column"; break;
16581663
case MagicIdentifierLiteralExpr::DSOHandle: OS << "#dsohandle"; break;
16591664
}
1665+
1666+
if (E->isString()) {
1667+
OS << " builtin_initializer=";
1668+
E->getBuiltinInitializer().dump(OS);
1669+
OS << " initializer=";
1670+
E->getInitializer().dump(OS);
1671+
}
16601672
OS << ')';
16611673
}
16621674

lib/AST/Expr.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ ConcreteDeclRef Expr::getReferencedDecl() const {
370370
NO_REFERENCE(MagicIdentifierLiteral);
371371
NO_REFERENCE(DiscardAssignment);
372372

373-
SIMPLE_REFERENCE(DeclRef, getDecl);
373+
SIMPLE_REFERENCE(DeclRef, getDeclRef);
374374
SIMPLE_REFERENCE(SuperRef, getSelf);
375375

376376
case ExprKind::Type: {
@@ -381,7 +381,7 @@ ConcreteDeclRef Expr::getReferencedDecl() const {
381381
return ident->getComponentRange().back()->getBoundDecl();
382382
}
383383

384-
SIMPLE_REFERENCE(OtherConstructorDeclRef, getDecl);
384+
SIMPLE_REFERENCE(OtherConstructorDeclRef, getDeclRef);
385385

386386
PASS_THROUGH_REFERENCE(DotSyntaxBaseIgnored, getRHS);
387387

@@ -439,8 +439,8 @@ ConcreteDeclRef Expr::getReferencedDecl() const {
439439
NO_REFERENCE(PostfixUnary);
440440
NO_REFERENCE(Binary);
441441
NO_REFERENCE(DotSyntaxCall);
442-
NO_REFERENCE(ConstructorRefCall);
443442

443+
PASS_THROUGH_REFERENCE(ConstructorRefCall, getFn);
444444
PASS_THROUGH_REFERENCE(Load, getSubExpr);
445445
NO_REFERENCE(TupleShuffle);
446446
NO_REFERENCE(UnresolvedTypeConversion);

0 commit comments

Comments
 (0)