@@ -2801,6 +2801,96 @@ static std::optional<Identifier> parseSingleAttrOptionImpl(
28012801 return P.Context .getIdentifier (parsedName);
28022802}
28032803
2804+ ParserResult<LifetimeAttr> Parser::parseLifetimeAttribute (SourceLoc atLoc,
2805+ SourceLoc loc) {
2806+ ParserStatus status;
2807+ SmallVector<LifetimeDependenceSpecifier> lifetimeEntries;
2808+
2809+ if (!Context.LangOpts .hasFeature (Feature::NonescapableTypes)) {
2810+ diagnose (loc, diag::requires_experimental_feature, " lifetime attribute" ,
2811+ false , getFeatureName (Feature::NonescapableTypes));
2812+ status.setIsParseError ();
2813+ return status;
2814+ }
2815+
2816+ if (!Tok.isFollowingLParen ()) {
2817+ diagnose (loc, diag::expected_lparen_after_lifetime_dependence);
2818+ status.setIsParseError ();
2819+ return status;
2820+ }
2821+ // consume the l_paren
2822+ auto lParenLoc = consumeToken ();
2823+
2824+ SourceLoc rParenLoc;
2825+ bool foundParamId = false ;
2826+ status = parseList (
2827+ tok::r_paren, lParenLoc, rParenLoc, /* AllowSepAfterLast*/ false ,
2828+ diag::expected_rparen_after_lifetime_dependence, [&]() -> ParserStatus {
2829+ ParserStatus listStatus;
2830+ foundParamId = true ;
2831+ switch (Tok.getKind ()) {
2832+ case tok::identifier: {
2833+ Identifier paramName;
2834+ auto paramLoc =
2835+ consumeIdentifier (paramName, /* diagnoseDollarPrefix=*/ false );
2836+ if (paramName.is (" immortal" )) {
2837+ lifetimeEntries.push_back (
2838+ LifetimeDependenceSpecifier::
2839+ getImmortalLifetimeDependenceSpecifier (paramLoc));
2840+ } else {
2841+ lifetimeEntries.push_back (
2842+ LifetimeDependenceSpecifier::
2843+ getNamedLifetimeDependenceSpecifier (paramLoc, paramName));
2844+ }
2845+ break ;
2846+ }
2847+ case tok::integer_literal: {
2848+ SourceLoc paramLoc;
2849+ unsigned paramNum;
2850+ if (parseUnsignedInteger (
2851+ paramNum, paramLoc,
2852+ diag::expected_param_index_lifetime_dependence)) {
2853+ listStatus.setIsParseError ();
2854+ return listStatus;
2855+ }
2856+ lifetimeEntries.push_back (
2857+ LifetimeDependenceSpecifier::
2858+ getOrderedLifetimeDependenceSpecifier (paramLoc, paramNum));
2859+ break ;
2860+ }
2861+ case tok::kw_self: {
2862+ auto paramLoc = consumeToken (tok::kw_self);
2863+ lifetimeEntries.push_back (
2864+ LifetimeDependenceSpecifier::getSelfLifetimeDependenceSpecifier (
2865+ paramLoc));
2866+ break ;
2867+ }
2868+ default :
2869+ diagnose (
2870+ Tok,
2871+ diag::
2872+ expected_identifier_or_index_or_self_after_lifetime_dependence);
2873+ listStatus.setIsParseError ();
2874+ return listStatus;
2875+ }
2876+ return listStatus;
2877+ });
2878+
2879+ if (!foundParamId) {
2880+ diagnose (
2881+ Tok,
2882+ diag::expected_identifier_or_index_or_self_after_lifetime_dependence);
2883+ status.setIsParseError ();
2884+ return status;
2885+ }
2886+
2887+ assert (!lifetimeEntries.empty ());
2888+ SourceRange range (loc, rParenLoc);
2889+ return ParserResult<LifetimeAttr>(
2890+ LifetimeAttr::create (Context, atLoc, SourceRange (loc, rParenLoc),
2891+ /* implicit */ false , lifetimeEntries));
2892+ }
2893+
28042894// / Parses a (possibly optional) argument for an attribute containing a single, arbitrary identifier.
28052895// /
28062896// / \param P The parser object.
@@ -4062,6 +4152,13 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
40624152 Attributes.add (attr);
40634153 break ;
40644154 }
4155+ case DeclAttrKind::Lifetime: {
4156+ auto Attr = parseLifetimeAttribute (AtLoc, Loc);
4157+ Status |= Attr;
4158+ if (Attr.isNonNull ())
4159+ Attributes.add (Attr.get ());
4160+ break ;
4161+ }
40654162 }
40664163
40674164 if (DuplicateAttribute) {
@@ -5147,7 +5244,7 @@ ParserStatus Parser::parseLifetimeDependenceSpecifiers(
51475244 specifierList.push_back (
51485245 LifetimeDependenceSpecifier::
51495246 getNamedLifetimeDependenceSpecifier (
5150- paramLoc, lifetimeDependenceKind, paramName ));
5247+ paramLoc, paramName, lifetimeDependenceKind ));
51515248 }
51525249 break ;
51535250 }
@@ -5163,7 +5260,7 @@ ParserStatus Parser::parseLifetimeDependenceSpecifiers(
51635260 specifierList.push_back (
51645261 LifetimeDependenceSpecifier::
51655262 getOrderedLifetimeDependenceSpecifier (
5166- paramLoc, lifetimeDependenceKind, paramNum ));
5263+ paramLoc, paramNum, lifetimeDependenceKind ));
51675264 break ;
51685265 }
51695266 case tok::kw_self: {
0 commit comments