ToolChain.cpp revision 5b222059399ec9cccba7a393dc470adfb8a3db0f
1//===--- ToolChain.cpp - Collections of tools for one platform ------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "Tools.h" 11#include "clang/Driver/ToolChain.h" 12#include "clang/Basic/ObjCRuntime.h" 13#include "clang/Driver/Action.h" 14#include "clang/Driver/Arg.h" 15#include "clang/Driver/ArgList.h" 16#include "clang/Driver/Driver.h" 17#include "clang/Driver/DriverDiagnostic.h" 18#include "clang/Driver/Option.h" 19#include "clang/Driver/Options.h" 20#include "llvm/ADT/StringSwitch.h" 21#include "llvm/Support/ErrorHandling.h" 22using namespace clang::driver; 23using namespace clang; 24 25ToolChain::ToolChain(const Driver &D, const llvm::Triple &T, 26 const ArgList &A) 27 : D(D), Triple(T), Args(A) { 28} 29 30ToolChain::~ToolChain() { 31 // Free tool implementations. 32 for (llvm::DenseMap<unsigned, Tool*>::iterator 33 it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 34 delete it->second; 35} 36 37const Driver &ToolChain::getDriver() const { 38 return D; 39} 40 41bool ToolChain::useIntegratedAs() const { 42 return Args.hasFlag(options::OPT_integrated_as, 43 options::OPT_no_integrated_as, 44 IsIntegratedAssemblerDefault()); 45} 46 47std::string ToolChain::getDefaultUniversalArchName() const { 48 // In universal driver terms, the arch name accepted by -arch isn't exactly 49 // the same as the ones that appear in the triple. Roughly speaking, this is 50 // an inverse of the darwin::getArchTypeForDarwinArchName() function, but the 51 // only interesting special case is powerpc. 52 switch (Triple.getArch()) { 53 case llvm::Triple::ppc: 54 return "ppc"; 55 case llvm::Triple::ppc64: 56 return "ppc64"; 57 default: 58 return Triple.getArchName(); 59 } 60} 61 62bool ToolChain::IsUnwindTablesDefault() const { 63 return false; 64} 65 66Tool &ToolChain::SelectTool(const JobAction &JA) const { 67 Action::ActionClass Key; 68 if (getDriver().ShouldUseClangCompiler(JA)) 69 Key = Action::AnalyzeJobClass; 70 else 71 Key = JA.getKind(); 72 73 Tool *&T = Tools[Key]; 74 if (T) 75 return *T; 76 77 if (getDriver().ShouldUseClangCompiler(JA)) 78 T = new tools::Clang(*this); 79 else 80 T = constructTool(Key); 81 82 return *T; 83} 84 85std::string ToolChain::GetFilePath(const char *Name) const { 86 return D.GetFilePath(Name, *this); 87 88} 89 90std::string ToolChain::GetProgramPath(const char *Name) const { 91 return D.GetProgramPath(Name, *this); 92} 93 94types::ID ToolChain::LookupTypeForExtension(const char *Ext) const { 95 return types::lookupTypeForExtension(Ext); 96} 97 98bool ToolChain::HasNativeLLVMSupport() const { 99 return false; 100} 101 102ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const { 103 return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC, 104 VersionTuple()); 105} 106 107/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting. 108// 109// FIXME: tblgen this. 110static const char *getARMTargetCPU(const ArgList &Args, 111 const llvm::Triple &Triple) { 112 // For Darwin targets, the -arch option (which is translated to a 113 // corresponding -march option) should determine the architecture 114 // (and the Mach-O slice) regardless of any -mcpu options. 115 if (!Triple.isOSDarwin()) { 116 // FIXME: Warn on inconsistent use of -mcpu and -march. 117 // If we have -mcpu=, use that. 118 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 119 return A->getValue(); 120 } 121 122 StringRef MArch; 123 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { 124 // Otherwise, if we have -march= choose the base CPU for that arch. 125 MArch = A->getValue(); 126 } else { 127 // Otherwise, use the Arch from the triple. 128 MArch = Triple.getArchName(); 129 } 130 131 return llvm::StringSwitch<const char *>(MArch) 132 .Cases("armv2", "armv2a","arm2") 133 .Case("armv3", "arm6") 134 .Case("armv3m", "arm7m") 135 .Cases("armv4", "armv4t", "arm7tdmi") 136 .Cases("armv5", "armv5t", "arm10tdmi") 137 .Cases("armv5e", "armv5te", "arm1026ejs") 138 .Case("armv5tej", "arm926ej-s") 139 .Cases("armv6", "armv6k", "arm1136jf-s") 140 .Case("armv6j", "arm1136j-s") 141 .Cases("armv6z", "armv6zk", "arm1176jzf-s") 142 .Case("armv6t2", "arm1156t2-s") 143 .Cases("armv6m", "armv6-m", "cortex-m0") 144 .Cases("armv7", "armv7a", "armv7-a", "cortex-a8") 145 .Cases("armv7l", "armv7-l", "cortex-a8") 146 .Cases("armv7f", "armv7-f", "cortex-a9-mp") 147 .Cases("armv7s", "armv7-s", "swift") 148 .Cases("armv7r", "armv7-r", "cortex-r4") 149 .Cases("armv7m", "armv7-m", "cortex-m3") 150 .Cases("armv7em", "armv7e-m", "cortex-m4") 151 .Case("ep9312", "ep9312") 152 .Case("iwmmxt", "iwmmxt") 153 .Case("xscale", "xscale") 154 // If all else failed, return the most base CPU LLVM supports. 155 .Default("arm7tdmi"); 156} 157 158/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular 159/// CPU. 160// 161// FIXME: This is redundant with -mcpu, why does LLVM use this. 162// FIXME: tblgen this, or kill it! 163static const char *getLLVMArchSuffixForARM(StringRef CPU) { 164 return llvm::StringSwitch<const char *>(CPU) 165 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t") 166 .Cases("arm720t", "arm9", "arm9tdmi", "v4t") 167 .Cases("arm920", "arm920t", "arm922t", "v4t") 168 .Cases("arm940t", "ep9312","v4t") 169 .Cases("arm10tdmi", "arm1020t", "v5") 170 .Cases("arm9e", "arm926ej-s", "arm946e-s", "v5e") 171 .Cases("arm966e-s", "arm968e-s", "arm10e", "v5e") 172 .Cases("arm1020e", "arm1022e", "xscale", "iwmmxt", "v5e") 173 .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "v6") 174 .Cases("arm1176jzf-s", "mpcorenovfp", "mpcore", "v6") 175 .Cases("arm1156t2-s", "arm1156t2f-s", "v6t2") 176 .Cases("cortex-a5", "cortex-a7", "cortex-a8", "v7") 177 .Cases("cortex-a9", "cortex-a15", "v7") 178 .Case("cortex-r5", "v7r") 179 .Case("cortex-m0", "v6m") 180 .Case("cortex-m3", "v7m") 181 .Case("cortex-m4", "v7em") 182 .Case("cortex-a9-mp", "v7f") 183 .Case("swift", "v7s") 184 .Default(""); 185} 186 187std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, 188 types::ID InputType) const { 189 switch (getTriple().getArch()) { 190 default: 191 return getTripleString(); 192 193 case llvm::Triple::arm: 194 case llvm::Triple::thumb: { 195 // FIXME: Factor into subclasses. 196 llvm::Triple Triple = getTriple(); 197 198 // Thumb2 is the default for V7 on Darwin. 199 // 200 // FIXME: Thumb should just be another -target-feaure, not in the triple. 201 StringRef Suffix = 202 getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple)); 203 bool ThumbDefault = Suffix.startswith("v6m") || 204 (Suffix.startswith("v7") && getTriple().isOSDarwin()); 205 std::string ArchName = "arm"; 206 207 // Assembly files should start in ARM mode. 208 if (InputType != types::TY_PP_Asm && 209 Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault)) 210 ArchName = "thumb"; 211 Triple.setArchName(ArchName + Suffix.str()); 212 213 return Triple.getTriple(); 214 } 215 } 216} 217 218std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args, 219 types::ID InputType) const { 220 // Diagnose use of Darwin OS deployment target arguments on non-Darwin. 221 if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ, 222 options::OPT_miphoneos_version_min_EQ, 223 options::OPT_mios_simulator_version_min_EQ)) 224 getDriver().Diag(diag::err_drv_clang_unsupported) 225 << A->getAsString(Args); 226 227 return ComputeLLVMTriple(Args, InputType); 228} 229 230void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 231 ArgStringList &CC1Args) const { 232 // Each toolchain should provide the appropriate include flags. 233} 234 235void ToolChain::addClangTargetOptions(const ArgList &DriverArgs, 236 ArgStringList &CC1Args) const { 237} 238 239ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType( 240 const ArgList &Args) const 241{ 242 if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) { 243 StringRef Value = A->getValue(); 244 if (Value == "compiler-rt") 245 return ToolChain::RLT_CompilerRT; 246 if (Value == "libgcc") 247 return ToolChain::RLT_Libgcc; 248 getDriver().Diag(diag::err_drv_invalid_rtlib_name) 249 << A->getAsString(Args); 250 } 251 252 return GetDefaultRuntimeLibType(); 253} 254 255ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ 256 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 257 StringRef Value = A->getValue(); 258 if (Value == "libc++") 259 return ToolChain::CST_Libcxx; 260 if (Value == "libstdc++") 261 return ToolChain::CST_Libstdcxx; 262 getDriver().Diag(diag::err_drv_invalid_stdlib_name) 263 << A->getAsString(Args); 264 } 265 266 return ToolChain::CST_Libstdcxx; 267} 268 269/// \brief Utility function to add a system include directory to CC1 arguments. 270/*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs, 271 ArgStringList &CC1Args, 272 const Twine &Path) { 273 CC1Args.push_back("-internal-isystem"); 274 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 275} 276 277/// \brief Utility function to add a system include directory with extern "C" 278/// semantics to CC1 arguments. 279/// 280/// Note that this should be used rarely, and only for directories that 281/// historically and for legacy reasons are treated as having implicit extern 282/// "C" semantics. These semantics are *ignored* by and large today, but its 283/// important to preserve the preprocessor changes resulting from the 284/// classification. 285/*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs, 286 ArgStringList &CC1Args, 287 const Twine &Path) { 288 CC1Args.push_back("-internal-externc-isystem"); 289 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 290} 291 292/// \brief Utility function to add a list of system include directories to CC1. 293/*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs, 294 ArgStringList &CC1Args, 295 ArrayRef<StringRef> Paths) { 296 for (ArrayRef<StringRef>::iterator I = Paths.begin(), E = Paths.end(); 297 I != E; ++I) { 298 CC1Args.push_back("-internal-isystem"); 299 CC1Args.push_back(DriverArgs.MakeArgString(*I)); 300 } 301} 302 303void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 304 ArgStringList &CC1Args) const { 305 // Header search paths should be handled by each of the subclasses. 306 // Historically, they have not been, and instead have been handled inside of 307 // the CC1-layer frontend. As the logic is hoisted out, this generic function 308 // will slowly stop being called. 309 // 310 // While it is being called, replicate a bit of a hack to propagate the 311 // '-stdlib=' flag down to CC1 so that it can in turn customize the C++ 312 // header search paths with it. Once all systems are overriding this 313 // function, the CC1 flag and this line can be removed. 314 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ); 315} 316 317void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args, 318 ArgStringList &CmdArgs) const { 319 CXXStdlibType Type = GetCXXStdlibType(Args); 320 321 switch (Type) { 322 case ToolChain::CST_Libcxx: 323 CmdArgs.push_back("-lc++"); 324 break; 325 326 case ToolChain::CST_Libstdcxx: 327 CmdArgs.push_back("-lstdc++"); 328 break; 329 } 330} 331 332void ToolChain::AddCCKextLibArgs(const ArgList &Args, 333 ArgStringList &CmdArgs) const { 334 CmdArgs.push_back("-lcc_kext"); 335} 336 337bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args, 338 ArgStringList &CmdArgs) const { 339 // Check if -ffast-math or -funsafe-math is enabled. 340 Arg *A = Args.getLastArg(options::OPT_ffast_math, 341 options::OPT_fno_fast_math, 342 options::OPT_funsafe_math_optimizations, 343 options::OPT_fno_unsafe_math_optimizations); 344 345 if (!A || A->getOption().getID() == options::OPT_fno_fast_math || 346 A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations) 347 return false; 348 349 // If crtfastmath.o exists add it to the arguments. 350 std::string Path = GetFilePath("crtfastmath.o"); 351 if (Path == "crtfastmath.o") // Not found. 352 return false; 353 354 CmdArgs.push_back(Args.MakeArgString(Path)); 355 return true; 356} 357