Use ClassDecl::ForeignKind to model Clang's objc_runtime_visible.

We're now correctly checking for inheritance, adding @objc methods,
and adding @objc protocols for both CF types and objc_runtime_visible
classes (those without visible symbols). The latter is used for some
of the types in Dispatch, which has exposed some of the classes that
were considered implementation details on past OSs.

We still don't properly implement using 'as?' to check conformance to
a Swift protocol for a CF or objc_runtime_visible type, but we can do
that later.

rdar://problem/26850367
This commit is contained in:
Jordan Rose
2016-06-30 11:20:58 -07:00
parent 53118e9a5f
commit 3b6e40c030
16 changed files with 235 additions and 65 deletions

View File

@@ -292,10 +292,8 @@ llvm::Constant *irgen::tryEmitConstantHeapMetadataRef(IRGenModule &IGM,
if (doesClassMetadataRequireDynamicInitialization(IGM, theDecl))
return nullptr;
// Otherwise, just respect genericity and Objective-C runtime visibility.
} else if ((theDecl->isGenericContext()
&& !isTypeErasedGenericClass(theDecl))
|| theDecl->isOnlyObjCRuntimeVisible()) {
// Otherwise, just respect genericity.
} else if (theDecl->isGenericContext() && !isTypeErasedGenericClass(theDecl)){
return nullptr;
}
@@ -331,13 +329,15 @@ llvm::Value *irgen::emitObjCHeapMetadataRef(IRGenFunction &IGF,
bool allowUninitialized) {
// If the class is visible only through the Objective-C runtime, form the
// appropriate runtime call.
if (theClass->isOnlyObjCRuntimeVisible()) {
if (theClass->getForeignClassKind() == ClassDecl::ForeignKind::RuntimeOnly) {
SmallString<64> scratch;
auto className =
IGF.IGM.getAddrOfGlobalString(theClass->getObjCRuntimeName(scratch));
return IGF.Builder.CreateCall(IGF.IGM.getLookUpClassFn(), className);
}
assert(!theClass->isForeign());
Address classRef = IGF.IGM.getAddrOfObjCClassRef(theClass);
auto classObject = IGF.Builder.CreateLoad(classRef);
if (allowUninitialized) return classObject;
@@ -5438,7 +5438,6 @@ IRGenModule::getAddrOfForeignTypeMetadataCandidate(CanType type) {
if (auto classType = dyn_cast<ClassType>(type)) {
assert(!classType.getParent());
auto classDecl = classType->getDecl();
// FIXME: Differentiate between the different kinds of foreign classes.
assert(classDecl->isForeign());
ForeignClassMetadataBuilder builder(*this, classDecl);