mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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:
@@ -5058,7 +5058,31 @@ bool SILParserTUState::parseSILVTable(Parser &P) {
|
||||
if (!Linkage)
|
||||
Linkage = stripExternalFromLinkage(Func->getLinkage());
|
||||
}
|
||||
vtableEntries.emplace_back(Ref, Func, Linkage.getValue());
|
||||
|
||||
auto Kind = SILVTable::Entry::Kind::Normal;
|
||||
if (P.Tok.is(tok::l_square)) {
|
||||
P.consumeToken(tok::l_square);
|
||||
if (P.Tok.isNot(tok::identifier)) {
|
||||
P.diagnose(P.Tok.getLoc(), diag::sil_vtable_bad_entry_kind);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (P.Tok.getText() == "override") {
|
||||
P.consumeToken();
|
||||
Kind = SILVTable::Entry::Kind::Override;
|
||||
} else if (P.Tok.getText() == "inherited") {
|
||||
P.consumeToken();
|
||||
Kind = SILVTable::Entry::Kind::Inherited;
|
||||
} else {
|
||||
P.diagnose(P.Tok.getLoc(), diag::sil_vtable_bad_entry_kind);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (P.parseToken(tok::r_square, diag::sil_vtable_expect_rsquare))
|
||||
return true;
|
||||
}
|
||||
|
||||
vtableEntries.emplace_back(Ref, Func, Kind, Linkage.getValue());
|
||||
} while (P.Tok.isNot(tok::r_brace) && P.Tok.isNot(tok::eof));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user