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);
115 D.Diag(clang::diag::err_drv_no_such_file) <<
Filename;
119 Args.getAllArgValues(options::OPT_fxray_never_instrument)) {
121 NeverInstrumentFiles.push_back(
Filename);
124 D.Diag(clang::diag::err_drv_no_such_file) <<
Filename;
128 Args.getAllArgValues(options::OPT_fxray_attr_list)) {
133 D.Diag(clang::diag::err_drv_no_such_file) <<
Filename;
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...
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
The JSON file list parser is used to communicate input to InstallAPI.
XRayInstrMask parseXRayInstrValue(StringRef Value)
Parses a command line argument into a mask.
void clear(XRayInstrMask K=XRayInstrKind::All)
bool has(XRayInstrMask K) const