|
|
@@ -23,11 +23,22 @@
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
#include "llvm/IR/LLVMContext.h"
|
|
|
#include "llvm/Support/FileSystem.h"
|
|
|
+#include "llvm/Support/LLVMDriver.h"
|
|
|
#include "llvm/Support/Path.h"
|
|
|
#include "llvm/Support/Program.h"
|
|
|
#include "llvm/Support/VirtualFileSystem.h"
|
|
|
#include "llvm/TargetParser/Host.h"
|
|
|
|
|
|
+// Defined in:
|
|
|
+// https://github.com/llvm/llvm-project/blob/main/clang/tools/driver/driver.cpp
|
|
|
+//
|
|
|
+// While not in a header, this is the API used by llvm-driver.cpp for
|
|
|
+// busyboxing.
|
|
|
+//
|
|
|
+// NOLINTNEXTLINE(readability-identifier-naming)
|
|
|
+auto clang_main(int Argc, char** Argv, const llvm::ToolContext& ToolContext)
|
|
|
+ -> int;
|
|
|
+
|
|
|
namespace Carbon {
|
|
|
|
|
|
ClangRunner::ClangRunner(const InstallPaths* install_paths,
|
|
|
@@ -51,7 +62,6 @@ auto ClangRunner::Run(llvm::ArrayRef<llvm::StringRef> args) -> bool {
|
|
|
maybe_v_arg = v_arg_storage;
|
|
|
}
|
|
|
|
|
|
- CARBON_CHECK(!args.empty());
|
|
|
CARBON_VLOG("Running Clang driver with arguments: \n");
|
|
|
|
|
|
// Render the arguments into null-terminated C-strings for use by the Clang
|
|
|
@@ -113,9 +123,23 @@ auto ClangRunner::Run(llvm::ArrayRef<llvm::StringRef> args) -> bool {
|
|
|
driver.Dir = installation_->llvm_install_bin();
|
|
|
CARBON_VLOG("Setting bin directory to: {0}\n", driver.Dir);
|
|
|
|
|
|
- // TODO: Directly run in-process rather than using a subprocess. This is both
|
|
|
- // more efficient and makes debugging (much) easier. Needs code like:
|
|
|
- // driver.CC1Main = [](llvm::SmallVectorImpl<const char*>& argv) {};
|
|
|
+ // When there's only one command being run, this will run it in-process.
|
|
|
+ // However, a `clang` invocation may cause multiple `cc1` invocations, which
|
|
|
+ // still subprocess. See `InProcess` comment at:
|
|
|
+ // https://github.com/llvm/llvm-project/blob/86ce8e4504c06ecc3cc42f002ad4eb05cac10925/clang/lib/Driver/Job.cpp#L411-L413
|
|
|
+ //
|
|
|
+ // TODO: It would be nice to find a way to set up the driver's understanding
|
|
|
+ // of the executable name in a way that causes the multiple `cc1` invocations
|
|
|
+ // to actually result in `carbon clang -- ...` invocations (even if as
|
|
|
+ // subprocesses). This may dovetail with having symlinks that redirect to a
|
|
|
+ // busybox of LLD as well, and having even the subprocesses consistently run
|
|
|
+ // the Carbon install toolchain and not a system toolchain whenever possible.
|
|
|
+ driver.CC1Main = [](llvm::SmallVectorImpl<const char*>& argv) -> int {
|
|
|
+ llvm::ToolContext tool_context;
|
|
|
+ return clang_main(argv.size(), const_cast<char**>(argv.data()),
|
|
|
+ tool_context);
|
|
|
+ };
|
|
|
+
|
|
|
std::unique_ptr<clang::driver::Compilation> compilation(
|
|
|
driver.BuildCompilation(cstr_args));
|
|
|
CARBON_CHECK(compilation, "Should always successfully allocate!");
|