Skip to content

Commit 317a379

Browse files
committed
[DefaultOverrides] SIL printing/parsing.
1 parent 89e5e3d commit 317a379

File tree

9 files changed

+250
-0
lines changed

9 files changed

+250
-0
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,14 @@ ERROR(sil_witness_assoc_conf_not_found,none,
763763
ERROR(sil_witness_protocol_conformance_not_found,none,
764764
"sil protocol conformance not found", ())
765765

766+
// SIL default override table
767+
ERROR(sil_default_override_func_not_found,none,
768+
"sil function not found %0", (Identifier))
769+
ERROR(sil_default_override_class_not_found,none,
770+
"sil class not found %0", (Identifier))
771+
ERROR(sil_default_override_decl_not_class,none,
772+
"sil decl found for %0 is not a class", (Identifier))
773+
766774
// SIL differentiability witnesses
767775
ERROR(sil_diff_witness_expected_token,PointsToFirstBadToken,
768776
"expected '%0' in differentiability witness", (StringRef))

include/swift/AST/TokenKinds.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ SIL_KEYWORD(sil_moveonlydeinit)
272272
SIL_KEYWORD(sil_global)
273273
SIL_KEYWORD(sil_witness_table)
274274
SIL_KEYWORD(sil_default_witness_table)
275+
SIL_KEYWORD(sil_default_override_table)
275276
SIL_KEYWORD(sil_differentiability_witness)
276277
SIL_KEYWORD(sil_coverage_map)
277278
SIL_KEYWORD(sil_scope)

include/swift/Parse/ParseSILSupport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace swift {
3333
virtual bool parseSILGlobal(Parser &P) = 0;
3434
virtual bool parseSILWitnessTable(Parser &P) = 0;
3535
virtual bool parseSILDefaultWitnessTable(Parser &P) = 0;
36+
virtual bool parseSILDefaultOverrideTable(Parser &P) = 0;
3637
virtual bool parseSILDifferentiabilityWitness(Parser &P) = 0;
3738
virtual bool parseSILCoverageMap(Parser &P) = 0;
3839
virtual bool parseSILProperty(Parser &P) = 0;

include/swift/SIL/SILDefaultOverrideTable.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,12 @@ class SILDefaultOverrideTable
236236
/// The default override of `method` to be provided when `original` is
237237
/// present.
238238
SILFunction *impl;
239+
240+
/// Print the entry.
241+
void print(llvm::raw_ostream &os, bool verbose = false) const;
242+
243+
/// Dump the entry to stderr.
244+
void dump() const;
239245
};
240246

241247
private:
@@ -304,6 +310,12 @@ class SILDefaultOverrideTable
304310

305311
/// Verify that the default override table is well-formed.
306312
void verify(const SILModule &M) const;
313+
314+
/// Print the default override table.
315+
void print(llvm::raw_ostream &os, bool verbose = false) const;
316+
317+
/// Dump the default override table to stderr.
318+
void dump() const;
307319
};
308320

309321
} // namespace swift

lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ bool Parser::parseTopLevelSIL() {
289289
CASE_SIL(sil_global, SILGlobal)
290290
CASE_SIL(sil_witness_table, SILWitnessTable)
291291
CASE_SIL(sil_default_witness_table, SILDefaultWitnessTable)
292+
CASE_SIL(sil_default_override_table, SILDefaultOverrideTable)
292293
CASE_SIL(sil_differentiability_witness, SILDifferentiabilityWitness)
293294
CASE_SIL(sil_coverage_map, SILCoverageMap)
294295
CASE_SIL(sil_property, SILProperty)
@@ -5944,6 +5945,7 @@ bool Parser::isStartOfSILDecl() {
59445945
case tok::kw_sil_global:
59455946
case tok::kw_sil_witness_table:
59465947
case tok::kw_sil_default_witness_table:
5948+
case tok::kw_sil_default_override_table:
59475949
case tok::kw_sil_differentiability_witness:
59485950
case tok::kw_sil_coverage_map:
59495951
case tok::kw_sil_scope:

lib/SIL/IR/SILPrinter.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3876,6 +3876,28 @@ printSILDefaultWitnessTables(SILPrintContext &Ctx,
38763876
wt->print(Ctx.OS(), Ctx.printVerbose());
38773877
}
38783878

3879+
static void printSILDefaultOverrideTables(
3880+
SILPrintContext &Ctx,
3881+
const SILModule::DefaultOverrideTableListType &tables) {
3882+
if (!Ctx.sortSIL()) {
3883+
for (const auto &table : tables)
3884+
table.print(Ctx.OS(), Ctx.printVerbose());
3885+
return;
3886+
}
3887+
3888+
std::vector<const SILDefaultOverrideTable *> sorted;
3889+
sorted.reserve(tables.size());
3890+
for (const auto &table : tables)
3891+
sorted.push_back(&table);
3892+
std::sort(sorted.begin(), sorted.end(),
3893+
[](const auto *left, const auto *right) -> bool {
3894+
return left->getClass()->getName().compare(
3895+
right->getClass()->getName()) == -1;
3896+
});
3897+
for (const auto *table : sorted)
3898+
table->print(Ctx.OS(), Ctx.printVerbose());
3899+
}
3900+
38793901
static void printSILDifferentiabilityWitnesses(
38803902
SILPrintContext &Ctx,
38813903
const SILModule::DifferentiabilityWitnessListType &diffWitnesses) {
@@ -4111,6 +4133,7 @@ void SILModule::print(SILPrintContext &PrintCtx, ModuleDecl *M,
41114133
printSILVTables(PrintCtx, getVTables());
41124134
printSILWitnessTables(PrintCtx, getWitnessTableList());
41134135
printSILDefaultWitnessTables(PrintCtx, getDefaultWitnessTableList());
4136+
printSILDefaultOverrideTables(PrintCtx, getDefaultOverrideTableList());
41144137
printSILCoverageMaps(PrintCtx, getCoverageMaps());
41154138
printSILProperties(PrintCtx, getPropertyList());
41164139
printSILMoveOnlyDeinits(PrintCtx, getMoveOnlyDeinits());
@@ -4365,6 +4388,49 @@ void SILDefaultWitnessTable::dump() const {
43654388
print(llvm::errs());
43664389
}
43674390

4391+
void SILDefaultOverrideTable::Entry::print(llvm::raw_ostream &out,
4392+
bool verbose) const {
4393+
PrintOptions QualifiedSILTypeOptions = PrintOptions::printQualifiedSILType();
4394+
out << " ";
4395+
// #replacement.declref : #original.declref : @function
4396+
method.print(out);
4397+
out << ": ";
4398+
original.print(out);
4399+
out << ": ";
4400+
4401+
auto *decl = method.getDecl();
4402+
QualifiedSILTypeOptions.CurrentModule =
4403+
decl->getDeclContext()->getParentModule();
4404+
decl->getInterfaceType().print(out, QualifiedSILTypeOptions);
4405+
out << " : ";
4406+
impl->printName(out);
4407+
out << "\t// " << demangleSymbol(impl->getName());
4408+
out << '\n';
4409+
}
4410+
4411+
void SILDefaultOverrideTable::Entry::dump() const {
4412+
print(llvm::errs(), /*verbose=*/false);
4413+
}
4414+
4415+
void SILDefaultOverrideTable::print(llvm::raw_ostream &OS, bool Verbose) const {
4416+
// sil_default_override_table [<Linkage>] <Protocol> <MinSize>
4417+
PrintOptions QualifiedSILTypeOptions = PrintOptions::printQualifiedSILType();
4418+
OS << "sil_default_override_table ";
4419+
printLinkage(OS, getLinkage(), ForDefinition);
4420+
OS << decl->getName() << " {\n";
4421+
4422+
PrintOptions options = PrintOptions::printSIL();
4423+
options.GenericSig = decl->getGenericSignatureOfContext().getPointer();
4424+
4425+
for (auto &entry : getEntries()) {
4426+
entry.print(OS, Verbose);
4427+
}
4428+
4429+
OS << "}\n\n";
4430+
}
4431+
4432+
void SILDefaultOverrideTable::dump() const { print(llvm::errs()); }
4433+
43684434
void SILDifferentiabilityWitness::print(llvm::raw_ostream &OS,
43694435
bool verbose) const {
43704436
OS << "// differentiability witness for "

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7857,6 +7857,27 @@ bool SILParserState::parseSILMoveOnlyDeinit(Parser &parser) {
78577857
return false;
78587858
}
78597859

7860+
static ClassDecl *parseClassDecl(Parser &P, SILParser &SP) {
7861+
Identifier DeclName;
7862+
SourceLoc DeclLoc;
7863+
if (SP.parseSILIdentifier(DeclName, DeclLoc, diag::expected_sil_value_name))
7864+
return nullptr;
7865+
7866+
// Find the protocol decl. The protocol can be imported.
7867+
llvm::PointerUnion<ValueDecl *, ModuleDecl *> Res =
7868+
lookupTopDecl(P, DeclName, /*typeLookup=*/true);
7869+
assert(Res.is<ValueDecl *>() && "Protocol look-up should return a Decl");
7870+
ValueDecl *VD = Res.get<ValueDecl *>();
7871+
if (!VD) {
7872+
P.diagnose(DeclLoc, diag::sil_default_override_class_not_found, DeclName);
7873+
return nullptr;
7874+
}
7875+
auto *decl = dyn_cast<ClassDecl>(VD);
7876+
if (!decl)
7877+
P.diagnose(DeclLoc, diag::sil_default_override_decl_not_class, DeclName);
7878+
return decl;
7879+
}
7880+
78607881
static ProtocolDecl *parseProtocolDecl(Parser &P, SILParser &SP) {
78617882
Identifier DeclName;
78627883
SourceLoc DeclLoc;
@@ -8444,6 +8465,100 @@ bool SILParserState::parseSILDefaultWitnessTable(Parser &P) {
84448465
return false;
84458466
}
84468467

8468+
/// Parser a single SIL default override table entry and add it to \p entries.
8469+
/// sil-default-override-entry:
8470+
/// SILDeclRef ':' SILDeclRef ':' @SILFunctionName
8471+
static bool parseSILDefaultOverrideTableEntry(
8472+
Parser &P, SILModule &M, ClassDecl *proto, GenericSignature witnessSig,
8473+
GenericParamList *witnessParams, SILParser &parser,
8474+
std::vector<SILDefaultOverrideTable::Entry> &entries) {
8475+
Identifier EntryKeyword;
8476+
SourceLoc KeywordLoc;
8477+
8478+
SILDeclRef replacement;
8479+
if (parser.parseSILDeclRef(replacement, true) ||
8480+
P.parseToken(tok::colon, diag::expected_sil_witness_colon))
8481+
return true;
8482+
8483+
SILDeclRef original;
8484+
if (parser.parseSILDeclRef(original, true) ||
8485+
P.parseToken(tok::colon, diag::expected_sil_witness_colon))
8486+
return true;
8487+
8488+
SILFunction *impl = nullptr;
8489+
Identifier implName;
8490+
SourceLoc implLoc;
8491+
if (P.parseToken(tok::at_sign, diag::expected_sil_function_name) ||
8492+
parser.parseSILIdentifier(implName, implLoc,
8493+
diag::expected_sil_value_name))
8494+
return true;
8495+
8496+
impl = M.lookUpFunction(implName.str());
8497+
if (!impl) {
8498+
P.diagnose(implLoc, diag::sil_default_override_func_not_found, implName);
8499+
return true;
8500+
}
8501+
8502+
entries.push_back(
8503+
SILDefaultOverrideTable::Entry{replacement, original, impl});
8504+
8505+
return false;
8506+
}
8507+
8508+
/// decl-sil-default-override ::= 'sil_default_override_table'
8509+
/// sil-linkage identifier
8510+
/// decl-sil-default-override-body
8511+
/// decl-sil-default-override-body:
8512+
/// '{' sil-default-override-entry* '}'
8513+
/// sil-default-override-entry:
8514+
/// SILDeclRef ':' SILDeclRef ':' @SILFunctionName
8515+
bool SILParserState::parseSILDefaultOverrideTable(Parser &P) {
8516+
P.consumeToken(tok::kw_sil_default_override_table);
8517+
SILParser OverrideState(P);
8518+
8519+
// Parse the linkage.
8520+
std::optional<SILLinkage> Linkage;
8521+
parseSILLinkage(Linkage, P);
8522+
8523+
// Parse the class.
8524+
ClassDecl *decl = parseClassDecl(P, OverrideState);
8525+
if (!decl)
8526+
return true;
8527+
8528+
OverrideState.ContextGenericSig = decl->getGenericSignature();
8529+
OverrideState.ContextGenericParams = decl->getGenericParams();
8530+
8531+
// Parse the body.
8532+
SourceLoc LBraceLoc = P.Tok.getLoc();
8533+
P.consumeToken(tok::l_brace);
8534+
8535+
// We need to turn on InSILBody to parse SILDeclRef.
8536+
Lexer::SILBodyRAII Tmp(*P.L);
8537+
8538+
// Parse the entry list.
8539+
std::vector<SILDefaultOverrideTable::Entry> entries;
8540+
8541+
if (P.Tok.isNot(tok::r_brace)) {
8542+
do {
8543+
if (parseSILDefaultOverrideTableEntry(
8544+
P, M, decl, decl->getGenericSignature(), decl->getGenericParams(),
8545+
OverrideState, entries))
8546+
return true;
8547+
} while (P.Tok.isNot(tok::r_brace) && P.Tok.isNot(tok::eof));
8548+
}
8549+
8550+
SourceLoc RBraceLoc;
8551+
P.parseMatchingToken(tok::r_brace, RBraceLoc, diag::expected_sil_rbrace,
8552+
LBraceLoc);
8553+
8554+
// Default to public linkage.
8555+
if (!Linkage)
8556+
Linkage = SILLinkage::Public;
8557+
8558+
SILDefaultOverrideTable::define(M, *Linkage, decl, entries);
8559+
return false;
8560+
}
8561+
84478562
/// decl-sil-differentiability-witness ::=
84488563
/// 'sil_differentiability_witness'
84498564
/// ('[' 'serialized' ']')?

lib/SIL/Parser/SILParserState.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class SILParserState : public SILParserStateBase {
5858
bool parseSILGlobal(Parser &P) override;
5959
bool parseSILWitnessTable(Parser &P) override;
6060
bool parseSILDefaultWitnessTable(Parser &P) override;
61+
bool parseSILDefaultOverrideTable(Parser &P) override;
6162
bool parseSILDifferentiabilityWitness(Parser &P) override;
6263
bool parseSILCoverageMap(Parser &P) override;
6364
bool parseSILProperty(Parser &P) override;

test/SIL/Parser/default_override.sil

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %target-sil-opt %s \
2+
// RUN: -enable-library-evolution \
3+
// RUN: -enable-experimental-feature CoroutineAccessors \
4+
// RUN: | %FileCheck %s
5+
6+
// REQUIRES: swift_feature_CoroutineAccessors
7+
8+
sil_stage canonical
9+
10+
import Builtin
11+
12+
struct Int {
13+
var _value: Builtin.Int64
14+
}
15+
16+
open class B {
17+
open var i: Int { read set }
18+
}
19+
20+
sil @B_i_read : $@yield_once @convention(method) (@guaranteed B) -> @yields Int
21+
sil @B_i_read2 : $@yield_once_2 @convention(method) (@guaranteed B) -> @yields Int
22+
sil @B_i_set : $@convention(method) (Int, @guaranteed B) -> ()
23+
sil @B_i_modify : $@yield_once @convention(method) (@guaranteed B) -> @yields @inout Int
24+
sil @B_i_modify2 : $@yield_once_2 @convention(method) (@guaranteed B) -> @yields @inout Int
25+
26+
sil_vtable B {
27+
#B.i!read: (B) -> () -> () : @B_i_read
28+
#B.i!read2: (B) -> () -> () : @B_i_read2
29+
#B.i!setter: (B) -> (Int) -> () : @B_i_set
30+
#B.i!modify: (B) -> () -> () : @B_i_modify
31+
#B.i!modify2: (B) -> () -> () : @B_i_modify2
32+
}
33+
34+
sil @B_i_read2_default_override : $@yield_once_2 @convention(method) (@guaranteed B) -> @yields Int
35+
sil @B_i_modify2_default_override : $@yield_once_2 @convention(method) (@guaranteed B) -> @yields @inout Int
36+
37+
// CHECK-LABEL: sil_default_override_table B {
38+
// CHECK-NEXT: #B.i!read2: #B.i!read: (B) -> () -> () : @B_i_read2_default_override
39+
// CHECK-NEXT: #B.i!modify2: #B.i!modify: (B) -> () -> () : @B_i_modify2_default_override
40+
// CHECK-NEXT: }
41+
sil_default_override_table B {
42+
#B.i!read2: #B.i!read: (B) -> () -> () : @B_i_read2_default_override
43+
#B.i!modify2: #B.i!modify: (B) -> () -> () : @B_i_modify2_default_override
44+
}

0 commit comments

Comments
 (0)