@@ -791,6 +791,11 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
791791 if (Options.excludeAttr (DA))
792792 continue ;
793793
794+ // Skip inverse ABIAttrs--these are an implementation detail.
795+ if (auto abiAttr = dyn_cast<ABIAttr>(DA))
796+ if (abiAttr->isInverse ())
797+ continue ;
798+
794799 // In the public interfaces of -library-level=api modules, skip attributes
795800 // that reference SPI platforms.
796801 if (Options.printPublicInterface () && libraryLevelAPI &&
@@ -1011,6 +1016,13 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
10111016 }
10121017 break ;
10131018 }
1019+
1020+ case DeclAttrKind::ABI:
1021+ // Inverse attributes should never be printed.
1022+ if (cast<ABIAttr>(this )->isInverse ())
1023+ return false ;
1024+ break ;
1025+
10141026 default :
10151027 break ;
10161028 }
@@ -1573,6 +1585,17 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
15731585 break ;
15741586 }
15751587
1588+ case DeclAttrKind::ABI: {
1589+ auto *attr = cast<ABIAttr>(this );
1590+ Printer << " @abi(" ;
1591+ ASSERT (!attr->isInverse () && " should be skipped above" );
1592+ if (attr->abiDecl )
1593+ attr->abiDecl ->print (Printer, Options);
1594+ Printer << " )" ;
1595+
1596+ break ;
1597+ }
1598+
15761599#define SIMPLE_DECL_ATTR (X, CLASS, ...) case DeclAttrKind::CLASS:
15771600#include " swift/AST/DeclAttr.def"
15781601 llvm_unreachable (" handled above" );
@@ -1618,6 +1641,8 @@ StringRef DeclAttribute::getAttrName() const {
16181641 case DeclAttrKind::CLASS: \
16191642 return #NAME;
16201643#include " swift/AST/DeclAttr.def"
1644+ case DeclAttrKind::ABI:
1645+ return " abi" ;
16211646 case DeclAttrKind::SILGenName:
16221647 return " _silgen_name" ;
16231648 case DeclAttrKind::Alignment:
@@ -2805,6 +2830,38 @@ LifetimeAttr *LifetimeAttr::create(ASTContext &context, SourceLoc atLoc,
28052830 return new (context) LifetimeAttr (atLoc, baseRange, implicit, entry);
28062831}
28072832
2833+ void ABIAttr::connectToInverse (Decl *owner) const {
2834+ if (isInverse ())
2835+ return ;
2836+
2837+ // If necessary, convert abiDecl's PBD to a specific VarDecl.
2838+ auto correspondingDecl = abiDecl;
2839+ if (auto PBD = dyn_cast<PatternBindingDecl>(correspondingDecl)) {
2840+ if (!isa<VarDecl>(owner))
2841+ // Invalid code (e.g. `@abi(var x) func x()`). Won't be able to connect.
2842+ return ;
2843+
2844+ correspondingDecl =
2845+ PBD->getVarAtSimilarStructuralPosition (cast<VarDecl>(owner));
2846+ }
2847+
2848+ if (!correspondingDecl)
2849+ return ;
2850+
2851+ auto inverseAttr = correspondingDecl->getAttrs ().getAttribute <ABIAttr>();
2852+ ASSERT (inverseAttr && inverseAttr->isInverse ());
2853+
2854+ // Reverse of the above: If we're trying to connect to a VarDecl, connect to
2855+ // its PBD instead.
2856+ auto inverseCorrespondingDecl = owner;
2857+ if (auto VD = dyn_cast<VarDecl>(inverseCorrespondingDecl))
2858+ if (auto PBD = VD->getParentPatternBinding ())
2859+ inverseCorrespondingDecl = PBD;
2860+
2861+ inverseAttr->abiDecl = inverseCorrespondingDecl;
2862+ }
2863+
2864+
28082865void swift::simple_display (llvm::raw_ostream &out, const DeclAttribute *attr) {
28092866 if (attr)
28102867 attr->print (out);
0 commit comments