@@ -2817,6 +2817,7 @@ bool Parser::canParseCustomAttribute() {
2817
2817
2818
2818
ParserResult<CustomAttr> Parser::parseCustomAttribute (
2819
2819
SourceLoc atLoc, PatternBindingInitializer *&initContext) {
2820
+ assert (Tok.is (tok::identifier));
2820
2821
SyntaxContext->setCreateSyntax (SyntaxKind::CustomAttribute);
2821
2822
2822
2823
// Parse a custom attribute.
@@ -3054,7 +3055,7 @@ bool Parser::canParseTypeAttribute() {
3054
3055
TypeAttributes attrs; // ignored
3055
3056
PatternBindingInitializer *initContext = nullptr ;
3056
3057
return !parseTypeAttribute (attrs, /* atLoc=*/ SourceLoc (), initContext,
3057
- /* justChecking*/ true );
3058
+ /* justChecking*/ true ). isError () ;
3058
3059
}
3059
3060
3060
3061
// / Parses the '@differentiable' type attribute argument (no argument list,
@@ -3213,16 +3214,28 @@ bool Parser::parseConventionAttributeInternal(
3213
3214
// / \param justChecking - if true, we're just checking whether we
3214
3215
// / canParseTypeAttribute; don't emit any diagnostics, and there's
3215
3216
// / no need to actually record the attribute
3216
- bool Parser::parseTypeAttribute (TypeAttributes &Attributes, SourceLoc AtLoc,
3217
- PatternBindingInitializer *&initContext,
3218
- bool justChecking) {
3217
+ ParserStatus Parser::parseTypeAttribute (TypeAttributes &Attributes,
3218
+ SourceLoc AtLoc,
3219
+ PatternBindingInitializer *&initContext,
3220
+ bool justChecking) {
3219
3221
// If this not an identifier, the attribute is malformed.
3220
3222
if (Tok.isNot (tok::identifier) &&
3221
3223
// These are keywords that we accept as attribute names.
3222
3224
Tok.isNot (tok::kw_in) && Tok.isNot (tok::kw_inout)) {
3225
+
3226
+ if (Tok.is (tok::code_complete)) {
3227
+ if (!justChecking) {
3228
+ if (CodeCompletion) {
3229
+ CodeCompletion->completeTypeAttrBeginning ();
3230
+ }
3231
+ }
3232
+ consumeToken (tok::code_complete);
3233
+ return makeParserCodeCompletionStatus ();
3234
+ }
3235
+
3223
3236
if (!justChecking)
3224
3237
diagnose (Tok, diag::expected_attribute_name);
3225
- return true ;
3238
+ return makeParserError () ;
3226
3239
}
3227
3240
3228
3241
// Determine which attribute it is, and diagnose it if unknown.
@@ -3250,7 +3263,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3250
3263
if (declAttrID != DAK_Count) {
3251
3264
// This is a valid decl attribute so they should have put it on the decl
3252
3265
// instead of the type.
3253
- if (justChecking) return true ;
3266
+ if (justChecking) return makeParserError () ;
3254
3267
3255
3268
// If this is the first attribute, and if we are on a simple decl, emit a
3256
3269
// fixit to move the attribute. Otherwise, we don't have the location of
@@ -3285,21 +3298,22 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3285
3298
backtrack.cancelBacktrack ();
3286
3299
}
3287
3300
3288
- return true ;
3301
+ return makeParserError () ;
3289
3302
}
3290
3303
3291
3304
// If we're just checking, try to parse now.
3292
3305
if (justChecking)
3293
- return !canParseCustomAttribute ();
3306
+ return canParseCustomAttribute () ? makeParserSuccess ()
3307
+ : makeParserError ();
3294
3308
3295
3309
// Parse as a custom attribute.
3296
3310
auto customAttrResult = parseCustomAttribute (AtLoc, initContext);
3297
3311
if (customAttrResult.isParseErrorOrHasCompletion ())
3298
- return true ;
3312
+ return customAttrResult ;
3299
3313
3300
3314
if (auto attr = customAttrResult.get ())
3301
3315
Attributes.addCustomAttr (attr);
3302
- return false ;
3316
+ return makeParserSuccess () ;
3303
3317
}
3304
3318
3305
3319
// Ok, it is a valid attribute, eat it, and then process it.
@@ -3313,19 +3327,19 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3313
3327
if (failedToParse) {
3314
3328
if (Tok.is (tok::r_paren))
3315
3329
consumeToken ();
3316
- return true ;
3330
+ return makeParserError () ;
3317
3331
}
3318
3332
}
3319
3333
3320
3334
// In just-checking mode, we only need to consume the tokens, and we don't
3321
3335
// want to do any other analysis.
3322
3336
if (justChecking)
3323
- return false ;
3337
+ return makeParserSuccess () ;
3324
3338
3325
3339
// Diagnose duplicated attributes.
3326
3340
if (Attributes.has (attr)) {
3327
3341
diagnose (AtLoc, diag::duplicate_attribute, /* isModifier=*/ false );
3328
- return false ;
3342
+ return makeParserSuccess () ;
3329
3343
}
3330
3344
3331
3345
// Handle any attribute-specific processing logic.
@@ -3347,7 +3361,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3347
3361
case TAK_objc_metatype:
3348
3362
if (!isInSILMode ()) {
3349
3363
diagnose (AtLoc, diag::only_allowed_in_sil, Text);
3350
- return false ;
3364
+ return makeParserSuccess () ;
3351
3365
}
3352
3366
break ;
3353
3367
@@ -3356,27 +3370,27 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3356
3370
case TAK_sil_unowned:
3357
3371
if (!isInSILMode ()) {
3358
3372
diagnose (AtLoc, diag::only_allowed_in_sil, Text);
3359
- return false ;
3373
+ return makeParserSuccess () ;
3360
3374
}
3361
3375
3362
3376
if (Attributes.hasOwnership ()) {
3363
3377
diagnose (AtLoc, diag::duplicate_attribute, /* isModifier*/ false );
3364
- return false ;
3378
+ return makeParserSuccess () ;
3365
3379
}
3366
3380
break ;
3367
3381
3368
3382
// 'inout' attribute.
3369
3383
case TAK_inout:
3370
3384
if (!isInSILMode ()) {
3371
3385
diagnose (AtLoc, diag::inout_not_attribute);
3372
- return false ;
3386
+ return makeParserSuccess () ;
3373
3387
}
3374
3388
break ;
3375
3389
3376
3390
case TAK_opened: {
3377
3391
if (!isInSILMode ()) {
3378
3392
diagnose (AtLoc, diag::only_allowed_in_sil, " opened" );
3379
- return false ;
3393
+ return makeParserSuccess () ;
3380
3394
}
3381
3395
3382
3396
// Parse the opened existential ID string in parens
@@ -3410,7 +3424,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3410
3424
Attributes.differentiabilityKind = DifferentiabilityKind::Normal;
3411
3425
if (parseDifferentiableTypeAttributeArgument (
3412
3426
*this , Attributes, /* emitDiagnostics=*/ !justChecking))
3413
- return true ;
3427
+ return makeParserError () ;
3414
3428
// Only 'reverse' is supported today.
3415
3429
// TODO: Change this to an error once clients have migrated to 'reverse'.
3416
3430
if (Attributes.differentiabilityKind == DifferentiabilityKind::Normal) {
@@ -3432,31 +3446,31 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3432
3446
auto beginLoc = Tok.getLoc ();
3433
3447
if (!consumeIfNotAtStartOfLine (tok::l_paren)) {
3434
3448
diagnose (Tok, diag::attr_expected_lparen, " _opaqueReturnTypeOf" , false );
3435
- return true ;
3449
+ return makeParserError () ;
3436
3450
}
3437
3451
3438
3452
if (!Tok.is (tok::string_literal)) {
3439
3453
diagnose (Tok, diag::opened_attribute_id_value);
3440
- return true ;
3454
+ return makeParserError () ;
3441
3455
}
3442
3456
auto mangling = Tok.getText ().slice (1 , Tok.getText ().size () - 1 );
3443
3457
consumeToken (tok::string_literal);
3444
3458
3445
3459
if (!Tok.is (tok::comma)) {
3446
3460
diagnose (Tok, diag::attr_expected_comma, " _opaqueReturnTypeOf" , false );
3447
- return true ;
3461
+ return makeParserError () ;
3448
3462
}
3449
3463
consumeToken (tok::comma);
3450
3464
3451
3465
if (!Tok.is (tok::integer_literal)) {
3452
3466
diagnose (Tok, diag::attr_expected_string_literal, " _opaqueReturnTypeOf" );
3453
- return true ;
3467
+ return makeParserError () ;
3454
3468
}
3455
3469
3456
3470
unsigned index;
3457
3471
if (Tok.getText ().getAsInteger (10 , index)) {
3458
3472
diagnose (Tok, diag::attr_expected_string_literal, " _opaqueReturnTypeOf" );
3459
- return true ;
3473
+ return makeParserError () ;
3460
3474
}
3461
3475
consumeToken (tok::integer_literal);
3462
3476
@@ -3471,7 +3485,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3471
3485
}
3472
3486
3473
3487
Attributes.setAttr (attr, AtLoc);
3474
- return false ;
3488
+ return makeParserSuccess () ;
3475
3489
}
3476
3490
3477
3491
// / \verbatim
@@ -3705,9 +3719,10 @@ bool Parser::parseDeclModifierList(DeclAttributes &Attributes,
3705
3719
// / '@' attribute
3706
3720
// / '@' attribute attribute-list-clause
3707
3721
// / \endverbatim
3708
- bool Parser::parseTypeAttributeListPresent (ParamDecl::Specifier &Specifier,
3709
- SourceLoc &SpecifierLoc,
3710
- TypeAttributes &Attributes) {
3722
+ ParserStatus
3723
+ Parser::parseTypeAttributeListPresent (ParamDecl::Specifier &Specifier,
3724
+ SourceLoc &SpecifierLoc,
3725
+ TypeAttributes &Attributes) {
3711
3726
PatternBindingInitializer *initContext = nullptr ;
3712
3727
Specifier = ParamDecl::Specifier::Default;
3713
3728
while (Tok.is (tok::kw_inout) ||
@@ -3731,21 +3746,23 @@ bool Parser::parseTypeAttributeListPresent(ParamDecl::Specifier &Specifier,
3731
3746
SpecifierLoc = consumeToken ();
3732
3747
}
3733
3748
3749
+ ParserStatus status;
3734
3750
SyntaxParsingContext AttrListCtx (SyntaxContext, SyntaxKind::AttributeList);
3735
3751
while (Tok.is (tok::at_sign)) {
3736
3752
// Ignore @substituted in SIL mode and leave it for the type parser.
3737
3753
if (isInSILMode () && peekToken ().getText () == " substituted" )
3738
- return false ;
3754
+ return status ;
3739
3755
3740
3756
if (Attributes.AtLoc .isInvalid ())
3741
3757
Attributes.AtLoc = Tok.getLoc ();
3742
3758
SyntaxParsingContext AttrCtx (SyntaxContext, SyntaxKind::Attribute);
3743
3759
SourceLoc AtLoc = consumeToken ();
3744
- if (parseTypeAttribute (Attributes, AtLoc, initContext))
3745
- return true ;
3760
+ status |= parseTypeAttribute (Attributes, AtLoc, initContext);
3761
+ if (status.isError ())
3762
+ return status;
3746
3763
}
3747
3764
3748
- return false ;
3765
+ return status ;
3749
3766
}
3750
3767
3751
3768
static bool isStartOfOperatorDecl (const Token &Tok, const Token &Tok2) {
0 commit comments