Skip to content

Commit 84fb496

Browse files
committed
[Parse] Add parsing for @execution(concurrent | caller) attribute in type context
1 parent f206956 commit 84fb496

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,14 @@ ERROR(attr_isolated_expected_rparen,none,
16831683
ERROR(attr_isolated_expected_kind,none,
16841684
"expected 'any' as the isolation kind", ())
16851685

1686+
ERROR(attr_execution_expected_lparen,none,
1687+
"expected '(' after '@execution'",
1688+
())
1689+
ERROR(attr_execution_expected_rparen,none,
1690+
"expected ')' after execution behavior", ())
1691+
ERROR(attr_execution_expected_kind,none,
1692+
"expected 'concurrent' or 'caller' as the execution behavior", ())
1693+
16861694
ERROR(attr_private_import_expected_rparen,none,
16871695
"expected ')' after function name for @_private", ())
16881696
ERROR(attr_private_import_expected_sourcefile, none,

lib/Parse/ParseDecl.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4788,6 +4788,50 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
47884788
return makeParserSuccess();
47894789
}
47904790

4791+
case TypeAttrKind::Execution: {
4792+
SourceLoc lpLoc = Tok.getLoc(), behaviorLoc, rpLoc;
4793+
if (!consumeIfNotAtStartOfLine(tok::l_paren)) {
4794+
if (!justChecking) {
4795+
diagnose(Tok, diag::attr_execution_expected_lparen);
4796+
// TODO: should we suggest removing the `@`?
4797+
}
4798+
return makeParserError();
4799+
}
4800+
4801+
bool invalid = false;
4802+
std::optional<ExecutionKind> behavior;
4803+
if (isIdentifier(Tok, "concurrent")) {
4804+
behaviorLoc = consumeToken(tok::identifier);
4805+
behavior = ExecutionKind::Concurrent;
4806+
} else if (isIdentifier(Tok, "caller")) {
4807+
behaviorLoc = consumeToken(tok::identifier);
4808+
behavior = ExecutionKind::Caller;
4809+
} else {
4810+
if (!justChecking) {
4811+
diagnose(Tok, diag::attr_execution_expected_kind);
4812+
}
4813+
invalid = true;
4814+
consumeIf(tok::identifier);
4815+
}
4816+
4817+
if (justChecking && !Tok.is(tok::r_paren))
4818+
return makeParserError();
4819+
if (parseMatchingToken(tok::r_paren, rpLoc,
4820+
diag::attr_execution_expected_rparen,
4821+
lpLoc))
4822+
return makeParserError();
4823+
4824+
if (invalid)
4825+
return makeParserError();
4826+
assert(behavior);
4827+
4828+
if (!justChecking) {
4829+
result = new (Context) ExecutionTypeAttr(AtLoc, attrLoc, {lpLoc, rpLoc},
4830+
{*behavior, behaviorLoc});
4831+
}
4832+
return makeParserSuccess();
4833+
}
4834+
47914835
case TypeAttrKind::Opened: {
47924836
// Parse the opened existential ID string in parens
47934837
SourceLoc beginLoc = Tok.getLoc(), idLoc, endLoc;

0 commit comments

Comments
 (0)