@@ -301,8 +301,10 @@ class InheritedProtocolCollector {
301301 static const StringLiteral DummyProtocolName;
302302
303303 using AvailableAttrList = TinyPtrVector<const AvailableAttr *>;
304+ using OtherAttrList = TinyPtrVector<const DeclAttribute*>;
304305 using ProtocolAndAvailability =
305- std::tuple<ProtocolDecl *, AvailableAttrList, bool /* isUnchecked*/ >;
306+ std::tuple<ProtocolDecl *, AvailableAttrList, bool /* isUnchecked*/ ,
307+ OtherAttrList>;
306308
307309 // / Protocols that will be included by the ASTPrinter without any extra work.
308310 SmallVector<ProtocolDecl *, 8 > IncludedProtocols;
@@ -338,6 +340,17 @@ class InheritedProtocolCollector {
338340 return cache.getValue ();
339341 }
340342
343+ static OtherAttrList getOtherAttrList (const Decl *D) {
344+ OtherAttrList results;
345+ while (D) {
346+ for (auto *result: D->getAttrs ().getAttributes <OriginallyDefinedInAttr>()) {
347+ results.push_back (result);
348+ }
349+ D = D->getDeclContext ()->getAsDecl ();
350+ }
351+ return results;
352+ }
353+
341354 static bool canPrintProtocolTypeNormally (Type type, const Decl *D) {
342355 return isPublicOrUsableFromInline (type);
343356 }
@@ -369,7 +382,8 @@ class InheritedProtocolCollector {
369382 ExtraProtocols.push_back (
370383 ProtocolAndAvailability (protoTy->getDecl (),
371384 getAvailabilityAttrs (D, availableAttrs),
372- inherited.isUnchecked ));
385+ inherited.isUnchecked ,
386+ getOtherAttrList (D)));
373387 }
374388 // FIXME: This ignores layout constraints, but currently we don't support
375389 // any of those besides 'AnyObject'.
@@ -389,7 +403,8 @@ class InheritedProtocolCollector {
389403 ExtraProtocols.push_back (
390404 ProtocolAndAvailability (conf->getProtocol (),
391405 getAvailabilityAttrs (D, availableAttrs),
392- isUncheckedConformance (conf)));
406+ isUncheckedConformance (conf),
407+ getOtherAttrList (D)));
393408 }
394409 }
395410 }
@@ -550,6 +565,7 @@ class InheritedProtocolCollector {
550565 auto proto = std::get<0 >(protoAndAvailability);
551566 auto availability = std::get<1 >(protoAndAvailability);
552567 auto isUnchecked = std::get<2 >(protoAndAvailability);
568+ auto otherAttrs = std::get<3 >(protoAndAvailability);
553569 proto->walkInheritedProtocols (
554570 [&](ProtocolDecl *inherited) -> TypeWalker::Action {
555571 if (!handledProtocols.insert (inherited).second )
@@ -571,7 +587,8 @@ class InheritedProtocolCollector {
571587 conformanceDeclaredInModule (M, nominal, inherited) &&
572588 !M->isImportedImplementationOnly (inherited->getParentModule ())) {
573589 protocolsToPrint.push_back (
574- ProtocolAndAvailability (inherited, availability, isUnchecked));
590+ ProtocolAndAvailability (inherited, availability, isUnchecked,
591+ otherAttrs));
575592 return TypeWalker::Action::SkipChildren;
576593 }
577594
@@ -586,6 +603,7 @@ class InheritedProtocolCollector {
586603 auto proto = std::get<0 >(protoAndAvailability);
587604 auto availability = std::get<1 >(protoAndAvailability);
588605 auto isUnchecked = std::get<2 >(protoAndAvailability);
606+ auto otherAttrs = std::get<3 >(protoAndAvailability);
589607
590608 bool haveFeatureChecks = printOptions.PrintCompatibilityFeatureChecks &&
591609 printCompatibilityFeatureChecksPre (printer, proto);
@@ -595,6 +613,7 @@ class InheritedProtocolCollector {
595613 attrs.insert (attrs.end (), availability.begin (), availability.end ());
596614 auto spiAttributes = proto->getAttrs ().getAttributes <SPIAccessControlAttr>();
597615 attrs.insert (attrs.end (), spiAttributes.begin (), spiAttributes.end ());
616+ attrs.insert (attrs.end (), otherAttrs.begin (), otherAttrs.end ());
598617 DeclAttributes::print (printer, printOptions, attrs);
599618
600619 printer << " extension " ;
0 commit comments