Skip to content

[5.9][SourceKit] Pass 'swiftc' path to Driver when creating frontend args #65151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/swift/Driver/FrontendUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ void ExpandResponseFilesWithRetry(llvm::StringSaver &Saver,
/// Generates the list of arguments that would be passed to the compiler
/// frontend from the given driver arguments.
///
/// \param DriverPath The path to 'swiftc'.
/// \param ArgList The driver arguments (i.e. normal arguments for \c swiftc).
/// \param Diags The DiagnosticEngine used to report any errors parsing the
/// arguments.
Expand All @@ -48,7 +49,8 @@ void ExpandResponseFilesWithRetry(llvm::StringSaver &Saver,
/// \note This function is not intended to create invocations which are
/// suitable for use in REPL or immediate modes.
bool getSingleFrontendInvocationFromDriverArguments(
ArrayRef<const char *> ArgList, DiagnosticEngine &Diags,
StringRef DriverPath, ArrayRef<const char *> ArgList,
DiagnosticEngine &Diags,
llvm::function_ref<bool(ArrayRef<const char *> FrontendArgs)> Action,
bool ForceNoOutputs = false);

Expand Down
7 changes: 5 additions & 2 deletions include/swift/IDETool/CompileInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace ide {

/// Manages \c CompilerInstance for completion like operations.
class CompileInstance {
const std::string &SwiftExecutablePath;
const std::string &RuntimeResourcePath;
const std::string &DiagnosticDocumentationPath;
const std::shared_ptr<swift::PluginRegistry> Plugins;
Expand Down Expand Up @@ -67,10 +68,12 @@ class CompileInstance {
std::shared_ptr<std::atomic<bool>> CancellationFlag);

public:
CompileInstance(const std::string &RuntimeResourcePath,
CompileInstance(const std::string &SwiftExecutablePath,
const std::string &RuntimeResourcePath,
const std::string &DiagnosticDocumentationPath,
std::shared_ptr<swift::PluginRegistry> Plugins = nullptr)
: RuntimeResourcePath(RuntimeResourcePath),
: SwiftExecutablePath(SwiftExecutablePath),
RuntimeResourcePath(RuntimeResourcePath),
DiagnosticDocumentationPath(DiagnosticDocumentationPath),
Plugins(Plugins), CachedCIInvalidated(false), CachedReuseCount(0) {}

Expand Down
4 changes: 2 additions & 2 deletions lib/Driver/FrontendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ static void removeSupplementaryOutputs(llvm::opt::ArgList &ArgList) {
}

bool swift::driver::getSingleFrontendInvocationFromDriverArguments(
ArrayRef<const char *> Argv, DiagnosticEngine &Diags,
StringRef DriverPath, ArrayRef<const char *> Argv, DiagnosticEngine &Diags,
llvm::function_ref<bool(ArrayRef<const char *> FrontendArgs)> Action,
bool ForceNoOutputs) {
SmallVector<const char *, 16> Args;
Expand Down Expand Up @@ -87,7 +87,7 @@ bool swift::driver::getSingleFrontendInvocationFromDriverArguments(
ExpandResponseFilesWithRetry(Saver, Args);

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

// Don't check for the existence of input files, since the user of the
// CompilerInvocation may wish to remap inputs to source buffers.
Expand Down
6 changes: 5 additions & 1 deletion lib/IDETool/CompileInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,14 @@ bool CompileInstance::setupCI(
DiagnosticDocumentationPath.c_str()});
args.append(origArgs.begin(), origArgs.end());

SmallString<256> driverPath(SwiftExecutablePath);
llvm::sys::path::remove_filename(driverPath);
llvm::sys::path::append(driverPath, "swiftc");

CompilerInvocation invocation;
bool invocationCreationFailed =
driver::getSingleFrontendInvocationFromDriverArguments(
args, Diags,
driverPath, args, Diags,
[&](ArrayRef<const char *> FrontendArgs) {
return invocation.parseArgs(FrontendArgs, Diags);
},
Expand Down
7 changes: 6 additions & 1 deletion lib/IDETool/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,14 @@ bool ide::initCompilerInvocation(
StreamDiagConsumer DiagConsumer(ErrOS);
Diags.addConsumer(DiagConsumer);

// Derive 'swiftc' path from 'swift-frontend' path (swiftExecutablePath).
SmallString<256> driverPath(swiftExecutablePath);
llvm::sys::path::remove_filename(driverPath);
llvm::sys::path::append(driverPath, "swiftc");

bool InvocationCreationFailed =
driver::getSingleFrontendInvocationFromDriverArguments(
Args, Diags,
driverPath, Args, Diags,
[&](ArrayRef<const char *> FrontendArgs) {
return Invocation.parseArgs(
FrontendArgs, Diags, /*ConfigurationFileBuffers=*/nullptr,
Expand Down
47 changes: 47 additions & 0 deletions test/SourceKit/Macros/macro_option_set.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

@OptionSet<UInt8>
struct ShippingOptions {
private enum Options: Int {
case nextDay
case secondDay
case priority
case standard
}

static let express: ShippingOptions = [.nextDay, .secondDay]
static let all: ShippingOptions = [.express, .priority, .standard]
}

func test(opts: ShippingOptions) {
let _ = ShippingOptions.nextDay
}

// REQUIRES: swift_swift_parser

// RUN: %empty-directory(%t)
// RUN: %sourcekitd-test \
// RUN: -shell -- echo '## DIAGS ##' == \
// RUN: -req=diags %s -- %s ==\
// RUN: -shell -- echo '## CURSOR ##' == \
// RUN: -req=cursor -pos=16:27 %s -- %s == \
// RUN: -shell -- echo '## COMPLETE ##' == \
// RUN: -req=complete -pos=16:27 %s -- %s == \
// RUN: -shell -- echo '## COMPILE ##' == \
// RUN: -req=compile -name test -- -c %s -module-name TestModule -o %t/out.o \
// RUN: | %FileCheck %s

// CHECK-LABEL: ## DIAGS ##
// CHECK: key.diagnostics: [
// CHECK-NEXT: ]

// CHECK-LABEL: ## CURSOR ##
// CHECK: source.lang.swift.ref.var.static

// CHECK-LABEL: ## COMPLETE ##
// CHECK: key.results: [
// CHECK: key.description: "secondDay"

// CHECK-LABEL: ## COMPILE ##
// CHECK: key.diagnostics: [
// CHECK-NEXT: ],
// CHECK: key.value: 0
7 changes: 4 additions & 3 deletions tools/SourceKit/lib/SwiftLang/SwiftCompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ compile::SessionManager::getSession(StringRef name) {
}

bool inserted = false;
std::tie(i, inserted) = sessions.try_emplace(
name, std::make_shared<compile::Session>(
RuntimeResourcePath, DiagnosticDocumentationPath, Plugins));
std::tie(i, inserted) =
sessions.try_emplace(name, std::make_shared<compile::Session>(
SwiftExecutablePath, RuntimeResourcePath,
DiagnosticDocumentationPath, Plugins));
assert(inserted);
return i->second;
}
Expand Down
3 changes: 2 additions & 1 deletion tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,8 @@ SwiftLangSupport::SwiftLangSupport(SourceKit::Context &SKCtx)
SKCtx.getGlobalConfiguration());

CompileManager = std::make_shared<compile::SessionManager>(
RuntimeResourcePath, DiagnosticDocumentationPath, Plugins);
SwiftExecutablePath, RuntimeResourcePath, DiagnosticDocumentationPath,
Plugins);

// By default, just use the in-memory cache.
CCCache->inMemory = std::make_unique<ide::CodeCompletionCache>();
Expand Down
17 changes: 11 additions & 6 deletions tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,12 @@ class Session {
swift::ide::CompileInstance Compiler;

public:
Session(const std::string &RuntimeResourcePath,
Session(const std::string &SwiftExecutablePath,
const std::string &RuntimeResourcePath,
const std::string &DiagnosticDocumentationPath,
std::shared_ptr<swift::PluginRegistry> Plugins)
: Compiler(RuntimeResourcePath, DiagnosticDocumentationPath, Plugins) {}
: Compiler(SwiftExecutablePath, RuntimeResourcePath,
DiagnosticDocumentationPath, Plugins) {}

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

class SessionManager {
const std::string &SwiftExecutablePath;
const std::string &RuntimeResourcePath;
const std::string &DiagnosticDocumentationPath;
const std::shared_ptr<swift::PluginRegistry> Plugins;
Expand All @@ -317,10 +320,12 @@ class SessionManager {
mutable llvm::sys::Mutex mtx;

public:
SessionManager(std::string &RuntimeResourcePath,
std::string &DiagnosticDocumentationPath,
std::shared_ptr<swift::PluginRegistry> Plugins)
: RuntimeResourcePath(RuntimeResourcePath),
SessionManager(const std::string &SwiftExecutablePath,
const std::string &RuntimeResourcePath,
const std::string &DiagnosticDocumentationPath,
const std::shared_ptr<swift::PluginRegistry> Plugins)
: SwiftExecutablePath(SwiftExecutablePath),
RuntimeResourcePath(RuntimeResourcePath),
DiagnosticDocumentationPath(DiagnosticDocumentationPath),
Plugins(Plugins) {}

Expand Down
11 changes: 6 additions & 5 deletions tools/swift-ide-test/ModuleAPIDiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,8 @@ std::shared_ptr<sma::Module> createSMAModel(ModuleDecl *M) {

} // unnamed namespace

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

CompilerInvocation Invocation;
bool HadError = driver::getSingleFrontendInvocationFromDriverArguments(
CStringArgs, Diags, [&](ArrayRef<const char *> FrontendArgs) {
return Invocation.parseArgs(FrontendArgs, Diags);
});
MainExecutablePath, CStringArgs, Diags,
[&](ArrayRef<const char *> FrontendArgs) {
return Invocation.parseArgs(FrontendArgs, Diags);
});

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

return 0;
}

3 changes: 2 additions & 1 deletion tools/swift-ide-test/ModuleAPIDiff.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

namespace swift {

int doGenerateModuleAPIDescription(StringRef MainExecutablePath,
int doGenerateModuleAPIDescription(StringRef DriverPath,
StringRef MainExecutablePath,
ArrayRef<std::string> Args);

} // end namespace swift
Expand Down
51 changes: 34 additions & 17 deletions tools/swift-ide-test/swift-ide-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4169,22 +4169,26 @@ static int doPrintUSRs(const CompilerInvocation &InitInvok,
return 0;
}

static int doTestCreateCompilerInvocation(ArrayRef<const char *> Args, bool ForceNoOutputs) {
static int doTestCreateCompilerInvocation(StringRef DriverPath,
ArrayRef<const char *> Args,
bool ForceNoOutputs) {
PrintingDiagnosticConsumer PDC;
SourceManager SM;
DiagnosticEngine Diags(SM);
Diags.addConsumer(PDC);

CompilerInvocation CI;
bool HadError = driver::getSingleFrontendInvocationFromDriverArguments(
Args, Diags, [&](ArrayRef<const char *> FrontendArgs) {
llvm::outs() << "Frontend Arguments BEGIN\n";
for (const char *arg : FrontendArgs) {
llvm::outs() << arg << "\n";
}
llvm::outs() << "Frontend Arguments END\n";
return CI.parseArgs(FrontendArgs, Diags);
}, ForceNoOutputs);
DriverPath, Args, Diags,
[&](ArrayRef<const char *> FrontendArgs) {
llvm::outs() << "Frontend Arguments BEGIN\n";
for (const char *arg : FrontendArgs) {
llvm::outs() << arg << "\n";
}
llvm::outs() << "Frontend Arguments END\n";
return CI.parseArgs(FrontendArgs, Diags);
},
ForceNoOutputs);

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

// Derive 'swiftc' path from 'swift-ide-test' path.
std::string getDriverPath(StringRef MainExecutablePath) {
SmallString<256> driverPath(MainExecutablePath);
llvm::sys::path::remove_filename(driverPath); // remove 'swift-ide-test'.
llvm::sys::path::remove_filename(driverPath); // remove 'bin'.
if (llvm::sys::path::filename(driverPath) == "local") {
llvm::sys::path::remove_filename(driverPath); // remove 'local'.
}
llvm::sys::path::append(driverPath, "bin", "swiftc");
return std::string(driverPath);
}

int main(int argc, char *argv[]) {
PROGRAM_START(argc, argv);
INITIALIZE_LLVM();
initializeSwiftModules();

std::string mainExecutablePath = llvm::sys::fs::getMainExecutable(
argv[0], reinterpret_cast<void *>(&anchorForGetMainExecutable));

std::string driverPath = getDriverPath(mainExecutablePath);

if (argc > 1) {
// Handle integrated test tools which do not use
// llvm::cl::ParseCommandLineOptions.
Expand All @@ -4229,7 +4250,7 @@ int main(int argc, char *argv[]) {
ForceNoOutputs = true;
Args = Args.drop_front();
}
return doTestCreateCompilerInvocation(Args, ForceNoOutputs);
return doTestCreateCompilerInvocation(driverPath, Args, ForceNoOutputs);
}
}

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

if (options::Action == ActionType::GenerateModuleAPIDescription) {
return doGenerateModuleAPIDescription(
llvm::sys::fs::getMainExecutable(
argv[0], reinterpret_cast<void *>(&anchorForGetMainExecutable)),
options::InputFilenames);
return doGenerateModuleAPIDescription(driverPath, mainExecutablePath,
options::InputFilenames);
}

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

InitInvok.setMainExecutablePath(
llvm::sys::fs::getMainExecutable(argv[0],
reinterpret_cast<void *>(&anchorForGetMainExecutable)));
InitInvok.setMainExecutablePath(mainExecutablePath);
InitInvok.setModuleName(options::ModuleName);

InitInvok.setSDKPath(options::SDK);
Expand Down