[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:
Doug Gregor
2016-04-05 22:25:47 -07:00
parent a02573e088
commit ab8253cfde
3 changed files with 41 additions and 9 deletions

View File

@@ -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();

View File

@@ -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,12 +1471,16 @@ public:
getSubstFnType(), fn));
} else {
// Directly call the peer constructor.
setCallee(Callee::forDirect(SGF,
setCallee(
Callee::forDirect(
SGF,
SILDeclRef(ctorRef->getDecl(),
useAllocatingCtor
? SILDeclRef::Kind::Allocator
: SILDeclRef::Kind::Initializer,
SILDeclRef::ConstructAtBestResilienceExpansion),
SILDeclRef::ConstructAtBestResilienceExpansion,
SILDeclRef::ConstructAtNaturalUncurryLevel,
requiresForeignEntryPoint(ctorRef->getDecl())),
getSubstFnType(useAllocatingCtor), fn));
}

View File

@@ -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)
}
}