Skip to content

[Parse] Drop Swift3 support for conditional compilation condition #17789

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -1504,15 +1504,6 @@ ERROR(unsupported_platform_condition_argument,none,
(StringRef))
ERROR(unsupported_conditional_compilation_expression_type,none,
"invalid conditional compilation expression", ())
WARNING(swift3_unsupported_conditional_compilation_expression_type,none,
"ignoring invalid conditional compilation expression, "
"which will be rejected in future version of Swift", ())
WARNING(swift3_conditional_compilation_expression_compound,none,
"ignoring parentheses in compound name, "
"which will be rejected in future version of Swift", ())
WARNING(swift3_conditional_compilation_expression_precedence,none,
"future version of Swift have different rule for evaluating condition; "
"add parentheses to make the condition compatible with Swift4", ())
ERROR(unsupported_conditional_compilation_integer,none,
"'%0' is not a valid conditional compilation expression, use '%1'",
(StringRef, StringRef))
Expand Down
105 changes: 5 additions & 100 deletions lib/Parse/ParseIfConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,9 @@ class ValidateIfConfigCondition :
auto UDRE = dyn_cast<UnresolvedDeclRefExpr>(E);
if (!UDRE ||
!UDRE->hasName() ||
UDRE->getRefKind() != Kind)
UDRE->getRefKind() != Kind ||
UDRE->getName().isCompoundName())
return None;
if (UDRE->getName().isCompoundName()) {
if (!Ctx.isSwiftVersion3())
return None;
// Swift3 used to accept compound names; warn and return the basename.
D.diagnose(UDRE->getNameLoc().getLParenLoc(),
diag::swift3_conditional_compilation_expression_compound)
.fixItRemove({ UDRE->getNameLoc().getLParenLoc(),
UDRE->getNameLoc().getRParenLoc() });
}

return UDRE->getName().getBaseIdentifier().str();
}
Expand Down Expand Up @@ -155,59 +147,6 @@ class ValidateIfConfigCondition :
return LHS;
}

// In Swift3 mode, leave sequence as a sequence because it has strange
// evaluation rule. See 'EvaluateIfConfigCondition::visitSequenceExpr'.
Expr *validateSequence(ArrayRef<Expr *> &S) {
assert(Ctx.isSwiftVersion3());

SmallVector<Expr *, 3> Filtered;
SmallVector<unsigned, 2> AndIdxs;
Filtered.push_back(validate(S[0]));
S = S.slice(1);

while (!S.empty()) {
auto OpName = getDeclRefStr(S[0], DeclRefKind::BinaryOperator);
if (!OpName.hasValue() || (*OpName != "||" && *OpName != "&&")) {
// Warning and ignore in Swift3 mode.
D.diagnose(
S[0]->getLoc(),
diag::swift3_unsupported_conditional_compilation_expression_type)
.highlight({ S[0]->getLoc(), S[1]->getEndLoc() });
} else {
// Remember the start and end of '&&' sequence.
bool InAnd = (AndIdxs.size() & 1) == 1;
if ((*OpName == "&&" && !InAnd) || (*OpName == "||" && InAnd))
AndIdxs.push_back(Filtered.size() - 1);

Filtered.push_back(S[0]);
Filtered.push_back(validate(S[1]));
}
S = S.slice(2);
}
assert((Filtered.size() & 1) == 1);

// If the last OpName is '&&', close it with a parenthesis, except if the
// operators are '&&' only.
if ((1 == (AndIdxs.size() & 1)) && AndIdxs.back() > 0)
AndIdxs.push_back(Filtered.size() - 1);
// Emit fix-its to make this sequence compatilble with Swift >=4 even in
// Swift3 mode.
if (AndIdxs.size() >= 2) {
assert((AndIdxs.size() & 1) == 0);
auto diag = D.diagnose(
Filtered[AndIdxs[0]]->getStartLoc(),
diag::swift3_conditional_compilation_expression_precedence);
for (unsigned i = 0, e = AndIdxs.size(); i < e; i += 2) {
diag.fixItInsert(Filtered[AndIdxs[i]]->getStartLoc(), "(");
diag.fixItInsertAfter(Filtered[AndIdxs[i + 1]]->getEndLoc(), ")");
}
}

if (Filtered.size() == 1)
return Filtered[0];
return SequenceExpr::create(Ctx, Filtered);
}

public:
ValidateIfConfigCondition(ASTContext &Ctx, DiagnosticEngine &D)
: Ctx(Ctx), D(D), HasError(false) {}
Expand Down Expand Up @@ -369,14 +308,9 @@ class ValidateIfConfigCondition :
// Fold sequence expression for non-Swift3 mode.
Expr *visitSequenceExpr(SequenceExpr *E) {
ArrayRef<Expr*> Elts = E->getElements();
Expr *foldedExpr;
if (Ctx.isSwiftVersion3()) {
foldedExpr = validateSequence(Elts);
} else {
auto LHS = validate(Elts[0]);
Elts = Elts.slice(1);
foldedExpr = foldSequence(LHS, Elts);
}
Expr *foldedExpr = validate(Elts[0]);
Elts = Elts.slice(1);
foldedExpr = foldSequence(foldedExpr, Elts);
assert(Elts.empty());
return foldedExpr;
}
Expand Down Expand Up @@ -477,42 +411,13 @@ class EvaluateIfConfigCondition :
}

bool visitBinaryExpr(BinaryExpr *E) {
assert(!Ctx.isSwiftVersion3() && "BinaryExpr in Swift3 mode");
auto OpName = getDeclRefStr(E->getFn());
auto Args = E->getArg()->getElements();
if (OpName == "||") return visit(Args[0]) || visit(Args[1]);
if (OpName == "&&") return visit(Args[0]) && visit(Args[1]);
llvm_unreachable("unsupported binary operator");
}

bool visitSequenceExpr(SequenceExpr *E) {
assert(Ctx.isSwiftVersion3() && "SequenceExpr in non-Swift3 mode");
ArrayRef<Expr *> Elems = E->getElements();
auto Result = visit(Elems[0]);
Elems = Elems.slice(1);
while (!Elems.empty()) {
auto OpName = getDeclRefStr(Elems[0]);

if (OpName == "||") {
Result = Result || visit(Elems[1]);
if (Result)
// Note that this is the Swift3 behavior.
// e.g. 'false || true && false' evaluates to 'true'.
return true;
} else if (OpName == "&&") {
Result = Result && visit(Elems[1]);
if (!Result)
// Ditto.
// e.g. 'false && true || true' evaluates to 'false'.
return false;
} else {
llvm_unreachable("must be removed in validation phase");
}
Elems = Elems.slice(2);
}
return Result;
}

bool visitExpr(Expr *E) { llvm_unreachable("Unvalidated condition?"); }
};

Expand Down