mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Import as memory] SILGen for delegation to a C function imported as an initializer.
Always statically dispatch to C functions imported as members, and call to the foreign entry point. This gets us through SILGen, but DI is still deeply unhappy with the resulting SIL.
This commit is contained in:
@@ -35,6 +35,10 @@ swift::getMethodDispatch(AbstractFunctionDecl *method) {
|
||||
if (method->hasForcedStaticDispatch())
|
||||
return MethodDispatch::Static;
|
||||
|
||||
// Import-as-member declarations are always statically referenced.
|
||||
if (method->isImportAsMember())
|
||||
return MethodDispatch::Static;
|
||||
|
||||
// If this declaration is in a class but not marked final, then it is
|
||||
// always dynamically dispatched.
|
||||
auto dc = method->getDeclContext();
|
||||
|
||||
@@ -1440,7 +1440,8 @@ public:
|
||||
// that's the only thing that's witnessed. For classes,
|
||||
// this is the initializing constructor, to which we will dynamically
|
||||
// dispatch.
|
||||
if (SelfParam.getSubstRValueType()->getRValueInstanceType()->is<ArchetypeType>()
|
||||
if (SelfParam.getSubstRValueType()->getRValueInstanceType()
|
||||
->is<ArchetypeType>()
|
||||
&& isa<ProtocolDecl>(ctorRef->getDecl()->getDeclContext())) {
|
||||
// Look up the witness for the constructor.
|
||||
auto constant = SILDeclRef(ctorRef->getDecl(),
|
||||
@@ -1470,13 +1471,17 @@ public:
|
||||
getSubstFnType(), fn));
|
||||
} else {
|
||||
// Directly call the peer constructor.
|
||||
setCallee(Callee::forDirect(SGF,
|
||||
SILDeclRef(ctorRef->getDecl(),
|
||||
useAllocatingCtor
|
||||
? SILDeclRef::Kind::Allocator
|
||||
: SILDeclRef::Kind::Initializer,
|
||||
SILDeclRef::ConstructAtBestResilienceExpansion),
|
||||
getSubstFnType(useAllocatingCtor), fn));
|
||||
setCallee(
|
||||
Callee::forDirect(
|
||||
SGF,
|
||||
SILDeclRef(ctorRef->getDecl(),
|
||||
useAllocatingCtor
|
||||
? SILDeclRef::Kind::Allocator
|
||||
: SILDeclRef::Kind::Initializer,
|
||||
SILDeclRef::ConstructAtBestResilienceExpansion,
|
||||
SILDeclRef::ConstructAtNaturalUncurryLevel,
|
||||
requiresForeignEntryPoint(ctorRef->getDecl())),
|
||||
getSubstFnType(useAllocatingCtor), fn));
|
||||
}
|
||||
|
||||
// Set up the substitutions, if we have any.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// RUN: %target-swift-frontend -emit-sil -I %S/../IDE/Inputs/custom-modules %s 2>&1 | FileCheck --check-prefix=SIL %s
|
||||
// RUN: %target-swift-frontend -emit-silgen -I %S/../IDE/Inputs/custom-modules %s 2>&1 | FileCheck --check-prefix=SIL %s
|
||||
// REQUIRES: objc_interop
|
||||
import ImportAsMember.A
|
||||
import ImportAsMember.Proto
|
||||
import ImportAsMember.Class
|
||||
|
||||
public func returnGlobalVar() -> Double {
|
||||
return Struct1.globalVar
|
||||
@@ -22,3 +23,25 @@ public func useProto(p: IAMProto) {
|
||||
|
||||
// SIL-LABEL: sil {{.*}}anchor{{.*}} () -> () {
|
||||
func anchor() {}
|
||||
|
||||
// SIL-LABEL: sil {{.*}}useClass{{.*}}
|
||||
// SIL: bb0([[D:%[0-9]+]] : $Double, [[OPTS:%[0-9]+]] : $SomeClass.Options):
|
||||
public func useClass(d: Double, opts: SomeClass.Options) {
|
||||
// SIL: [[CTOR:%[0-9]+]] = function_ref @MakeIAMSomeClass : $@convention(c) (Double) -> @autoreleased SomeClass
|
||||
// SIL: [[OBJ:%[0-9]+]] = apply [[CTOR]]([[D]])
|
||||
let o = SomeClass(value: d)
|
||||
|
||||
// SIL: [[APPLY_FN:%[0-9]+]] = function_ref @IAMSomeClassApplyOptions : $@convention(c) (SomeClass, SomeClass.Options) -> ()
|
||||
// SIL: apply [[APPLY_FN]]([[OBJ]], [[OPTS]])
|
||||
o.applyOptions(opts)
|
||||
}
|
||||
|
||||
extension SomeClass {
|
||||
// SIL-LABEL: sil hidden @_TFE16import_as_memberCSo9SomeClasscfT6doubleSd_S0_
|
||||
// SIL: bb0([[DOUBLE:%[0-9]+]] : $Double
|
||||
// SIL: [[FNREF:%[0-9]+]] = function_ref @MakeIAMSomeClass
|
||||
// SIL: apply [[FNREF]]([[DOUBLE]])
|
||||
convenience init(double: Double) {
|
||||
self.init(value: double)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user