@@ -2549,195 +2549,190 @@ Parser::parseMacroRoleAttribute(
2549
2549
bool sawNames = false ;
2550
2550
SmallVector<MacroIntroducedDeclName, 2 > names;
2551
2551
SmallVector<TypeExpr *, 2 > conformances;
2552
- auto argumentsStatus = parseList (tok::r_paren, lParenLoc, rParenLoc,
2553
- /* AllowSepAfterLast=*/ Context.LangOpts .hasFeature (Feature::TrailingComma),
2554
- diag::expected_rparen_expr_list,
2555
- [&] {
2556
- ParserStatus status;
2557
-
2558
- if (consumeIf (tok::code_complete)) {
2559
- status.setHasCodeCompletionAndIsError ();
2560
- if (!sawRole) {
2561
- sawRole = true ;
2562
- if (this ->CodeCompletionCallbacks ) {
2563
- this ->CodeCompletionCallbacks ->completeDeclAttrParam (
2564
- getCustomSyntaxAttributeKind (isAttached), 0 , /* HasLabel=*/ false );
2565
- }
2566
- } else if (!sawNames) {
2567
- if (this ->CodeCompletionCallbacks ) {
2568
- this ->CodeCompletionCallbacks ->completeDeclAttrParam (
2569
- getCustomSyntaxAttributeKind (isAttached), 1 , /* HasLabel=*/ false );
2552
+ auto argumentsStatus = parseList (
2553
+ tok::r_paren, lParenLoc, rParenLoc,
2554
+ /* AllowSepAfterLast=*/ true , diag::expected_rparen_expr_list, [&] {
2555
+ ParserStatus status;
2556
+
2557
+ if (consumeIf (tok::code_complete)) {
2558
+ status.setHasCodeCompletionAndIsError ();
2559
+ if (!sawRole) {
2560
+ sawRole = true ;
2561
+ if (this ->CodeCompletionCallbacks ) {
2562
+ this ->CodeCompletionCallbacks ->completeDeclAttrParam (
2563
+ getCustomSyntaxAttributeKind (isAttached), 0 ,
2564
+ /* HasLabel=*/ false );
2565
+ }
2566
+ } else if (!sawNames) {
2567
+ if (this ->CodeCompletionCallbacks ) {
2568
+ this ->CodeCompletionCallbacks ->completeDeclAttrParam (
2569
+ getCustomSyntaxAttributeKind (isAttached), 1 ,
2570
+ /* HasLabel=*/ false );
2571
+ }
2572
+ }
2570
2573
}
2571
- }
2572
- }
2573
-
2574
- // Parse the argment label, if there is one.
2575
- Identifier fieldName;
2576
- SourceLoc fieldNameLoc;
2577
- parseOptionalArgumentLabel (fieldName, fieldNameLoc);
2578
2574
2579
- // If there is a field name, it better be 'names'.
2580
- if (!(fieldName.empty () || fieldName.is (" names" ) ||
2581
- fieldName.is (" conformances" ))) {
2582
- diagnose (
2583
- fieldNameLoc, diag::macro_attribute_unknown_label, isAttached,
2584
- fieldName);
2585
- status.setIsParseError ();
2586
- return status;
2587
- }
2575
+ // Parse the argment label, if there is one.
2576
+ Identifier fieldName;
2577
+ SourceLoc fieldNameLoc;
2578
+ parseOptionalArgumentLabel (fieldName, fieldNameLoc);
2579
+
2580
+ // If there is a field name, it better be 'names'.
2581
+ if (!(fieldName.empty () || fieldName.is (" names" ) ||
2582
+ fieldName.is (" conformances" ))) {
2583
+ diagnose (fieldNameLoc, diag::macro_attribute_unknown_label,
2584
+ isAttached, fieldName);
2585
+ status.setIsParseError ();
2586
+ return status;
2587
+ }
2588
2588
2589
- // If there is no field name and we haven't seen either names or the role,
2590
- // this is the role.
2591
- if (fieldName.empty () && !sawConformances && !sawNames && !sawRole) {
2592
- // Whether we saw anything we tried to treat as a role.
2593
- sawRole = true ;
2594
-
2595
- auto diagKind = isAttached
2596
- ? diag::macro_role_attr_expected_attached_kind
2597
- : diag::macro_role_attr_expected_freestanding_kind;
2598
- Identifier roleName;
2599
- SourceLoc roleNameLoc;
2600
- if (Tok.is (tok::kw_extension)) {
2601
- roleNameLoc = consumeToken ();
2602
- role = MacroRole::Extension;
2603
- } else if (parseIdentifier (roleName, roleNameLoc, diagKind,
2604
- /* diagnoseDollarPrefix=*/ true )) {
2605
- status.setIsParseError ();
2606
- return status;
2607
- }
2589
+ // If there is no field name and we haven't seen either names or the
2590
+ // role, this is the role.
2591
+ if (fieldName.empty () && !sawConformances && !sawNames && !sawRole) {
2592
+ // Whether we saw anything we tried to treat as a role.
2593
+ sawRole = true ;
2594
+
2595
+ auto diagKind =
2596
+ isAttached ? diag::macro_role_attr_expected_attached_kind
2597
+ : diag::macro_role_attr_expected_freestanding_kind;
2598
+ Identifier roleName;
2599
+ SourceLoc roleNameLoc;
2600
+ if (Tok.is (tok::kw_extension)) {
2601
+ roleNameLoc = consumeToken ();
2602
+ role = MacroRole::Extension;
2603
+ } else if (parseIdentifier (roleName, roleNameLoc, diagKind,
2604
+ /* diagnoseDollarPrefix=*/ true )) {
2605
+ status.setIsParseError ();
2606
+ return status;
2607
+ }
2608
2608
2609
- if (!role)
2610
- role = getMacroRole (roleName.str ());
2609
+ if (!role)
2610
+ role = getMacroRole (roleName.str ());
2611
2611
2612
- if (!role) {
2613
- diagnose (roleNameLoc, diag::macro_role_attr_expected_kind, isAttached);
2614
- status.setIsParseError ();
2615
- return status;
2616
- }
2617
- if (!isMacroSupported (*role, Context)) {
2618
- diagnose (roleNameLoc, diag::macro_experimental, roleName.str (), " " );
2619
- status.setIsParseError ();
2620
- return status;
2621
- }
2612
+ if (!role) {
2613
+ diagnose (roleNameLoc, diag::macro_role_attr_expected_kind,
2614
+ isAttached);
2615
+ status.setIsParseError ();
2616
+ return status;
2617
+ }
2618
+ if (!isMacroSupported (*role, Context)) {
2619
+ diagnose (roleNameLoc, diag::macro_experimental, roleName.str (), " " );
2620
+ status.setIsParseError ();
2621
+ return status;
2622
+ }
2622
2623
2623
- // Check that the role makes sense.
2624
- if (isAttached == !isAttachedMacro (*role)) {
2625
- diagnose (
2626
- roleNameLoc, diag::macro_role_syntax_mismatch, isAttached, roleName
2627
- );
2624
+ // Check that the role makes sense.
2625
+ if (isAttached == !isAttachedMacro (*role)) {
2626
+ diagnose (roleNameLoc, diag::macro_role_syntax_mismatch, isAttached,
2627
+ roleName);
2628
2628
2629
- status.setIsParseError ();
2630
- return status;
2631
- }
2629
+ status.setIsParseError ();
2630
+ return status;
2631
+ }
2632
2632
2633
- return status;
2634
- }
2633
+ return status;
2634
+ }
2635
2635
2636
- if (fieldName.is (" conformances" ) ||
2637
- (fieldName.empty () && sawConformances && !sawNames)) {
2638
- if (fieldName.is (" conformances" ) && sawConformances) {
2639
- diagnose (fieldNameLoc.isValid () ? fieldNameLoc : Tok.getLoc (),
2640
- diag::macro_attribute_duplicate_label,
2641
- isAttached,
2642
- " conformances" );
2643
- }
2636
+ if (fieldName.is (" conformances" ) ||
2637
+ (fieldName.empty () && sawConformances && !sawNames)) {
2638
+ if (fieldName.is (" conformances" ) && sawConformances) {
2639
+ diagnose (fieldNameLoc.isValid () ? fieldNameLoc : Tok.getLoc (),
2640
+ diag::macro_attribute_duplicate_label, isAttached,
2641
+ " conformances" );
2642
+ }
2644
2643
2645
- sawConformances = true ;
2644
+ sawConformances = true ;
2646
2645
2647
- // Parse the introduced conformances
2648
- auto type = parseType ();
2649
- auto *typeExpr = new (Context) TypeExpr (type.get ());
2650
- conformances.push_back (typeExpr);
2646
+ // Parse the introduced conformances
2647
+ auto type = parseType ();
2648
+ auto *typeExpr = new (Context) TypeExpr (type.get ());
2649
+ conformances.push_back (typeExpr);
2651
2650
2652
- return status;
2653
- }
2651
+ return status;
2652
+ }
2654
2653
2655
- // If the field name is empty and we haved seen "names", or the field name
2656
- // is "names" but we've already seen the argument label, complain.
2657
- if (fieldName.empty () != sawNames) {
2658
- diagnose (fieldNameLoc.isValid () ? fieldNameLoc : Tok.getLoc (),
2659
- sawNames ? diag::macro_attribute_duplicate_label
2660
- : diag::macro_attribute_missing_label,
2661
- isAttached,
2662
- " names" );
2663
- }
2664
- sawNames = true ;
2665
-
2666
- // Parse the introduced name kind.
2667
- Identifier introducedNameKind;
2668
- SourceLoc introducedNameKindLoc;
2669
- if (consumeIf (tok::code_complete)) {
2670
- status.setHasCodeCompletionAndIsError ();
2671
- if (this ->CodeCompletionCallbacks ) {
2672
- this ->CodeCompletionCallbacks ->completeDeclAttrParam (
2673
- getCustomSyntaxAttributeKind (isAttached), 1 , /* HasLabel=*/ true );
2674
- }
2675
- } else if (parseIdentifier (introducedNameKind, introducedNameKindLoc,
2676
- diag::macro_attribute_unknown_argument_form,
2677
- /* diagnoseDollarPrefix=*/ true )) {
2678
- status.setIsParseError ();
2679
- return status;
2680
- }
2654
+ // If the field name is empty and we haved seen "names", or the field
2655
+ // name is "names" but we've already seen the argument label, complain.
2656
+ if (fieldName.empty () != sawNames) {
2657
+ diagnose (fieldNameLoc.isValid () ? fieldNameLoc : Tok.getLoc (),
2658
+ sawNames ? diag::macro_attribute_duplicate_label
2659
+ : diag::macro_attribute_missing_label,
2660
+ isAttached, " names" );
2661
+ }
2662
+ sawNames = true ;
2663
+
2664
+ // Parse the introduced name kind.
2665
+ Identifier introducedNameKind;
2666
+ SourceLoc introducedNameKindLoc;
2667
+ if (consumeIf (tok::code_complete)) {
2668
+ status.setHasCodeCompletionAndIsError ();
2669
+ if (this ->CodeCompletionCallbacks ) {
2670
+ this ->CodeCompletionCallbacks ->completeDeclAttrParam (
2671
+ getCustomSyntaxAttributeKind (isAttached), 1 , /* HasLabel=*/ true );
2672
+ }
2673
+ } else if (parseIdentifier (introducedNameKind, introducedNameKindLoc,
2674
+ diag::macro_attribute_unknown_argument_form,
2675
+ /* diagnoseDollarPrefix=*/ true )) {
2676
+ status.setIsParseError ();
2677
+ return status;
2678
+ }
2681
2679
2682
- auto introducedKind = getMacroIntroducedDeclNameKind (introducedNameKind);
2683
- if (!introducedKind) {
2684
- diagnose (
2685
- introducedNameKindLoc, diag::macro_attribute_unknown_name_kind,
2686
- introducedNameKind
2687
- );
2688
- status.setIsParseError ();
2689
- return status;
2690
- }
2680
+ auto introducedKind =
2681
+ getMacroIntroducedDeclNameKind (introducedNameKind);
2682
+ if (!introducedKind) {
2683
+ diagnose (introducedNameKindLoc,
2684
+ diag::macro_attribute_unknown_name_kind, introducedNameKind);
2685
+ status.setIsParseError ();
2686
+ return status;
2687
+ }
2691
2688
2692
- // If we don't need an argument, we're done.
2693
- if (!macroIntroducedNameRequiresArgument (*introducedKind)) {
2694
- // If there is an argument, complain about it.
2695
- if (Tok.is (tok::l_paren)) {
2696
- diagnose (
2697
- Tok, diag::macro_attribute_introduced_name_requires_no_argument,
2698
- introducedNameKind);
2699
- skipSingle ();
2700
- }
2689
+ // If we don't need an argument, we're done.
2690
+ if (!macroIntroducedNameRequiresArgument (*introducedKind)) {
2691
+ // If there is an argument, complain about it.
2692
+ if (Tok.is (tok::l_paren)) {
2693
+ diagnose (Tok,
2694
+ diag::macro_attribute_introduced_name_requires_no_argument,
2695
+ introducedNameKind);
2696
+ skipSingle ();
2697
+ }
2701
2698
2702
- names.push_back (MacroIntroducedDeclName (*introducedKind));
2703
- return status;
2704
- }
2699
+ names.push_back (MacroIntroducedDeclName (*introducedKind));
2700
+ return status;
2701
+ }
2705
2702
2706
- if (!Tok.is (tok::l_paren)) {
2707
- diagnose (
2708
- Tok, diag::macro_attribute_introduced_name_requires_argument,
2709
- introducedNameKind);
2710
- status.setIsParseError ();
2711
- return status;
2712
- }
2703
+ if (!Tok.is (tok::l_paren)) {
2704
+ diagnose (Tok, diag::macro_attribute_introduced_name_requires_argument,
2705
+ introducedNameKind);
2706
+ status.setIsParseError ();
2707
+ return status;
2708
+ }
2713
2709
2714
- // Parse the name.
2715
- (void )consumeToken (tok::l_paren);
2716
- DeclNameLoc nameLoc;
2717
- DeclNameRef name = parseDeclNameRef (
2718
- nameLoc, diag::macro_attribute_unknown_argument_form,
2719
- (DeclNameFlag::AllowOperators |
2720
- DeclNameFlag::AllowKeywords |
2721
- DeclNameFlag::AllowKeywordsUsingSpecialNames |
2722
- DeclNameFlag::AllowCompoundNames |
2723
- DeclNameFlag::AllowZeroArgCompoundNames));
2724
- if (!name) {
2725
- status.setIsParseError ();
2726
- return status;
2727
- }
2710
+ // Parse the name.
2711
+ (void )consumeToken (tok::l_paren);
2712
+ DeclNameLoc nameLoc;
2713
+ DeclNameRef name = parseDeclNameRef (
2714
+ nameLoc, diag::macro_attribute_unknown_argument_form,
2715
+ (DeclNameFlag::AllowOperators | DeclNameFlag::AllowKeywords |
2716
+ DeclNameFlag::AllowKeywordsUsingSpecialNames |
2717
+ DeclNameFlag::AllowCompoundNames |
2718
+ DeclNameFlag::AllowZeroArgCompoundNames));
2719
+ if (!name) {
2720
+ status.setIsParseError ();
2721
+ return status;
2722
+ }
2728
2723
2729
- SourceLoc rParenLoc;
2730
- if (!consumeIf (tok::r_paren, rParenLoc)) {
2731
- diagnose (Tok, diag::attr_expected_rparen, attrName, false );
2732
- rParenLoc = Tok.getLoc ();
2733
- }
2724
+ SourceLoc rParenLoc;
2725
+ if (!consumeIf (tok::r_paren, rParenLoc)) {
2726
+ diagnose (Tok, diag::attr_expected_rparen, attrName, false );
2727
+ rParenLoc = Tok.getLoc ();
2728
+ }
2734
2729
2735
- // Add the name we introduced.
2736
- names.push_back (
2737
- MacroIntroducedDeclName (*introducedKind, name.getFullName ()));
2730
+ // Add the name we introduced.
2731
+ names.push_back (
2732
+ MacroIntroducedDeclName (*introducedKind, name.getFullName ()));
2738
2733
2739
- return status;
2740
- });
2734
+ return status;
2735
+ });
2741
2736
2742
2737
if (argumentsStatus.isErrorOrHasCompletion ())
2743
2738
return argumentsStatus;
@@ -6804,10 +6799,13 @@ ParserStatus Parser::parseInheritance(
6804
6799
ParserStatus Status;
6805
6800
SourceLoc prevComma;
6806
6801
bool HasNextType;
6802
+ bool IsEndOfList;
6807
6803
do {
6808
6804
SWIFT_DEFER {
6809
6805
// Check for a ',', which indicates that there are more protocols coming.
6810
6806
HasNextType = consumeIf (tok::comma, prevComma);
6807
+ IsEndOfList = (Context.LangOpts .hasFeature (Feature::TrailingComma) &&
6808
+ (Tok.is (tok::l_brace) || Tok.is (tok::kw_where)));
6811
6809
};
6812
6810
// Parse the 'class' keyword for a class requirement.
6813
6811
if (Tok.is (tok::kw_class)) {
@@ -6859,7 +6857,7 @@ ParserStatus Parser::parseInheritance(
6859
6857
// Record the type if its a single type.
6860
6858
if (ParsedTypeResult.isNonNull ())
6861
6859
Inherited.push_back (InheritedEntry (ParsedTypeResult.get ()));
6862
- } while (HasNextType);
6860
+ } while (HasNextType && !IsEndOfList );
6863
6861
6864
6862
return Status;
6865
6863
}
0 commit comments