IRGen: Map SIL metatypes back to ObjC classes.

For ObjC class method calls, map a metatype value back to an objc Class before emitting the ObjC call. This is dumb because we already map the original Class to a Swift metatype when we map the metatype instruction, but it gets ObjC class method calls working. Now that SIL keeps use chains, we could be easily smarter about this.

Swift SVN r4558
This commit is contained in:
Joe Groff
2013-03-30 23:40:35 +00:00
parent d6b30f71f0
commit 0034475514
3 changed files with 16 additions and 7 deletions

View File

@@ -769,25 +769,32 @@ void irgen::addObjCMethodCallImplicitArguments(IRGenFunction &IGF,
CallEmission &emission,
ValueDecl *method,
ManagedValue self,
CanType selfType,
CanType searchType) {
// Compute the selector.
Selector selector(method);
// Emit the self or super argument.
Explosion selfValues(ExplosionKind::Minimal);
Explosion args(ExplosionKind::Minimal);
// super.constructor references an instance method (even though the
// decl is really a 'static' member).
bool isInstanceMethod
= isa<ConstructorDecl>(method) || method->isInstanceMember();
// Map a class parameter back to an ObjC Class value (the heap metadata).
if (!isInstanceMethod) {
CanType selfInstanceType(selfType->castTo<MetaTypeType>()->getInstanceType());
self = ManagedValue(emitClassHeapMetadataRefForMetatype(IGF, self.getValue(),
selfInstanceType));
}
if (searchType) {
emitSuperArgument(IGF, isInstanceMethod, self, selfValues,
emitSuperArgument(IGF, isInstanceMethod, self, args,
searchType);
} else {
selfValues.add(self);
args.add(self);
}
assert(selfValues.size() == 1);
assert(args.size() == 1);
// Add the selector value.
auto selectorRef = IGF.IGM.getAddrOfObjCSelectorRef(selector.str());
@@ -805,10 +812,10 @@ void irgen::addObjCMethodCallImplicitArguments(IRGenFunction &IGF,
selectorV = IGF.Builder.CreateLoad(Address(selectorRef,
IGF.IGM.getPointerAlignment()));
}
selfValues.addUnmanaged(selectorV);
args.addUnmanaged(selectorV);
// Add that to the emission.
emission.addArg(selfValues);
emission.addArg(args);
}
/// Prepare a call using ObjC method dispatch.

View File

@@ -50,6 +50,7 @@ namespace irgen {
CallEmission &emission,
ValueDecl *method,
ManagedValue self,
CanType selfType,
CanType searchType);
CallEmission prepareObjCMethodCall(IRGenFunction &IGF,

View File

@@ -602,6 +602,7 @@ void IRGenSILFunction::visitApplyInst(swift::ApplyInst *i) {
addObjCMethodCallImplicitArguments(*this, emission,
calleeLV.getObjCMethod().getMethodDecl(),
selfArg.claimNext(),
thisValue.getType().getSwiftType(),
calleeLV.getObjCMethod().getSuperSearchType());
arg = 1;