Skip to content

Commit 882b439

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 db020c1 commit 882b439

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
@@ -1594,6 +1594,7 @@ VTables
15941594

15951595
decl ::= sil-vtable
15961596
sil-vtable ::= 'sil_vtable' identifier '{' sil-vtable-entry* '}'
1597+
sil-vtable ::= 'sil_vtable' sil-type '{' sil-vtable-entry* '}'
15971598

15981599
sil-vtable-entry ::= sil-decl-ref ':' sil-linkage? sil-function-name
15991600

@@ -1656,6 +1657,13 @@ class (such as ``C.bas`` in ``C``'s vtable).
16561657
In case the SIL function is a thunk, the function name is preceded with the
16571658
linkage of the original implementing function.
16581659

1660+
If the vtable refers to a specialized class, a SIL type specifies the bound
1661+
generic class type::
1662+
1663+
sil_vtable $G<Int> {
1664+
// ...
1665+
}
1666+
16591667
Witness Tables
16601668
~~~~~~~~~~~~~~
16611669
::

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
@@ -3973,7 +3973,12 @@ void SILVTable::print(llvm::raw_ostream &OS, bool Verbose) const {
39733973
OS << "sil_vtable ";
39743974
if (isSerialized())
39753975
OS << "[serialized] ";
3976-
OS << getClass()->getName() << " {\n";
3976+
if (SILType classTy = getClassType()) {
3977+
OS << classTy;
3978+
} else {
3979+
OS << getClass()->getName();
3980+
}
3981+
OS << " {\n";
39773982

39783983
for (auto &entry : getEntries()) {
39793984
OS << " ";

lib/SIL/Parser/ParseSIL.cpp

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

7434-
// Parse the class name.
7435-
Identifier Name;
7436-
SourceLoc Loc;
7437-
if (VTableState.parseSILIdentifier(Name, Loc,
7438-
diag::expected_sil_value_name))
7439-
return true;
74407434

7441-
// Find the class decl.
7442-
llvm::PointerUnion<ValueDecl*, ModuleDecl *> Res =
7443-
lookupTopDecl(P, Name, /*typeLookup=*/true);
7444-
assert(Res.is<ValueDecl*>() && "Class look-up should return a Decl");
7445-
ValueDecl *VD = Res.get<ValueDecl*>();
7446-
if (!VD) {
7447-
P.diagnose(Loc, diag::sil_vtable_class_not_found, Name);
7448-
return true;
7449-
}
7435+
ClassDecl *theClass = nullptr;
7436+
SILType specializedClassTy;
7437+
if (P.Tok.isNot(tok::sil_dollar)) {
7438+
// Parse the class name.
7439+
Identifier Name;
7440+
SourceLoc Loc;
7441+
if (VTableState.parseSILIdentifier(Name, Loc,
7442+
diag::expected_sil_value_name))
7443+
return true;
74507444

7451-
auto *theClass = dyn_cast<ClassDecl>(VD);
7452-
if (!theClass) {
7453-
P.diagnose(Loc, diag::sil_vtable_class_not_found, Name);
7454-
return true;
7445+
// Find the class decl.
7446+
llvm::PointerUnion<ValueDecl*, ModuleDecl *> Res =
7447+
lookupTopDecl(P, Name, /*typeLookup=*/true);
7448+
assert(Res.is<ValueDecl*>() && "Class look-up should return a Decl");
7449+
ValueDecl *VD = Res.get<ValueDecl*>();
7450+
if (!VD) {
7451+
P.diagnose(Loc, diag::sil_vtable_class_not_found, Name);
7452+
return true;
7453+
}
7454+
7455+
theClass = dyn_cast<ClassDecl>(VD);
7456+
if (!theClass) {
7457+
P.diagnose(Loc, diag::sil_vtable_class_not_found, Name);
7458+
return true;
7459+
}
7460+
} else {
7461+
if (SILParser(P).parseSILType(specializedClassTy))
7462+
return true;
7463+
theClass = specializedClassTy.getClassOrBoundGenericClass();
7464+
if (!theClass) {
7465+
return true;
7466+
}
74557467
}
74567468

74577469
SourceLoc LBraceLoc = P.Tok.getLoc();
@@ -7519,7 +7531,7 @@ bool SILParserState::parseSILVTable(Parser &P) {
75197531
P.parseMatchingToken(tok::r_brace, RBraceLoc, diag::expected_sil_rbrace,
75207532
LBraceLoc);
75217533

7522-
SILVTable::create(M, theClass, Serialized, vtableEntries);
7534+
SILVTable::create(M, theClass, specializedClassTy, Serialized, vtableEntries);
75237535
return false;
75247536
}
75257537

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)