@@ -430,10 +430,11 @@ static bool isShortFormAvailabilityImpliedByOther(const AvailableAttr *Attr,
430
430
// / @available(OSX 10.10, iOS 8.0, *)
431
431
static void printShortFormAvailable (ArrayRef<const DeclAttribute *> Attrs,
432
432
ASTPrinter &Printer,
433
- const PrintOptions &Options) {
433
+ const PrintOptions &Options,
434
+ bool forAtSpecialize = false ) {
434
435
assert (!Attrs.empty ());
435
-
436
- Printer << " @available(" ;
436
+ if (!forAtSpecialize)
437
+ Printer << " @available(" ;
437
438
auto FirstAvail = cast<AvailableAttr>(Attrs.front ());
438
439
if (Attrs.size () == 1 &&
439
440
FirstAvail->getPlatformAgnosticAvailability () !=
@@ -445,8 +446,9 @@ static void printShortFormAvailable(ArrayRef<const DeclAttribute *> Attrs,
445
446
assert (FirstAvail->isPackageDescriptionVersionSpecific ());
446
447
Printer << " _PackageDescription " ;
447
448
}
448
- Printer << FirstAvail->Introduced .getValue ().getAsString ()
449
- << " )" ;
449
+ Printer << FirstAvail->Introduced .getValue ().getAsString ();
450
+ if (!forAtSpecialize)
451
+ Printer << " )" ;
450
452
} else {
451
453
for (auto *DA : Attrs) {
452
454
auto *AvailAttr = cast<AvailableAttr>(DA);
@@ -458,9 +460,12 @@ static void printShortFormAvailable(ArrayRef<const DeclAttribute *> Attrs,
458
460
Printer << platformString (AvailAttr->Platform ) << " "
459
461
<< AvailAttr->Introduced .getValue ().getAsString () << " , " ;
460
462
}
461
- Printer << " *)" ;
463
+ Printer << " *" ;
464
+ if (!forAtSpecialize)
465
+ Printer << " )" ;
462
466
}
463
- Printer.printNewline ();
467
+ if (!forAtSpecialize)
468
+ Printer.printNewline ();
464
469
}
465
470
466
471
// / The kind of a parameter in a `wrt:` differentiation parameters clause:
@@ -745,6 +750,53 @@ SourceLoc DeclAttributes::getStartLoc(bool forModifiers) const {
745
750
return lastAttr ? lastAttr->getRangeWithAt ().Start : SourceLoc ();
746
751
}
747
752
753
+ static void printAvailableAttr (const AvailableAttr *Attr, ASTPrinter &Printer,
754
+ const PrintOptions &Options) {
755
+ if (Attr->isLanguageVersionSpecific ())
756
+ Printer << " swift" ;
757
+ else if (Attr->isPackageDescriptionVersionSpecific ())
758
+ Printer << " _PackageDescription" ;
759
+ else
760
+ Printer << Attr->platformString ();
761
+
762
+ if (Attr->isUnconditionallyUnavailable ())
763
+ Printer << " , unavailable" ;
764
+ else if (Attr->isUnconditionallyDeprecated ())
765
+ Printer << " , deprecated" ;
766
+
767
+ if (Attr->Introduced )
768
+ Printer << " , introduced: " << Attr->Introduced .getValue ().getAsString ();
769
+ if (Attr->Deprecated )
770
+ Printer << " , deprecated: " << Attr->Deprecated .getValue ().getAsString ();
771
+ if (Attr->Obsoleted )
772
+ Printer << " , obsoleted: " << Attr->Obsoleted .getValue ().getAsString ();
773
+
774
+ if (!Attr->Rename .empty ()) {
775
+ Printer << " , renamed: \" " << Attr->Rename << " \" " ;
776
+ } else if (Attr->RenameDecl ) {
777
+ Printer << " , renamed: \" " ;
778
+ if (auto *Accessor = dyn_cast<AccessorDecl>(Attr->RenameDecl )) {
779
+ SmallString<32 > Name;
780
+ llvm::raw_svector_ostream OS (Name);
781
+ Accessor->printUserFacingName (OS);
782
+ Printer << Name.str ();
783
+ } else {
784
+ Printer << Attr->RenameDecl ->getName ();
785
+ }
786
+ Printer << " \" " ;
787
+ }
788
+
789
+ // If there's no message, but this is specifically an imported
790
+ // "unavailable in Swift" attribute, synthesize a message to look good in
791
+ // the generated interface.
792
+ if (!Attr->Message .empty ()) {
793
+ Printer << " , message: " ;
794
+ Printer.printEscapedStringLiteral (Attr->Message );
795
+ } else if (Attr->getPlatformAgnosticAvailability () ==
796
+ PlatformAgnosticAvailabilityKind::UnavailableInSwift)
797
+ Printer << " , message: \" Not available in Swift\" " ;
798
+ }
799
+
748
800
bool DeclAttribute::printImpl (ASTPrinter &Printer, const PrintOptions &Options,
749
801
const Decl *D) const {
750
802
@@ -890,51 +942,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
890
942
Printer.printAttrName (" @available" );
891
943
Printer << " (" ;
892
944
auto Attr = cast<AvailableAttr>(this );
893
- if (Attr->isLanguageVersionSpecific ())
894
- Printer << " swift" ;
895
- else if (Attr->isPackageDescriptionVersionSpecific ())
896
- Printer << " _PackageDescription" ;
897
- else
898
- Printer << Attr->platformString ();
899
-
900
- if (Attr->isUnconditionallyUnavailable ())
901
- Printer << " , unavailable" ;
902
- else if (Attr->isUnconditionallyDeprecated ())
903
- Printer << " , deprecated" ;
904
-
905
- if (Attr->Introduced )
906
- Printer << " , introduced: " << Attr->Introduced .getValue ().getAsString ();
907
- if (Attr->Deprecated )
908
- Printer << " , deprecated: " << Attr->Deprecated .getValue ().getAsString ();
909
- if (Attr->Obsoleted )
910
- Printer << " , obsoleted: " << Attr->Obsoleted .getValue ().getAsString ();
911
-
912
- if (!Attr->Rename .empty ()) {
913
- Printer << " , renamed: \" " << Attr->Rename << " \" " ;
914
- } else if (Attr->RenameDecl ) {
915
- Printer << " , renamed: \" " ;
916
- if (auto *Accessor = dyn_cast<AccessorDecl>(Attr->RenameDecl )) {
917
- SmallString<32 > Name;
918
- llvm::raw_svector_ostream OS (Name);
919
- Accessor->printUserFacingName (OS);
920
- Printer << Name.str ();
921
- } else {
922
- Printer << Attr->RenameDecl ->getName ();
923
- }
924
- Printer << " \" " ;
925
- }
926
-
927
- // If there's no message, but this is specifically an imported
928
- // "unavailable in Swift" attribute, synthesize a message to look good in
929
- // the generated interface.
930
- if (!Attr->Message .empty ()) {
931
- Printer << " , message: " ;
932
- Printer.printEscapedStringLiteral (Attr->Message );
933
- }
934
- else if (Attr->getPlatformAgnosticAvailability ()
935
- == PlatformAgnosticAvailabilityKind::UnavailableInSwift)
936
- Printer << " , message: \" Not available in Swift\" " ;
937
-
945
+ printAvailableAttr (Attr, Printer, Options);
938
946
Printer << " )" ;
939
947
break ;
940
948
}
@@ -984,6 +992,21 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
984
992
Printer << " kind: " << kind << " , " ;
985
993
if (target)
986
994
Printer << " target: " << target << " , " ;
995
+ auto availAttrs = attr->getAvailabeAttrs ();
996
+ if (!availAttrs.empty ()) {
997
+ Printer << " availability: " ;
998
+ auto numAttrs = availAttrs.size ();
999
+ if (numAttrs == 1 ) {
1000
+ printAvailableAttr (availAttrs[0 ], Printer, Options);
1001
+ Printer << " ; " ;
1002
+ } else {
1003
+ SmallVector<const DeclAttribute *, 8 > tmp (availAttrs.begin (),
1004
+ availAttrs.end ());
1005
+ printShortFormAvailable (tmp, Printer, Options,
1006
+ true /* forAtSpecialize*/ );
1007
+ Printer << " ; " ;
1008
+ }
1009
+ }
987
1010
SmallVector<Requirement, 4 > requirementsScratch;
988
1011
auto requirements = attr->getSpecializedSignature ().getRequirements ();
989
1012
auto *FnDecl = dyn_cast_or_null<AbstractFunctionDecl>(D);
@@ -1663,13 +1686,18 @@ SpecializeAttr::SpecializeAttr(SourceLoc atLoc, SourceRange range,
1663
1686
SpecializationKind kind,
1664
1687
GenericSignature specializedSignature,
1665
1688
DeclNameRef targetFunctionName,
1666
- ArrayRef<Identifier> spiGroups)
1689
+ ArrayRef<Identifier> spiGroups,
1690
+ ArrayRef<AvailableAttr *> availableAttrs)
1667
1691
: DeclAttribute(DAK_Specialize, atLoc, range,
1668
1692
/* Implicit=*/ clause == nullptr ),
1669
1693
trailingWhereClause(clause), specializedSignature(specializedSignature),
1670
- targetFunctionName(targetFunctionName), numSPIGroups(spiGroups.size()) {
1694
+ targetFunctionName(targetFunctionName), numSPIGroups(spiGroups.size()),
1695
+ numAvailableAttrs(availableAttrs.size()) {
1671
1696
std::uninitialized_copy (spiGroups.begin (), spiGroups.end (),
1672
1697
getTrailingObjects<Identifier>());
1698
+ std::uninitialized_copy (availableAttrs.begin (), availableAttrs.end (),
1699
+ getTrailingObjects<AvailableAttr *>());
1700
+
1673
1701
Bits.SpecializeAttr .exported = exported;
1674
1702
Bits.SpecializeAttr .kind = unsigned (kind);
1675
1703
}
@@ -1684,35 +1712,41 @@ SpecializeAttr *SpecializeAttr::create(ASTContext &Ctx, SourceLoc atLoc,
1684
1712
bool exported, SpecializationKind kind,
1685
1713
DeclNameRef targetFunctionName,
1686
1714
ArrayRef<Identifier> spiGroups,
1715
+ ArrayRef<AvailableAttr *> availableAttrs,
1687
1716
GenericSignature specializedSignature) {
1688
- unsigned size = totalSizeToAlloc<Identifier>(spiGroups.size ());
1717
+ unsigned size = totalSizeToAlloc<Identifier, AvailableAttr *>(
1718
+ spiGroups.size (), availableAttrs.size ());
1689
1719
void *mem = Ctx.Allocate (size, alignof (SpecializeAttr));
1690
1720
return new (mem)
1691
1721
SpecializeAttr (atLoc, range, clause, exported, kind, specializedSignature,
1692
- targetFunctionName, spiGroups);
1722
+ targetFunctionName, spiGroups, availableAttrs );
1693
1723
}
1694
1724
1695
1725
SpecializeAttr *SpecializeAttr::create (ASTContext &ctx, bool exported,
1696
1726
SpecializationKind kind,
1697
1727
ArrayRef<Identifier> spiGroups,
1728
+ ArrayRef<AvailableAttr *> availableAttrs,
1698
1729
GenericSignature specializedSignature,
1699
1730
DeclNameRef targetFunctionName) {
1700
- unsigned size = totalSizeToAlloc<Identifier>(spiGroups.size ());
1731
+ unsigned size = totalSizeToAlloc<Identifier, AvailableAttr *>(
1732
+ spiGroups.size (), availableAttrs.size ());
1701
1733
void *mem = ctx.Allocate (size, alignof (SpecializeAttr));
1702
- return new (mem)
1703
- SpecializeAttr ( SourceLoc (), SourceRange (), nullptr , exported, kind,
1704
- specializedSignature, targetFunctionName, spiGroups);
1734
+ return new (mem) SpecializeAttr (
1735
+ SourceLoc (), SourceRange (), nullptr , exported, kind, specializedSignature ,
1736
+ targetFunctionName, spiGroups, availableAttrs );
1705
1737
}
1706
1738
1707
1739
SpecializeAttr *SpecializeAttr::create (
1708
1740
ASTContext &ctx, bool exported, SpecializationKind kind,
1709
- ArrayRef<Identifier> spiGroups, GenericSignature specializedSignature,
1710
- DeclNameRef targetFunctionName, LazyMemberLoader *resolver, uint64_t data) {
1711
- unsigned size = totalSizeToAlloc<Identifier>(spiGroups.size ());
1741
+ ArrayRef<Identifier> spiGroups, ArrayRef<AvailableAttr *> availableAttrs,
1742
+ GenericSignature specializedSignature, DeclNameRef targetFunctionName,
1743
+ LazyMemberLoader *resolver, uint64_t data) {
1744
+ unsigned size = totalSizeToAlloc<Identifier, AvailableAttr *>(
1745
+ spiGroups.size (), availableAttrs.size ());
1712
1746
void *mem = ctx.Allocate (size, alignof (SpecializeAttr));
1713
- auto *attr = new (mem)
1714
- SpecializeAttr ( SourceLoc (), SourceRange (), nullptr , exported, kind,
1715
- specializedSignature, targetFunctionName, spiGroups);
1747
+ auto *attr = new (mem) SpecializeAttr (
1748
+ SourceLoc (), SourceRange (), nullptr , exported, kind, specializedSignature ,
1749
+ targetFunctionName, spiGroups, availableAttrs );
1716
1750
attr->resolver = resolver;
1717
1751
attr->resolverContextData = data;
1718
1752
return attr;
0 commit comments