14 #include "clang/Config/config.h" 19 #include "llvm/ADT/StringExtras.h" 20 #include "llvm/Option/ArgList.h" 21 #include "llvm/Support/FileSystem.h" 22 #include "llvm/Support/Path.h" 27 using namespace clang;
32 return llvm::StringSwitch<StringRef>(Cpu)
41 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_double))
42 D.
Diag(diag::warn_drv_deprecated_arg)
43 << A->getAsString(Args) <<
"-mhvx-length=128B";
44 if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx_double))
45 D.
Diag(diag::warn_drv_deprecated_arg) << A->getAsString(Args) <<
"-mno-hvx";
47 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
48 StringRef Val = A->getValue();
49 if (!Val.equals_lower(
"64b") && !Val.equals_lower(
"128b"))
50 D.
Diag(diag::err_drv_unsupported_option_argument)
51 << A->getOption().getName() << Val;
57 std::vector<StringRef> &Features,
63 StringRef HVXFeature, HVXLength;
67 if (Arg *A = Args.getLastArg(
68 options::OPT_mno_hexagon_hvx, options::OPT_mno_hexagon_hvx_double,
69 options::OPT_mhexagon_hvx, options::OPT_mhexagon_hvx_EQ)) {
70 if (A->getOption().matches(options::OPT_mno_hexagon_hvx) ||
71 A->getOption().matches(options::OPT_mno_hexagon_hvx_double)) {
73 }
else if (A->getOption().matches(options::OPT_mhexagon_hvx_EQ)) {
75 HVXFeature = Cpu = A->getValue();
76 HVXFeature = Args.MakeArgString(llvm::Twine(
"+hvx") + HVXFeature.lower());
77 }
else if (A->getOption().matches(options::OPT_mhexagon_hvx)) {
79 HVXFeature = Args.MakeArgString(llvm::Twine(
"+hvx") + Cpu);
81 Features.push_back(HVXFeature);
85 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ,
86 options::OPT_mhexagon_hvx_double)) {
89 D.
Diag(diag::err_drv_invalid_hvx_length);
90 else if (A->getOption().matches(options::OPT_mhexagon_hvx_length_EQ))
91 HVXLength = A->getValue();
92 else if (A->getOption().matches(options::OPT_mhexagon_hvx_double))
99 if (!HVXLength.empty()) {
101 Args.MakeArgString(llvm::Twine(
"+hvx-length") + HVXLength.lower());
102 Features.push_back(HVXFeature);
108 std::vector<StringRef> &Features) {
110 options::OPT_m_hexagon_Features_Group);
112 bool UseLongCalls =
false;
113 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
114 options::OPT_mno_long_calls)) {
115 if (A->getOption().matches(options::OPT_mlong_calls))
119 Features.push_back(UseLongCalls ?
"+long-calls" :
"-long-calls");
127 ArgStringList &CmdArgs)
const {
134 const char *LinkingOutput)
const {
138 const Driver &D = HTC.getDriver();
139 ArgStringList CmdArgs;
141 CmdArgs.push_back(
"-march=hexagon");
143 RenderExtraToolArgs(JA, CmdArgs);
145 const char *AsName =
"hexagon-llvm-mc";
146 CmdArgs.push_back(
"-filetype=obj");
147 CmdArgs.push_back(Args.MakeArgString(
152 CmdArgs.push_back(
"-o");
155 assert(Output.
isNothing() &&
"Unexpected output");
156 CmdArgs.push_back(
"-fsyntax-only");
160 CmdArgs.push_back(Args.MakeArgString(
"-gpsize=" + Twine(G.getValue())));
163 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
173 for (
const auto &II : Inputs) {
176 D.
Diag(clang::diag::err_drv_no_linker_llvm_support)
177 << HTC.getTripleString();
178 else if (II.getType() == types::TY_AST)
179 D.
Diag(clang::diag::err_drv_no_ast_support)
180 << HTC.getTripleString();
181 else if (II.getType() == types::TY_ModuleFile)
182 D.
Diag(diag::err_drv_no_module_support)
183 << HTC.getTripleString();
186 CmdArgs.push_back(II.getFilename());
190 II.getInputArg().render(Args, CmdArgs);
193 auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName));
194 C.
addCommand(llvm::make_unique<Command>(JA, *
this, Exec, CmdArgs, Inputs));
198 ArgStringList &CmdArgs)
const {
205 const ArgList &Args, ArgStringList &CmdArgs,
206 const char *LinkingOutput) {
213 bool IsStatic = Args.hasArg(options::OPT_static);
214 bool IsShared = Args.hasArg(options::OPT_shared);
215 bool IsPIE = Args.hasArg(options::OPT_pie);
216 bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
217 bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
218 bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
220 bool UseShared = IsShared && !IsStatic;
225 Args.ClaimAllArgs(options::OPT_g_Group);
226 Args.ClaimAllArgs(options::OPT_emit_llvm);
227 Args.ClaimAllArgs(options::OPT_w);
229 Args.ClaimAllArgs(options::OPT_static_libgcc);
234 if (Args.hasArg(options::OPT_s))
235 CmdArgs.push_back(
"-s");
237 if (Args.hasArg(options::OPT_r))
238 CmdArgs.push_back(
"-r");
241 CmdArgs.push_back(Opt.c_str());
243 CmdArgs.push_back(
"-march=hexagon");
245 CmdArgs.push_back(Args.MakeArgString(
"-mcpu=hexagon" + CpuVer));
248 CmdArgs.push_back(
"-shared");
250 CmdArgs.push_back(
"-call_shared");
254 CmdArgs.push_back(
"-static");
256 if (IsPIE && !IsShared)
257 CmdArgs.push_back(
"-pie");
260 CmdArgs.push_back(Args.MakeArgString(
"-G" + Twine(G.getValue())));
261 UseG0 = G.getValue() == 0;
267 CmdArgs.push_back(
"-o");
273 std::vector<std::string> OsLibs;
274 bool HasStandalone =
false;
276 for (
const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
278 OsLibs.emplace_back(A->getValue());
279 HasStandalone = HasStandalone || (OsLibs.back() ==
"standalone");
281 if (OsLibs.empty()) {
282 OsLibs.push_back(
"standalone");
283 HasStandalone =
true;
289 const std::string MCpuSuffix =
"/" + CpuVer.str();
290 const std::string MCpuG0Suffix = MCpuSuffix +
"/G0";
291 const std::string RootDir =
293 const std::string StartSubDir =
294 "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
296 auto Find = [&HTC] (
const std::string &RootDir,
const std::string &SubDir,
297 const char *Name) -> std::string {
298 std::string RelName = SubDir + Name;
300 if (llvm::sys::fs::exists(P))
302 return RootDir + RelName;
305 if (IncStdLib && IncStartFiles) {
308 std::string Crt0SA = Find(RootDir, StartSubDir,
"/crt0_standalone.o");
309 CmdArgs.push_back(Args.MakeArgString(Crt0SA));
311 std::string Crt0 = Find(RootDir, StartSubDir,
"/crt0.o");
312 CmdArgs.push_back(Args.MakeArgString(Crt0));
314 std::string Init = UseShared
315 ? Find(RootDir, StartSubDir +
"/pic",
"/initS.o")
316 : Find(RootDir, StartSubDir,
"/init.o");
317 CmdArgs.push_back(Args.MakeArgString(Init));
324 for (
const auto &LibPath : LibPaths)
325 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
330 Args.AddAllArgs(CmdArgs,
331 {options::OPT_T_Group, options::OPT_e, options::OPT_s,
332 options::OPT_t, options::OPT_u_Group});
339 if (IncStdLib && IncDefLibs) {
343 CmdArgs.push_back(
"-lm");
346 CmdArgs.push_back(
"--start-group");
349 for (StringRef Lib : OsLibs)
350 CmdArgs.push_back(Args.MakeArgString(
"-l" + Lib));
351 CmdArgs.push_back(
"-lc");
353 CmdArgs.push_back(
"-lgcc");
355 CmdArgs.push_back(
"--end-group");
361 if (IncStdLib && IncStartFiles) {
362 std::string Fini = UseShared
363 ? Find(RootDir, StartSubDir +
"/pic",
"/finiS.o")
364 : Find(RootDir, StartSubDir,
"/fini.o");
365 CmdArgs.push_back(Args.MakeArgString(Fini));
373 const char *LinkingOutput)
const {
376 ArgStringList CmdArgs;
380 std::string
Linker = HTC.GetProgramPath(
"hexagon-link");
381 C.
addCommand(llvm::make_unique<Command>(JA, *
this, Args.MakeArgString(Linker),
388 std::string HexagonToolChain::getHexagonTargetDir(
389 const std::string &InstalledDir,
391 std::string InstallRelDir;
392 const Driver &D = getDriver();
395 for (
auto &I : PrefixDirs)
399 if (getVFS().exists(InstallRelDir = InstalledDir +
"/../target"))
400 return InstallRelDir;
406 const ArgList &Args) {
408 if (Arg *A = Args.getLastArg(options::OPT_G)) {
410 }
else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
411 options::OPT_fPIC)) {
416 if (!Gn.getAsInteger(10, G))
422 void HexagonToolChain::getHexagonLibraryPaths(
const ArgList &Args,
424 const Driver &D = getDriver();
429 for (Arg *A : Args.filtered(options::OPT_L))
430 for (
const char *
Value : A->getValues())
431 LibPaths.push_back(
Value);
436 std::vector<std::string> RootDirs;
438 std::back_inserter(RootDirs));
442 if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end())
443 RootDirs.push_back(TargetDir);
445 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
447 bool HasG0 = Args.hasArg(options::OPT_shared);
448 if (
auto G = getSmallDataThreshold(Args))
449 HasG0 = G.getValue() == 0;
451 const std::string CpuVer = GetTargetCPUVersion(Args).str();
452 for (
auto &Dir : RootDirs) {
453 std::string LibDir = Dir +
"/hexagon/lib";
454 std::string LibDirCpu = LibDir +
'/' + CpuVer;
457 LibPaths.push_back(LibDirCpu +
"/G0/pic");
458 LibPaths.push_back(LibDirCpu +
"/G0");
460 LibPaths.push_back(LibDirCpu);
461 LibPaths.push_back(LibDir);
465 HexagonToolChain::HexagonToolChain(
const Driver &D,
const llvm::Triple &Triple,
466 const llvm::opt::ArgList &Args)
467 :
Linux(D, Triple, Args) {
473 const std::string BinDir(TargetDir +
"/bin");
497 const llvm::opt::ArgList &DriverArgs)
const {
499 Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
503 if (A->getOption().matches(options::OPT_O0))
505 if (A->getOption().matches(options::OPT_Ofast) ||
506 A->getOption().matches(options::OPT_O4))
508 assert(A->getNumValues() != 0);
509 StringRef S(A->getValue());
510 if (S ==
"s" || S ==
"z" || S.empty())
516 if (S.getAsInteger(10, OptLevel))
522 ArgStringList &CC1Args,
524 if (DriverArgs.hasArg(options::OPT_ffp_contract))
528 CC1Args.push_back(
"-ffp-contract=fast");
532 ArgStringList &CC1Args)
const {
533 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
534 DriverArgs.hasArg(options::OPT_nostdlibinc))
545 const llvm::opt::ArgList &DriverArgs,
546 llvm::opt::ArgStringList &CC1Args)
const {
550 DriverArgs, CC1Args);
555 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
559 StringRef
Value = A->getValue();
560 if (Value !=
"libstdc++")
561 getDriver().
Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
575 Arg *CpuArg =
nullptr;
576 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
579 StringRef CPU = CpuArg ? CpuArg->getValue() :
GetDefaultCPU();
580 if (CPU.startswith(
"hexagon"))
581 return CPU.substr(
sizeof(
"hexagon") - 1);
DiagnosticBuilder Diag(unsigned DiagID) const
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
void addCommand(std::unique_ptr< Command > C)
vfs::FileSystem & getVFS() const
std::string InstalledDir
The path to the installed clang directory, if any.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
Dataflow Directional Tag Classes.
Defines the virtual file system interface vfs::FileSystem.
const char * getInstalledDir() const
Get the path to where the clang executable was installed.
bool exists(const Twine &Path)
Check whether a file exists. Provided for convenience.
Compilation - A set of tasks to perform for a single driver invocation.
bool isLLVMIR(ID Id)
Is this LLVM IR.