1 | //===-- llvm-driver.cpp ---------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/ADT/StringExtras.h" |
10 | #include "llvm/ADT/StringRef.h" |
11 | #include "llvm/Support/CommandLine.h" |
12 | #include "llvm/Support/ErrorHandling.h" |
13 | #include "llvm/Support/InitLLVM.h" |
14 | #include "llvm/Support/LLVMDriver.h" |
15 | #include "llvm/Support/Path.h" |
16 | #include "llvm/Support/WithColor.h" |
17 | |
18 | using namespace llvm; |
19 | |
20 | #define LLVM_DRIVER_TOOL(tool, entry) \ |
21 | int entry##_main(int argc, char **argv, const llvm::ToolContext &); |
22 | #include "LLVMDriverTools.def" |
23 | |
24 | constexpr char subcommands[] = |
25 | #define LLVM_DRIVER_TOOL(tool, entry) " " tool "\n" |
26 | #include "LLVMDriverTools.def" |
27 | ; |
28 | |
29 | static void printHelpMessage() { |
30 | llvm::outs() << "OVERVIEW: llvm toolchain driver\n\n" |
31 | << "USAGE: llvm [subcommand] [options]\n\n" |
32 | << "SUBCOMMANDS:\n\n" |
33 | << subcommands |
34 | << "\n Type \"llvm <subcommand> --help\" to get more help on a " |
35 | "specific subcommand\n\n" |
36 | << "OPTIONS:\n\n --help - Display this message" ; |
37 | } |
38 | |
39 | static int findTool(int Argc, char **Argv, const char *Argv0) { |
40 | if (!Argc) { |
41 | printHelpMessage(); |
42 | return 1; |
43 | } |
44 | |
45 | StringRef ToolName = Argv[0]; |
46 | |
47 | if (ToolName == "--help" ) { |
48 | printHelpMessage(); |
49 | return 0; |
50 | } |
51 | |
52 | StringRef Stem = sys::path::stem(path: ToolName); |
53 | auto Is = [=](StringRef Tool) { |
54 | auto IsImpl = [=](StringRef Stem) { |
55 | auto I = Stem.rfind_insensitive(Str: Tool); |
56 | return I != StringRef::npos && (I + Tool.size() == Stem.size() || |
57 | !llvm::isAlnum(C: Stem[I + Tool.size()])); |
58 | }; |
59 | for (StringRef S : {Stem, sys::path::filename(path: ToolName)}) |
60 | if (IsImpl(S)) |
61 | return true; |
62 | return false; |
63 | }; |
64 | |
65 | auto MakeDriverArgs = [=]() -> llvm::ToolContext { |
66 | if (ToolName != Argv0) |
67 | return {.Path: Argv0, .PrependArg: ToolName.data(), .NeedsPrependArg: true}; |
68 | return {.Path: Argv0, .PrependArg: sys::path::filename(path: Argv0).data(), .NeedsPrependArg: false}; |
69 | }; |
70 | |
71 | #define LLVM_DRIVER_TOOL(tool, entry) \ |
72 | if (Is(tool)) \ |
73 | return entry##_main(Argc, Argv, MakeDriverArgs()); |
74 | #include "LLVMDriverTools.def" |
75 | |
76 | if (Is("llvm" ) || Argv0 == Argv[0]) |
77 | return findTool(Argc: Argc - 1, Argv: Argv + 1, Argv0); |
78 | |
79 | printHelpMessage(); |
80 | return 1; |
81 | } |
82 | |
83 | int main(int Argc, char **Argv) { |
84 | llvm::InitLLVM X(Argc, Argv); |
85 | return findTool(Argc, Argv, Argv0: Argv[0]); |
86 | } |
87 | |