Skip to content

Commit 75abee8

Browse files
committed
ModuleInterface: skip override keywords when overriding an invisible decl from super class
When we are printing Swift interface, we have to skip the override keyword if the overriden decl is invisible from the interface. Otherwise, an error will occur while building the Swift module because the overriding decl doesn't override anything. We couldn't skip every `override` keywords because they change the ABI if the overriden decl is also publicly visible. For public-override-internal case, having `override` doesn't have ABI implication. Thus we can skip them. rdar://58562780
1 parent 3978d81 commit 75abee8

File tree

5 files changed

+44
-6
lines changed

5 files changed

+44
-6
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,6 +2697,11 @@ class ValueDecl : public Decl {
26972697
return !isObjC() && isDynamic();
26982698
}
26992699

2700+
bool isEffectiveLinkageMoreVisibleThan(ValueDecl *other) const {
2701+
return (std::min(getEffectiveAccess(), AccessLevel::Public) >
2702+
std::min(other->getEffectiveAccess(), AccessLevel::Public));
2703+
}
2704+
27002705
/// Set whether this type is 'dynamic' or not.
27012706
void setIsDynamic(bool value);
27022707

@@ -5983,11 +5988,6 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
59835988
/// vtable.
59845989
bool needsNewVTableEntry() const;
59855990

5986-
bool isEffectiveLinkageMoreVisibleThan(ValueDecl *other) const {
5987-
return (std::min(getEffectiveAccess(), AccessLevel::Public) >
5988-
std::min(other->getEffectiveAccess(), AccessLevel::Public));
5989-
}
5990-
59915991
bool isSynthesized() const {
59925992
return Bits.AbstractFunctionDecl.Synthesized;
59935993
}

include/swift/AST/PrintOptions.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,10 @@ struct PrintOptions {
276276
/// Prints type variables and unresolved types in an expanded notation suitable
277277
/// for debugging.
278278
bool PrintTypesForDebugging = false;
279-
279+
280+
/// Whether this print option is for printing .swiftinterface file
281+
bool IsForSwiftInterface = false;
282+
280283
/// How to print opaque return types.
281284
enum class OpaqueReturnTypePrintingMode {
282285
/// 'some P1 & P2'.

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(bool preferTypeRepr,
103103
bool printFullConvention,
104104
bool printSPIs) {
105105
PrintOptions result;
106+
result.IsForSwiftInterface = true;
106107
result.PrintLongAttrsOnSeparateLines = true;
107108
result.TypeDefinitions = true;
108109
result.PrintIfConfig = false;

lib/AST/Attr.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,26 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
750750
case DAK_Rethrows:
751751
case DAK_Infix:
752752
return false;
753+
case DAK_Override: {
754+
if (!Options.IsForSwiftInterface)
755+
break;
756+
// When we are printing Swift interface, we have to skip the override keyword
757+
// if the overriden decl is invisible from the interface. Otherwise, an error
758+
// will occur while building the Swift module because the overriding decl
759+
// doesn't override anything.
760+
// We couldn't skip every `override` keywords becuase they change the
761+
// ABI if the overriden decl is also publically visible.
762+
// For public-override-internal case, having `override` doesn't have ABI
763+
// implication. Thus we can skip them.
764+
if (auto *VD = dyn_cast<ValueDecl>(D)) {
765+
if (auto *BD = VD->getOverriddenDecl()) {
766+
if (!BD->hasClangNode() &&
767+
VD->isEffectiveLinkageMoreVisibleThan(BD))
768+
return false;
769+
}
770+
}
771+
break;
772+
}
753773
default:
754774
break;
755775
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -typecheck -module-name Foo -emit-module-interface-path %t/Foo.swiftinterface %s
3+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Foo.swiftinterface -o %t/Foo.swiftmodule
4+
5+
public class BaseClass {
6+
var property: Int { return 1 }
7+
func doSomething() { }
8+
subscript(index: Int) -> Int { get { return 0 } set(newValue) {} }
9+
}
10+
public class DerivedClass: BaseClass {
11+
public override var property : Int { return 0 }
12+
public override func doSomething() { }
13+
public override subscript(index: Int) -> Int { get {return 0} set(newValue) {} }
14+
}

0 commit comments

Comments
 (0)