From 7e6b5b24a4bb7c7c06451ef68a43876937c16941 Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Tue, 16 Mar 2021 23:44:08 +0100 Subject: [PATCH] [Driver] Don't validate arclite linking if the driver is only set up to get the swift-frontend invocation If the driver is only set up to get the frontend invocation (e.g. from sourcekitd), don't validate that we can link against ARCLite because a) we don't care about link-time when we are only interested in the frontend invocation b) finding arclite might cause us to find clang using xcrun which in turn can cause sourcekitd to hang. rdar://50659268 --- include/swift/Driver/Driver.h | 13 +++++++++++++ lib/Driver/DarwinToolChains.cpp | 12 +++++++++--- lib/Driver/FrontendUtil.cpp | 2 ++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/swift/Driver/Driver.h b/include/swift/Driver/Driver.h index 167395da9c073..b27e2db299b57 100644 --- a/include/swift/Driver/Driver.h +++ b/include/swift/Driver/Driver.h @@ -200,6 +200,11 @@ class Driver { /// Indicates whether the driver should check that the input files exist. bool CheckInputFilesExist = true; + /// Indicates that this driver never actually executes any commands but is + /// just set up to retrieve the swift-frontend invocation that would be + /// executed during compilation. + bool IsDummyDriverForFrontendInvocation = false; + public: Driver(StringRef DriverExecutable, StringRef Name, ArrayRef Args, DiagnosticEngine &Diags); @@ -226,6 +231,14 @@ class Driver { void setCheckInputFilesExist(bool Value) { CheckInputFilesExist = Value; } + bool isDummyDriverForFrontendInvocation() const { + return IsDummyDriverForFrontendInvocation; + } + + void setIsDummyDriverForFrontendInvocation(bool Value) { + IsDummyDriverForFrontendInvocation = Value; + } + /// Creates an appropriate ToolChain for a given driver, given the target /// specified in \p Args (or the default target). Sets the value of \c /// DefaultTargetTriple from \p Args as a side effect. diff --git a/lib/Driver/DarwinToolChains.cpp b/lib/Driver/DarwinToolChains.cpp index 95accad29f2bd..a0ee603a9f3ef 100644 --- a/lib/Driver/DarwinToolChains.cpp +++ b/lib/Driver/DarwinToolChains.cpp @@ -901,9 +901,15 @@ void toolchains::Darwin::validateArguments(DiagnosticEngine &diags, const llvm::opt::ArgList &args, StringRef defaultTarget) const { - // Validating arclite library path when link-objc-runtime. - validateLinkObjcRuntimeARCLiteLib(*this, diags, args); - + if (!getDriver().isDummyDriverForFrontendInvocation()) { + // Validating arclite library path when link-objc-runtime. + // If the driver is just set up to retrieve the swift-frontend invocation, + // we don't care about link-time, so we can skip this step, which may be + // expensive since it might call to `xcrun` to find `clang` and `arclite` + // relative to `clang`. + validateLinkObjcRuntimeARCLiteLib(*this, diags, args); + } + // Validating apple platforms deployment targets. validateDeploymentTarget(*this, diags, args); validateTargetVariant(*this, diags, args, defaultTarget); diff --git a/lib/Driver/FrontendUtil.cpp b/lib/Driver/FrontendUtil.cpp index 2f2c8c8c3171d..9be9def90fc2f 100644 --- a/lib/Driver/FrontendUtil.cpp +++ b/lib/Driver/FrontendUtil.cpp @@ -75,6 +75,8 @@ bool swift::driver::getSingleFrontendInvocationFromDriverArguments( // CompilerInvocation may wish to remap inputs to source buffers. TheDriver.setCheckInputFilesExist(false); + TheDriver.setIsDummyDriverForFrontendInvocation(true); + std::unique_ptr ArgList = TheDriver.parseArgStrings(ArrayRef(Args).slice(1)); if (Diags.hadAnyError())