@@ -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