Skip to content

Commit 6e8b80c

Browse files
committed
SIL: add printing and parsing support for specialized vtables
If the vtable refers to a specialized class, a SIL type specifies the bound generic class type: ``` sil_vtable $G<Int> { // ... } ```
1 parent 61ed95a commit 6e8b80c

File tree

6 files changed

+59
-22
lines changed

6 files changed

+59
-22
lines changed

docs/SIL.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,7 @@ VTables
16081608

16091609
decl ::= sil-vtable
16101610
sil-vtable ::= 'sil_vtable' identifier '{' sil-vtable-entry* '}'
1611+
sil-vtable ::= 'sil_vtable' sil-type '{' sil-vtable-entry* '}'
16111612

16121613
sil-vtable-entry ::= sil-decl-ref ':' sil-linkage? sil-function-name
16131614

@@ -1670,6 +1671,13 @@ class (such as ``C.bas`` in ``C``'s vtable).
16701671
In case the SIL function is a thunk, the function name is preceded with the
16711672
linkage of the original implementing function.
16721673

1674+
If the vtable refers to a specialized class, a SIL type specifies the bound
1675+
generic class type::
1676+
1677+
sil_vtable $G<Int> {
1678+
// ...
1679+
}
1680+
16731681
Witness Tables
16741682
~~~~~~~~~~~~~~
16751683
::

include/swift/SIL/SILVTable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class SILVTable final : public SILAllocated<SILVTable>,
115115
/// The ClassDecl mapped to this VTable.
116116
ClassDecl *Class;
117117

118+
/// The class type if this is a specialized vtable, otherwise null.
118119
SILType classType;
119120

120121
/// Whether or not this vtable is serialized, which allows

lib/SIL/IR/SILPrinter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3988,7 +3988,12 @@ void SILVTable::print(llvm::raw_ostream &OS, bool Verbose) const {
39883988
OS << "sil_vtable ";
39893989
if (isSerialized())
39903990
OS << "[serialized] ";
3991-
OS << getClass()->getName() << " {\n";
3991+
if (SILType classTy = getClassType()) {
3992+
OS << classTy;
3993+
} else {
3994+
OS << getClass()->getName();
3995+
}
3996+
OS << " {\n";
39923997

39933998
for (auto &entry : getEntries()) {
39943999
OS << " ";

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7452,27 +7452,39 @@ bool SILParserState::parseSILVTable(Parser &P) {
74527452
nullptr, nullptr, VTableState, M))
74537453
return true;
74547454

7455-
// Parse the class name.
7456-
Identifier Name;
7457-
SourceLoc Loc;
7458-
if (VTableState.parseSILIdentifier(Name, Loc,
7459-
diag::expected_sil_value_name))
7460-
return true;
74617455

7462-
// Find the class decl.
7463-
llvm::PointerUnion<ValueDecl*, ModuleDecl *> Res =
7464-
lookupTopDecl(P, Name, /*typeLookup=*/true);
7465-
assert(Res.is<ValueDecl*>() && "Class look-up should return a Decl");
7466-
ValueDecl *VD = Res.get<ValueDecl*>();
7467-
if (!VD) {
7468-
P.diagnose(Loc, diag::sil_vtable_class_not_found, Name);
7469-
return true;
7470-
}
7456+
ClassDecl *theClass = nullptr;
7457+
SILType specializedClassTy;
7458+
if (P.Tok.isNot(tok::sil_dollar)) {
7459+
// Parse the class name.
7460+
Identifier Name;
7461+
SourceLoc Loc;
7462+
if (VTableState.parseSILIdentifier(Name, Loc,
7463+
diag::expected_sil_value_name))
7464+
return true;
74717465

7472-
auto *theClass = dyn_cast<ClassDecl>(VD);
7473-
if (!theClass) {
7474-
P.diagnose(Loc, diag::sil_vtable_class_not_found, Name);
7475-
return true;
7466+
// Find the class decl.
7467+
llvm::PointerUnion<ValueDecl*, ModuleDecl *> Res =
7468+
lookupTopDecl(P, Name, /*typeLookup=*/true);
7469+
assert(Res.is<ValueDecl*>() && "Class look-up should return a Decl");
7470+
ValueDecl *VD = Res.get<ValueDecl*>();
7471+
if (!VD) {
7472+
P.diagnose(Loc, diag::sil_vtable_class_not_found, Name);
7473+
return true;
7474+
}
7475+
7476+
theClass = dyn_cast<ClassDecl>(VD);
7477+
if (!theClass) {
7478+
P.diagnose(Loc, diag::sil_vtable_class_not_found, Name);
7479+
return true;
7480+
}
7481+
} else {
7482+
if (SILParser(P).parseSILType(specializedClassTy))
7483+
return true;
7484+
theClass = specializedClassTy.getClassOrBoundGenericClass();
7485+
if (!theClass) {
7486+
return true;
7487+
}
74767488
}
74777489

74787490
SourceLoc LBraceLoc = P.Tok.getLoc();
@@ -7540,7 +7552,7 @@ bool SILParserState::parseSILVTable(Parser &P) {
75407552
P.parseMatchingToken(tok::r_brace, RBraceLoc, diag::expected_sil_rbrace,
75417553
LBraceLoc);
75427554

7543-
SILVTable::create(M, theClass, Serialized, vtableEntries);
7555+
SILVTable::create(M, theClass, specializedClassTy, Serialized, vtableEntries);
75447556
return false;
75457557
}
75467558

test/SIL/Parser/basic.sil

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,3 +1807,14 @@ sil_vtable Foo2 {
18071807
#Foo.subscript!getter: @Foo_subscript_getter [inherited] [nonoverridden]
18081808
#Foo.subscript!setter: @Foo_subscript_setter [override]
18091809
}
1810+
1811+
class GenKlass<T> {}
1812+
1813+
// CHECK-LABEL: sil_vtable GenKlass {
1814+
sil_vtable GenKlass {
1815+
}
1816+
1817+
// CHECK-LABEL: sil_vtable $GenKlass<Int> {
1818+
sil_vtable $GenKlass<Int> {
1819+
}
1820+

test/embedded/classes-generic-no-stdlib.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public func bar(t: T2) -> MyClass<T2> {
4141
// CHECK-SIL: #MyClass.deinit!deallocator: @$s4main7MyClassCfDAA2T1V_Tg5 // specialized MyClass.__deallocating_deinit
4242
// CHECK-SIL: }
4343

44-
// CHECK-SIL: sil_vtable MyClass {
44+
// CHECK-SIL: sil_vtable $MyClass<T2> {
4545
// CHECK-SIL: #MyClass.t!getter: <T> (MyClass<T>) -> () -> T : @$s4main7MyClassC1txvgAA2T2V_Tg5 // specialized MyClass.t.getter
4646
// CHECK-SIL: #MyClass.t!setter: <T> (MyClass<T>) -> (T) -> () : @$s4main7MyClassC1txvsAA2T2V_Tg5 // specialized MyClass.t.setter
4747
// CHECK-SIL: #MyClass.t!modify: <T> (MyClass<T>) -> () -> () : @$s4main7MyClassC1txvMAA2T2V_Tg5 // specialized MyClass.t.modify

0 commit comments

Comments
 (0)