diff --git a/testing/file_test/file_test_base.h b/testing/file_test/file_test_base.h index 081ff76bff72..eb4c4b6de210 100644 --- a/testing/file_test/file_test_base.h +++ b/testing/file_test/file_test_base.h @@ -60,7 +60,7 @@ class FileTestBase : public testing::Test { bool success; // Per-file success results. May be empty. - llvm::SmallVector> per_file_success; + llvm::SmallVector> per_file_success; }; explicit FileTestBase(llvm::StringRef test_name) : test_name_(test_name) {} diff --git a/toolchain/check/check_fuzzer.cpp b/toolchain/check/check_fuzzer.cpp index 9de206f5cfe1..15de287d9a1c 100644 --- a/toolchain/check/check_fuzzer.cpp +++ b/toolchain/check/check_fuzzer.cpp @@ -27,7 +27,7 @@ extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, /*RequiresNullTerminator=*/false))); llvm::raw_null_ostream null_ostream; - Driver driver(fs, null_ostream, null_ostream); + Driver driver(fs, "", null_ostream, null_ostream); // TODO: Get checking to a point where it can handle invalid parse trees // without crashing. diff --git a/toolchain/driver/driver.cpp b/toolchain/driver/driver.cpp index 1cf01cc62733..e829414ccc95 100644 --- a/toolchain/driver/driver.cpp +++ b/toolchain/driver/driver.cpp @@ -643,7 +643,7 @@ class Driver::CompilationUnit { Driver* driver_; SharedValueStores value_stores_; const CompileOptions& options_; - llvm::StringRef input_filename_; + std::string input_filename_; // Copied from driver_ for CARBON_VLOG. llvm::raw_pwrite_stream* vlog_stream_; @@ -677,8 +677,11 @@ auto Driver::Compile(const CompileOptions& options) -> RunResult { // TODO: Should expand this into a more rich system to search for the core // package source code. if (options.prelude_import) { + llvm::SmallString<256> prelude_file(data_dir_); + llvm::sys::path::append(prelude_file, llvm::sys::path::Style::posix, + "core/prelude.carbon"); units.push_back(std::make_unique( - this, options, &stream_consumer, "core/prelude.carbon")); + this, options, &stream_consumer, prelude_file)); } // Add the input source files. @@ -710,7 +713,7 @@ auto Driver::Compile(const CompileOptions& options) -> RunResult { for (const auto& unit : units) { result.success &= unit->success(); result.per_file_success.push_back( - {unit->input_filename(), unit->success()}); + {unit->input_filename().str(), unit->success()}); } return result; }; diff --git a/toolchain/driver/driver.h b/toolchain/driver/driver.h index 5ed8367659e2..9c8226c8ea45 100644 --- a/toolchain/driver/driver.h +++ b/toolchain/driver/driver.h @@ -27,14 +27,18 @@ class Driver { // Per-file success results. May be empty if files aren't individually // processed. - llvm::SmallVector> per_file_success; + llvm::SmallVector> per_file_success; }; // Constructs a driver with any error or informational output directed to a // specified stream. - Driver(llvm::vfs::FileSystem& fs, llvm::raw_pwrite_stream& output_stream, + Driver(llvm::vfs::FileSystem& fs, llvm::StringRef data_dir, + llvm::raw_pwrite_stream& output_stream, llvm::raw_pwrite_stream& error_stream) - : fs_(fs), output_stream_(output_stream), error_stream_(error_stream) {} + : fs_(fs), + data_dir_(data_dir), + output_stream_(output_stream), + error_stream_(error_stream) {} // Parses the given arguments into both a subcommand to select the operation // to perform and any arguments to that subcommand. @@ -61,9 +65,18 @@ class Driver { // Implements the compile subcommand of the driver. auto Compile(const CompileOptions& options) -> RunResult; + // The filesystem for source code. llvm::vfs::FileSystem& fs_; + + // The path within fs for data files. + std::string data_dir_; + + // Standard output; stdout. llvm::raw_pwrite_stream& output_stream_; + // Error output; stderr. llvm::raw_pwrite_stream& error_stream_; + + // For CARBON_VLOG. llvm::raw_pwrite_stream* vlog_stream_ = nullptr; }; diff --git a/toolchain/driver/driver_fuzzer.cpp b/toolchain/driver/driver_fuzzer.cpp index 863e6ba40da1..c5949a7123c0 100644 --- a/toolchain/driver/driver_fuzzer.cpp +++ b/toolchain/driver/driver_fuzzer.cpp @@ -68,7 +68,7 @@ extern "C" auto LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) llvm::vfs::InMemoryFileSystem fs; TestRawOstream error_stream; llvm::raw_null_ostream dest; - Driver d(fs, dest, error_stream); + Driver d(fs, "", dest, error_stream); if (!d.RunCommand(args).success) { if (error_stream.TakeStr().find("ERROR:") == std::string::npos) { llvm::errs() << "No error message on a failure!\n"; diff --git a/toolchain/driver/driver_main.cpp b/toolchain/driver/driver_main.cpp index 41533f55090e..c02ffee13d3f 100644 --- a/toolchain/driver/driver_main.cpp +++ b/toolchain/driver/driver_main.cpp @@ -8,6 +8,7 @@ #include "common/init_llvm.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Path.h" #include "toolchain/driver/driver.h" auto main(int argc, char** argv) -> int { @@ -25,7 +26,16 @@ auto main(int argc, char** argv) -> int { llvm::SmallVector args(argv + 1, argv + argc); auto fs = llvm::vfs::getRealFileSystem(); - Carbon::Driver driver(*fs, llvm::outs(), llvm::errs()); + + // Construct the data directory relative to the executable location. + static int static_for_main_addr; + std::string exe = + llvm::sys::fs::getMainExecutable(argv[0], &static_for_main_addr); + llvm::SmallString<256> data_dir(llvm::sys::path::parent_path(exe)); + llvm::sys::path::append(data_dir, llvm::sys::path::Style::posix, + "carbon.runfiles/_main/"); + + Carbon::Driver driver(*fs, data_dir, llvm::outs(), llvm::errs()); bool success = driver.RunCommand(args).success; return success ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/toolchain/driver/driver_test.cpp b/toolchain/driver/driver_test.cpp index f1d89c36539f..3a4583aeae4d 100644 --- a/toolchain/driver/driver_test.cpp +++ b/toolchain/driver/driver_test.cpp @@ -40,7 +40,7 @@ static auto ReadFile(std::filesystem::path path) -> std::string { class DriverTest : public testing::Test { protected: - DriverTest() : driver_(fs_, test_output_stream_, test_error_stream_) { + DriverTest() : driver_(fs_, "", test_output_stream_, test_error_stream_) { char* tmpdir_env = getenv("TEST_TMPDIR"); CARBON_CHECK(tmpdir_env != nullptr); test_tmpdir_ = tmpdir_env; diff --git a/toolchain/sem_ir/yaml_test.cpp b/toolchain/sem_ir/yaml_test.cpp index bf2a02682573..66b27b06cb28 100644 --- a/toolchain/sem_ir/yaml_test.cpp +++ b/toolchain/sem_ir/yaml_test.cpp @@ -35,7 +35,7 @@ TEST(SemIRTest, YAML) { "test.carbon", /*ModificationTime=*/0, llvm::MemoryBuffer::getMemBuffer("fn F() { var x: () = (); return; }"))); TestRawOstream print_stream; - Driver d(fs, print_stream, llvm::errs()); + Driver d(fs, "", print_stream, llvm::errs()); auto run_result = d.RunCommand({"compile", "--no-prelude-import", "--phase=check", "--dump-raw-sem-ir", "test.carbon"}); diff --git a/toolchain/testing/file_test.cpp b/toolchain/testing/file_test.cpp index 1134cb761bec..de0625638913 100644 --- a/toolchain/testing/file_test.cpp +++ b/toolchain/testing/file_test.cpp @@ -31,7 +31,7 @@ class ToolchainFileTest : public FileTestBase { llvm::raw_pwrite_stream& stderr) -> ErrorOr override { CARBON_RETURN_IF_ERROR(AddFile(fs, "core/prelude.carbon")); - Driver driver(fs, stdout, stderr); + Driver driver(fs, "", stdout, stderr); auto driver_result = driver.RunCommand(test_args); RunResult result{