ToolChain.cpp revision 1fed452f1e5486e1c3e6204fb5e284189b19ea7f
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/HostInfo.h" 18#include "clang/Driver/Options.h" 19 20using namespace clang::driver; 21 22ToolChain::ToolChain(const HostInfo &_Host, const llvm::Triple &_Triple) 23 : Host(_Host), Triple(_Triple) { 24} 25 26ToolChain::~ToolChain() { 27} 28 29const Driver &ToolChain::getDriver() const { 30 return Host.getDriver(); 31} 32 33std::string ToolChain::GetFilePath(const char *Name) const { 34 return Host.getDriver().GetFilePath(Name, *this); 35 36} 37 38std::string ToolChain::GetProgramPath(const char *Name, bool WantFile) const { 39 return Host.getDriver().GetProgramPath(Name, *this, WantFile); 40} 41 42types::ID ToolChain::LookupTypeForExtension(const char *Ext) const { 43 return types::lookupTypeForExtension(Ext); 44} 45 46/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting. 47// 48// FIXME: tblgen this. 49static const char *getARMTargetCPU(const ArgList &Args, 50 const llvm::Triple &Triple) { 51 // FIXME: Warn on inconsistent use of -mcpu and -march. 52 53 // If we have -mcpu=, use that. 54 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) 55 return A->getValue(Args); 56 57 llvm::StringRef MArch; 58 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { 59 // Otherwise, if we have -march= choose the base CPU for that arch. 60 MArch = A->getValue(Args); 61 } else { 62 // Otherwise, use the Arch from the triple. 63 MArch = Triple.getArchName(); 64 } 65 66 if (MArch == "armv2" || MArch == "armv2a") 67 return "arm2"; 68 if (MArch == "armv3") 69 return "arm6"; 70 if (MArch == "armv3m") 71 return "arm7m"; 72 if (MArch == "armv4" || MArch == "armv4t") 73 return "arm7tdmi"; 74 if (MArch == "armv5" || MArch == "armv5t") 75 return "arm10tdmi"; 76 if (MArch == "armv5e" || MArch == "armv5te") 77 return "arm1026ejs"; 78 if (MArch == "armv5tej") 79 return "arm926ej-s"; 80 if (MArch == "armv6" || MArch == "armv6k") 81 return "arm1136jf-s"; 82 if (MArch == "armv6j") 83 return "arm1136j-s"; 84 if (MArch == "armv6z" || MArch == "armv6zk") 85 return "arm1176jzf-s"; 86 if (MArch == "armv6t2") 87 return "arm1156t2-s"; 88 if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a") 89 return "cortex-a8"; 90 if (MArch == "armv7r" || MArch == "armv7-r") 91 return "cortex-r4"; 92 if (MArch == "armv7m" || MArch == "armv7-m") 93 return "cortex-m3"; 94 if (MArch == "ep9312") 95 return "ep9312"; 96 if (MArch == "iwmmxt") 97 return "iwmmxt"; 98 if (MArch == "xscale") 99 return "xscale"; 100 101 // If all else failed, return the most base CPU LLVM supports. 102 return "arm7tdmi"; 103} 104 105/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular 106/// CPU. 107// 108// FIXME: This is redundant with -mcpu, why does LLVM use this. 109// FIXME: tblgen this, or kill it! 110static const char *getLLVMArchSuffixForARM(llvm::StringRef CPU) { 111 if (CPU == "arm7tdmi" || CPU == "arm7tdmi-s" || CPU == "arm710t" || 112 CPU == "arm720t" || CPU == "arm9" || CPU == "arm9tdmi" || 113 CPU == "arm920" || CPU == "arm920t" || CPU == "arm922t" || 114 CPU == "arm940t" || CPU == "ep9312") 115 return "v4t"; 116 117 if (CPU == "arm10tdmi" || CPU == "arm1020t") 118 return "v5"; 119 120 if (CPU == "arm9e" || CPU == "arm926ej-s" || CPU == "arm946e-s" || 121 CPU == "arm966e-s" || CPU == "arm968e-s" || CPU == "arm10e" || 122 CPU == "arm1020e" || CPU == "arm1022e" || CPU == "xscale" || 123 CPU == "iwmmxt") 124 return "v5e"; 125 126 if (CPU == "arm1136j-s" || CPU == "arm1136jf-s" || CPU == "arm1176jz-s" || 127 CPU == "arm1176jzf-s" || CPU == "mpcorenovfp" || CPU == "mpcore") 128 return "v6"; 129 130 if (CPU == "arm1156t2-s" || CPU == "arm1156t2f-s") 131 return "v6t2"; 132 133 if (CPU == "cortex-a8" || CPU == "cortex-a9") 134 return "v7"; 135 136 return ""; 137} 138 139std::string ToolChain::ComputeLLVMTriple(const ArgList &Args) const { 140 switch (getTriple().getArch()) { 141 default: 142 return getTripleString(); 143 144 case llvm::Triple::arm: 145 case llvm::Triple::thumb: { 146 // FIXME: Factor into subclasses. 147 llvm::Triple Triple = getTriple(); 148 149 // Thumb2 is the default for V7 on Darwin. 150 // 151 // FIXME: Thumb should just be another -target-feaure, not in the triple. 152 llvm::StringRef Suffix = 153 getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple)); 154 bool ThumbDefault = 155 (Suffix == "v7" && getTriple().getOS() == llvm::Triple::Darwin); 156 std::string ArchName = "arm"; 157 if (Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault)) 158 ArchName = "thumb"; 159 Triple.setArchName(ArchName + Suffix.str()); 160 161 return Triple.getTriple(); 162 } 163 } 164} 165 166std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args) const { 167 // Diagnose use of -mmacosx-version-min and -miphoneos-version-min on 168 // non-Darwin. 169 if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ, 170 options::OPT_miphoneos_version_min_EQ)) 171 getDriver().Diag(clang::diag::err_drv_clang_unsupported) 172 << A->getAsString(Args); 173 174 return ComputeLLVMTriple(Args); 175} 176 177ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ 178 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { 179 llvm::StringRef Value = A->getValue(Args); 180 if (Value == "libc++") 181 return ToolChain::CST_Libcxx; 182 if (Value == "libstdc++") 183 return ToolChain::CST_Libstdcxx; 184 getDriver().Diag(clang::diag::err_drv_invalid_stdlib_name) 185 << A->getAsString(Args); 186 } 187 188 return ToolChain::CST_Libstdcxx; 189} 190 191void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args, 192 ArgStringList &CmdArgs) const { 193 CXXStdlibType Type = GetCXXStdlibType(Args); 194 195 switch (Type) { 196 case ToolChain::CST_Libcxx: 197 CmdArgs.push_back("-cxx-system-include"); 198 CmdArgs.push_back("/usr/include/c++/v1"); 199 break; 200 201 case ToolChain::CST_Libstdcxx: 202 // Currently handled by the mass of goop in InitHeaderSearch. 203 break; 204 } 205} 206 207void ToolChain::AddClangCXXStdlibLibArgs(const ArgList &Args, 208 ArgStringList &CmdArgs) const { 209 CXXStdlibType Type = GetCXXStdlibType(Args); 210 211 switch (Type) { 212 case ToolChain::CST_Libcxx: 213 CmdArgs.push_back("-lc++"); 214 break; 215 216 case ToolChain::CST_Libstdcxx: 217 CmdArgs.push_back("-lstdc++"); 218 break; 219 } 220} 221