clang: lib/Driver/XRayArgs.cpp Source File (original) (raw)

1

2

3

4

5

6

7

13#include "llvm/ADT/StringExtras.h"

14#include "llvm/ADT/StringSwitch.h"

15#include "llvm/Support/SpecialCaseList.h"

16#include "llvm/Support/VirtualFileSystem.h"

17

18using namespace clang;

21

23

26 const llvm::Triple &Triple = TC.getTriple();

27 if (!Args.hasFlag(options::OPT_fxray_instrument,

28 options::OPT_fno_xray_instrument, false))

29 return;

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:

35 break;

36 default:

37 D.Diag(diag::err_drv_unsupported_opt_for_target)

38 << XRayInstrument->getSpelling() << Triple.str();

39 break;

40 }

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:

56 break;

57 default:

58 D.Diag(diag::err_drv_unsupported_opt_for_target)

59 << XRayInstrument->getSpelling() << Triple.str();

60 }

61 } else {

62 D.Diag(diag::err_drv_unsupported_opt_for_target)

63 << XRayInstrument->getSpelling() << Triple.str();

64 }

65

66 if (Args.hasFlag(options::OPT_fxray_shared, options::OPT_fno_xray_shared,

67 false)) {

68 XRayShared = true;

69

70

71 switch (Triple.getArch()) {

72 case llvm::Triple::aarch64:

73 case llvm::Triple::x86_64:

74 break;

75 default:

76 D.Diag(diag::err_drv_unsupported_opt_for_target)

77 << "-fxray-shared" << Triple.str();

78 }

79

81 if (!PICLvl) {

82 D.Diag(diag::err_opt_not_valid_without_opt) << "-fxray-shared"

83 << "-fPIC";

84 }

85 }

86

87

88

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();

92

93 if (!Args.hasFlag(options::OPT_fxray_link_deps,

94 options::OPT_fno_xray_link_deps, true))

95 XRayRT = false;

96

97 auto Bundles =

98 Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);

99 if (Bundles.empty())

101 else

102 for (const auto &B : Bundles) {

104 llvm::SplitString(B, BundleParts, ",");

105 for (const auto &P : BundleParts) {

106

107 auto Valid = llvm::StringSwitch(P)

108 .Cases("none", "all", "function", "function-entry",

109 "function-exit", "custom", true)

110 .Default(false);

111

112 if (!Valid) {

113 D.Diag(clang::diag::err_drv_invalid_value)

114 << "-fxray-instrumentation-bundle=" << P;

115 continue;

116 }

117

120 InstrumentationBundle.clear();

121 break;

122 }

123

124 InstrumentationBundle.Mask |= Mask;

125 }

126 }

127

128

129

131 Args.getAllArgValues(options::OPT_fxray_always_instrument)) {

132 if (D.getVFS().exists(Filename)) {

133 AlwaysInstrumentFiles.push_back(Filename);

134 ExtraDeps.push_back(Filename);

135 } else

136 D.Diag(clang::diag::err_drv_no_such_file) << Filename;

137 }

138

140 Args.getAllArgValues(options::OPT_fxray_never_instrument)) {

141 if (D.getVFS().exists(Filename)) {

142 NeverInstrumentFiles.push_back(Filename);

143 ExtraDeps.push_back(Filename);

144 } else

145 D.Diag(clang::diag::err_drv_no_such_file) << Filename;

146 }

147

149 Args.getAllArgValues(options::OPT_fxray_attr_list)) {

150 if (D.getVFS().exists(Filename)) {

151 AttrListFiles.push_back(Filename);

152 ExtraDeps.push_back(Filename);

153 } else

154 D.Diag(clang::diag::err_drv_no_such_file) << Filename;

155 }

156

157

158 auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes);

159 if (SpecifiedModes.empty())

161 else

162 for (const auto &Arg : SpecifiedModes) {

163

165 llvm::SplitString(Arg, ModeParts, ",");

166 for (const auto &M : ModeParts)

167 if (M == "none")

168 Modes.clear();

169 else if (M == "all")

171 else

172 Modes.push_back(std::string(M));

173 }

174

175

176 llvm::sort(Modes);

177 Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end());

178}

179

181 ArgStringList &CmdArgs, types::ID InputType) const {

182 if (!XRayInstrument)

183 return;

185 XRayInstrument->render(Args, CmdArgs);

186

187

188

189

190

191 Args.addOptInFlag(CmdArgs, options::OPT_fxray_always_emit_customevents,

192 options::OPT_fno_xray_always_emit_customevents);

193

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);

200

201 if (XRayShared)

202 Args.addOptInFlag(CmdArgs, options::OPT_fxray_shared,

203 options::OPT_fno_xray_shared);

204

205 if (const Arg *A =

206 Args.getLastArg(options::OPT_fxray_instruction_threshold_EQ)) {

208 StringRef S = A->getValue();

209 if (S.getAsInteger(0, Value) || Value < 0)

210 D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;

211 else

212 A->render(Args, CmdArgs);

213 }

214

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);

223 }

224 if (const Arg *A =

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);

233 }

234

235 for (const auto &Always : AlwaysInstrumentFiles) {

236 SmallString<64> AlwaysInstrumentOpt("-fxray-always-instrument=");

237 AlwaysInstrumentOpt += Always;

238 CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));

239 }

240

241 for (const auto &Never : NeverInstrumentFiles) {

242 SmallString<64> NeverInstrumentOpt("-fxray-never-instrument=");

243 NeverInstrumentOpt += Never;

244 CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));

245 }

246

247 for (const auto &AttrFile : AttrListFiles) {

249 AttrListFileOpt += AttrFile;

250 CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt));

251 }

252

253 for (const auto &Dep : ExtraDeps) {

255 ExtraDepOpt += Dep;

256 CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));

257 }

258

259 for (const auto &Mode : Modes) {

261 ModeOpt += Mode;

262 CmdArgs.push_back(Args.MakeArgString(ModeOpt));

263 }

264

265 SmallString<64> Bundle("-fxray-instrumentation-bundle=");

266 if (InstrumentationBundle.full()) {

267 Bundle += "all";

268 } else if (InstrumentationBundle.empty()) {

269 Bundle += "none";

270 } else {

273 Bundle += "function";

275 Bundle += "function-entry";

277 Bundle += "function-exit";

278

280 Bundle += "custom";

282 Bundle += "typed";

283 }

284 CmdArgs.push_back(Args.MakeArgString(Bundle));

285}

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