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"
24 using namespace clang::driver;
25 using namespace clang::driver::tools;
26 using namespace clang::driver::toolchains;
27 using namespace clang;
28 using namespace llvm::opt;
32 ArgStringList &CmdArgs)
const {
39 const char *LinkingOutput)
const {
43 const Driver &D = HTC.getDriver();
44 ArgStringList CmdArgs;
46 std::string MArchString =
"-march=hexagon";
47 CmdArgs.push_back(Args.MakeArgString(MArchString));
49 RenderExtraToolArgs(JA, CmdArgs);
51 std::string AsName =
"hexagon-llvm-mc";
52 std::string MCpuString =
"-mcpu=hexagon" +
54 CmdArgs.push_back(
"-filetype=obj");
55 CmdArgs.push_back(Args.MakeArgString(MCpuString));
58 CmdArgs.push_back(
"-o");
61 assert(Output.
isNothing() &&
"Unexpected output");
62 CmdArgs.push_back(
"-fsyntax-only");
66 std::string N = llvm::utostr(G.getValue());
67 CmdArgs.push_back(Args.MakeArgString(std::string(
"-gpsize=") + N));
70 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
80 for (
const auto &II : Inputs) {
83 D.
Diag(clang::diag::err_drv_no_linker_llvm_support)
84 << HTC.getTripleString();
85 else if (II.getType() == types::TY_AST)
86 D.
Diag(clang::diag::err_drv_no_ast_support)
87 << HTC.getTripleString();
88 else if (II.getType() == types::TY_ModuleFile)
89 D.
Diag(diag::err_drv_no_module_support)
90 << HTC.getTripleString();
93 CmdArgs.push_back(II.getFilename());
97 II.getInputArg().render(Args, CmdArgs);
100 auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName.c_str()));
101 C.
addCommand(llvm::make_unique<Command>(JA, *
this, Exec, CmdArgs, Inputs));
105 ArgStringList &CmdArgs)
const {
112 const ArgList &Args, ArgStringList &CmdArgs,
113 const char *LinkingOutput) {
120 bool IsStatic = Args.hasArg(options::OPT_static);
121 bool IsShared = Args.hasArg(options::OPT_shared);
122 bool IsPIE = Args.hasArg(options::OPT_pie);
123 bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
124 bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
125 bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
127 bool UseShared = IsShared && !IsStatic;
132 Args.ClaimAllArgs(options::OPT_g_Group);
133 Args.ClaimAllArgs(options::OPT_emit_llvm);
134 Args.ClaimAllArgs(options::OPT_w);
136 Args.ClaimAllArgs(options::OPT_static_libgcc);
141 if (Args.hasArg(options::OPT_s))
142 CmdArgs.push_back(
"-s");
144 if (Args.hasArg(options::OPT_r))
145 CmdArgs.push_back(
"-r");
148 CmdArgs.push_back(Opt.c_str());
150 CmdArgs.push_back(
"-march=hexagon");
153 std::string MCpuString =
"-mcpu=hexagon" + CpuVer;
154 CmdArgs.push_back(Args.MakeArgString(MCpuString));
157 CmdArgs.push_back(
"-shared");
159 CmdArgs.push_back(
"-call_shared");
163 CmdArgs.push_back(
"-static");
165 if (IsPIE && !IsShared)
166 CmdArgs.push_back(
"-pie");
169 std::string N = llvm::utostr(G.getValue());
170 CmdArgs.push_back(Args.MakeArgString(std::string(
"-G") + N));
171 UseG0 = G.getValue() == 0;
177 CmdArgs.push_back(
"-o");
183 std::vector<std::string> OsLibs;
184 bool HasStandalone =
false;
186 for (
const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
188 OsLibs.emplace_back(A->getValue());
189 HasStandalone = HasStandalone || (OsLibs.back() ==
"standalone");
191 if (OsLibs.empty()) {
192 OsLibs.push_back(
"standalone");
193 HasStandalone =
true;
199 const std::string MCpuSuffix =
"/" + CpuVer;
200 const std::string MCpuG0Suffix = MCpuSuffix +
"/G0";
201 const std::string RootDir =
203 const std::string StartSubDir =
204 "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
206 auto Find = [&HTC] (
const std::string &RootDir,
const std::string &SubDir,
207 const char *
Name) -> std::string {
208 std::string RelName = SubDir +
Name;
210 if (llvm::sys::fs::exists(P))
212 return RootDir + RelName;
215 if (IncStdLib && IncStartFiles) {
218 std::string Crt0SA = Find(RootDir, StartSubDir,
"/crt0_standalone.o");
219 CmdArgs.push_back(Args.MakeArgString(Crt0SA));
221 std::string Crt0 = Find(RootDir, StartSubDir,
"/crt0.o");
222 CmdArgs.push_back(Args.MakeArgString(Crt0));
224 std::string Init = UseShared
225 ? Find(RootDir, StartSubDir +
"/pic",
"/initS.o")
226 : Find(RootDir, StartSubDir,
"/init.o");
227 CmdArgs.push_back(Args.MakeArgString(Init));
234 for (
const auto &LibPath : LibPaths)
235 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
240 Args.AddAllArgs(CmdArgs,
241 {options::OPT_T_Group, options::OPT_e, options::OPT_s,
242 options::OPT_t, options::OPT_u_Group});
249 if (IncStdLib && IncDefLibs) {
252 CmdArgs.push_back(
"-lm");
255 CmdArgs.push_back(
"--start-group");
258 for (
const std::string &Lib : OsLibs)
259 CmdArgs.push_back(Args.MakeArgString(
"-l" + Lib));
260 CmdArgs.push_back(
"-lc");
262 CmdArgs.push_back(
"-lgcc");
264 CmdArgs.push_back(
"--end-group");
270 if (IncStdLib && IncStartFiles) {
271 std::string Fini = UseShared
272 ? Find(RootDir, StartSubDir +
"/pic",
"/finiS.o")
273 : Find(RootDir, StartSubDir,
"/fini.o");
274 CmdArgs.push_back(Args.MakeArgString(Fini));
282 const char *LinkingOutput)
const {
285 ArgStringList CmdArgs;
289 std::string
Linker = HTC.GetProgramPath(
"hexagon-link");
290 C.
addCommand(llvm::make_unique<Command>(JA, *
this, Args.MakeArgString(Linker),
297 std::string HexagonToolChain::getHexagonTargetDir(
298 const std::string &InstalledDir,
300 std::string InstallRelDir;
301 const Driver &D = getDriver();
304 for (
auto &
I : PrefixDirs)
308 if (getVFS().exists(InstallRelDir = InstalledDir +
"/../target"))
309 return InstallRelDir;
315 const ArgList &Args) {
317 if (Arg *A = Args.getLastArg(options::OPT_G)) {
319 }
else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
320 options::OPT_fPIC)) {
325 if (!Gn.getAsInteger(10, G))
331 void HexagonToolChain::getHexagonLibraryPaths(
const ArgList &Args,
333 const Driver &D = getDriver();
338 for (Arg *A : Args.filtered(options::OPT_L))
339 for (
const char *
Value : A->getValues())
340 LibPaths.push_back(
Value);
345 std::vector<std::string> RootDirs;
347 std::back_inserter(RootDirs));
351 if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end())
352 RootDirs.push_back(TargetDir);
354 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
356 bool HasG0 = Args.hasArg(options::OPT_shared);
357 if (
auto G = getSmallDataThreshold(Args))
358 HasG0 = G.getValue() == 0;
360 const std::string CpuVer = GetTargetCPUVersion(Args).str();
361 for (
auto &Dir : RootDirs) {
362 std::string LibDir = Dir +
"/hexagon/lib";
363 std::string LibDirCpu = LibDir +
'/' + CpuVer;
366 LibPaths.push_back(LibDirCpu +
"/G0/pic");
367 LibPaths.push_back(LibDirCpu +
"/G0");
369 LibPaths.push_back(LibDirCpu);
370 LibPaths.push_back(LibDir);
374 HexagonToolChain::HexagonToolChain(
const Driver &D,
const llvm::Triple &Triple,
375 const llvm::opt::ArgList &Args)
376 :
Linux(D, Triple, Args) {
382 const std::string BinDir(TargetDir +
"/bin");
406 const llvm::opt::ArgList &DriverArgs)
const {
408 Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
412 if (A->getOption().matches(options::OPT_O0))
414 if (A->getOption().matches(options::OPT_Ofast) ||
415 A->getOption().matches(options::OPT_O4))
417 assert(A->getNumValues() != 0);
418 StringRef
S(A->getValue());
419 if (
S ==
"s" ||
S ==
"z" ||
S.empty())
425 if (
S.getAsInteger(10, OptLevel))
431 ArgStringList &CC1Args,
433 if (DriverArgs.hasArg(options::OPT_ffp_contract))
437 CC1Args.push_back(
"-ffp-contract=fast");
441 ArgStringList &CC1Args)
const {
442 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
443 DriverArgs.hasArg(options::OPT_nostdlibinc))
454 const llvm::opt::ArgList &DriverArgs,
455 llvm::opt::ArgStringList &CC1Args)
const {
459 DriverArgs, CC1Args);
464 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
468 StringRef
Value = A->getValue();
469 if (Value !=
"libstdc++")
470 getDriver().
Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
484 Arg *CpuArg =
nullptr;
485 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
488 StringRef CPU = CpuArg ? CpuArg->getValue() :
GetDefaultCPU();
489 if (CPU.startswith(
"hexagon"))
490 return CPU.substr(
sizeof(
"hexagon") - 1);
static void constructHexagonLinkArgs(Compilation &C, const JobAction &JA, const toolchains::HexagonToolChain &HTC, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, ArgStringList &CmdArgs, const char *LinkingOutput)
DiagnosticBuilder Diag(unsigned DiagID) const
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
const char * getInstalledDir() const
Get the path to where the clang executable was installed.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
detail::InMemoryDirectory::const_iterator I
void addCommand(std::unique_ptr< Command > C)
vfs::FileSystem & getVFS() const
std::string InstalledDir
The path to the installed clang directory, if any.
Defines the virtual file system interface vfs::FileSystem.
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.