14 #include "llvm/ADT/StringExtras.h" 15 #include "llvm/ADT/StringSwitch.h" 16 #include "llvm/Support/FileSystem.h" 17 #include "llvm/Support/Path.h" 18 #include "llvm/Support/ScopedPrinter.h" 19 #include "llvm/Support/SpecialCaseList.h" 21 using namespace clang;
26 constexpr
char XRayInstrumentOption[] =
"-fxray-instrument";
27 constexpr
char XRayInstructionThresholdOption[] =
28 "-fxray-instruction-threshold=";
29 constexpr
const char *
const XRaySupportedModes[] = {
"xray-fdr",
"xray-basic"};
34 const llvm::Triple &Triple = TC.
getTriple();
35 if (Args.hasFlag(options::OPT_fxray_instrument,
36 options::OPT_fnoxray_instrument,
false)) {
37 if (Triple.getOS() == llvm::Triple::Linux) {
38 switch (Triple.getArch()) {
39 case llvm::Triple::x86_64:
40 case llvm::Triple::arm:
41 case llvm::Triple::aarch64:
42 case llvm::Triple::ppc64le:
43 case llvm::Triple::mips:
44 case llvm::Triple::mipsel:
45 case llvm::Triple::mips64:
46 case llvm::Triple::mips64el:
49 D.
Diag(diag::err_drv_clang_unsupported)
50 << (std::string(XRayInstrumentOption) +
" on " + Triple.str());
52 }
else if (Triple.isOSFreeBSD() ||
53 Triple.isOSOpenBSD() ||
54 Triple.isOSNetBSD() ||
55 Triple.getOS() == llvm::Triple::Darwin) {
56 if (Triple.getArch() != llvm::Triple::x86_64) {
57 D.
Diag(diag::err_drv_clang_unsupported)
58 << (std::string(XRayInstrumentOption) +
" on " + Triple.str());
60 }
else if (Triple.getOS() == llvm::Triple::Fuchsia) {
61 switch (Triple.getArch()) {
62 case llvm::Triple::x86_64:
63 case llvm::Triple::aarch64:
66 D.
Diag(diag::err_drv_clang_unsupported)
67 << (std::string(XRayInstrumentOption) +
" on " + Triple.str());
70 D.
Diag(diag::err_drv_clang_unsupported)
71 << (std::string(XRayInstrumentOption) +
" on " + Triple.str());
73 XRayInstrument =
true;
75 Args.getLastArg(options::OPT_fxray_instruction_threshold_,
76 options::OPT_fxray_instruction_threshold_EQ)) {
77 StringRef S = A->getValue();
78 if (S.getAsInteger(0, InstructionThreshold) || InstructionThreshold < 0)
79 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
86 if (Args.hasFlag(options::OPT_fxray_always_emit_customevents,
87 options::OPT_fnoxray_always_emit_customevents,
false))
88 XRayAlwaysEmitCustomEvents =
true;
90 if (Args.hasFlag(options::OPT_fxray_always_emit_typedevents,
91 options::OPT_fnoxray_always_emit_typedevents,
false))
92 XRayAlwaysEmitTypedEvents =
true;
94 if (!Args.hasFlag(options::OPT_fxray_link_deps,
95 options::OPT_fnoxray_link_deps,
true))
99 Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
103 for (
const auto &B : Bundles) {
105 llvm::SplitString(B, BundleParts,
",");
106 for (
const auto &
P : BundleParts) {
108 auto Valid = llvm::StringSwitch<bool>(
P)
109 .Cases(
"none",
"all",
"function",
"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)) {
132 if (llvm::sys::fs::exists(
Filename)) {
133 AlwaysInstrumentFiles.push_back(
Filename);
140 Args.getAllArgValues(options::OPT_fxray_never_instrument)) {
141 if (llvm::sys::fs::exists(
Filename)) {
142 NeverInstrumentFiles.push_back(
Filename);
149 Args.getAllArgValues(options::OPT_fxray_attr_list)) {
150 if (llvm::sys::fs::exists(
Filename)) {
158 auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes);
159 if (SpecifiedModes.empty())
160 llvm::copy(XRaySupportedModes, std::back_inserter(Modes));
162 for (
const auto &Arg : SpecifiedModes) {
165 llvm::SplitString(Arg, ModeParts,
",");
166 for (
const auto &M : ModeParts)
170 llvm::copy(XRaySupportedModes, std::back_inserter(Modes));
177 Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end());
182 ArgStringList &CmdArgs,
types::ID InputType)
const {
186 CmdArgs.push_back(XRayInstrumentOption);
188 if (XRayAlwaysEmitCustomEvents)
189 CmdArgs.push_back(
"-fxray-always-emit-customevents");
191 if (XRayAlwaysEmitTypedEvents)
192 CmdArgs.push_back(
"-fxray-always-emit-typedevents");
194 CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
195 Twine(InstructionThreshold)));
197 for (
const auto &Always : AlwaysInstrumentFiles) {
199 AlwaysInstrumentOpt += Always;
200 CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));
203 for (
const auto &Never : NeverInstrumentFiles) {
205 NeverInstrumentOpt += Never;
206 CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
209 for (
const auto &AttrFile : AttrListFiles) {
211 AttrListFileOpt += AttrFile;
212 CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt));
215 for (
const auto &Dep : ExtraDeps) {
218 CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
221 for (
const auto &Mode : Modes) {
224 CmdArgs.push_back(Args.MakeArgString(ModeOpt));
228 if (InstrumentationBundle.full()) {
230 }
else if (InstrumentationBundle.empty()) {
234 Bundle +=
"function";
240 CmdArgs.push_back(Args.MakeArgString(Bundle));
constexpr XRayInstrMask Typed
constexpr XRayInstrMask Function
DiagnosticBuilder Diag(unsigned DiagID) const
for(auto typeArg :T->getTypeArgsAsWritten())
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
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)