Parse and check raw values on enum cases.

Iff an enum declares a raw type, its cases may declare raw values or else have them assigned to them implicitly by autoincrementing from zero, like in C. If the raw type is float-, string-, or char-literal-convertible, there is no autoincrement, and the raw values must all be explicit. The raw type is rejected if any cases have payloads.

We don't yet diagnose duplicate raw values. That'll come next. We also don't yet serialize or deserialize the raw values. We don't strictly need to do this, since the RawRepresentable protocol conformance will be exported from the module as API, but Jordan pointed out that, for fragile raw values, this would be good for documents/jump-to-definition purposes, so we have a plan for only serializing the literals without having to deal with fully general expression serialization.

Swift SVN r8545
This commit is contained in:
Joe Groff
2013-09-21 04:31:26 +00:00
parent efd8e75647
commit c4b4db732f
8 changed files with 201 additions and 33 deletions

View File

@@ -1890,6 +1890,31 @@ ParserStatus Parser::parseDeclEnumCase(unsigned Flags,
}
}
// See if there's a raw value expression.
SourceLoc EqualsLoc;
ParserResult<Expr> RawValueExpr;
LiteralExpr *LiteralRawValueExpr = nullptr;
if (Tok.is(tok::equal)) {
EqualsLoc = consumeToken();
RawValueExpr = parseExpr(diag::expected_expr_enum_case_raw_value);
if (RawValueExpr.hasCodeCompletion()) {
Status.setHasCodeCompletion();
return Status;
}
if (RawValueExpr.isNull()) {
Status.setIsParseError();
return Status;
}
// The raw value must be syntactically a simple literal.
LiteralRawValueExpr = dyn_cast<LiteralExpr>(RawValueExpr.getPtrOrNull());
if (!LiteralRawValueExpr
|| isa<InterpolatedStringLiteralExpr>(LiteralRawValueExpr)) {
diagnose(RawValueExpr.getPtrOrNull()->getLoc(),
diag::nonliteral_enum_case_raw_value);
LiteralRawValueExpr = nullptr;
}
}
// For recovery, again make sure the the user didn't try to spell a switch
// case label:
// 'case Identifier:' or
@@ -1906,6 +1931,8 @@ ParserStatus Parser::parseDeclEnumCase(unsigned Flags,
ArgType.getPtrOrNull(),
ArrowLoc,
ResultType.getPtrOrNull(),
EqualsLoc,
LiteralRawValueExpr,
CurDeclContext);
Elements.push_back(result);