Skip to content

Commit 400f338

Browse files
authored
Merge pull request #7078 from swiftix/wip-textual-sil-sildeclrefs
Use function signatures for SILDeclRefs in witness_tables, vtables and witness_method instructions
2 parents 07a229a + 8ad61d5 commit 400f338

File tree

113 files changed

+956
-673
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+956
-673
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,12 @@ struct PrintOptions {
455455
return result;
456456
}
457457

458+
static PrintOptions printQualifiedSILType() {
459+
PrintOptions result = PrintOptions::printSIL();
460+
result.FullyQualifiedTypesIfAmbiguous = true;
461+
return result;
462+
}
463+
458464
/// \brief Retrieve the set of options that prints everything.
459465
///
460466
/// This is only intended for debug output.

lib/Parse/ParseSIL.cpp

Lines changed: 78 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ namespace {
293293
SmallVector<ValueDecl *, 4> values;
294294
return parseSILDeclRef(Result, values);
295295
}
296+
bool parseSILDeclRef(SILDeclRef &Member, bool FnTypeRequired);
296297
bool parseGlobalName(Identifier &Name);
297298
bool parseValueName(UnresolvedValueName &Name);
298299
bool parseValueRef(SILValue &Result, SILType Ty, SILLocation Loc,
@@ -1623,6 +1624,75 @@ static bool parseStoreOwnershipQualifier(StoreOwnershipQualifier &Result,
16231624
return false;
16241625
}
16251626

1627+
bool SILParser::parseSILDeclRef(SILDeclRef &Member, bool FnTypeRequired) {
1628+
SourceLoc TyLoc;
1629+
SmallVector<ValueDecl *, 4> values;
1630+
if (parseSILDeclRef(Member, values))
1631+
return true;
1632+
1633+
// : ( or : < means that what follows is function type.
1634+
if (!P.Tok.is(tok::colon))
1635+
return false;
1636+
1637+
if (FnTypeRequired &&
1638+
!P.peekToken().is(tok::l_paren) &&
1639+
!P.peekToken().isContextualPunctuator("<"))
1640+
return false;
1641+
1642+
// Type of the SILDeclRef is optional to be compatible with the old format.
1643+
if (!P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":")) {
1644+
// Parse the type for SILDeclRef.
1645+
Optional<Scope> GenericsScope;
1646+
GenericsScope.emplace(&P, ScopeKind::Generics);
1647+
ParserResult<TypeRepr> TyR = P.parseType();
1648+
GenericsScope.reset();
1649+
if (TyR.isNull())
1650+
return true;
1651+
TypeLoc Ty = TyR.get();
1652+
1653+
// The type can be polymorphic.
1654+
GenericEnvironment *genericEnv = nullptr;
1655+
if (auto fnType = dyn_cast<FunctionTypeRepr>(TyR.get())) {
1656+
if (auto generics = fnType->getGenericParams()) {
1657+
assert(!Ty.wasValidated() && Ty.getType().isNull());
1658+
1659+
genericEnv = handleSILGenericParams(P.Context, generics, &P.SF);
1660+
fnType->setGenericEnvironment(genericEnv);
1661+
}
1662+
}
1663+
1664+
if (performTypeLocChecking(Ty, /*isSILType=*/ false, genericEnv))
1665+
return true;
1666+
1667+
// Pick the ValueDecl that has the right type.
1668+
ValueDecl *TheDecl = nullptr;
1669+
auto declTy = Ty.getType()->getCanonicalType();
1670+
auto unlabeledDecl =
1671+
declTy->getUnlabeledType(P.Context)->getCanonicalType();
1672+
for (unsigned I = 0, E = values.size(); I < E; I++) {
1673+
auto lookupTy = values[I]->getInterfaceType();
1674+
auto unlabeledLookup =
1675+
lookupTy->getUnlabeledType(P.Context)->getCanonicalType();
1676+
if (unlabeledDecl == unlabeledLookup) {
1677+
TheDecl = values[I];
1678+
// Update SILDeclRef to point to the right Decl.
1679+
Member.loc = TheDecl;
1680+
break;
1681+
}
1682+
if (values.size() == 1 && !TheDecl) {
1683+
P.diagnose(TyLoc, diag::sil_member_decl_type_mismatch, declTy,
1684+
lookupTy);
1685+
return true;
1686+
}
1687+
}
1688+
if (!TheDecl) {
1689+
P.diagnose(TyLoc, diag::sil_member_decl_not_found);
1690+
return true;
1691+
}
1692+
}
1693+
return false;
1694+
}
1695+
16261696
/// sil-instruction-def ::= (sil-value-name '=')? sil-instruction
16271697
/// (',' sil-scope-ref)? (',' sil-loc)?
16281698
bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
@@ -3046,64 +3116,16 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
30463116
SourceLoc TyLoc;
30473117
SmallVector<ValueDecl *, 4> values;
30483118
if (parseTypedValueRef(Val, B) ||
3049-
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
3050-
parseSILDeclRef(Member, values) ||
3051-
P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":"))
3052-
return true;
3053-
3054-
// Parse the type for SILDeclRef.
3055-
Optional<Scope> GenericsScope;
3056-
GenericsScope.emplace(&P, ScopeKind::Generics);
3057-
ParserResult<TypeRepr> TyR = P.parseType();
3058-
GenericsScope.reset();
3059-
if (TyR.isNull())
3119+
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ","))
30603120
return true;
3061-
TypeLoc Ty = TyR.get();
3062-
3063-
// The type can be polymorphic.
3064-
GenericEnvironment *genericEnv = nullptr;
3065-
if (auto fnType = dyn_cast<FunctionTypeRepr>(TyR.get())) {
3066-
if (auto generics = fnType->getGenericParams()) {
3067-
assert(!Ty.wasValidated() && Ty.getType().isNull());
30683121

3069-
genericEnv = handleSILGenericParams(P.Context, generics, &P.SF);
3070-
fnType->setGenericEnvironment(genericEnv);
3071-
}
3072-
}
3073-
3074-
if (performTypeLocChecking(Ty, /*IsSILType=*/ false, genericEnv))
3122+
if (parseSILDeclRef(Member, true))
30753123
return true;
30763124

30773125
if (P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
30783126
parseSILType(MethodTy, TyLoc) ||
30793127
parseSILDebugLocation(InstLoc, B))
30803128
return true;
3081-
3082-
// Pick the ValueDecl that has the right type.
3083-
ValueDecl *TheDecl = nullptr;
3084-
auto declTy = Ty.getType()->getCanonicalType();
3085-
auto unlabeledDecl =
3086-
declTy->getUnlabeledType(P.Context)->getCanonicalType();
3087-
for (unsigned I = 0, E = values.size(); I < E; I++) {
3088-
auto lookupTy = values[I]->getInterfaceType();
3089-
auto unlabeledLookup =
3090-
lookupTy->getUnlabeledType(P.Context)->getCanonicalType();
3091-
if (unlabeledDecl == unlabeledLookup) {
3092-
TheDecl = values[I];
3093-
// Update SILDeclRef to point to the right Decl.
3094-
Member.loc = TheDecl;
3095-
break;
3096-
}
3097-
if (values.size() == 1 && !TheDecl) {
3098-
P.diagnose(TyLoc, diag::sil_member_decl_type_mismatch, declTy,
3099-
lookupTy);
3100-
return true;
3101-
}
3102-
}
3103-
if (!TheDecl) {
3104-
P.diagnose(TyLoc, diag::sil_member_decl_not_found);
3105-
return true;
3106-
}
31073129

31083130
switch (Opcode) {
31093131
default: llvm_unreachable("Out of sync with parent switch");
@@ -3132,8 +3154,9 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
31323154
SourceLoc TyLoc;
31333155
if (P.parseToken(tok::sil_dollar, diag::expected_tok_in_sil_instr, "$") ||
31343156
parseASTType(LookupTy) ||
3135-
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
3136-
parseSILDeclRef(Member))
3157+
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ","))
3158+
return true;
3159+
if (parseSILDeclRef(Member, true))
31373160
return true;
31383161
// Optional operand.
31393162
SILValue Operand;
@@ -4422,7 +4445,7 @@ bool Parser::parseSILVTable() {
44224445
SILDeclRef Ref;
44234446
Identifier FuncName;
44244447
SourceLoc FuncLoc;
4425-
if (VTableState.parseSILDeclRef(Ref))
4448+
if (VTableState.parseSILDeclRef(Ref, true))
44264449
return true;
44274450
SILFunction *Func = nullptr;
44284451
Optional<SILLinkage> Linkage = SILLinkage::Private;
@@ -4799,7 +4822,7 @@ bool Parser::parseSILWitnessTable() {
47994822
SILDeclRef Ref;
48004823
Identifier FuncName;
48014824
SourceLoc FuncLoc;
4802-
if (WitnessState.parseSILDeclRef(Ref) ||
4825+
if (WitnessState.parseSILDeclRef(Ref, true) ||
48034826
parseToken(tok::colon, diag::expected_sil_witness_colon))
48044827
return true;
48054828

@@ -4894,7 +4917,7 @@ bool Parser::parseSILDefaultWitnessTable() {
48944917
SILDeclRef Ref;
48954918
Identifier FuncName;
48964919
SourceLoc FuncLoc;
4897-
if (WitnessState.parseSILDeclRef(Ref) ||
4920+
if (WitnessState.parseSILDeclRef(Ref, true) ||
48984921
parseToken(tok::colon, diag::expected_sil_witness_colon))
48994922
return true;
49004923

lib/SIL/SILPrinter.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,19 +1447,24 @@ class SILPrinter : public SILVisitor<SILPrinter> {
14471447
void visitClassMethodInst(ClassMethodInst *AMI) {
14481448
printMethodInst(AMI, AMI->getOperand());
14491449
*this << " : " << AMI->getMember().getDecl()->getInterfaceType();
1450-
*this << " , ";
1450+
*this << ", ";
14511451
*this << AMI->getType();
14521452
}
14531453
void visitSuperMethodInst(SuperMethodInst *AMI) {
14541454
printMethodInst(AMI, AMI->getOperand());
14551455
*this << " : " << AMI->getMember().getDecl()->getInterfaceType();
1456-
*this << " , ";
1456+
*this << ", ";
14571457
*this << AMI->getType();
14581458
}
14591459
void visitWitnessMethodInst(WitnessMethodInst *WMI) {
1460+
PrintOptions QualifiedSILTypeOptions =
1461+
PrintOptions::printQualifiedSILType();
1462+
QualifiedSILTypeOptions.CurrentModule = WMI->getModule().getSwiftModule();
14601463
if (WMI->isVolatile())
14611464
*this << "[volatile] ";
1462-
*this << "$" << WMI->getLookupType() << ", " << WMI->getMember();
1465+
*this << "$" << WMI->getLookupType() << ", " << WMI->getMember() << " : ";
1466+
WMI->getMember().getDecl()->getInterfaceType().print(
1467+
PrintState.OS, QualifiedSILTypeOptions);
14631468
if (!WMI->getTypeDependentOperands().empty()) {
14641469
*this << ", ";
14651470
*this << getIDAndType(WMI->getTypeDependentOperands()[0].get());
@@ -2182,10 +2187,30 @@ void ValueBase::printInContext(llvm::raw_ostream &OS) const {
21822187

21832188
void SILVTable::print(llvm::raw_ostream &OS, bool Verbose) const {
21842189
OS << "sil_vtable " << getClass()->getName() << " {\n";
2190+
PrintOptions QualifiedSILTypeOptions = PrintOptions::printQualifiedSILType();
21852191
for (auto &entry : getEntries()) {
21862192
OS << " ";
21872193
entry.Method.print(OS);
21882194
OS << ": ";
2195+
2196+
bool HasSingleImplementation = false;
2197+
switch (entry.Method.kind) {
2198+
default:
2199+
break;
2200+
case SILDeclRef::Kind::IVarDestroyer:
2201+
case SILDeclRef::Kind::Destroyer:
2202+
case SILDeclRef::Kind::Deallocator:
2203+
HasSingleImplementation = true;
2204+
}
2205+
// No need to emit the signature for methods that may have only
2206+
// single implementation, e.g. for destructors.
2207+
if (!HasSingleImplementation) {
2208+
QualifiedSILTypeOptions.CurrentModule =
2209+
entry.Method.getDecl()->getDeclContext()->getParentModule();
2210+
entry.Method.getDecl()->getInterfaceType().print(OS,
2211+
QualifiedSILTypeOptions);
2212+
OS << " : ";
2213+
}
21892214
if (entry.Linkage !=
21902215
stripExternalFromLinkage(entry.Implementation->getLinkage())) {
21912216
OS << getLinkageString(entry.Linkage);
@@ -2202,6 +2227,7 @@ void SILVTable::dump() const {
22022227

22032228
void SILWitnessTable::print(llvm::raw_ostream &OS, bool Verbose) const {
22042229
PrintOptions Options = PrintOptions::printSIL();
2230+
PrintOptions QualifiedSILTypeOptions = PrintOptions::printQualifiedSILType();
22052231
OS << "sil_witness_table ";
22062232
printLinkage(OS, getLinkage(), /*isDefinition*/ isDefinition());
22072233
if (isFragile())
@@ -2227,6 +2253,13 @@ void SILWitnessTable::print(llvm::raw_ostream &OS, bool Verbose) const {
22272253
OS << "method ";
22282254
methodWitness.Requirement.print(OS);
22292255
OS << ": ";
2256+
QualifiedSILTypeOptions.CurrentModule =
2257+
methodWitness.Requirement.getDecl()
2258+
->getDeclContext()
2259+
->getParentModule();
2260+
methodWitness.Requirement.getDecl()->getInterfaceType().print(
2261+
OS, QualifiedSILTypeOptions);
2262+
OS << " : ";
22302263
if (methodWitness.Witness) {
22312264
methodWitness.Witness->printName(OS);
22322265
OS << "\t// "
@@ -2284,6 +2317,7 @@ void SILWitnessTable::dump() const {
22842317

22852318
void SILDefaultWitnessTable::print(llvm::raw_ostream &OS, bool Verbose) const {
22862319
// sil_default_witness_table [<Linkage>] <Protocol> <MinSize>
2320+
PrintOptions QualifiedSILTypeOptions = PrintOptions::printQualifiedSILType();
22872321
OS << "sil_default_witness_table ";
22882322
printLinkage(OS, getLinkage(), ForDefinition);
22892323
OS << getProtocol()->getName() << " {\n";
@@ -2298,6 +2332,11 @@ void SILDefaultWitnessTable::print(llvm::raw_ostream &OS, bool Verbose) const {
22982332
OS << " method ";
22992333
witness.getRequirement().print(OS);
23002334
OS << ": ";
2335+
QualifiedSILTypeOptions.CurrentModule =
2336+
witness.getRequirement().getDecl()->getDeclContext()->getParentModule();
2337+
witness.getRequirement().getDecl()->getInterfaceType().print(
2338+
OS, QualifiedSILTypeOptions);
2339+
OS << " : ";
23012340
witness.getWitness()->printName(OS);
23022341
OS << "\t// "
23032342
<< demangleSymbolAsString(witness.getWitness()->getName());

test/IRGen/dynamic_init.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ bb0(%0 : $@thick C.Type):
2424
// CHECK: [[CTOR:%[0-9]+]] = load %C12dynamic_init1C* (%swift.type*)*, %C12dynamic_init1C* (%swift.type*)** [[VTABLE_OFFSET]], align 8
2525
// CHECK: [[CTOR_I8:%[0-9]+]] = bitcast %C12dynamic_init1C* (%swift.type*)* [[CTOR]] to i8*
2626
// CHECK: [[CTOR_FN:%[0-9]+]] = bitcast i8* [[CTOR_I8]] to %C12dynamic_init1C* (%swift.type*)*
27-
%2 = class_method %0 : $@thick C.Type, #C.init!allocator.1 : (C.Type) -> () -> C , $@convention(method) (@thick C.Type) -> @owned C
27+
%2 = class_method %0 : $@thick C.Type, #C.init!allocator.1 : (C.Type) -> () -> C, $@convention(method) (@thick C.Type) -> @owned C
2828
// CHECK: [[RESULT:%[0-9]+]] = call %C12dynamic_init1C* [[CTOR_FN]](%swift.type* %0)
2929
%3 = apply %2(%0) : $@convention(method) (@thick C.Type) -> @owned C
3030
// CHECK: call void bitcast (void (%swift.refcounted*)* @swift_rt_swift_release to void (%C12dynamic_init1C*)*)(%C12dynamic_init1C* [[RESULT]])

test/IRGen/exactcast2.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ sil @_TFC4main4HashCfMS0_FT_S0_ : $@convention(thin) (@thick Hash.Type) -> @owne
2626

2727
sil @_TFC4main4Hash6updatefS0_FT_T_ : $@convention(method) (@guaranteed Hash) -> () {
2828
bb0(%0 : $Hash):
29-
%1 = class_method %0 : $Hash, #Hash.hash!1 : (Hash) -> () -> () , $@convention(method) (@guaranteed Hash) -> () // user: %9
29+
%1 = class_method %0 : $Hash, #Hash.hash!1 : (Hash) -> () -> (), $@convention(method) (@guaranteed Hash) -> () // user: %9
3030
checked_cast_br [exact] %0 : $Hash to $MD5, bb2, bb3 // id: %2
3131

3232
bb1: // Preds: bb2 bb3

test/IRGen/objc_factory_method.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ sil @_TFCSo4HiveCfMS_FT5queenGSQCSo3Bee__S_ : $@convention(thin) (@owned Optiona
2222
bb0(%0 : $Optional<Bee>, %1 : $@thick Hive.Type):
2323
%2 = thick_to_objc_metatype %1 : $@thick Hive.Type to $@objc_metatype Hive.Type // users: %3, %4
2424
// CHECK: load i8*, i8** @"\01L_selector(hiveWithQueen:)"
25-
%3 = class_method %2 : $@objc_metatype Hive.Type, #Hive.init!allocator.1.foreign : (Hive.Type) -> (ImplicitlyUnwrappedOptional<Bee>) -> Hive! , $@convention(objc_method) (Optional<Bee>, @objc_metatype Hive.Type) -> @autoreleased Optional<Hive> // user: %4
25+
%3 = class_method %2 : $@objc_metatype Hive.Type, #Hive.init!allocator.1.foreign : (Hive.Type) -> (ImplicitlyUnwrappedOptional<Bee>) -> Hive!, $@convention(objc_method) (Optional<Bee>, @objc_metatype Hive.Type) -> @autoreleased Optional<Hive> // user: %4
2626
// CHECK: call {{.*}} @objc_msgSend
2727
%4 = apply %3(%0, %2) : $@convention(objc_method) (Optional<Bee>, @objc_metatype Hive.Type) -> @autoreleased Optional<Hive> // users: %5, %6
2828
// CHECK: call {{.*}} @objc_autorelease

test/IRGen/partial_apply.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ entry(%f : $@callee_owned (Builtin.Word) -> (), %x : $Builtin.Word):
108108

109109
sil @objc_partial_apply : $@convention(thin) ObjCClass -> @callee_owned Int -> () {
110110
entry(%c : $ObjCClass):
111-
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.method!1.foreign : (ObjCClass) -> (Int) -> () , $@convention(objc_method) (Int, ObjCClass) -> ()
111+
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.method!1.foreign : (ObjCClass) -> (Int) -> (), $@convention(objc_method) (Int, ObjCClass) -> ()
112112
%p = partial_apply %m(%c) : $@convention(objc_method) (Int, ObjCClass) -> ()
113113
return %p : $@callee_owned Int -> ()
114114
}
@@ -129,7 +129,7 @@ entry(%c : $ObjCClass):
129129
// CHECK: [[VAL:%.*]] = load double, double* [[ORIGINXVAL]]
130130
sil @objc_partial_apply_indirect_sil_argument : $@convention(thin) ObjCClass -> @callee_owned NSRect -> () {
131131
entry(%c : $ObjCClass):
132-
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.method2!1.foreign : (ObjCClass) -> (NSRect) -> () , $@convention(objc_method) (NSRect, ObjCClass) -> ()
132+
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.method2!1.foreign : (ObjCClass) -> (NSRect) -> (), $@convention(objc_method) (NSRect, ObjCClass) -> ()
133133
%p = partial_apply %m(%c) : $@convention(objc_method) (NSRect, ObjCClass) -> ()
134134
return %p : $@callee_owned NSRect -> ()
135135
}
@@ -153,7 +153,7 @@ entry(%c : $ObjCClass):
153153

154154
sil @objc_partial_apply_consumes_self : $@convention(thin) ObjCClass -> @callee_owned () -> @owned ObjCClass {
155155
entry(%c : $ObjCClass):
156-
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.fakeInitFamily!1.foreign : (ObjCClass) -> () -> ObjCClass , $@convention(objc_method) (@owned ObjCClass) -> @owned ObjCClass
156+
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.fakeInitFamily!1.foreign : (ObjCClass) -> () -> ObjCClass, $@convention(objc_method) (@owned ObjCClass) -> @owned ObjCClass
157157
%p = partial_apply %m(%c) : $@convention(objc_method) (@owned ObjCClass) -> @owned ObjCClass
158158
return %p : $@callee_owned () -> @owned ObjCClass
159159
}

0 commit comments

Comments
 (0)