Skip to content

Commit 17cba71

Browse files
authored
Merge pull request swiftlang#40196 from nkcsgexi/85426499
2 parents 551604a + 2f2ee1b commit 17cba71

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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 ";
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// Ensure the originallyDefinedIn attribute is printed in swiftinterface files for synthesized extensions
4+
// RUN: %target-swift-frontend-typecheck -emit-module-interface-path %t/Foo.swiftinterface %s -module-name Foo
5+
// RUN: %FileCheck %s < %t/Foo.swiftinterface
6+
7+
@available(OSX 10.7, iOS 7.0, *)
8+
@_originallyDefinedIn(module: "Bar", OSX 10.9, iOS 13.0)
9+
public enum MyCase: Int {
10+
case first
11+
case second
12+
}
13+
14+
// CHECK: @_originallyDefinedIn(module: "Bar", macOS 10.9)
15+
// CHECK: @_originallyDefinedIn(module: "Bar", iOS 13.0)
16+
// CHECK: public enum MyCase : Swift.Int
17+
18+
// CHECK: @_originallyDefinedIn(module: "Bar", macOS 10.9)
19+
// CHECK: @_originallyDefinedIn(module: "Bar", iOS 13.0)
20+
// CHECK: extension Foo.MyCase : Swift.Equatable {}
21+
22+
// CHECK: @_originallyDefinedIn(module: "Bar", macOS 10.9)
23+
// CHECK: @_originallyDefinedIn(module: "Bar", iOS 13.0)
24+
// CHECK: extension Foo.MyCase : Swift.Hashable {}
25+

0 commit comments

Comments
 (0)