@@ -358,6 +358,7 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
358
358
while (HasUpcomingEntry) {
359
359
SyntaxParsingContext EntryContext (SyntaxContext,
360
360
SyntaxKind::AvailabilityArgument);
361
+ auto ArgumentLoc = Tok.getLoc ();
361
362
AnyAnnotations = true ;
362
363
StringRef ArgumentKindStr = Tok.getText ();
363
364
ParamIndex++;
@@ -382,8 +383,8 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
382
383
}
383
384
384
385
if (ArgumentKind == IsInvalid) {
385
- diagnose (Tok. getLoc () , diag::attr_availability_expected_option, AttrName)
386
- .highlight (SourceRange (Tok. getLoc () ));
386
+ diagnose (ArgumentLoc , diag::attr_availability_expected_option, AttrName)
387
+ .highlight (SourceRange (ArgumentLoc ));
387
388
if (Tok.is (tok::code_complete) && CodeCompletion) {
388
389
CodeCompletion->completeDeclAttrParam (DAK_Available, ParamIndex);
389
390
consumeToken (tok::code_complete);
@@ -395,6 +396,13 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
395
396
396
397
consumeToken ();
397
398
399
+ auto diagnoseDuplicate = [&](bool WasEmpty) {
400
+ if (!WasEmpty) {
401
+ diagnose (ArgumentLoc, diag::attr_availability_invalid_duplicate,
402
+ ArgumentKindStr);
403
+ }
404
+ };
405
+
398
406
switch (ArgumentKind) {
399
407
case IsMessage:
400
408
case IsRenamed: {
@@ -427,6 +435,7 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
427
435
}
428
436
429
437
if (ArgumentKind == IsMessage) {
438
+ diagnoseDuplicate (Message.empty ());
430
439
Message = Value.getValue ();
431
440
} else {
432
441
ParsedDeclName parsedName = parseDeclName (Value.getValue ());
@@ -435,6 +444,7 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
435
444
AnyArgumentInvalid = true ;
436
445
break ;
437
446
}
447
+ diagnoseDuplicate (Renamed.empty ());
438
448
Renamed = Value.getValue ();
439
449
}
440
450
@@ -476,6 +486,7 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
476
486
? Introduced
477
487
: (ArgumentKind == IsDeprecated) ? Deprecated : Obsoleted;
478
488
489
+ bool VerArgWasEmpty = VerArg.empty ();
479
490
if (parseVersionTuple (
480
491
VerArg.Version , VerArg.Range ,
481
492
Diagnostic (diag::attr_availability_expected_version, AttrName))) {
@@ -484,6 +495,7 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
484
495
consumeToken ();
485
496
}
486
497
VerArg.DelimiterLoc = DelimiterLoc;
498
+ diagnoseDuplicate (VerArgWasEmpty);
487
499
488
500
SyntaxContext->createNodeInPlace (SyntaxKind::AvailabilityLabeledArgument);
489
501
0 commit comments