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 "clang/Driver/ToolChain.h" 11 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/Options.h" 18 #include "llvm/ADT/StringSwitch.h" 19 #include "llvm/Support/ErrorHandling.h" 20 #include "clang/Basic/ObjCRuntime.h" 21 using namespace clang::driver; 22 using namespace clang; 23 24 ToolChain::ToolChain(const Driver &D, const llvm::Triple &T) 25 : D(D), Triple(T) { 26 } 27 28 ToolChain::~ToolChain() { 29 } 30 31 const Driver &ToolChain::getDriver() const { 32 return D; 33 } 34 35 bool ToolChain::IsUnwindTablesDefault() const { 36 return false; 37 } 38 39 std::string ToolChain::GetFilePath(const char *Name) const { 40 return D.GetFilePath(Name, *this); 41 42 } 43 44 std::string ToolChain::GetProgramPath(const char *Name, bool WantFile) const { 45 return D.GetProgramPath(Name, *this, WantFile); 46 } 47 48 types::ID ToolChain::LookupTypeForExtension(const char *Ext) const { 49 return types::lookupTypeForExtension(Ext); 50 } 51 52 bool ToolChain::HasNativeLLVMSupport() const { 53 return false; 54 } 55 56 ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const { 57 return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC, 58 VersionTuple()); 59 } 60 61 /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting. 62 // 63 // FIXME: tblgen this. 64 static const char *getARMTargetCPU(const ArgList &Args, 65 const llvm::Triple &Triple) { 66 // For Darwin targets, the -arch option (which is translated to a 67 // corresponding -march option) should determine the architecture 68 // (and the Mach-O slice) regardless of any -mcpu options. 69 if (!Triple.isOSDarwin()) { 70 // FIXME: Warn on inconsistent use of -mcpu and -march. 71 // If we have -mcpu=, use that. 72 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 73 return A->getValue(Args); 74 } 75 76 StringRef MArch; 77 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { 78 // Otherwise, if we have -march= choose the base CPU for that arch. 79 MArch = A->getValue(Args); 80 } else { 81 // Otherwise, use the Arch from the triple. 82 MArch = Triple.getArchName(); 83 } 84 85 return llvm::StringSwitch<const char *>(MArch) 86 .Cases("armv2", "armv2a","arm2") 87 .Case("armv3", "arm6") 88 .Case("armv3m", "arm7m") 89 .Cases("armv4", "armv4t", "arm7tdmi") 90 .Cases("armv5", "armv5t", "arm10tdmi") 91 .Cases("armv5e", "armv5te", "arm1026ejs") 92 .Case("armv5tej", "arm926ej-s") 93 .Cases("armv6", "armv6k", "arm1136jf-s") 94 .Case("armv6j", "arm1136j-s") 95 .Cases("armv6z", "armv6zk", "arm1176jzf-s") 96 .Case("armv6t2", "arm1156t2-s") 97 .Cases("armv7", "armv7a", "armv7-a", "cortex-a8") 98 .Cases("armv7f", "armv7-f", "cortex-a9-mp") 99 .Cases("armv7s", "armv7-s", "swift") 100 .Cases("armv7r", "armv7-r", "cortex-r4") 101 .Cases("armv7m", "armv7-m", "cortex-m3") 102 .Case("ep9312", "ep9312") 103 .Case("iwmmxt", "iwmmxt") 104 .Case("xscale", "xscale") 105 .Cases("armv6m", "armv6-m", "cortex-m0") 106 // If all else failed, return the most base CPU LLVM supports. 107 .Default("arm7tdmi"); 108 } 109 110 /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular 111 /// CPU. 112 // 113 // FIXME: This is redundant with -mcpu, why does LLVM use this. 114 // FIXME: tblgen this, or kill it! 115 static const char *getLLVMArchSuffixForARM(StringRef CPU) { 116 return llvm::StringSwitch<const char *>(CPU) 117 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t") 118 .Cases("arm720t", "arm9", "arm9tdmi", "v4t") 119 .Cases("arm920", "arm920t", "arm922t", "v4t") 120 .Cases("arm940t", "ep9312","v4t") 121 .Cases("arm10tdmi", "arm1020t", "v5") 122 .Cases("arm9e", "arm926ej-s", "arm946e-s", "v5e") 123 .Cases("arm966e-s", "arm968e-s", "arm10e", "v5e") 124 .Cases("arm1020e", "arm1022e", "xscale", "iwmmxt", "v5e") 125 .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "v6") 126 .Cases("arm1176jzf-s", "mpcorenovfp", "mpcore", "v6") 127 .Cases("arm1156t2-s", "arm1156t2f-s", "v6t2") 128 .Cases("cortex-a8", "cortex-a9", "cortex-a15", "v7") 129 .Case("cortex-m3", "v7m") 130 .Case("cortex-m4", "v7m") 131 .Case("cortex-m0", "v6m") 132 .Case("cortex-a9-mp", "v7f") 133 .Case("swift", "v7s") 134 .Default(""); 135 } 136 137 std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, 138 types::ID InputType) const { 139 switch (getTriple().getArch()) { 140 default: 141 return getTripleString(); 142 143 case llvm::Triple::arm: 144 case llvm::Triple::thumb: { 145 // FIXME: Factor into subclasses. 146 llvm::Triple Triple = getTriple(); 147 148 // Thumb2 is the default for V7 on Darwin. 149 // 150 // FIXME: Thumb should just be another -target-feaure, not in the triple. 151 StringRef Suffix = 152 getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple)); 153 bool ThumbDefault = (Suffix.startswith("v7") && getTriple().isOSDarwin()); 154 std::string ArchName = "arm"; 155 156 // Assembly files should start in ARM mode. 157 if (InputType != types::TY_PP_Asm && 158 Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault)) 159 ArchName = "thumb"; 160 Triple.setArchName(ArchName + Suffix.str()); 161 162 return Triple.getTriple(); 163 } 164 } 165 } 166 167 std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args, 168 types::ID InputType) const { 169 // Diagnose use of Darwin OS deployment target arguments on non-Darwin. 170 if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ, 171 options::OPT_miphoneos_version_min_EQ, 172 options::OPT_mios_simulator_version_min_EQ)) 173 getDriver().Diag(diag::err_drv_clang_unsupported) 174 << A->getAsString(Args); 175 176 return ComputeLLVMTriple(Args, InputType); 177 } 178 179 void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 180 ArgStringList &CC1Args) const { 181 // Each toolchain should provide the appropriate include flags. 182 } 183 184 void ToolChain::addClangTargetOptions(ArgStringList &CC1Args) const { 185 } 186 187 ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType( 188 const ArgList &Args) const 189 { 190 if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) { 191 StringRef Value = A->getValue(Args); 192 if (Value == "compiler-rt") 193 return ToolChain::RLT_CompilerRT; 194 if (Value == "libgcc") 195 return ToolChain::RLT_Libgcc; 196 getDriver().Diag(diag::err_drv_invalid_rtlib_name) 197 << A->getAsString(Args); 198 } 199 200 return GetDefaultRuntimeLibType(); 201 } 202 203 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ 204 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 205 StringRef Value = A->getValue(Args); 206 if (Value == "libc++") 207 return ToolChain::CST_Libcxx; 208 if (Value == "libstdc++") 209 return ToolChain::CST_Libstdcxx; 210 getDriver().Diag(diag::err_drv_invalid_stdlib_name) 211 << A->getAsString(Args); 212 } 213 214 return ToolChain::CST_Libstdcxx; 215 } 216 217 /// \brief Utility function to add a system include directory to CC1 arguments. 218 /*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs, 219 ArgStringList &CC1Args, 220 const Twine &Path) { 221 CC1Args.push_back("-internal-isystem"); 222 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 223 } 224 225 /// \brief Utility function to add a system include directory with extern "C" 226 /// semantics to CC1 arguments. 227 /// 228 /// Note that this should be used rarely, and only for directories that 229 /// historically and for legacy reasons are treated as having implicit extern 230 /// "C" semantics. These semantics are *ignored* by and large today, but its 231 /// important to preserve the preprocessor changes resulting from the 232 /// classification. 233 /*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs, 234 ArgStringList &CC1Args, 235 const Twine &Path) { 236 CC1Args.push_back("-internal-externc-isystem"); 237 CC1Args.push_back(DriverArgs.MakeArgString(Path)); 238 } 239 240 /// \brief Utility function to add a list of system include directories to CC1. 241 /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs, 242 ArgStringList &CC1Args, 243 ArrayRef<StringRef> Paths) { 244 for (ArrayRef<StringRef>::iterator I = Paths.begin(), E = Paths.end(); 245 I != E; ++I) { 246 CC1Args.push_back("-internal-isystem"); 247 CC1Args.push_back(DriverArgs.MakeArgString(*I)); 248 } 249 } 250 251 void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 252 ArgStringList &CC1Args) const { 253 // Header search paths should be handled by each of the subclasses. 254 // Historically, they have not been, and instead have been handled inside of 255 // the CC1-layer frontend. As the logic is hoisted out, this generic function 256 // will slowly stop being called. 257 // 258 // While it is being called, replicate a bit of a hack to propagate the 259 // '-stdlib=' flag down to CC1 so that it can in turn customize the C++ 260 // header search paths with it. Once all systems are overriding this 261 // function, the CC1 flag and this line can be removed. 262 DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ); 263 } 264 265 void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args, 266 ArgStringList &CmdArgs) const { 267 CXXStdlibType Type = GetCXXStdlibType(Args); 268 269 switch (Type) { 270 case ToolChain::CST_Libcxx: 271 CmdArgs.push_back("-lc++"); 272 break; 273 274 case ToolChain::CST_Libstdcxx: 275 CmdArgs.push_back("-lstdc++"); 276 break; 277 } 278 } 279 280 void ToolChain::AddCCKextLibArgs(const ArgList &Args, 281 ArgStringList &CmdArgs) const { 282 CmdArgs.push_back("-lcc_kext"); 283 } 284