xref: /llvm-project/llvm/tools/llvm-driver/llvm-driver.cpp (revision 1079d9c9c00822790a4226ecac5ae6fababdcac1)
1f06abbb3SChris Bieneman //===-- llvm-driver.cpp ---------------------------------------------------===//
2f06abbb3SChris Bieneman //
3f06abbb3SChris Bieneman // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f06abbb3SChris Bieneman // See https://llvm.org/LICENSE.txt for license information.
5f06abbb3SChris Bieneman // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f06abbb3SChris Bieneman //
7f06abbb3SChris Bieneman //===----------------------------------------------------------------------===//
8f06abbb3SChris Bieneman 
9f06abbb3SChris Bieneman #include "llvm/ADT/StringExtras.h"
10f06abbb3SChris Bieneman #include "llvm/ADT/StringRef.h"
11f06abbb3SChris Bieneman #include "llvm/Support/CommandLine.h"
12f06abbb3SChris Bieneman #include "llvm/Support/ErrorHandling.h"
133c6f47d6SAlexandre Ganea #include "llvm/Support/InitLLVM.h"
141f173a06SAlex Brachet #include "llvm/Support/LLVMDriver.h"
15f06abbb3SChris Bieneman #include "llvm/Support/Path.h"
16f06abbb3SChris Bieneman #include "llvm/Support/WithColor.h"
17f06abbb3SChris Bieneman 
18f06abbb3SChris Bieneman using namespace llvm;
19f06abbb3SChris Bieneman 
201f173a06SAlex Brachet #define LLVM_DRIVER_TOOL(tool, entry)                                          \
211f173a06SAlex Brachet   int entry##_main(int argc, char **argv, const llvm::ToolContext &);
22f06abbb3SChris Bieneman #include "LLVMDriverTools.def"
23f06abbb3SChris Bieneman 
24f06abbb3SChris Bieneman constexpr char subcommands[] =
25f06abbb3SChris Bieneman #define LLVM_DRIVER_TOOL(tool, entry) "  " tool "\n"
26f06abbb3SChris Bieneman #include "LLVMDriverTools.def"
27f06abbb3SChris Bieneman     ;
28f06abbb3SChris Bieneman 
29f06abbb3SChris Bieneman static void printHelpMessage() {
30f06abbb3SChris Bieneman   llvm::outs() << "OVERVIEW: llvm toolchain driver\n\n"
31f06abbb3SChris Bieneman                << "USAGE: llvm [subcommand] [options]\n\n"
32f06abbb3SChris Bieneman                << "SUBCOMMANDS:\n\n"
33f06abbb3SChris Bieneman                << subcommands
34f06abbb3SChris Bieneman                << "\n  Type \"llvm <subcommand> --help\" to get more help on a "
35f06abbb3SChris Bieneman                   "specific subcommand\n\n"
36*1079d9c9SR                << "OPTIONS:\n\n  --help - Display this message\n";
37f06abbb3SChris Bieneman }
38f06abbb3SChris Bieneman 
393e57aa30SAlex Brachet static int findTool(int Argc, char **Argv, const char *Argv0) {
40f06abbb3SChris Bieneman   if (!Argc) {
41f06abbb3SChris Bieneman     printHelpMessage();
42f06abbb3SChris Bieneman     return 1;
43f06abbb3SChris Bieneman   }
44f06abbb3SChris Bieneman 
45f06abbb3SChris Bieneman   StringRef ToolName = Argv[0];
46f06abbb3SChris Bieneman 
47f06abbb3SChris Bieneman   if (ToolName == "--help") {
48f06abbb3SChris Bieneman     printHelpMessage();
49f06abbb3SChris Bieneman     return 0;
50f06abbb3SChris Bieneman   }
51f06abbb3SChris Bieneman 
52f06abbb3SChris Bieneman   StringRef Stem = sys::path::stem(ToolName);
53f06abbb3SChris Bieneman   auto Is = [=](StringRef Tool) {
541fda6f68SAlex Brachet     auto IsImpl = [=](StringRef Stem) {
55f06abbb3SChris Bieneman       auto I = Stem.rfind_insensitive(Tool);
56f06abbb3SChris Bieneman       return I != StringRef::npos && (I + Tool.size() == Stem.size() ||
57f06abbb3SChris Bieneman                                       !llvm::isAlnum(Stem[I + Tool.size()]));
58f06abbb3SChris Bieneman     };
59693a5ca6SAlex Brachet     for (StringRef S : {Stem, sys::path::filename(ToolName)})
601fda6f68SAlex Brachet       if (IsImpl(S))
611fda6f68SAlex Brachet         return true;
621fda6f68SAlex Brachet     return false;
631fda6f68SAlex Brachet   };
64f06abbb3SChris Bieneman 
653e57aa30SAlex Brachet   auto MakeDriverArgs = [=]() -> llvm::ToolContext {
663e57aa30SAlex Brachet     if (ToolName != Argv0)
673e57aa30SAlex Brachet       return {Argv0, ToolName.data(), true};
683e57aa30SAlex Brachet     return {Argv0, sys::path::filename(Argv0).data(), false};
693e57aa30SAlex Brachet   };
703e57aa30SAlex Brachet 
71f06abbb3SChris Bieneman #define LLVM_DRIVER_TOOL(tool, entry)                                          \
72f06abbb3SChris Bieneman   if (Is(tool))                                                                \
733e57aa30SAlex Brachet     return entry##_main(Argc, Argv, MakeDriverArgs());
74f06abbb3SChris Bieneman #include "LLVMDriverTools.def"
75f06abbb3SChris Bieneman 
7692d3c329SAlex Brachet   if (Is("llvm") || Argv0 == Argv[0])
773e57aa30SAlex Brachet     return findTool(Argc - 1, Argv + 1, Argv0);
78f06abbb3SChris Bieneman 
79f06abbb3SChris Bieneman   printHelpMessage();
80f06abbb3SChris Bieneman   return 1;
81f06abbb3SChris Bieneman }
82f06abbb3SChris Bieneman 
833c6f47d6SAlexandre Ganea int main(int Argc, char **Argv) {
843c6f47d6SAlexandre Ganea   llvm::InitLLVM X(Argc, Argv);
853c6f47d6SAlexandre Ganea   return findTool(Argc, Argv, Argv[0]);
863c6f47d6SAlexandre Ganea }
87