Skip to content

Commit 95838dc

Browse files
author
Eli Friedman
committed
Move the SequenceExpr transformation from the expression pre-check into the main expression type-checking visitor.
Swift SVN r2002
1 parent 2289b10 commit 95838dc

File tree

4 files changed

+33
-25
lines changed

4 files changed

+33
-25
lines changed

include/swift/AST/Expr.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,11 @@ class ApplyExpr : public Expr {
14571457
void setFn(Expr *e) { Fn = e; }
14581458

14591459
Expr *getArg() const { return Arg; }
1460-
void setArg(Expr *e) { Arg = e; }
1460+
void setArg(Expr *e) {
1461+
assert((getKind() != ExprKind::Binary || isa<TupleExpr>(e)) &&
1462+
"BinaryExprs must have a TupleExpr as the argument");
1463+
Arg = e;
1464+
}
14611465

14621466
ValueDecl *getCalledValue() const;
14631467

@@ -1513,11 +1517,13 @@ class BinaryExpr : public ApplyExpr {
15131517
: ApplyExpr(ExprKind::Binary, Fn, Arg, Ty) {}
15141518

15151519
SourceLoc getLoc() const { return getFn()->getLoc(); }
1516-
1520+
15171521
SourceRange getSourceRange() const {
15181522
return getArg()->getSourceRange();
15191523
}
15201524

1525+
TupleExpr *getArg() const { return cast<TupleExpr>(ApplyExpr::getArg()); }
1526+
15211527
// Implement isa/cast/dyncast/etc.
15221528
static bool classof(const BinaryExpr *) { return true; }
15231529
static bool classof(const Expr *E) { return E->getKind() == ExprKind::Binary;}

lib/Sema/TypeCheckExpr.cpp

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,9 @@ class SemaExpressionTree :
641641
<< E->getSourceRange();
642642
return nullptr;
643643
}
644-
644+
645+
Expr *makeBinOp(Expr *Op, Expr *LHS, Expr *RHS);
646+
Expr *foldSequence(Expr *LHS, ArrayRef<Expr*> &S, unsigned MinPrecedence);
645647
Expr *visitSequenceExpr(SequenceExpr *E);
646648

647649
void PreProcessBraceStmt(BraceStmt *BS);
@@ -842,18 +844,26 @@ static InfixData getInfixData(TypeChecker &TC, Expr *E) {
842844
return InfixData(~0U, Associativity::Left);
843845
}
844846

845-
static Expr *makeBinOp(TypeChecker &TC, Expr *Op, Expr *LHS, Expr *RHS) {
847+
Expr *SemaExpressionTree::makeBinOp(Expr *Op, Expr *LHS, Expr *RHS) {
848+
if (!LHS || !RHS)
849+
return nullptr;
850+
851+
// Build the argument to the operation.
846852
Expr *ArgElts[] = { LHS, RHS };
847853
auto ArgElts2 = TC.Context.AllocateCopy(MutableArrayRef<Expr*>(ArgElts));
848854
TupleExpr *Arg = new (TC.Context) TupleExpr(SourceLoc(),
849855
ArgElts2, 0, SourceLoc());
850-
return new (TC.Context) BinaryExpr(Op, Arg);
856+
if (TC.semaTupleExpr(Arg))
857+
return nullptr;
858+
859+
// Build the operation.
860+
return visit(new (TC.Context) BinaryExpr(Op, Arg));
851861
}
852862

853863
/// foldSequence - Take a sequence of expressions and fold a prefix of
854864
/// it into a tree of BinaryExprs using precedence parsing.
855-
static Expr *foldSequence(TypeChecker &TC, Expr *LHS, ArrayRef<Expr*> &S,
856-
unsigned MinPrecedence) {
865+
Expr *SemaExpressionTree::foldSequence(Expr *LHS, ArrayRef<Expr*> &S,
866+
unsigned MinPrecedence) {
857867
// Invariant: S is even-sized.
858868
// Invariant: All elements at even indices are operator references.
859869
assert(!S.empty());
@@ -888,7 +898,7 @@ static Expr *foldSequence(TypeChecker &TC, Expr *LHS, ArrayRef<Expr*> &S,
888898
// both left-associative, fold LHS and RHS immediately.
889899
if (Op1Info.getPrecedence() > Op2Info.getPrecedence() ||
890900
(Op1Info == Op2Info && Op1Info.isLeftAssociative())) {
891-
LHS = makeBinOp(TC, Op1, LHS, RHS);
901+
LHS = makeBinOp(Op1, LHS, RHS);
892902
RHS = S[1];
893903
Op1 = Op2;
894904
Op1Info = Op2Info;
@@ -901,7 +911,7 @@ static Expr *foldSequence(TypeChecker &TC, Expr *LHS, ArrayRef<Expr*> &S,
901911
// higher-precedence operators starting from this point, then
902912
// repeat.
903913
if (Op1Info.getPrecedence() < Op2Info.getPrecedence()) {
904-
RHS = foldSequence(TC, RHS, S, Op1Info.getPrecedence() + 1);
914+
RHS = foldSequence(RHS, S, Op1Info.getPrecedence() + 1);
905915
continue;
906916
}
907917

@@ -910,14 +920,14 @@ static Expr *foldSequence(TypeChecker &TC, Expr *LHS, ArrayRef<Expr*> &S,
910920
// recursively fold operators starting from this point, then
911921
// immediately fold LHS and RHS.
912922
if (Op1Info == Op2Info && Op1Info.isRightAssociative()) {
913-
RHS = foldSequence(TC, RHS, S, Op1Info.getPrecedence());
914-
LHS = makeBinOp(TC, Op1, LHS, RHS);
923+
RHS = foldSequence(RHS, S, Op1Info.getPrecedence());
924+
LHS = makeBinOp(Op1, LHS, RHS);
915925

916926
// If we've drained the entire sequence, we're done.
917927
if (S.empty()) return LHS;
918928

919929
// Otherwise, start all over with our new LHS.
920-
return foldSequence(TC, LHS, S, MinPrecedence);
930+
return foldSequence(LHS, S, MinPrecedence);
921931
}
922932

923933
// If we ended up here, it's because we have two operators
@@ -936,33 +946,29 @@ static Expr *foldSequence(TypeChecker &TC, Expr *LHS, ArrayRef<Expr*> &S,
936946
}
937947

938948
// Recover by arbitrarily binding the first two.
939-
LHS = makeBinOp(TC, Op1, LHS, RHS);
940-
return foldSequence(TC, LHS, S, MinPrecedence);
949+
LHS = makeBinOp(Op1, LHS, RHS);
950+
return foldSequence(LHS, S, MinPrecedence);
941951
}
942952

943953
// Fold LHS and RHS together and declare completion.
944-
return makeBinOp(TC, Op1, LHS, RHS);
954+
return makeBinOp(Op1, LHS, RHS);
945955
}
946956

947957
/// foldSequence - Take a SequenceExpr and fold it into a tree of
948958
/// BinaryExprs using precedence parsing.
949-
Expr *TypeChecker::foldSequence(SequenceExpr *E) {
959+
Expr *SemaExpressionTree::visitSequenceExpr(SequenceExpr *E) {
950960
ArrayRef<Expr*> Elts = E->getElements();
951961
assert(Elts.size() > 1 && "inadequate number of elements in sequence");
952962
assert((Elts.size() & 1) == 1 && "even number of elements in sequence");
953963

954964
Expr *LHS = Elts[0];
955965
Elts = Elts.slice(1);
956966

957-
Expr *Result = ::foldSequence(*this, LHS, Elts, /*min precedence*/ 0);
967+
Expr *Result = foldSequence(LHS, Elts, /*min precedence*/ 0);
958968
assert(Elts.empty());
959969
return Result;
960970
}
961971

962-
Expr *SemaExpressionTree::visitSequenceExpr(SequenceExpr *E) {
963-
llvm_unreachable("visiting sequence expression during normal type-checking!");
964-
}
965-
966972
Expr *TypeChecker::recheckTypes(Expr *E) {
967973
if (!E)
968974
return nullptr;

lib/Sema/TypeCheckStmt.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -856,8 +856,6 @@ void swift::performTypeChecking(TranslationUnit *TU, unsigned StartElem) {
856856
return BindName(UDRE, CurFuncDecls.empty() ? 0 : CurFuncDecls.back(),
857857
TC);
858858
}
859-
if (SequenceExpr *SE = dyn_cast<SequenceExpr>(E))
860-
return TC.foldSequence(SE);
861859
return E;
862860
}
863861
};

lib/Sema/TypeChecker.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,6 @@ class TypeChecker {
122122
Expr *convertToRValue(Expr *E);
123123
Expr *convertLValueToRValue(LValueType *SrcLT, Expr *E);
124124
Expr *convertToMaterializable(Expr *E);
125-
126-
Expr *foldSequence(SequenceExpr *E);
127125

128126
/// conformsToProtocol - Determine whether the given type conforms to the
129127
/// given protocol.

0 commit comments

Comments
 (0)