@@ -318,10 +318,11 @@ class InheritedProtocolCollector {
318
318
static const StringLiteral DummyProtocolName;
319
319
320
320
using AvailableAttrList = TinyPtrVector<const AvailableAttr *>;
321
- using OtherAttrList = TinyPtrVector<const DeclAttribute*>;
321
+ using OriginallyDefinedInAttrList =
322
+ TinyPtrVector<const OriginallyDefinedInAttr *>;
322
323
using ProtocolAndAvailability =
323
- std::tuple<ProtocolDecl *, AvailableAttrList, bool /* isUnchecked*/ ,
324
- OtherAttrList >;
324
+ std::tuple<ProtocolDecl *, AvailableAttrList, bool /* isUnchecked*/ ,
325
+ OriginallyDefinedInAttrList >;
325
326
326
327
// / Protocols that will be included by the ASTPrinter without any extra work.
327
328
SmallVector<ProtocolDecl *, 8 > IncludedProtocols;
@@ -357,10 +358,12 @@ class InheritedProtocolCollector {
357
358
return cache.getValue ();
358
359
}
359
360
360
- static OtherAttrList getOtherAttrList (const Decl *D) {
361
- OtherAttrList results;
361
+ static OriginallyDefinedInAttrList
362
+ getOriginallyDefinedInAttrList (const Decl *D) {
363
+ OriginallyDefinedInAttrList results;
362
364
while (D) {
363
- for (auto *result: D->getAttrs ().getAttributes <OriginallyDefinedInAttr>()) {
365
+ for (auto *result :
366
+ D->getAttrs ().getAttributes <OriginallyDefinedInAttr>()) {
364
367
results.push_back (result);
365
368
}
366
369
D = D->getDeclContext ()->getAsDecl ();
@@ -396,11 +399,9 @@ class InheritedProtocolCollector {
396
399
if (canPrintNormally)
397
400
IncludedProtocols.push_back (protoDecl);
398
401
else
399
- ExtraProtocols.push_back (
400
- ProtocolAndAvailability (protoDecl,
401
- getAvailabilityAttrs (D, availableAttrs),
402
- inherited.isUnchecked ,
403
- getOtherAttrList (D)));
402
+ ExtraProtocols.push_back (ProtocolAndAvailability (
403
+ protoDecl, getAvailabilityAttrs (D, availableAttrs),
404
+ inherited.isUnchecked , getOriginallyDefinedInAttrList (D)));
404
405
}
405
406
// FIXME: This ignores layout constraints, but currently we don't support
406
407
// any of those besides 'AnyObject'.
@@ -417,11 +418,9 @@ class InheritedProtocolCollector {
417
418
for (auto *conf : localConformances) {
418
419
if (conf->getSourceKind () != ConformanceEntryKind::Synthesized)
419
420
continue ;
420
- ExtraProtocols.push_back (
421
- ProtocolAndAvailability (conf->getProtocol (),
422
- getAvailabilityAttrs (D, availableAttrs),
423
- isUncheckedConformance (conf),
424
- getOtherAttrList (D)));
421
+ ExtraProtocols.push_back (ProtocolAndAvailability (
422
+ conf->getProtocol (), getAvailabilityAttrs (D, availableAttrs),
423
+ isUncheckedConformance (conf), getOriginallyDefinedInAttrList (D)));
425
424
}
426
425
}
427
426
}
@@ -628,7 +627,7 @@ class InheritedProtocolCollector {
628
627
auto proto = std::get<0 >(protoAndAvailability);
629
628
auto availability = std::get<1 >(protoAndAvailability);
630
629
auto isUnchecked = std::get<2 >(protoAndAvailability);
631
- auto otherAttrs = std::get<3 >(protoAndAvailability);
630
+ auto originallyDefinedInAttrs = std::get<3 >(protoAndAvailability);
632
631
633
632
// Create a synthesized ExtensionDecl for the conformance.
634
633
ASTContext &ctx = M->getASTContext ();
@@ -640,21 +639,24 @@ class InheritedProtocolCollector {
640
639
extension->setImplicit ();
641
640
642
641
// Build up synthesized DeclAttributes for the extension.
643
- TinyPtrVector<const DeclAttribute *> attrs;
644
- attrs.insert (attrs.end (), availability.begin (), availability.end ());
645
- auto spiAttributes =
646
- proto->getAttrs ().getAttributes <SPIAccessControlAttr>();
647
- attrs.insert (attrs.end (), spiAttributes.begin (), spiAttributes.end ());
648
- attrs.insert (attrs.end (), otherAttrs.begin (), otherAttrs.end ());
642
+ TinyPtrVector<const DeclAttribute *> clonedAttrs;
643
+ for (auto *attr : availability) {
644
+ clonedAttrs.push_back (attr->clone (ctx, /* implicit*/ true ));
645
+ }
646
+ for (auto *attr : proto->getAttrs ().getAttributes <SPIAccessControlAttr>()) {
647
+ clonedAttrs.push_back (attr->clone (ctx, /* implicit*/ true ));
648
+ }
649
+ for (auto *attr : originallyDefinedInAttrs) {
650
+ clonedAttrs.push_back (attr->clone (ctx, /* implicit*/ true ));
651
+ }
649
652
650
653
// Since DeclAttributes is a linked list where each added attribute becomes
651
654
// the head, we need to add these attributes in reverse order to reproduce
652
655
// the order in which previous implementations printed these attributes.
653
- DeclAttributes declAttrs ;
654
- for ( auto attr = attrs. rbegin (), end = attrs. rend (); attr != end; ++attr) {
655
- declAttrs .add (const_cast <DeclAttribute *>(*attr));
656
+ for ( auto attr = clonedAttrs. rbegin (), end = clonedAttrs. rend () ;
657
+ attr != end; ++attr) {
658
+ extension-> getAttrs () .add (const_cast <DeclAttribute *>(*attr));
656
659
}
657
- extension->getAttrs () = declAttrs;
658
660
659
661
ctx.evaluator .cacheOutput (ExtendedTypeRequest{extension},
660
662
nominal->getDeclaredType ());
0 commit comments