14#include "llvm/ADT/StringExtras.h"
15#include "llvm/ADT/StringSwitch.h"
16#include "llvm/Support/Path.h"
17#include "llvm/Support/ScopedPrinter.h"
18#include "llvm/Support/SpecialCaseList.h"
19#include "llvm/Support/VirtualFileSystem.h"
29 const llvm::Triple &Triple = TC.
getTriple();
30 if (!Args.hasFlag(options::OPT_fxray_instrument,
31 options::OPT_fno_xray_instrument,
false))
33 XRayInstrument = Args.getLastArg(options::OPT_fxray_instrument);
34 if (Triple.isMacOSX()) {
35 switch (Triple.getArch()) {
36 case llvm::Triple::aarch64:
37 case llvm::Triple::x86_64:
40 D.
Diag(diag::err_drv_unsupported_opt_for_target)
41 << XRayInstrument->getSpelling() << Triple.str();
44 }
else if (Triple.isOSBinFormatELF()) {
45 switch (Triple.getArch()) {
46 case llvm::Triple::x86_64:
47 case llvm::Triple::arm:
48 case llvm::Triple::aarch64:
49 case llvm::Triple::hexagon:
50 case llvm::Triple::ppc64le:
51 case llvm::Triple::loongarch64:
52 case llvm::Triple::mips:
53 case llvm::Triple::mipsel:
54 case llvm::Triple::mips64:
55 case llvm::Triple::mips64el:
58 D.
Diag(diag::err_drv_unsupported_opt_for_target)
59 << XRayInstrument->getSpelling() << Triple.str();
62 D.
Diag(diag::err_drv_unsupported_opt_for_target)
63 << XRayInstrument->getSpelling() << Triple.str();
68 if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ))
69 D.
Diag(diag::err_drv_argument_not_allowed_with)
70 << XRayInstrument->getSpelling() << A->getSpelling();
72 if (!Args.hasFlag(options::OPT_fxray_link_deps,
73 options::OPT_fno_xray_link_deps,
true))
77 Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
81 for (
const auto &B : Bundles) {
83 llvm::SplitString(B, BundleParts,
",");
84 for (
const auto &
P : BundleParts) {
86 auto Valid = llvm::StringSwitch<bool>(
P)
87 .Cases(
"none",
"all",
"function",
"function-entry",
88 "function-exit",
"custom",
true)
92 D.
Diag(clang::diag::err_drv_invalid_value)
93 <<
"-fxray-instrumentation-bundle=" <<
P;
99 InstrumentationBundle.
clear();
103 InstrumentationBundle.
Mask |= Mask;
110 Args.getAllArgValues(options::OPT_fxray_always_instrument)) {
112 AlwaysInstrumentFiles.push_back(
Filename);
119 Args.getAllArgValues(options::OPT_fxray_never_instrument)) {
121 NeverInstrumentFiles.push_back(
Filename);
128 Args.getAllArgValues(options::OPT_fxray_attr_list)) {
137 auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes);
138 if (SpecifiedModes.empty())
141 for (
const auto &Arg : SpecifiedModes) {
144 llvm::SplitString(Arg, ModeParts,
",");
145 for (
const auto &M : ModeParts)
151 Modes.push_back(std::string(M));
156 Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end());
160 ArgStringList &CmdArgs,
types::ID InputType)
const {
164 XRayInstrument->render(Args, CmdArgs);
170 Args.addOptInFlag(CmdArgs, options::OPT_fxray_always_emit_customevents,
171 options::OPT_fno_xray_always_emit_customevents);
173 Args.addOptInFlag(CmdArgs, options::OPT_fxray_always_emit_typedevents,
174 options::OPT_fno_xray_always_emit_typedevents);
175 Args.addOptInFlag(CmdArgs, options::OPT_fxray_ignore_loops,
176 options::OPT_fno_xray_ignore_loops);
177 Args.addOptOutFlag(CmdArgs, options::OPT_fxray_function_index,
178 options::OPT_fno_xray_function_index);
181 Args.getLastArg(options::OPT_fxray_instruction_threshold_EQ)) {
183 StringRef S = A->getValue();
185 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
187 A->render(Args, CmdArgs);
190 int XRayFunctionGroups = 1;
191 int XRaySelectedFunctionGroup = 0;
192 if (
const Arg *A = Args.getLastArg(options::OPT_fxray_function_groups)) {
193 StringRef S = A->getValue();
194 if (S.getAsInteger(0, XRayFunctionGroups) || XRayFunctionGroups < 1)
195 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
196 if (XRayFunctionGroups > 1)
197 A->render(Args, CmdArgs);
200 Args.getLastArg(options::OPT_fxray_selected_function_group)) {
201 StringRef S = A->getValue();
202 if (S.getAsInteger(0, XRaySelectedFunctionGroup) ||
203 XRaySelectedFunctionGroup < 0 ||
204 XRaySelectedFunctionGroup >= XRayFunctionGroups)
205 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
206 if (XRaySelectedFunctionGroup != 0)
207 A->render(Args, CmdArgs);
210 for (
const auto &Always : AlwaysInstrumentFiles) {
212 AlwaysInstrumentOpt += Always;
213 CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));
216 for (
const auto &
Never : NeverInstrumentFiles) {
218 NeverInstrumentOpt +=
Never;
219 CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
222 for (
const auto &AttrFile : AttrListFiles) {
224 AttrListFileOpt += AttrFile;
225 CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt));
228 for (
const auto &Dep : ExtraDeps) {
231 CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
234 for (
const auto &Mode : Modes) {
237 CmdArgs.push_back(Args.MakeArgString(ModeOpt));
241 if (InstrumentationBundle.
full()) {
243 }
else if (InstrumentationBundle.
empty()) {
248 Bundle +=
"function";
250 Bundle +=
"function-entry";
252 Bundle +=
"function-exit";
259 CmdArgs.push_back(Args.MakeArgString(Bundle));
constexpr const char * XRaySupportedModes[]
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
DiagnosticBuilder Diag(unsigned DiagID) const
llvm::vfs::FileSystem & getVFS() const
void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const
XRayArgs(const ToolChain &TC, const llvm::opt::ArgList &Args)
Parses the XRay arguments from an argument list.
constexpr XRayInstrMask Typed
constexpr XRayInstrMask FunctionExit
constexpr XRayInstrMask None
constexpr XRayInstrMask FunctionEntry
constexpr XRayInstrMask All
constexpr XRayInstrMask Custom
XRayInstrMask parseXRayInstrValue(StringRef Value)
Parses a command line argument into a mask.
void clear(XRayInstrMask K=XRayInstrKind::All)
bool has(XRayInstrMask K) const