LLVM 24.0.0git
Driver.cpp
Go to the documentation of this file.
1//===-- 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
10
14#include "llvm/Support/Path.h"
15
16#include <cassert>
17#include <string>
18#include <system_error>
19#include <utility>
20#include <vector>
21
22using namespace llvm;
23
24namespace {
25
26bool matchesToolName(StringRef RegisteredName, StringRef InvokedName) {
27 StringRef Stem = sys::path::stem(InvokedName);
29 auto Matches = [RegisteredName](StringRef Candidate) {
30 size_t Position = Candidate.rfind_insensitive(RegisteredName);
31 return Position != StringRef::npos &&
32 (Position + RegisteredName.size() == Candidate.size() ||
33 !llvm::isAlnum(Candidate[Position + RegisteredName.size()]));
34 };
35 return Matches(Stem) || Matches(Filename);
36}
37
38bool isMulticallName(StringRef Name) { return matchesToolName("llvm", Name); }
39
40} // namespace
41
44 std::string ExecutablePath;
45 std::vector<std::pair<std::string, ToolMainFn>> Tools;
46
47 Impl(int &Argc, char **&Argv, ArrayRef<CallableTool> RegisteredTools,
48 bool InstallPipeSignalExitHandler, bool NeedsPOSIXUtilitySignalHandling)
49 : Initialization(Argc, Argv, InstallPipeSignalExitHandler,
50 NeedsPOSIXUtilitySignalHandling),
51 ExecutablePath(Argv[0]) {
52 Tools.reserve(RegisteredTools.size());
53 for (const CallableTool &Tool : RegisteredTools)
54 Tools.emplace_back(Tool.Name.str(), Tool.Main);
55 }
56};
57
58ToolSession::ToolSession(int &Argc, char **&Argv, ArrayRef<CallableTool> Tools,
59 bool InstallPipeSignalExitHandler,
60 bool NeedsPOSIXUtilitySignalHandling) {
61 assert(Argc > 0 && Argv && Argv[0] && "ToolSession requires a valid argv[0]");
62 PImpl =
63 std::make_unique<Impl>(Argc, Argv, Tools, InstallPipeSignalExitHandler,
64 NeedsPOSIXUtilitySignalHandling);
65}
66
68
69ErrorOr<CallableTool> ToolSession::findTool(StringRef Name) const {
70 StringRef Stem = sys::path::stem(Name);
72 for (const auto &[RegisteredName, Main] : PImpl->Tools)
73 if (Stem.equals_insensitive(RegisteredName) ||
74 Filename.equals_insensitive(RegisteredName))
75 return CallableTool{RegisteredName, Main};
76
77 for (const auto &[RegisteredName, Main] : PImpl->Tools)
78 if (matchesToolName(RegisteredName, Name))
79 return CallableTool{RegisteredName, Main};
80 return make_error_code(std::errc::no_such_file_or_directory);
81}
82
83ToolContext ToolSession::makeContext(StringRef RegisteredName,
84 const char *PrependArg) {
85 ErrorOr<CallableTool> ExecutableTool = findTool(PImpl->ExecutablePath);
86 bool NeedsPrependArg =
87 !ExecutableTool ||
88 !ExecutableTool->Name.equals_insensitive(RegisteredName);
89 ToolContext Context(PImpl->ExecutablePath.c_str(), PrependArg,
90 NeedsPrependArg);
91 Context.Session = this;
92 return Context;
93}
94
96 if (Args.empty())
97 return make_error_code(std::errc::invalid_argument);
98
99 StringRef InvokedName = Args.front();
100 ErrorOr<CallableTool> Tool = findTool(InvokedName);
101 if (!Tool) {
102 if (InvokedName != PImpl->ExecutablePath && !isMulticallName(InvokedName))
103 return make_error_code(std::errc::no_such_file_or_directory);
104 Args = Args.drop_front();
105 if (Args.empty())
106 return make_error_code(std::errc::invalid_argument);
107 InvokedName = Args.front();
108 Tool = findTool(InvokedName);
109 }
110
111 if (!Tool)
112 return Tool.getError();
113
114 std::string PrependArg = sys::path::stem(InvokedName).str();
115 ToolContext Context = makeContext(Tool->Name, PrependArg.c_str());
116 SmallVector<char *, 16> MutableArgs;
117 MutableArgs.reserve(Args.size() + 1);
118 for (const char *Arg : Args)
119 MutableArgs.push_back(const_cast<char *>(Arg));
120 MutableArgs.push_back(nullptr);
121 return Tool->Main(Args.size(), MutableArgs.data(), Context);
122}
123
125 if (!Session)
126 return make_error_code(std::errc::operation_not_permitted);
127 return Session->findTool(Name);
128}
129
131 if (!Session)
132 return make_error_code(std::errc::operation_not_permitted);
133 return Session->callTool(Args);
134}
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static constexpr StringLiteral Filename
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
Represents either an error or a value T.
Definition ErrorOr.h:56
std::error_code getError() const
Definition ErrorOr.h:152
void reserve(size_type N)
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
static constexpr size_t npos
Definition StringRef.h:58
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
Definition StringRef.h:170
Describes how a tool was invoked and provides access to its host session.
Definition Driver.h:36
LLVM_ABI ErrorOr< int > callTool(ArrayRef< const char * > Args) const
Invokes another tool registered with the same host session.
Definition Driver.cpp:130
LLVM_ABI ErrorOr< CallableTool > getCallableTool(StringRef Name) const
Finds a tool registered with the session that owns this context.
Definition Driver.cpp:124
ToolSession(int &Argc, char **&Argv, ArrayRef< CallableTool > Tools, bool InstallPipeSignalExitHandler=true, bool NeedsPOSIXUtilitySignalHandling=false)
Definition Driver.cpp:58
ErrorOr< int > callTool(ArrayRef< const char * > Args)
Invokes the tool named by Args[0].
Definition Driver.cpp:95
friend class ToolContext
Definition Driver.h:91
LLVM_ABI StringRef stem(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get stem.
Definition Path.cpp:596
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition Path.cpp:594
This is an optimization pass for GlobalISel generic memory operations.
std::error_code make_error_code(BitcodeError E)
bool isAlnum(char C)
Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...
std::vector< std::pair< std::string, ToolMainFn > > Tools
Definition Driver.cpp:45
std::string ExecutablePath
Definition Driver.cpp:44
Impl(int &Argc, char **&Argv, ArrayRef< CallableTool > RegisteredTools, bool InstallPipeSignalExitHandler, bool NeedsPOSIXUtilitySignalHandling)
Definition Driver.cpp:47
An LLVM command-line tool that can be invoked without creating a process.
Definition Driver.h:28