Skip to content

Commit 3517db4

Browse files
committed
[SourceKit] Pass 'swiftc' path to Driver when creating frontend args
Driver uses its path to derive the plugin paths (i.e. 'lib/swift/host/plugins' et al.) Previously it was a constant string 'swiftc' that caused SourceKit failed to find dylib plugins in the toolchain. Since 'SwiftLangSupport' knows the swift-frontend path, use it, but replacing the filename with 'swiftc', to derive the plugin paths. rdar://107849796
1 parent 6ec8a8c commit 3517db4

File tree

12 files changed

+127
-40
lines changed

12 files changed

+127
-40
lines changed

include/swift/Driver/FrontendUtil.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ void ExpandResponseFilesWithRetry(llvm::StringSaver &Saver,
3333
/// Generates the list of arguments that would be passed to the compiler
3434
/// frontend from the given driver arguments.
3535
///
36+
/// \param DriverPath The path to 'swiftc'.
3637
/// \param ArgList The driver arguments (i.e. normal arguments for \c swiftc).
3738
/// \param Diags The DiagnosticEngine used to report any errors parsing the
3839
/// arguments.
@@ -48,7 +49,8 @@ void ExpandResponseFilesWithRetry(llvm::StringSaver &Saver,
4849
/// \note This function is not intended to create invocations which are
4950
/// suitable for use in REPL or immediate modes.
5051
bool getSingleFrontendInvocationFromDriverArguments(
51-
ArrayRef<const char *> ArgList, DiagnosticEngine &Diags,
52+
StringRef DriverPath, ArrayRef<const char *> ArgList,
53+
DiagnosticEngine &Diags,
5254
llvm::function_ref<bool(ArrayRef<const char *> FrontendArgs)> Action,
5355
bool ForceNoOutputs = false);
5456

include/swift/IDETool/CompileInstance.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace ide {
3131

3232
/// Manages \c CompilerInstance for completion like operations.
3333
class CompileInstance {
34+
const std::string &SwiftExecutablePath;
3435
const std::string &RuntimeResourcePath;
3536
const std::string &DiagnosticDocumentationPath;
3637
const std::shared_ptr<swift::PluginRegistry> Plugins;
@@ -67,10 +68,12 @@ class CompileInstance {
6768
std::shared_ptr<std::atomic<bool>> CancellationFlag);
6869

6970
public:
70-
CompileInstance(const std::string &RuntimeResourcePath,
71+
CompileInstance(const std::string &SwiftExecutablePath,
72+
const std::string &RuntimeResourcePath,
7173
const std::string &DiagnosticDocumentationPath,
7274
std::shared_ptr<swift::PluginRegistry> Plugins = nullptr)
73-
: RuntimeResourcePath(RuntimeResourcePath),
75+
: SwiftExecutablePath(SwiftExecutablePath),
76+
RuntimeResourcePath(RuntimeResourcePath),
7477
DiagnosticDocumentationPath(DiagnosticDocumentationPath),
7578
Plugins(Plugins), CachedCIInvalidated(false), CachedReuseCount(0) {}
7679

lib/Driver/FrontendUtil.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static void removeSupplementaryOutputs(llvm::opt::ArgList &ArgList) {
5959
}
6060

6161
bool swift::driver::getSingleFrontendInvocationFromDriverArguments(
62-
ArrayRef<const char *> Argv, DiagnosticEngine &Diags,
62+
StringRef DriverPath, ArrayRef<const char *> Argv, DiagnosticEngine &Diags,
6363
llvm::function_ref<bool(ArrayRef<const char *> FrontendArgs)> Action,
6464
bool ForceNoOutputs) {
6565
SmallVector<const char *, 16> Args;
@@ -87,7 +87,7 @@ bool swift::driver::getSingleFrontendInvocationFromDriverArguments(
8787
ExpandResponseFilesWithRetry(Saver, Args);
8888

8989
// Force the driver into batch mode by specifying "swiftc" as the name.
90-
Driver TheDriver("swiftc", "swiftc", Args, Diags);
90+
Driver TheDriver(DriverPath, "swiftc", Args, Diags);
9191

9292
// Don't check for the existence of input files, since the user of the
9393
// CompilerInvocation may wish to remap inputs to source buffers.

lib/IDETool/CompileInstance.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,14 @@ bool CompileInstance::setupCI(
261261
DiagnosticDocumentationPath.c_str()});
262262
args.append(origArgs.begin(), origArgs.end());
263263

264+
SmallString<256> driverPath(SwiftExecutablePath);
265+
llvm::sys::path::remove_filename(driverPath);
266+
llvm::sys::path::append(driverPath, "swiftc");
267+
264268
CompilerInvocation invocation;
265269
bool invocationCreationFailed =
266270
driver::getSingleFrontendInvocationFromDriverArguments(
267-
args, Diags,
271+
driverPath, args, Diags,
268272
[&](ArrayRef<const char *> FrontendArgs) {
269273
return invocation.parseArgs(FrontendArgs, Diags);
270274
},

lib/IDETool/CompilerInvocation.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,14 @@ bool ide::initCompilerInvocation(
173173
StreamDiagConsumer DiagConsumer(ErrOS);
174174
Diags.addConsumer(DiagConsumer);
175175

176+
// Derive 'swiftc' path from 'swift-frontend' path (swiftExecutablePath).
177+
SmallString<256> driverPath(swiftExecutablePath);
178+
llvm::sys::path::remove_filename(driverPath);
179+
llvm::sys::path::append(driverPath, "swiftc");
180+
176181
bool InvocationCreationFailed =
177182
driver::getSingleFrontendInvocationFromDriverArguments(
178-
Args, Diags,
183+
driverPath, Args, Diags,
179184
[&](ArrayRef<const char *> FrontendArgs) {
180185
return Invocation.parseArgs(
181186
FrontendArgs, Diags, /*ConfigurationFileBuffers=*/nullptr,
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
2+
@OptionSet<UInt8>
3+
struct ShippingOptions {
4+
private enum Options: Int {
5+
case nextDay
6+
case secondDay
7+
case priority
8+
case standard
9+
}
10+
11+
static let express: ShippingOptions = [.nextDay, .secondDay]
12+
static let all: ShippingOptions = [.express, .priority, .standard]
13+
}
14+
15+
func test(opts: ShippingOptions) {
16+
let _ = ShippingOptions.nextDay
17+
}
18+
19+
// REQUIRES: swift_swift_parser
20+
21+
// RUN: %empty-directory(%t)
22+
// RUN: %sourcekitd-test \
23+
// RUN: -shell -- echo '## DIAGS ##' == \
24+
// RUN: -req=diags %s -- %s ==\
25+
// RUN: -shell -- echo '## CURSOR ##' == \
26+
// RUN: -req=cursor -pos=16:27 %s -- %s == \
27+
// RUN: -shell -- echo '## COMPLETE ##' == \
28+
// RUN: -req=complete -pos=16:27 %s -- %s == \
29+
// RUN: -shell -- echo '## COMPILE ##' == \
30+
// RUN: -req=compile -name test -- -c %s -module-name TestModule -o %t/out.o \
31+
// RUN: | %FileCheck %s
32+
33+
// CHECK-LABEL: ## DIAGS ##
34+
// CHECK: key.diagnostics: [
35+
// CHECK-NEXT: ]
36+
37+
// CHECK-LABEL: ## CURSOR ##
38+
// CHECK: source.lang.swift.ref.var.static
39+
40+
// CHECK-LABEL: ## COMPLETE ##
41+
// CHECK: key.results: [
42+
// CHECK: key.description: "secondDay"
43+
44+
// CHECK-LABEL: ## COMPILE ##
45+
// CHECK: key.diagnostics: [
46+
// CHECK-NEXT: ],
47+
// CHECK: key.value: 0

tools/SourceKit/lib/SwiftLang/SwiftCompile.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ compile::SessionManager::getSession(StringRef name) {
3131
}
3232

3333
bool inserted = false;
34-
std::tie(i, inserted) = sessions.try_emplace(
35-
name, std::make_shared<compile::Session>(
36-
RuntimeResourcePath, DiagnosticDocumentationPath, Plugins));
34+
std::tie(i, inserted) =
35+
sessions.try_emplace(name, std::make_shared<compile::Session>(
36+
SwiftExecutablePath, RuntimeResourcePath,
37+
DiagnosticDocumentationPath, Plugins));
3738
assert(inserted);
3839
return i->second;
3940
}

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ SwiftLangSupport::SwiftLangSupport(SourceKit::Context &SKCtx)
297297
SKCtx.getGlobalConfiguration());
298298

299299
CompileManager = std::make_shared<compile::SessionManager>(
300-
RuntimeResourcePath, DiagnosticDocumentationPath, Plugins);
300+
SwiftExecutablePath, RuntimeResourcePath, DiagnosticDocumentationPath,
301+
Plugins);
301302

302303
// By default, just use the in-memory cache.
303304
CCCache->inMemory = std::make_unique<ide::CodeCompletionCache>();

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,10 +292,12 @@ class Session {
292292
swift::ide::CompileInstance Compiler;
293293

294294
public:
295-
Session(const std::string &RuntimeResourcePath,
295+
Session(const std::string &SwiftExecutablePath,
296+
const std::string &RuntimeResourcePath,
296297
const std::string &DiagnosticDocumentationPath,
297298
std::shared_ptr<swift::PluginRegistry> Plugins)
298-
: Compiler(RuntimeResourcePath, DiagnosticDocumentationPath, Plugins) {}
299+
: Compiler(SwiftExecutablePath, RuntimeResourcePath,
300+
DiagnosticDocumentationPath, Plugins) {}
299301

300302
bool
301303
performCompile(llvm::ArrayRef<const char *> Args,
@@ -307,6 +309,7 @@ class Session {
307309
};
308310

309311
class SessionManager {
312+
const std::string &SwiftExecutablePath;
310313
const std::string &RuntimeResourcePath;
311314
const std::string &DiagnosticDocumentationPath;
312315
const std::shared_ptr<swift::PluginRegistry> Plugins;
@@ -317,10 +320,12 @@ class SessionManager {
317320
mutable llvm::sys::Mutex mtx;
318321

319322
public:
320-
SessionManager(std::string &RuntimeResourcePath,
321-
std::string &DiagnosticDocumentationPath,
322-
std::shared_ptr<swift::PluginRegistry> Plugins)
323-
: RuntimeResourcePath(RuntimeResourcePath),
323+
SessionManager(const std::string &SwiftExecutablePath,
324+
const std::string &RuntimeResourcePath,
325+
const std::string &DiagnosticDocumentationPath,
326+
const std::shared_ptr<swift::PluginRegistry> Plugins)
327+
: SwiftExecutablePath(SwiftExecutablePath),
328+
RuntimeResourcePath(RuntimeResourcePath),
324329
DiagnosticDocumentationPath(DiagnosticDocumentationPath),
325330
Plugins(Plugins) {}
326331

tools/swift-ide-test/ModuleAPIDiff.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,8 @@ std::shared_ptr<sma::Module> createSMAModel(ModuleDecl *M) {
896896

897897
} // unnamed namespace
898898

899-
int swift::doGenerateModuleAPIDescription(StringRef MainExecutablePath,
899+
int swift::doGenerateModuleAPIDescription(StringRef DriverPath,
900+
StringRef MainExecutablePath,
900901
ArrayRef<std::string> Args) {
901902
std::vector<const char *> CStringArgs;
902903
for (auto &S : Args) {
@@ -910,9 +911,10 @@ int swift::doGenerateModuleAPIDescription(StringRef MainExecutablePath,
910911

911912
CompilerInvocation Invocation;
912913
bool HadError = driver::getSingleFrontendInvocationFromDriverArguments(
913-
CStringArgs, Diags, [&](ArrayRef<const char *> FrontendArgs) {
914-
return Invocation.parseArgs(FrontendArgs, Diags);
915-
});
914+
MainExecutablePath, CStringArgs, Diags,
915+
[&](ArrayRef<const char *> FrontendArgs) {
916+
return Invocation.parseArgs(FrontendArgs, Diags);
917+
});
916918

917919
if (HadError) {
918920
llvm::errs() << "error: unable to create a CompilerInvocation\n";
@@ -941,4 +943,3 @@ int swift::doGenerateModuleAPIDescription(StringRef MainExecutablePath,
941943

942944
return 0;
943945
}
944-

tools/swift-ide-test/ModuleAPIDiff.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
namespace swift {
88

9-
int doGenerateModuleAPIDescription(StringRef MainExecutablePath,
9+
int doGenerateModuleAPIDescription(StringRef DriverPath,
10+
StringRef MainExecutablePath,
1011
ArrayRef<std::string> Args);
1112

1213
} // end namespace swift

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4169,22 +4169,26 @@ static int doPrintUSRs(const CompilerInvocation &InitInvok,
41694169
return 0;
41704170
}
41714171

4172-
static int doTestCreateCompilerInvocation(ArrayRef<const char *> Args, bool ForceNoOutputs) {
4172+
static int doTestCreateCompilerInvocation(StringRef DriverPath,
4173+
ArrayRef<const char *> Args,
4174+
bool ForceNoOutputs) {
41734175
PrintingDiagnosticConsumer PDC;
41744176
SourceManager SM;
41754177
DiagnosticEngine Diags(SM);
41764178
Diags.addConsumer(PDC);
41774179

41784180
CompilerInvocation CI;
41794181
bool HadError = driver::getSingleFrontendInvocationFromDriverArguments(
4180-
Args, Diags, [&](ArrayRef<const char *> FrontendArgs) {
4181-
llvm::outs() << "Frontend Arguments BEGIN\n";
4182-
for (const char *arg : FrontendArgs) {
4183-
llvm::outs() << arg << "\n";
4184-
}
4185-
llvm::outs() << "Frontend Arguments END\n";
4186-
return CI.parseArgs(FrontendArgs, Diags);
4187-
}, ForceNoOutputs);
4182+
DriverPath, Args, Diags,
4183+
[&](ArrayRef<const char *> FrontendArgs) {
4184+
llvm::outs() << "Frontend Arguments BEGIN\n";
4185+
for (const char *arg : FrontendArgs) {
4186+
llvm::outs() << arg << "\n";
4187+
}
4188+
llvm::outs() << "Frontend Arguments END\n";
4189+
return CI.parseArgs(FrontendArgs, Diags);
4190+
},
4191+
ForceNoOutputs);
41884192

41894193
if (HadError) {
41904194
llvm::errs() << "error: unable to create a CompilerInvocation\n";
@@ -4213,11 +4217,28 @@ static int doTestCompilerInvocationFromModule(StringRef ModuleFilePath) {
42134217
// without being given the address of a function in the main executable).
42144218
void anchorForGetMainExecutable() {}
42154219

4220+
// Derive 'swiftc' path from 'swift-ide-test' path.
4221+
std::string getDriverPath(StringRef MainExecutablePath) {
4222+
SmallString<256> driverPath(MainExecutablePath);
4223+
llvm::sys::path::remove_filename(driverPath); // remove 'swift-ide-test'.
4224+
llvm::sys::path::remove_filename(driverPath); // remove 'bin'.
4225+
if (llvm::sys::path::filename(driverPath) == "local") {
4226+
llvm::sys::path::remove_filename(driverPath); // remove 'local'.
4227+
}
4228+
llvm::sys::path::append(driverPath, "bin", "swiftc");
4229+
return std::string(driverPath);
4230+
}
4231+
42164232
int main(int argc, char *argv[]) {
42174233
PROGRAM_START(argc, argv);
42184234
INITIALIZE_LLVM();
42194235
initializeSwiftModules();
42204236

4237+
std::string mainExecutablePath = llvm::sys::fs::getMainExecutable(
4238+
argv[0], reinterpret_cast<void *>(&anchorForGetMainExecutable));
4239+
4240+
std::string driverPath = getDriverPath(mainExecutablePath);
4241+
42214242
if (argc > 1) {
42224243
// Handle integrated test tools which do not use
42234244
// llvm::cl::ParseCommandLineOptions.
@@ -4229,7 +4250,7 @@ int main(int argc, char *argv[]) {
42294250
ForceNoOutputs = true;
42304251
Args = Args.drop_front();
42314252
}
4232-
return doTestCreateCompilerInvocation(Args, ForceNoOutputs);
4253+
return doTestCreateCompilerInvocation(driverPath, Args, ForceNoOutputs);
42334254
}
42344255
}
42354256

@@ -4258,10 +4279,8 @@ int main(int argc, char *argv[]) {
42584279
}
42594280

42604281
if (options::Action == ActionType::GenerateModuleAPIDescription) {
4261-
return doGenerateModuleAPIDescription(
4262-
llvm::sys::fs::getMainExecutable(
4263-
argv[0], reinterpret_cast<void *>(&anchorForGetMainExecutable)),
4264-
options::InputFilenames);
4282+
return doGenerateModuleAPIDescription(driverPath, mainExecutablePath,
4283+
options::InputFilenames);
42654284
}
42664285

42674286
if (options::Action == ActionType::DumpCompletionCache) {
@@ -4328,9 +4347,7 @@ int main(int argc, char *argv[]) {
43284347
for (auto &File : options::InputFilenames)
43294348
InitInvok.getFrontendOptions().InputsAndOutputs.addInputFile(File);
43304349

4331-
InitInvok.setMainExecutablePath(
4332-
llvm::sys::fs::getMainExecutable(argv[0],
4333-
reinterpret_cast<void *>(&anchorForGetMainExecutable)));
4350+
InitInvok.setMainExecutablePath(mainExecutablePath);
43344351
InitInvok.setModuleName(options::ModuleName);
43354352

43364353
InitInvok.setSDKPath(options::SDK);

0 commit comments

Comments
 (0)