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() ||
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());
76 if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ))
77 D.
Diag(diag::err_drv_argument_not_allowed_with)
78 <<
"-fxray-instrument" << A->getSpelling();
80 XRayInstrument =
true;
82 Args.getLastArg(options::OPT_fxray_instruction_threshold_,
83 options::OPT_fxray_instruction_threshold_EQ)) {
84 StringRef S = A->getValue();
85 if (S.getAsInteger(0, InstructionThreshold) || InstructionThreshold < 0)
86 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
93 if (Args.hasFlag(options::OPT_fxray_always_emit_customevents,
94 options::OPT_fnoxray_always_emit_customevents,
false))
95 XRayAlwaysEmitCustomEvents =
true;
97 if (Args.hasFlag(options::OPT_fxray_always_emit_typedevents,
98 options::OPT_fnoxray_always_emit_typedevents,
false))
99 XRayAlwaysEmitTypedEvents =
true;
101 if (!Args.hasFlag(options::OPT_fxray_link_deps,
102 options::OPT_fnoxray_link_deps,
true))
106 Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
110 for (
const auto &B : Bundles) {
112 llvm::SplitString(B, BundleParts,
",");
113 for (
const auto &
P : BundleParts) {
115 auto Valid = llvm::StringSwitch<bool>(
P)
116 .Cases(
"none",
"all",
"function",
"custom",
true)
120 D.
Diag(clang::diag::err_drv_invalid_value)
121 <<
"-fxray-instrumentation-bundle=" <<
P;
127 InstrumentationBundle.clear();
131 InstrumentationBundle.Mask |= Mask;
138 Args.getAllArgValues(options::OPT_fxray_always_instrument)) {
140 AlwaysInstrumentFiles.push_back(
Filename);
147 Args.getAllArgValues(options::OPT_fxray_never_instrument)) {
149 NeverInstrumentFiles.push_back(
Filename);
156 Args.getAllArgValues(options::OPT_fxray_attr_list)) {
165 auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes);
166 if (SpecifiedModes.empty())
167 llvm::copy(XRaySupportedModes, std::back_inserter(Modes));
169 for (
const auto &Arg : SpecifiedModes) {
172 llvm::SplitString(Arg, ModeParts,
",");
173 for (
const auto &M : ModeParts)
177 llvm::copy(XRaySupportedModes, std::back_inserter(Modes));
184 Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end());
189 ArgStringList &CmdArgs,
types::ID InputType)
const {
193 CmdArgs.push_back(XRayInstrumentOption);
195 if (XRayAlwaysEmitCustomEvents)
196 CmdArgs.push_back(
"-fxray-always-emit-customevents");
198 if (XRayAlwaysEmitTypedEvents)
199 CmdArgs.push_back(
"-fxray-always-emit-typedevents");
201 CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
202 Twine(InstructionThreshold)));
204 for (
const auto &Always : AlwaysInstrumentFiles) {
206 AlwaysInstrumentOpt += Always;
207 CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));
210 for (
const auto &
Never : NeverInstrumentFiles) {
212 NeverInstrumentOpt +=
Never;
213 CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
216 for (
const auto &AttrFile : AttrListFiles) {
218 AttrListFileOpt += AttrFile;
219 CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt));
222 for (
const auto &Dep : ExtraDeps) {
225 CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
228 for (
const auto &Mode : Modes) {
231 CmdArgs.push_back(Args.MakeArgString(ModeOpt));
235 if (InstrumentationBundle.full()) {
237 }
else if (InstrumentationBundle.empty()) {
241 Bundle +=
"function";
247 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
llvm::vfs::FileSystem & getVFS() const
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)