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.isOSFreeBSD() ||
54 Triple.isOSOpenBSD() ||
55 Triple.isOSNetBSD() ||
56 Triple.getOS() == llvm::Triple::Darwin) {
57 if (Triple.getArch() != llvm::Triple::x86_64) {
58 D.
Diag(diag::err_drv_clang_unsupported)
59 << (std::string(XRayInstrumentOption) +
" on " + Triple.str());
61 }
else if (Triple.getOS() == llvm::Triple::Fuchsia) {
62 switch (Triple.getArch()) {
63 case llvm::Triple::x86_64:
64 case llvm::Triple::aarch64:
67 D.
Diag(diag::err_drv_clang_unsupported)
68 << (std::string(XRayInstrumentOption) +
" on " + Triple.str());
71 D.
Diag(diag::err_drv_clang_unsupported)
72 << (std::string(XRayInstrumentOption) +
" on " + Triple.str());
74 XRayInstrument =
true;
76 Args.getLastArg(options::OPT_fxray_instruction_threshold_,
77 options::OPT_fxray_instruction_threshold_EQ)) {
78 StringRef S = A->getValue();
79 if (S.getAsInteger(0, InstructionThreshold) || InstructionThreshold < 0)
80 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
87 if (Args.hasFlag(options::OPT_fxray_always_emit_customevents,
88 options::OPT_fnoxray_always_emit_customevents,
false))
89 XRayAlwaysEmitCustomEvents =
true;
91 if (Args.hasFlag(options::OPT_fxray_always_emit_typedevents,
92 options::OPT_fnoxray_always_emit_typedevents,
false))
93 XRayAlwaysEmitTypedEvents =
true;
95 if (!Args.hasFlag(options::OPT_fxray_link_deps,
96 options::OPT_fnoxray_link_deps,
true))
100 Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
104 for (
const auto &B : Bundles) {
106 llvm::SplitString(B, BundleParts,
",");
107 for (
const auto &
P : BundleParts) {
109 auto Valid = llvm::StringSwitch<bool>(
P)
110 .Cases(
"none",
"all",
"function",
"custom",
true)
114 D.
Diag(clang::diag::err_drv_invalid_value)
115 <<
"-fxray-instrumentation-bundle=" <<
P;
121 InstrumentationBundle.clear();
125 InstrumentationBundle.Mask |= Mask;
132 Args.getAllArgValues(options::OPT_fxray_always_instrument)) {
133 if (llvm::sys::fs::exists(
Filename)) {
134 AlwaysInstrumentFiles.push_back(
Filename);
141 Args.getAllArgValues(options::OPT_fxray_never_instrument)) {
142 if (llvm::sys::fs::exists(
Filename)) {
143 NeverInstrumentFiles.push_back(
Filename);
150 Args.getAllArgValues(options::OPT_fxray_attr_list)) {
151 if (llvm::sys::fs::exists(
Filename)) {
159 auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes);
160 if (SpecifiedModes.empty())
161 llvm::copy(XRaySupportedModes, std::back_inserter(Modes));
163 for (
const auto &Arg : SpecifiedModes) {
166 llvm::SplitString(Arg, ModeParts,
",");
167 for (
const auto &M : ModeParts)
171 llvm::copy(XRaySupportedModes, std::back_inserter(Modes));
178 Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end());
183 ArgStringList &CmdArgs,
types::ID InputType)
const {
187 CmdArgs.push_back(XRayInstrumentOption);
189 if (XRayAlwaysEmitCustomEvents)
190 CmdArgs.push_back(
"-fxray-always-emit-customevents");
192 if (XRayAlwaysEmitTypedEvents)
193 CmdArgs.push_back(
"-fxray-always-emit-typedevents");
195 CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
196 Twine(InstructionThreshold)));
198 for (
const auto &Always : AlwaysInstrumentFiles) {
200 AlwaysInstrumentOpt += Always;
201 CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));
204 for (
const auto &Never : NeverInstrumentFiles) {
206 NeverInstrumentOpt += Never;
207 CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
210 for (
const auto &AttrFile : AttrListFiles) {
212 AttrListFileOpt += AttrFile;
213 CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt));
216 for (
const auto &Dep : ExtraDeps) {
219 CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
222 for (
const auto &Mode : Modes) {
225 CmdArgs.push_back(Args.MakeArgString(ModeOpt));
229 if (InstrumentationBundle.full()) {
231 }
else if (InstrumentationBundle.empty()) {
235 Bundle +=
"function";
241 CmdArgs.push_back(Args.MakeArgString(Bundle));
constexpr XRayInstrMask Typed
constexpr XRayInstrMask Function
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 Custom
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)