ToolChains.cpp revision f36a06a9584cf351e1bb7c5ebf2f707ed416daba
1//===--- ToolChains.cpp - ToolChain Implementations ---------------------*-===// 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 "ToolChains.h" 11 12#include "clang/Driver/Arg.h" 13#include "clang/Driver/ArgList.h" 14#include "clang/Driver/Driver.h" 15#include "clang/Driver/DriverDiagnostic.h" 16#include "clang/Driver/HostInfo.h" 17#include "clang/Driver/Option.h" 18 19#include "llvm/ADT/StringExtras.h" 20#include "llvm/Support/raw_ostream.h" 21#include "llvm/System/Path.h" 22 23#include <cstdlib> // ::getenv 24 25using namespace clang::driver; 26using namespace clang::driver::toolchains; 27 28/// Darwin_X86 - Darwin tool chain for i386 and x86_64. 29 30Darwin_X86::Darwin_X86(const HostInfo &Host, const char *Arch, 31 const char *Platform, const char *OS, 32 const unsigned (&_DarwinVersion)[3], 33 const unsigned (&_GCCVersion)[3]) 34 : ToolChain(Host, Arch, Platform, OS) 35{ 36 DarwinVersion[0] = _DarwinVersion[0]; 37 DarwinVersion[1] = _DarwinVersion[1]; 38 DarwinVersion[2] = _DarwinVersion[2]; 39 GCCVersion[0] = _GCCVersion[0]; 40 GCCVersion[1] = _GCCVersion[1]; 41 GCCVersion[2] = _GCCVersion[2]; 42 43 llvm::raw_string_ostream(MacosxVersionMin) 44 << "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1]; 45 46 ToolChainDir = "i686-apple-darwin"; 47 ToolChainDir += llvm::utostr(DarwinVersion[0]); 48 ToolChainDir += "/"; 49 ToolChainDir += llvm::utostr(GCCVersion[0]); 50 ToolChainDir += '.'; 51 ToolChainDir += llvm::utostr(GCCVersion[1]); 52 ToolChainDir += '.'; 53 ToolChainDir += llvm::utostr(GCCVersion[2]); 54 55 std::string Path; 56 if (getArchName() == "x86_64") { 57 Path = getHost().getDriver().Dir; 58 Path += "/../lib/gcc/"; 59 Path += getToolChainDir(); 60 Path += "/x86_64"; 61 getFilePaths().push_back(Path); 62 63 Path = "/usr/lib/gcc/"; 64 Path += getToolChainDir(); 65 Path += "/x86_64"; 66 getFilePaths().push_back(Path); 67 } 68 69 Path = getHost().getDriver().Dir; 70 Path += "/../lib/gcc/"; 71 Path += getToolChainDir(); 72 getFilePaths().push_back(Path); 73 74 Path = "/usr/lib/gcc/"; 75 Path += getToolChainDir(); 76 getFilePaths().push_back(Path); 77 78 Path = getHost().getDriver().Dir; 79 Path += "/../libexec/gcc/"; 80 Path += getToolChainDir(); 81 getProgramPaths().push_back(Path); 82 83 Path = "/usr/libexec/gcc/"; 84 Path += getToolChainDir(); 85 getProgramPaths().push_back(Path); 86 87 Path = getHost().getDriver().Dir; 88 Path += "/../libexec"; 89 getProgramPaths().push_back(Path); 90 91 getProgramPaths().push_back(getHost().getDriver().Dir); 92} 93 94Darwin_X86::~Darwin_X86() { 95 // Free tool implementations. 96 for (llvm::DenseMap<unsigned, Tool*>::iterator 97 it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 98 delete it->second; 99} 100 101Tool &Darwin_X86::SelectTool(const Compilation &C, 102 const JobAction &JA) const { 103 Action::ActionClass Key; 104 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName())) 105 Key = Action::AnalyzeJobClass; 106 else 107 Key = JA.getKind(); 108 109 Tool *&T = Tools[Key]; 110 if (!T) { 111 switch (Key) { 112 case Action::InputClass: 113 case Action::BindArchClass: 114 assert(0 && "Invalid tool kind."); 115 case Action::PreprocessJobClass: 116 T = new tools::darwin::Preprocess(*this); break; 117 case Action::AnalyzeJobClass: 118 T = new tools::Clang(*this); break; 119 case Action::PrecompileJobClass: 120 case Action::CompileJobClass: 121 T = new tools::darwin::Compile(*this); break; 122 case Action::AssembleJobClass: 123 T = new tools::darwin::Assemble(*this); break; 124 case Action::LinkJobClass: 125 T = new tools::darwin::Link(*this, MacosxVersionMin.c_str()); break; 126 case Action::LipoJobClass: 127 T = new tools::darwin::Lipo(*this); break; 128 } 129 } 130 131 return *T; 132} 133 134DerivedArgList *Darwin_X86::TranslateArgs(InputArgList &Args) const { 135 DerivedArgList *DAL = new DerivedArgList(Args, false); 136 const OptTable &Opts = getHost().getDriver().getOpts(); 137 138 // FIXME: We really want to get out of the tool chain level argument 139 // translation business, as it makes the driver functionality much 140 // more opaque. For now, we follow gcc closely solely for the 141 // purpose of easily achieving feature parity & testability. Once we 142 // have something that works, we should reevaluate each translation 143 // and try to push it down into tool specific logic. 144 145 Arg *OSXVersion = 146 Args.getLastArg(options::OPT_mmacosx_version_min_EQ, false); 147 Arg *iPhoneVersion = 148 Args.getLastArg(options::OPT_miphoneos_version_min_EQ, false); 149 if (OSXVersion && iPhoneVersion) { 150 getHost().getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with) 151 << OSXVersion->getAsString(Args) 152 << iPhoneVersion->getAsString(Args); 153 } else if (!OSXVersion && !iPhoneVersion) { 154 // Chose the default version based on the arch. 155 // 156 // FIXME: This will need to be fixed when we merge in arm support. 157 158 // Look for MACOSX_DEPLOYMENT_TARGET, otherwise use the version 159 // from the host. 160 const char *Version = ::getenv("MACOSX_DEPLOYMENT_TARGET"); 161 if (!Version) 162 Version = MacosxVersionMin.c_str(); 163 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); 164 DAL->append(DAL->MakeJoinedArg(0, O, Version)); 165 } 166 167 for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) { 168 Arg *A = *it; 169 170 if (A->getOption().matches(options::OPT_Xarch__)) { 171 // FIXME: Canonicalize name. 172 if (getArchName() != A->getValue(Args, 0)) 173 continue; 174 175 // FIXME: The arg is leaked here, and we should have a nicer 176 // interface for this. 177 unsigned Prev, Index = Prev = A->getIndex() + 1; 178 Arg *XarchArg = Opts.ParseOneArg(Args, Index); 179 180 // If the argument parsing failed or more than one argument was 181 // consumed, the -Xarch_ argument's parameter tried to consume 182 // extra arguments. Emit an error and ignore. 183 // 184 // We also want to disallow any options which would alter the 185 // driver behavior; that isn't going to work in our model. We 186 // use isDriverOption() as an approximation, although things 187 // like -O4 are going to slip through. 188 if (!XarchArg || Index > Prev + 1 || 189 XarchArg->getOption().isDriverOption()) { 190 getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument) 191 << A->getAsString(Args); 192 continue; 193 } 194 195 XarchArg->setBaseArg(A); 196 A = XarchArg; 197 } 198 199 // Sob. These is strictly gcc compatible for the time being. Apple 200 // gcc translates options twice, which means that self-expanding 201 // options add duplicates. 202 options::ID id = A->getOption().getId(); 203 switch (id) { 204 default: 205 DAL->append(A); 206 break; 207 208 case options::OPT_mkernel: 209 case options::OPT_fapple_kext: 210 DAL->append(A); 211 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 212 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 213 break; 214 215 case options::OPT_dependency_file: 216 DAL->append(DAL->MakeSeparateArg(A, Opts.getOption(options::OPT_MF), 217 A->getValue(Args))); 218 break; 219 220 case options::OPT_gfull: 221 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag))); 222 DAL->append(DAL->MakeFlagArg(A, 223 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols))); 224 break; 225 226 case options::OPT_gused: 227 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_g_Flag))); 228 DAL->append(DAL->MakeFlagArg(A, 229 Opts.getOption(options::OPT_feliminate_unused_debug_symbols))); 230 break; 231 232 case options::OPT_fterminated_vtables: 233 case options::OPT_findirect_virtual_calls: 234 DAL->append(DAL->MakeFlagArg(A, 235 Opts.getOption(options::OPT_fapple_kext))); 236 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_static))); 237 break; 238 239 case options::OPT_shared: 240 DAL->append(DAL->MakeFlagArg(A, Opts.getOption(options::OPT_dynamiclib))); 241 break; 242 243 case options::OPT_fconstant_cfstrings: 244 DAL->append(DAL->MakeFlagArg(A, 245 Opts.getOption(options::OPT_mconstant_cfstrings))); 246 break; 247 248 case options::OPT_fno_constant_cfstrings: 249 DAL->append(DAL->MakeFlagArg(A, 250 Opts.getOption(options::OPT_mno_constant_cfstrings))); 251 break; 252 253 case options::OPT_Wnonportable_cfstrings: 254 DAL->append(DAL->MakeFlagArg(A, 255 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings))); 256 break; 257 258 case options::OPT_Wno_nonportable_cfstrings: 259 DAL->append(DAL->MakeFlagArg(A, 260 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings))); 261 break; 262 263 case options::OPT_fpascal_strings: 264 DAL->append(DAL->MakeFlagArg(A, 265 Opts.getOption(options::OPT_mpascal_strings))); 266 break; 267 268 case options::OPT_fno_pascal_strings: 269 DAL->append(DAL->MakeFlagArg(A, 270 Opts.getOption(options::OPT_mno_pascal_strings))); 271 break; 272 } 273 } 274 275 // FIXME: Actually, gcc always adds this, but it is filtered for 276 // duplicates somewhere. This also changes the order of things, so 277 // look it up. 278 if (getArchName() == "x86_64") 279 if (!Args.hasArg(options::OPT_m64, false)) 280 DAL->append(DAL->MakeFlagArg(0, Opts.getOption(options::OPT_m64))); 281 282 if (!Args.hasArg(options::OPT_mtune_EQ, false)) 283 DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), 284 "core2")); 285 286 return DAL; 287} 288 289bool Darwin_X86::IsMathErrnoDefault() const { 290 return false; 291} 292 293bool Darwin_X86::IsUnwindTablesDefault() const { 294 // FIXME: Gross; we should probably have some separate target 295 // definition, possibly even reusing the one in clang. 296 return getArchName() == "x86_64"; 297} 298 299const char *Darwin_X86::GetDefaultRelocationModel() const { 300 return "pic"; 301} 302 303const char *Darwin_X86::GetForcedPicModel() const { 304 if (getArchName() == "x86_64") 305 return "pic"; 306 return 0; 307} 308 309/// Generic_GCC - A tool chain using the 'gcc' command to perform 310/// all subcommands; this relies on gcc translating the majority of 311/// command line options. 312 313Generic_GCC::Generic_GCC(const HostInfo &Host, const char *Arch, 314 const char *Platform, const char *OS) 315 : ToolChain(Host, Arch, Platform, OS) 316{ 317 std::string Path(getHost().getDriver().Dir); 318 Path += "/../libexec"; 319 getProgramPaths().push_back(Path); 320 321 getProgramPaths().push_back(getHost().getDriver().Dir); 322} 323 324Generic_GCC::~Generic_GCC() { 325 // Free tool implementations. 326 for (llvm::DenseMap<unsigned, Tool*>::iterator 327 it = Tools.begin(), ie = Tools.end(); it != ie; ++it) 328 delete it->second; 329} 330 331Tool &Generic_GCC::SelectTool(const Compilation &C, 332 const JobAction &JA) const { 333 Action::ActionClass Key; 334 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName())) 335 Key = Action::AnalyzeJobClass; 336 else 337 Key = JA.getKind(); 338 339 Tool *&T = Tools[Key]; 340 if (!T) { 341 switch (Key) { 342 case Action::InputClass: 343 case Action::BindArchClass: 344 assert(0 && "Invalid tool kind."); 345 case Action::PreprocessJobClass: 346 T = new tools::gcc::Preprocess(*this); break; 347 case Action::PrecompileJobClass: 348 T = new tools::gcc::Precompile(*this); break; 349 case Action::AnalyzeJobClass: 350 T = new tools::Clang(*this); break; 351 case Action::CompileJobClass: 352 T = new tools::gcc::Compile(*this); break; 353 case Action::AssembleJobClass: 354 T = new tools::gcc::Assemble(*this); break; 355 case Action::LinkJobClass: 356 T = new tools::gcc::Link(*this); break; 357 358 // This is a bit ungeneric, but the only platform using a driver 359 // driver is Darwin. 360 case Action::LipoJobClass: 361 T = new tools::darwin::Lipo(*this); break; 362 } 363 } 364 365 return *T; 366} 367 368bool Generic_GCC::IsMathErrnoDefault() const { 369 return true; 370} 371 372bool Generic_GCC::IsUnwindTablesDefault() const { 373 // FIXME: Gross; we should probably have some separate target 374 // definition, possibly even reusing the one in clang. 375 return getArchName() == "x86_64"; 376} 377 378const char *Generic_GCC::GetDefaultRelocationModel() const { 379 return "static"; 380} 381 382const char *Generic_GCC::GetForcedPicModel() const { 383 return 0; 384} 385 386DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const { 387 return new DerivedArgList(Args, true); 388} 389 390/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. 391 392FreeBSD::FreeBSD(const HostInfo &Host, const char *Arch, 393 const char *Platform, const char *OS, bool Lib32) 394 : Generic_GCC(Host, Arch, Platform, OS) { 395 if (Lib32) { 396 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32"); 397 getFilePaths().push_back("/usr/lib32"); 398 } else { 399 getFilePaths().push_back(getHost().getDriver().Dir + "/../lib"); 400 getFilePaths().push_back("/usr/lib"); 401 } 402} 403 404Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const { 405 Action::ActionClass Key; 406 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName())) 407 Key = Action::AnalyzeJobClass; 408 else 409 Key = JA.getKind(); 410 411 Tool *&T = Tools[Key]; 412 if (!T) { 413 switch (Key) { 414 case Action::AssembleJobClass: 415 T = new tools::freebsd::Assemble(*this); break; 416 case Action::LinkJobClass: 417 T = new tools::freebsd::Link(*this); break; 418 default: 419 T = &Generic_GCC::SelectTool(C, JA); 420 } 421 } 422 423 return *T; 424} 425