1 //===--- ToolChain.cpp - Collections of tools for one platform ------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "clang/Driver/ToolChain.h"
12 #include "clang/Driver/Action.h"
13 #include "clang/Driver/Arg.h"
14 #include "clang/Driver/ArgList.h"
15 #include "clang/Driver/Driver.h"
16 #include "clang/Driver/DriverDiagnostic.h"
17 #include "clang/Driver/HostInfo.h"
18 #include "clang/Driver/Options.h"
20 using namespace clang::driver;
22 ToolChain::ToolChain(const HostInfo &_Host, const llvm::Triple &_Triple)
23 : Host(_Host), Triple(_Triple) {
26 ToolChain::~ToolChain() {
29 const Driver &ToolChain::getDriver() const {
30 return Host.getDriver();
33 std::string ToolChain::GetFilePath(const char *Name) const {
34 return Host.getDriver().GetFilePath(Name, *this);
38 std::string ToolChain::GetProgramPath(const char *Name, bool WantFile) const {
39 return Host.getDriver().GetProgramPath(Name, *this, WantFile);
42 types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
43 return types::lookupTypeForExtension(Ext);
46 bool ToolChain::HasNativeLLVMSupport() const {
50 /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting.
52 // FIXME: tblgen this.
53 static const char *getARMTargetCPU(const ArgList &Args,
54 const llvm::Triple &Triple) {
55 // FIXME: Warn on inconsistent use of -mcpu and -march.
57 // If we have -mcpu=, use that.
58 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
59 return A->getValue(Args);
61 llvm::StringRef MArch;
62 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
63 // Otherwise, if we have -march= choose the base CPU for that arch.
64 MArch = A->getValue(Args);
66 // Otherwise, use the Arch from the triple.
67 MArch = Triple.getArchName();
70 if (MArch == "armv2" || MArch == "armv2a")
74 if (MArch == "armv3m")
76 if (MArch == "armv4" || MArch == "armv4t")
78 if (MArch == "armv5" || MArch == "armv5t")
80 if (MArch == "armv5e" || MArch == "armv5te")
82 if (MArch == "armv5tej")
84 if (MArch == "armv6" || MArch == "armv6k")
86 if (MArch == "armv6j")
88 if (MArch == "armv6z" || MArch == "armv6zk")
89 return "arm1176jzf-s";
90 if (MArch == "armv6t2")
92 if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
94 if (MArch == "armv7r" || MArch == "armv7-r")
96 if (MArch == "armv7m" || MArch == "armv7-m")
98 if (MArch == "ep9312")
100 if (MArch == "iwmmxt")
102 if (MArch == "xscale")
105 // If all else failed, return the most base CPU LLVM supports.
109 /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
112 // FIXME: This is redundant with -mcpu, why does LLVM use this.
113 // FIXME: tblgen this, or kill it!
114 static const char *getLLVMArchSuffixForARM(llvm::StringRef CPU) {
115 if (CPU == "arm7tdmi" || CPU == "arm7tdmi-s" || CPU == "arm710t" ||
116 CPU == "arm720t" || CPU == "arm9" || CPU == "arm9tdmi" ||
117 CPU == "arm920" || CPU == "arm920t" || CPU == "arm922t" ||
118 CPU == "arm940t" || CPU == "ep9312")
121 if (CPU == "arm10tdmi" || CPU == "arm1020t")
124 if (CPU == "arm9e" || CPU == "arm926ej-s" || CPU == "arm946e-s" ||
125 CPU == "arm966e-s" || CPU == "arm968e-s" || CPU == "arm10e" ||
126 CPU == "arm1020e" || CPU == "arm1022e" || CPU == "xscale" ||
130 if (CPU == "arm1136j-s" || CPU == "arm1136jf-s" || CPU == "arm1176jz-s" ||
131 CPU == "arm1176jzf-s" || CPU == "mpcorenovfp" || CPU == "mpcore")
134 if (CPU == "arm1156t2-s" || CPU == "arm1156t2f-s")
137 if (CPU == "cortex-a8" || CPU == "cortex-a9")
143 std::string ToolChain::ComputeLLVMTriple(const ArgList &Args) const {
144 switch (getTriple().getArch()) {
146 return getTripleString();
148 case llvm::Triple::arm:
149 case llvm::Triple::thumb: {
150 // FIXME: Factor into subclasses.
151 llvm::Triple Triple = getTriple();
153 // Thumb2 is the default for V7 on Darwin.
155 // FIXME: Thumb should just be another -target-feaure, not in the triple.
156 llvm::StringRef Suffix =
157 getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
159 (Suffix == "v7" && getTriple().getOS() == llvm::Triple::Darwin);
160 std::string ArchName = "arm";
161 if (Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault))
163 Triple.setArchName(ArchName + Suffix.str());
165 return Triple.getTriple();
170 std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args) const {
171 // Diagnose use of -mmacosx-version-min and -miphoneos-version-min on
173 if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ,
174 options::OPT_miphoneos_version_min_EQ))
175 getDriver().Diag(clang::diag::err_drv_clang_unsupported)
176 << A->getAsString(Args);
178 return ComputeLLVMTriple(Args);
181 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
182 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
183 llvm::StringRef Value = A->getValue(Args);
184 if (Value == "libc++")
185 return ToolChain::CST_Libcxx;
186 if (Value == "libstdc++")
187 return ToolChain::CST_Libstdcxx;
188 getDriver().Diag(clang::diag::err_drv_invalid_stdlib_name)
189 << A->getAsString(Args);
192 return ToolChain::CST_Libstdcxx;
195 void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args,
196 ArgStringList &CmdArgs) const {
197 CXXStdlibType Type = GetCXXStdlibType(Args);
200 case ToolChain::CST_Libcxx:
201 CmdArgs.push_back("-cxx-system-include");
202 CmdArgs.push_back("/usr/include/c++/v1");
205 case ToolChain::CST_Libstdcxx:
206 // Currently handled by the mass of goop in InitHeaderSearch.
211 void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
212 ArgStringList &CmdArgs) const {
213 CXXStdlibType Type = GetCXXStdlibType(Args);
216 case ToolChain::CST_Libcxx:
217 CmdArgs.push_back("-lc++");
220 case ToolChain::CST_Libstdcxx:
221 CmdArgs.push_back("-lstdc++");
226 void ToolChain::AddCCKextLibArgs(const ArgList &Args,
227 ArgStringList &CmdArgs) const {
228 CmdArgs.push_back("-lcc_kext");