13#include "llvm/ADT/StringExtras.h"
14#include "llvm/ADT/StringSwitch.h"
15#include "llvm/Support/SpecialCaseList.h"
16#include "llvm/Support/VirtualFileSystem.h"
26 const llvm::Triple &Triple = TC.
getTriple();
27 if (!Args.hasFlag(options::OPT_fxray_instrument,
28 options::OPT_fno_xray_instrument,
false))
30 XRayInstrument = Args.getLastArg(options::OPT_fxray_instrument);
31 if (Triple.isMacOSX()) {
32 switch (Triple.getArch()) {
33 case llvm::Triple::aarch64:
34 case llvm::Triple::x86_64:
37 D.Diag(diag::err_drv_unsupported_opt_for_target)
38 << XRayInstrument->getSpelling() << Triple.str();
41 }
else if (Triple.isOSBinFormatELF()) {
42 switch (Triple.getArch()) {
43 case llvm::Triple::x86_64:
44 case llvm::Triple::arm:
45 case llvm::Triple::aarch64:
46 case llvm::Triple::hexagon:
47 case llvm::Triple::ppc64le:
48 case llvm::Triple::loongarch64:
49 case llvm::Triple::mips:
50 case llvm::Triple::mipsel:
51 case llvm::Triple::mips64:
52 case llvm::Triple::mips64el:
53 case llvm::Triple::systemz:
54 case llvm::Triple::riscv32:
55 case llvm::Triple::riscv64:
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();
66 if (Args.hasFlag(options::OPT_fxray_shared, options::OPT_fno_xray_shared,
71 switch (Triple.getArch()) {
72 case llvm::Triple::aarch64:
73 case llvm::Triple::x86_64:
76 D.Diag(diag::err_drv_unsupported_opt_for_target)
77 <<
"-fxray-shared" << Triple.str();
82 D.Diag(diag::err_opt_not_valid_without_opt) <<
"-fxray-shared"
89 if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ))
90 D.Diag(diag::err_drv_argument_not_allowed_with)
91 << XRayInstrument->getSpelling() << A->getSpelling();
93 if (!Args.hasFlag(options::OPT_fxray_link_deps,
94 options::OPT_fno_xray_link_deps,
true))
98 Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
102 for (
const auto &B : Bundles) {
104 llvm::SplitString(B, BundleParts,
",");
105 for (
const auto &
P : BundleParts) {
107 auto Valid = llvm::StringSwitch<bool>(
P)
108 .Cases(
"none",
"all",
"function",
"function-entry",
109 "function-exit",
"custom",
true)
113 D.Diag(clang::diag::err_drv_invalid_value)
114 <<
"-fxray-instrumentation-bundle=" <<
P;
120 InstrumentationBundle.
clear();
124 InstrumentationBundle.
Mask |= Mask;
131 Args.getAllArgValues(options::OPT_fxray_always_instrument)) {
133 AlwaysInstrumentFiles.push_back(
Filename);
136 D.Diag(clang::diag::err_drv_no_such_file) <<
Filename;
140 Args.getAllArgValues(options::OPT_fxray_never_instrument)) {
142 NeverInstrumentFiles.push_back(
Filename);
145 D.Diag(clang::diag::err_drv_no_such_file) <<
Filename;
149 Args.getAllArgValues(options::OPT_fxray_attr_list)) {
154 D.Diag(clang::diag::err_drv_no_such_file) <<
Filename;
158 auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes);
159 if (SpecifiedModes.empty())
162 for (
const auto &Arg : SpecifiedModes) {
165 llvm::SplitString(Arg, ModeParts,
",");
166 for (
const auto &M : ModeParts)
172 Modes.push_back(std::string(M));
177 Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end());
181 ArgStringList &CmdArgs,
types::ID InputType)
const {
185 XRayInstrument->render(Args, CmdArgs);
191 Args.addOptInFlag(CmdArgs, options::OPT_fxray_always_emit_customevents,
192 options::OPT_fno_xray_always_emit_customevents);
194 Args.addOptInFlag(CmdArgs, options::OPT_fxray_always_emit_typedevents,
195 options::OPT_fno_xray_always_emit_typedevents);
196 Args.addOptInFlag(CmdArgs, options::OPT_fxray_ignore_loops,
197 options::OPT_fno_xray_ignore_loops);
198 Args.addOptOutFlag(CmdArgs, options::OPT_fxray_function_index,
199 options::OPT_fno_xray_function_index);
202 Args.addOptInFlag(CmdArgs, options::OPT_fxray_shared,
203 options::OPT_fno_xray_shared);
206 Args.getLastArg(options::OPT_fxray_instruction_threshold_EQ)) {
208 StringRef S = A->getValue();
210 D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
212 A->render(Args, CmdArgs);
215 int XRayFunctionGroups = 1;
216 int XRaySelectedFunctionGroup = 0;
217 if (
const Arg *A = Args.getLastArg(options::OPT_fxray_function_groups)) {
218 StringRef S = A->getValue();
219 if (S.getAsInteger(0, XRayFunctionGroups) || XRayFunctionGroups < 1)
220 D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
221 if (XRayFunctionGroups > 1)
222 A->render(Args, CmdArgs);
225 Args.getLastArg(options::OPT_fxray_selected_function_group)) {
226 StringRef S = A->getValue();
227 if (S.getAsInteger(0, XRaySelectedFunctionGroup) ||
228 XRaySelectedFunctionGroup < 0 ||
229 XRaySelectedFunctionGroup >= XRayFunctionGroups)
230 D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
231 if (XRaySelectedFunctionGroup != 0)
232 A->render(Args, CmdArgs);
235 for (
const auto &Always : AlwaysInstrumentFiles) {
237 AlwaysInstrumentOpt += Always;
238 CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));
241 for (
const auto &
Never : NeverInstrumentFiles) {
243 NeverInstrumentOpt +=
Never;
244 CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
247 for (
const auto &AttrFile : AttrListFiles) {
249 AttrListFileOpt += AttrFile;
250 CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt));
253 for (
const auto &Dep : ExtraDeps) {
256 CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
259 for (
const auto &Mode : Modes) {
262 CmdArgs.push_back(Args.MakeArgString(ModeOpt));
266 if (InstrumentationBundle.
full()) {
268 }
else if (InstrumentationBundle.
empty()) {
273 Bundle +=
"function";
275 Bundle +=
"function-entry";
277 Bundle +=
"function-exit";
284 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