15 #include "llvm/ADT/StringExtras.h" 16 #include "llvm/ADT/StringSwitch.h" 17 #include "llvm/Support/FileSystem.h" 18 #include "llvm/Support/Path.h" 19 #include "llvm/Support/ScopedPrinter.h" 20 #include "llvm/Support/SpecialCaseList.h" 22 using namespace clang;
27 constexpr
char XRayInstrumentOption[] =
"-fxray-instrument";
28 constexpr
char XRayInstructionThresholdOption[] =
29 "-fxray-instruction-threshold=";
30 constexpr
const char *
const XRaySupportedModes[] = {
"xray-fdr",
"xray-basic"};
35 const llvm::Triple &Triple = TC.
getTriple();
36 if (Args.hasFlag(options::OPT_fxray_instrument,
37 options::OPT_fnoxray_instrument,
false)) {
38 if (Triple.getOS() == llvm::Triple::Linux) {
39 switch (Triple.getArch()) {
40 case llvm::Triple::x86_64:
41 case llvm::Triple::arm:
42 case llvm::Triple::aarch64:
43 case llvm::Triple::ppc64le:
44 case llvm::Triple::mips:
45 case llvm::Triple::mipsel:
46 case llvm::Triple::mips64:
47 case llvm::Triple::mips64el:
50 D.
Diag(diag::err_drv_clang_unsupported)
51 << (std::string(XRayInstrumentOption) +
" on " + Triple.str());
53 }
else if (Triple.getOS() == llvm::Triple::FreeBSD ||
54 Triple.getOS() == llvm::Triple::OpenBSD ||
55 Triple.getOS() == llvm::Triple::NetBSD) {
56 if (Triple.getArch() != llvm::Triple::x86_64) {
57 D.
Diag(diag::err_drv_clang_unsupported)
58 << (std::string(XRayInstrumentOption) +
" on " + Triple.str());
61 D.
Diag(diag::err_drv_clang_unsupported)
62 << (std::string(XRayInstrumentOption) +
" on " + Triple.str());
64 XRayInstrument =
true;
66 Args.getLastArg(options::OPT_fxray_instruction_threshold_,
67 options::OPT_fxray_instruction_threshold_EQ)) {
68 StringRef S = A->getValue();
69 if (S.getAsInteger(0, InstructionThreshold) || InstructionThreshold < 0)
70 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
77 if (Args.hasFlag(options::OPT_fxray_always_emit_customevents,
78 options::OPT_fnoxray_always_emit_customevents,
false))
79 XRayAlwaysEmitCustomEvents =
true;
81 if (Args.hasFlag(options::OPT_fxray_always_emit_typedevents,
82 options::OPT_fnoxray_always_emit_typedevents,
false))
83 XRayAlwaysEmitTypedEvents =
true;
85 if (!Args.hasFlag(options::OPT_fxray_link_deps,
86 options::OPT_fnoxray_link_deps,
true))
90 Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
94 for (
const auto &B : Bundles) {
96 llvm::SplitString(B, BundleParts,
",");
97 for (
const auto &
P : BundleParts) {
99 auto Valid = llvm::StringSwitch<bool>(
P)
100 .Cases(
"none",
"all",
"function",
"custom",
true)
104 D.
Diag(clang::diag::err_drv_invalid_value)
105 <<
"-fxray-instrumentation-bundle=" <<
P;
111 InstrumentationBundle.clear();
115 InstrumentationBundle.Mask |= Mask;
122 Args.getAllArgValues(options::OPT_fxray_always_instrument)) {
123 if (llvm::sys::fs::exists(
Filename)) {
124 AlwaysInstrumentFiles.push_back(
Filename);
131 Args.getAllArgValues(options::OPT_fxray_never_instrument)) {
132 if (llvm::sys::fs::exists(
Filename)) {
133 NeverInstrumentFiles.push_back(
Filename);
140 Args.getAllArgValues(options::OPT_fxray_attr_list)) {
141 if (llvm::sys::fs::exists(
Filename)) {
149 auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes);
150 if (SpecifiedModes.empty())
151 llvm::copy(XRaySupportedModes, std::back_inserter(Modes));
153 for (
const auto &Arg : SpecifiedModes) {
156 llvm::SplitString(Arg, ModeParts,
",");
157 for (
const auto &M : ModeParts)
161 llvm::copy(XRaySupportedModes, std::back_inserter(Modes));
167 llvm::sort(Modes.begin(), Modes.end());
168 Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end());
173 ArgStringList &CmdArgs,
types::ID InputType)
const {
177 CmdArgs.push_back(XRayInstrumentOption);
179 if (XRayAlwaysEmitCustomEvents)
180 CmdArgs.push_back(
"-fxray-always-emit-customevents");
182 if (XRayAlwaysEmitTypedEvents)
183 CmdArgs.push_back(
"-fxray-always-emit-typedevents");
185 CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
186 Twine(InstructionThreshold)));
188 for (
const auto &Always : AlwaysInstrumentFiles) {
190 AlwaysInstrumentOpt += Always;
191 CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));
194 for (
const auto &Never : NeverInstrumentFiles) {
196 NeverInstrumentOpt += Never;
197 CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
200 for (
const auto &AttrFile : AttrListFiles) {
202 AttrListFileOpt += AttrFile;
203 CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt));
206 for (
const auto &Dep : ExtraDeps) {
209 CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
212 for (
const auto &Mode : Modes) {
215 CmdArgs.push_back(Args.MakeArgString(ModeOpt));
DiagnosticBuilder Diag(unsigned DiagID) const
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
constexpr XRayInstrMask All
for(unsigned I=0, E=TL.getNumArgs();I !=E;++I)
constexpr XRayInstrMask None
Dataflow Directional Tag Classes.
XRayArgs(const ToolChain &TC, const llvm::opt::ArgList &Args)
Parses the XRay arguments from an argument list.
XRayInstrMask parseXRayInstrValue(StringRef Value)