Alexandre Ganea 3c6f47d6b8
[llvm-driver] Fix usage of InitLLVM on Windows (#76306)
Previously, some tools such as `clang` or `lld` which require strict
order for certain command-line options, such as `clang -cc1` or `lld
-flavor`, would not longer work on Windows, when these tools were linked
as part of `llvm-driver`. This was caused by `InitLLVM` which was part
of the `*_main()` function of these tools, which in turn calls
`windows::GetCommandLineArguments`. That function completly replaces
argc/argv by new UTF-8 contents, so any ajustements to argc/argv made by
`llvm-driver` prior to calling these tools was reset.

`InitLLVM` is now called by the `llvm-driver`. Any tool that
participates in (or is part of) the `llvm-driver` doesn't call
`InitLLVM` anymore.
2024-01-11 19:08:28 -05:00

87 lines
2.7 KiB
C++

//===-- llvm-driver.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/LLVMDriver.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/WithColor.h"
using namespace llvm;
#define LLVM_DRIVER_TOOL(tool, entry) \
int entry##_main(int argc, char **argv, const llvm::ToolContext &);
#include "LLVMDriverTools.def"
constexpr char subcommands[] =
#define LLVM_DRIVER_TOOL(tool, entry) " " tool "\n"
#include "LLVMDriverTools.def"
;
static void printHelpMessage() {
llvm::outs() << "OVERVIEW: llvm toolchain driver\n\n"
<< "USAGE: llvm [subcommand] [options]\n\n"
<< "SUBCOMMANDS:\n\n"
<< subcommands
<< "\n Type \"llvm <subcommand> --help\" to get more help on a "
"specific subcommand\n\n"
<< "OPTIONS:\n\n --help - Display this message";
}
static int findTool(int Argc, char **Argv, const char *Argv0) {
if (!Argc) {
printHelpMessage();
return 1;
}
StringRef ToolName = Argv[0];
if (ToolName == "--help") {
printHelpMessage();
return 0;
}
StringRef Stem = sys::path::stem(ToolName);
auto Is = [=](StringRef Tool) {
auto IsImpl = [=](StringRef Stem) {
auto I = Stem.rfind_insensitive(Tool);
return I != StringRef::npos && (I + Tool.size() == Stem.size() ||
!llvm::isAlnum(Stem[I + Tool.size()]));
};
for (StringRef S : {Stem, sys::path::filename(ToolName)})
if (IsImpl(S))
return true;
return false;
};
auto MakeDriverArgs = [=]() -> llvm::ToolContext {
if (ToolName != Argv0)
return {Argv0, ToolName.data(), true};
return {Argv0, sys::path::filename(Argv0).data(), false};
};
#define LLVM_DRIVER_TOOL(tool, entry) \
if (Is(tool)) \
return entry##_main(Argc, Argv, MakeDriverArgs());
#include "LLVMDriverTools.def"
if (Is("llvm") || Argv0 == Argv[0])
return findTool(Argc - 1, Argv + 1, Argv0);
printHelpMessage();
return 1;
}
int main(int Argc, char **Argv) {
llvm::InitLLVM X(Argc, Argv);
return findTool(Argc, Argv, Argv[0]);
}