mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user