Look for the C-Language Copy of UIApplicationMain

A long while back we added a copy of UIApplicaitonMain to the UIKit
overlay. This was intended to fix the signature of UIApplicationMain by
forcing clients to choose a non-deprecated copy with revised nullability
annotations that were compatible with the (then) interface of the (then)
CommandLine stdlib type. Since then, we've gone in a completely different
direction with type-based entrypoints and @main, but the compatibility
shims remain. This code was assuming that it would always find one
declaration of UIApplicationMain in the clang module, but that's not
a sound assumption to make. In certain scenarios, we can wind up finding
the overlay's copy of UIApplicationMain too. When that's the Swift
function, we reference a native-to-foreign thunk that we don't actually
wind up generating in the open-coding and this results in a nasty linker
error. Filter the available candidates here looking for the C copy of
UIApplicationMain.

rdar://101932338
This commit is contained in:
Robert Widmann
2022-11-04 10:22:38 -07:00
parent 4d16353146
commit fc52e7adc6

View File

@@ -631,16 +631,22 @@ void SILGenFunction::emitArtificialTopLevel(Decl *mainDecl) {
->loadModule(SourceLoc(),
ImportPath::Module(llvm::makeArrayRef(UIKitName)));
assert(UIKit && "couldn't find UIKit objc module?!");
SmallVector<ValueDecl *, 1> results;
SmallVector<ValueDecl *, 2> results;
UIKit->lookupQualified(UIKit,
DeclNameRef(ctx.getIdentifier("UIApplicationMain")),
NL_QualifiedDefault,
results);
assert(results.size() == 1
&& "couldn't find a unique UIApplicationMain in the UIKit ObjC "
"module?!");
ValueDecl *UIApplicationMainDecl = results.front();
// As the comment above alludes, using a qualified lookup into UIKit is
// *not* sound. In particular, it's possible for the lookup to find the
// (deprecated) Swift copy of UIApplicationMain in UIKit and try to call
// that instead of the C entrypoint. Let's try to force this to happen.
auto FoundUIApplicationMain = llvm::find_if(results, [](const ValueDecl *VD) {
return !VD->getClangNode().isNull();
});
assert(FoundUIApplicationMain != results.end() &&
"Could not find a UIApplicationMain to call!");
ValueDecl *UIApplicationMainDecl = *FoundUIApplicationMain;
auto mainRef = SILDeclRef(UIApplicationMainDecl).asForeign();
SILGenFunctionBuilder builder(SGM);