SIL: Record whether vtable entries are inherited or overridden

Consider a class hierarchy like the following:

class Base {
  func m1() {}
  func m2() {}
}

class Derived : Base {
  override func m2() {}
  func m3() {}
}

The SIL vtable for 'Derived' now records that the entry for m1
is inherited, the entry for m2 is an override, and the entry
for m3 is a new entry:

sil_vtable Derived {
  #Base.m1!1: (Base) -> () -> () : _T01a4BaseC2m1yyF [inherited]
  #Base.m2!1: (Base) -> () -> () : _T01a7DerivedC2m2yyF [override]
  #Derived.m3!1: (Derived) -> () -> () : _T01a7DerivedC2m3yyF
}

This additional information will allow IRGen to emit the vtable
for Derived resiliently, without referencing the symbol for
the inherited method m1() directly.
This commit is contained in:
Slava Pestov
2017-08-14 17:57:17 -04:00
parent fd253dabaf
commit 556d35d9b1
17 changed files with 349 additions and 170 deletions

View File

@@ -43,11 +43,27 @@ public:
// TODO: Entry should include substitutions needed to invoke an overridden
// generic base class method.
struct Entry {
enum Kind : uint8_t {
/// The vtable entry is for a method defined directly in this class.
Normal,
/// The vtable entry is inherited from the superclass.
Inherited,
/// The vtable entry is inherited from the superclass, and overridden
/// in this class.
Override,
};
Entry() : Implementation(nullptr), Linkage(SILLinkage::Private) { }
Entry()
: Implementation(nullptr),
TheKind(Kind::Normal),
Linkage(SILLinkage::Private) { }
Entry(SILDeclRef Method, SILFunction *Implementation, SILLinkage Linkage) :
Method(Method), Implementation(Implementation), Linkage(Linkage) { }
Entry(SILDeclRef Method, SILFunction *Implementation,
Kind TheKind, SILLinkage Linkage)
: Method(Method),
Implementation(Implementation),
TheKind(TheKind),
Linkage(Linkage) { }
/// The declaration reference to the least-derived method visible through
/// the class.
@@ -56,6 +72,9 @@ public:
/// The function which implements the method for the class.
SILFunction *Implementation;
/// The entry kind.
Kind TheKind;
/// The linkage of the implementing function.
///
/// This is usually the same as