Skip to content

Use function signatures for SILDeclRefs in witness_tables, vtables and witness_method instructions #4048

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 79 additions & 55 deletions lib/Parse/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ namespace {
SmallVector<ValueDecl *, 4> values;
return parseSILDeclRef(Result, values);
}
bool parseSILDeclRef(SILDeclRef &Member, bool FnTypeRequired);
bool parseGlobalName(Identifier &Name);
bool parseValueName(UnresolvedValueName &Name);
bool parseValueRef(SILValue &Result, SILType Ty, SILLocation Loc,
Expand Down Expand Up @@ -1623,6 +1624,76 @@ static bool parseStoreOwnershipQualifier(StoreOwnershipQualifier &Result,
return false;
}

bool SILParser::parseSILDeclRef(SILDeclRef &Member, bool FnTypeRequired) {
SourceLoc TyLoc;
SmallVector<ValueDecl *, 4> values;
if (parseSILDeclRef(Member, values))
return true;

// : ( or : < means that what follows is function type.
if (!P.Tok.is(tok::colon))
return false;

if (FnTypeRequired &&
!P.peekToken().is(tok::l_paren) &&
!P.peekToken().isContextualPunctuator("<"))
return false;

// Type of the SILDeclRef is optional, to be compatible with the old format.
if (!P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":")) {
// Parse the type for SILDeclRef.
Optional<Scope> GenericsScope;
GenericsScope.emplace(&P, ScopeKind::Generics);
ParserResult<TypeRepr> TyR = P.parseType();
GenericsScope.reset();
if (TyR.isNull())
return true;
TypeLoc Ty = TyR.get();

// The type can be polymorphic.
GenericEnvironment *genericEnv = nullptr;
if (auto fnType = dyn_cast<FunctionTypeRepr>(TyR.get())) {
if (auto generics = fnType->getGenericParams()) {
assert(!Ty.wasValidated() && Ty.getType().isNull());

genericEnv = handleSILGenericParams(P.Context, generics, &P.SF);
fnType->setGenericEnvironment(genericEnv);
}
}

if (performTypeLocChecking(Ty, /*isSILType=*/ false, genericEnv))
return true;

// Pick the ValueDecl that has the right type.
ValueDecl *TheDecl = nullptr;
auto declTy = Ty.getType()->getCanonicalType();
auto unlabeledDecl =
declTy->getUnlabeledType(P.Context)->getCanonicalType();
for (unsigned I = 0, E = values.size(); I < E; I++) {
auto *VD = values[I];
auto lookupTy = values[I]->getInterfaceType();
auto unlabeledLookup =
lookupTy->getUnlabeledType(P.Context)->getCanonicalType();
if (unlabeledDecl == unlabeledLookup) {
TheDecl = values[I];
// Update SILDeclRef to point to the right Decl.
Member.loc = TheDecl;
break;
}
if (values.size() == 1 && !TheDecl) {
P.diagnose(TyLoc, diag::sil_member_decl_type_mismatch, declTy,
lookupTy);
return true;
}
}
if (!TheDecl) {
P.diagnose(TyLoc, diag::sil_member_decl_not_found);
return true;
}
}
return false;
}

/// sil-instruction-def ::= (sil-value-name '=')? sil-instruction
/// (',' sil-scope-ref)? (',' sil-loc)?
bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
Expand Down Expand Up @@ -3044,64 +3115,16 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
SourceLoc TyLoc;
SmallVector<ValueDecl *, 4> values;
if (parseTypedValueRef(Val, B) ||
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
parseSILDeclRef(Member, values) ||
P.parseToken(tok::colon, diag::expected_tok_in_sil_instr, ":"))
return true;

// Parse the type for SILDeclRef.
Optional<Scope> GenericsScope;
GenericsScope.emplace(&P, ScopeKind::Generics);
ParserResult<TypeRepr> TyR = P.parseType();
GenericsScope.reset();
if (TyR.isNull())
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ","))
return true;
TypeLoc Ty = TyR.get();

// The type can be polymorphic.
GenericEnvironment *genericEnv = nullptr;
if (auto fnType = dyn_cast<FunctionTypeRepr>(TyR.get())) {
if (auto generics = fnType->getGenericParams()) {
assert(!Ty.wasValidated() && Ty.getType().isNull());

genericEnv = handleSILGenericParams(P.Context, generics, &P.SF);
fnType->setGenericEnvironment(genericEnv);
}
}

if (performTypeLocChecking(Ty, /*IsSILType=*/ false, genericEnv))
if (parseSILDeclRef(Member, true))
return true;

if (P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
parseSILType(MethodTy, TyLoc) ||
parseSILDebugLocation(InstLoc, B))
return true;

// Pick the ValueDecl that has the right type.
ValueDecl *TheDecl = nullptr;
auto declTy = Ty.getType()->getCanonicalType();
auto unlabeledDecl =
declTy->getUnlabeledType(P.Context)->getCanonicalType();
for (unsigned I = 0, E = values.size(); I < E; I++) {
auto lookupTy = values[I]->getInterfaceType();
auto unlabeledLookup =
lookupTy->getUnlabeledType(P.Context)->getCanonicalType();
if (unlabeledDecl == unlabeledLookup) {
TheDecl = values[I];
// Update SILDeclRef to point to the right Decl.
Member.loc = TheDecl;
break;
}
if (values.size() == 1 && !TheDecl) {
P.diagnose(TyLoc, diag::sil_member_decl_type_mismatch, declTy,
lookupTy);
return true;
}
}
if (!TheDecl) {
P.diagnose(TyLoc, diag::sil_member_decl_not_found);
return true;
}

switch (Opcode) {
default: llvm_unreachable("Out of sync with parent switch");
Expand Down Expand Up @@ -3130,8 +3153,9 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
SourceLoc TyLoc;
if (P.parseToken(tok::sil_dollar, diag::expected_tok_in_sil_instr, "$") ||
parseASTType(LookupTy) ||
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
parseSILDeclRef(Member))
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ","))
return true;
if (parseSILDeclRef(Member, true))
return true;
// Optional operand.
SILValue Operand;
Expand Down Expand Up @@ -4419,7 +4443,7 @@ bool Parser::parseSILVTable() {
SILDeclRef Ref;
Identifier FuncName;
SourceLoc FuncLoc;
if (VTableState.parseSILDeclRef(Ref))
if (VTableState.parseSILDeclRef(Ref, true))
return true;
SILFunction *Func = nullptr;
Optional<SILLinkage> Linkage = SILLinkage::Private;
Expand Down Expand Up @@ -4796,7 +4820,7 @@ bool Parser::parseSILWitnessTable() {
SILDeclRef Ref;
Identifier FuncName;
SourceLoc FuncLoc;
if (WitnessState.parseSILDeclRef(Ref) ||
if (WitnessState.parseSILDeclRef(Ref, true) ||
parseToken(tok::colon, diag::expected_sil_witness_colon))
return true;

Expand Down Expand Up @@ -4891,7 +4915,7 @@ bool Parser::parseSILDefaultWitnessTable() {
SILDeclRef Ref;
Identifier FuncName;
SourceLoc FuncLoc;
if (WitnessState.parseSILDeclRef(Ref) ||
if (WitnessState.parseSILDeclRef(Ref, true) ||
parseToken(tok::colon, diag::expected_sil_witness_colon))
return true;

Expand Down
16 changes: 10 additions & 6 deletions lib/SIL/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1447,19 +1447,20 @@ class SILPrinter : public SILVisitor<SILPrinter> {
void visitClassMethodInst(ClassMethodInst *AMI) {
printMethodInst(AMI, AMI->getOperand());
*this << " : " << AMI->getMember().getDecl()->getInterfaceType();
*this << " , ";
*this << ", ";
*this << AMI->getType();
}
void visitSuperMethodInst(SuperMethodInst *AMI) {
printMethodInst(AMI, AMI->getOperand());
*this << " : " << AMI->getMember().getDecl()->getInterfaceType();
*this << " , ";
*this << ", ";
*this << AMI->getType();
}
void visitWitnessMethodInst(WitnessMethodInst *WMI) {
if (WMI->isVolatile())
*this << "[volatile] ";
*this << "$" << WMI->getLookupType() << ", " << WMI->getMember();
*this << "$" << WMI->getLookupType() << ", " << WMI->getMember()
<< " : " << WMI->getMember().getDecl()->getInterfaceType();
if (!WMI->getTypeDependentOperands().empty()) {
*this << ", ";
*this << getIDAndType(WMI->getTypeDependentOperands()[0].get());
Expand Down Expand Up @@ -2185,7 +2186,8 @@ void SILVTable::print(llvm::raw_ostream &OS, bool Verbose) const {
for (auto &entry : getEntries()) {
OS << " ";
entry.Method.print(OS);
OS << ": ";
OS << ": " << entry.Method.getDecl()->getInterfaceType();
OS << " : ";
if (entry.Linkage !=
stripExternalFromLinkage(entry.Implementation->getLinkage())) {
OS << getLinkageString(entry.Linkage);
Expand Down Expand Up @@ -2226,7 +2228,8 @@ void SILWitnessTable::print(llvm::raw_ostream &OS, bool Verbose) const {
auto &methodWitness = witness.getMethodWitness();
OS << "method ";
methodWitness.Requirement.print(OS);
OS << ": ";
OS << ": " << methodWitness.Requirement.getDecl()->getInterfaceType();
OS << " : ";
if (methodWitness.Witness) {
methodWitness.Witness->printName(OS);
OS << "\t// "
Expand Down Expand Up @@ -2297,7 +2300,8 @@ void SILDefaultWitnessTable::print(llvm::raw_ostream &OS, bool Verbose) const {
// method #declref: @function
OS << " method ";
witness.getRequirement().print(OS);
OS << ": ";
OS << ": " << witness.getRequirement().getDecl()->getInterfaceType();
OS << " : ";
witness.getWitness()->printName(OS);
OS << "\t// "
<< demangleSymbolAsString(witness.getWitness()->getName());
Expand Down
2 changes: 1 addition & 1 deletion test/IRGen/dynamic_init.sil
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ bb0(%0 : $@thick C.Type):
// CHECK: [[CTOR:%[0-9]+]] = load %C12dynamic_init1C* (%swift.type*)*, %C12dynamic_init1C* (%swift.type*)** [[VTABLE_OFFSET]], align 8
// CHECK: [[CTOR_I8:%[0-9]+]] = bitcast %C12dynamic_init1C* (%swift.type*)* [[CTOR]] to i8*
// CHECK: [[CTOR_FN:%[0-9]+]] = bitcast i8* [[CTOR_I8]] to %C12dynamic_init1C* (%swift.type*)*
%2 = class_method %0 : $@thick C.Type, #C.init!allocator.1 : (C.Type) -> () -> C , $@convention(method) (@thick C.Type) -> @owned C
%2 = class_method %0 : $@thick C.Type, #C.init!allocator.1 : (C.Type) -> () -> C, $@convention(method) (@thick C.Type) -> @owned C
// CHECK: [[RESULT:%[0-9]+]] = call %C12dynamic_init1C* [[CTOR_FN]](%swift.type* %0)
%3 = apply %2(%0) : $@convention(method) (@thick C.Type) -> @owned C
// CHECK: call void bitcast (void (%swift.refcounted*)* @swift_rt_swift_release to void (%C12dynamic_init1C*)*)(%C12dynamic_init1C* [[RESULT]])
Expand Down
2 changes: 1 addition & 1 deletion test/IRGen/exactcast2.sil
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ sil @_TFC4main4HashCfMS0_FT_S0_ : $@convention(thin) (@thick Hash.Type) -> @owne

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

bb1: // Preds: bb2 bb3
Expand Down
2 changes: 1 addition & 1 deletion test/IRGen/objc_factory_method.sil
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ sil @_TFCSo4HiveCfMS_FT5queenGSQCSo3Bee__S_ : $@convention(thin) (@owned Optiona
bb0(%0 : $Optional<Bee>, %1 : $@thick Hive.Type):
%2 = thick_to_objc_metatype %1 : $@thick Hive.Type to $@objc_metatype Hive.Type // users: %3, %4
// CHECK: load i8*, i8** @"\01L_selector(hiveWithQueen:)"
%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
%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
// CHECK: call {{.*}} @objc_msgSend
%4 = apply %3(%0, %2) : $@convention(objc_method) (Optional<Bee>, @objc_metatype Hive.Type) -> @autoreleased Optional<Hive> // users: %5, %6
// CHECK: call {{.*}} @objc_autorelease
Expand Down
6 changes: 3 additions & 3 deletions test/IRGen/partial_apply.sil
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ entry(%f : $@callee_owned (Builtin.Word) -> (), %x : $Builtin.Word):

sil @objc_partial_apply : $@convention(thin) ObjCClass -> @callee_owned Int -> () {
entry(%c : $ObjCClass):
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.method!1.foreign : (ObjCClass) -> (Int) -> () , $@convention(objc_method) (Int, ObjCClass) -> ()
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.method!1.foreign : (ObjCClass) -> (Int) -> (), $@convention(objc_method) (Int, ObjCClass) -> ()
%p = partial_apply %m(%c) : $@convention(objc_method) (Int, ObjCClass) -> ()
return %p : $@callee_owned Int -> ()
}
Expand All @@ -129,7 +129,7 @@ entry(%c : $ObjCClass):
// CHECK: [[VAL:%.*]] = load double, double* [[ORIGINXVAL]]
sil @objc_partial_apply_indirect_sil_argument : $@convention(thin) ObjCClass -> @callee_owned NSRect -> () {
entry(%c : $ObjCClass):
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.method2!1.foreign : (ObjCClass) -> (NSRect) -> () , $@convention(objc_method) (NSRect, ObjCClass) -> ()
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.method2!1.foreign : (ObjCClass) -> (NSRect) -> (), $@convention(objc_method) (NSRect, ObjCClass) -> ()
%p = partial_apply %m(%c) : $@convention(objc_method) (NSRect, ObjCClass) -> ()
return %p : $@callee_owned NSRect -> ()
}
Expand All @@ -153,7 +153,7 @@ entry(%c : $ObjCClass):

sil @objc_partial_apply_consumes_self : $@convention(thin) ObjCClass -> @callee_owned () -> @owned ObjCClass {
entry(%c : $ObjCClass):
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.fakeInitFamily!1.foreign : (ObjCClass) -> () -> ObjCClass , $@convention(objc_method) (@owned ObjCClass) -> @owned ObjCClass
%m = class_method [volatile] %c : $ObjCClass, #ObjCClass.fakeInitFamily!1.foreign : (ObjCClass) -> () -> ObjCClass, $@convention(objc_method) (@owned ObjCClass) -> @owned ObjCClass
%p = partial_apply %m(%c) : $@convention(objc_method) (@owned ObjCClass) -> @owned ObjCClass
return %p : $@callee_owned () -> @owned ObjCClass
}
Expand Down
12 changes: 6 additions & 6 deletions test/IRGen/super.sil
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ bb0(%0 : $ChildToResilientParent):
debug_value %0 : $ChildToResilientParent, let, name "self", argno 1
strong_retain %0 : $ChildToResilientParent
%3 = upcast %0 : $ChildToResilientParent to $ResilientOutsideParent
%4 = super_method %0 : $ChildToResilientParent, #ResilientOutsideParent.method!1 : (ResilientOutsideParent) -> () -> () , $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
%4 = super_method %0 : $ChildToResilientParent, #ResilientOutsideParent.method!1 : (ResilientOutsideParent) -> () -> (), $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
%5 = apply %4(%3) : $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
strong_release %3 : $ResilientOutsideParent
%7 = tuple ()
Expand All @@ -63,7 +63,7 @@ sil @_T05super22ChildToResilientParentC11classMethodyyFZ : $@convention(method)
bb0(%0 : $@thick ChildToResilientParent.Type):
debug_value %0 : $@thick ChildToResilientParent.Type, let, name "self", argno 1
%2 = upcast %0 : $@thick ChildToResilientParent.Type to $@thick ResilientOutsideParent.Type
%3 = super_method %0 : $@thick ChildToResilientParent.Type, #ResilientOutsideParent.classMethod!1 : (ResilientOutsideParent.Type) -> () -> () , $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
%3 = super_method %0 : $@thick ChildToResilientParent.Type, #ResilientOutsideParent.classMethod!1 : (ResilientOutsideParent.Type) -> () -> (), $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
%4 = apply %3(%2) : $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
%5 = tuple ()
return %5 : $()
Expand All @@ -90,7 +90,7 @@ bb0(%0 : $ChildToFixedParent):
debug_value %0 : $ChildToFixedParent, let, name "self", argno 1
strong_retain %0 : $ChildToFixedParent
%3 = upcast %0 : $ChildToFixedParent to $OutsideParent
%4 = super_method %0 : $ChildToFixedParent, #OutsideParent.method!1 : (OutsideParent) -> () -> () , $@convention(method) (@guaranteed OutsideParent) -> ()
%4 = super_method %0 : $ChildToFixedParent, #OutsideParent.method!1 : (OutsideParent) -> () -> (), $@convention(method) (@guaranteed OutsideParent) -> ()
%5 = apply %4(%3) : $@convention(method) (@guaranteed OutsideParent) -> ()
strong_release %3 : $OutsideParent
%7 = tuple ()
Expand All @@ -110,7 +110,7 @@ sil @_T05super18ChildToFixedParentC11classMethodyyFZ : $@convention(method) (@th
bb0(%0 : $@thick ChildToFixedParent.Type):
debug_value %0 : $@thick ChildToFixedParent.Type, let, name "self", argno 1
%2 = upcast %0 : $@thick ChildToFixedParent.Type to $@thick OutsideParent.Type
%3 = super_method %0 : $@thick ChildToFixedParent.Type, #OutsideParent.classMethod!1 : (OutsideParent.Type) -> () -> () , $@convention(method) (@thick OutsideParent.Type) -> ()
%3 = super_method %0 : $@thick ChildToFixedParent.Type, #OutsideParent.classMethod!1 : (OutsideParent.Type) -> () -> (), $@convention(method) (@thick OutsideParent.Type) -> ()
%4 = apply %3(%2) : $@convention(method) (@thick OutsideParent.Type) -> ()
%5 = tuple ()
return %5 : $()
Expand All @@ -131,7 +131,7 @@ bb0(%0 : $ResilientOutsideChild):
debug_value %0 : $ResilientOutsideChild, let, name "self", argno 1
strong_retain %0 : $ResilientOutsideChild
%3 = upcast %0 : $ResilientOutsideChild to $ResilientOutsideParent
%4 = super_method %0 : $ResilientOutsideChild, #ResilientOutsideParent.method!1 : (ResilientOutsideParent) -> () -> () , $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
%4 = super_method %0 : $ResilientOutsideChild, #ResilientOutsideParent.method!1 : (ResilientOutsideParent) -> () -> (), $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
%5 = apply %4(%3) : $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
strong_release %3 : $ResilientOutsideParent
%7 = tuple ()
Expand All @@ -155,7 +155,7 @@ sil @_T015resilient_class21ResilientOutsideChildC5superE20callSuperClassMethodyy
bb0(%0 : $@thick ResilientOutsideChild.Type):
debug_value %0 : $@thick ResilientOutsideChild.Type, let, name "self", argno 1
%2 = upcast %0 : $@thick ResilientOutsideChild.Type to $@thick ResilientOutsideParent.Type
%3 = super_method %0 : $@thick ResilientOutsideChild.Type, #ResilientOutsideParent.classMethod!1 : (ResilientOutsideParent.Type) -> () -> () , $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
%3 = super_method %0 : $@thick ResilientOutsideChild.Type, #ResilientOutsideParent.classMethod!1 : (ResilientOutsideParent.Type) -> () -> (), $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
%4 = apply %3(%2) : $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
%5 = tuple ()
return %5 : $()
Expand Down
Loading