clang API Documentation

ToolChain.cpp
Go to the documentation of this file.
00001 //===--- ToolChain.cpp - Collections of tools for one platform ------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "Tools.h"
00011 #include "clang/Basic/ObjCRuntime.h"
00012 #include "clang/Driver/Action.h"
00013 #include "clang/Driver/Driver.h"
00014 #include "clang/Driver/DriverDiagnostic.h"
00015 #include "clang/Driver/Options.h"
00016 #include "clang/Driver/SanitizerArgs.h"
00017 #include "clang/Driver/ToolChain.h"
00018 #include "llvm/ADT/SmallString.h"
00019 #include "llvm/ADT/StringSwitch.h"
00020 #include "llvm/Option/Arg.h"
00021 #include "llvm/Option/ArgList.h"
00022 #include "llvm/Option/Option.h"
00023 #include "llvm/Support/ErrorHandling.h"
00024 #include "llvm/Support/FileSystem.h"
00025 using namespace clang::driver;
00026 using namespace clang;
00027 using namespace llvm::opt;
00028 
00029 ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
00030                      const ArgList &Args)
00031   : D(D), Triple(T), Args(Args) {
00032   if (Arg *A = Args.getLastArg(options::OPT_mthread_model))
00033     if (!isThreadModelSupported(A->getValue()))
00034       D.Diag(diag::err_drv_invalid_thread_model_for_target)
00035           << A->getValue()
00036           << A->getAsString(Args);
00037 }
00038 
00039 ToolChain::~ToolChain() {
00040 }
00041 
00042 const Driver &ToolChain::getDriver() const {
00043  return D;
00044 }
00045 
00046 bool ToolChain::useIntegratedAs() const {
00047   return Args.hasFlag(options::OPT_fintegrated_as,
00048                       options::OPT_fno_integrated_as,
00049                       IsIntegratedAssemblerDefault());
00050 }
00051 
00052 const SanitizerArgs& ToolChain::getSanitizerArgs() const {
00053   if (!SanitizerArguments.get())
00054     SanitizerArguments.reset(new SanitizerArgs(*this, Args));
00055   return *SanitizerArguments.get();
00056 }
00057 
00058 StringRef ToolChain::getDefaultUniversalArchName() const {
00059   // In universal driver terms, the arch name accepted by -arch isn't exactly
00060   // the same as the ones that appear in the triple. Roughly speaking, this is
00061   // an inverse of the darwin::getArchTypeForDarwinArchName() function, but the
00062   // only interesting special case is powerpc.
00063   switch (Triple.getArch()) {
00064   case llvm::Triple::ppc:
00065     return "ppc";
00066   case llvm::Triple::ppc64:
00067     return "ppc64";
00068   case llvm::Triple::ppc64le:
00069     return "ppc64le";
00070   default:
00071     return Triple.getArchName();
00072   }
00073 }
00074 
00075 bool ToolChain::IsUnwindTablesDefault() const {
00076   return false;
00077 }
00078 
00079 Tool *ToolChain::getClang() const {
00080   if (!Clang)
00081     Clang.reset(new tools::Clang(*this));
00082   return Clang.get();
00083 }
00084 
00085 Tool *ToolChain::buildAssembler() const {
00086   return new tools::ClangAs(*this);
00087 }
00088 
00089 Tool *ToolChain::buildLinker() const {
00090   llvm_unreachable("Linking is not supported by this toolchain");
00091 }
00092 
00093 Tool *ToolChain::getAssemble() const {
00094   if (!Assemble)
00095     Assemble.reset(buildAssembler());
00096   return Assemble.get();
00097 }
00098 
00099 Tool *ToolChain::getClangAs() const {
00100   if (!Assemble)
00101     Assemble.reset(new tools::ClangAs(*this));
00102   return Assemble.get();
00103 }
00104 
00105 Tool *ToolChain::getLink() const {
00106   if (!Link)
00107     Link.reset(buildLinker());
00108   return Link.get();
00109 }
00110 
00111 Tool *ToolChain::getTool(Action::ActionClass AC) const {
00112   switch (AC) {
00113   case Action::AssembleJobClass:
00114     return getAssemble();
00115 
00116   case Action::LinkJobClass:
00117     return getLink();
00118 
00119   case Action::InputClass:
00120   case Action::BindArchClass:
00121   case Action::LipoJobClass:
00122   case Action::DsymutilJobClass:
00123   case Action::VerifyDebugInfoJobClass:
00124     llvm_unreachable("Invalid tool kind.");
00125 
00126   case Action::CompileJobClass:
00127   case Action::PrecompileJobClass:
00128   case Action::PreprocessJobClass:
00129   case Action::AnalyzeJobClass:
00130   case Action::MigrateJobClass:
00131   case Action::VerifyPCHJobClass:
00132     return getClang();
00133   }
00134 
00135   llvm_unreachable("Invalid tool kind.");
00136 }
00137 
00138 Tool *ToolChain::SelectTool(const JobAction &JA) const {
00139   if (getDriver().ShouldUseClangCompiler(JA))
00140     return getClang();
00141   Action::ActionClass AC = JA.getKind();
00142   if (AC == Action::AssembleJobClass && useIntegratedAs())
00143     return getClangAs();
00144   return getTool(AC);
00145 }
00146 
00147 std::string ToolChain::GetFilePath(const char *Name) const {
00148   return D.GetFilePath(Name, *this);
00149 
00150 }
00151 
00152 std::string ToolChain::GetProgramPath(const char *Name) const {
00153   return D.GetProgramPath(Name, *this);
00154 }
00155 
00156 std::string ToolChain::GetLinkerPath() const {
00157   if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
00158     StringRef Suffix = A->getValue();
00159 
00160     // If we're passed -fuse-ld= with no argument, or with the argument ld,
00161     // then use whatever the default system linker is.
00162     if (Suffix.empty() || Suffix == "ld")
00163       return GetProgramPath("ld");
00164 
00165     llvm::SmallString<8> LinkerName("ld.");
00166     LinkerName.append(Suffix);
00167 
00168     std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
00169     if (llvm::sys::fs::exists(LinkerPath))
00170       return LinkerPath;
00171 
00172     getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
00173     return "";
00174   }
00175 
00176   return GetProgramPath("ld");
00177 }
00178 
00179 
00180 types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
00181   return types::lookupTypeForExtension(Ext);
00182 }
00183 
00184 bool ToolChain::HasNativeLLVMSupport() const {
00185   return false;
00186 }
00187 
00188 bool ToolChain::isCrossCompiling() const {
00189   llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
00190   switch (HostTriple.getArch()) {
00191   // The A32/T32/T16 instruction sets are not separate architectures in this
00192   // context.
00193   case llvm::Triple::arm:
00194   case llvm::Triple::armeb:
00195   case llvm::Triple::thumb:
00196   case llvm::Triple::thumbeb:
00197     return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
00198            getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
00199   default:
00200     return HostTriple.getArch() != getArch();
00201   }
00202 }
00203 
00204 ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const {
00205   return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC,
00206                      VersionTuple());
00207 }
00208 
00209 bool ToolChain::isThreadModelSupported(const StringRef Model) const {
00210   if (Model == "single") {
00211     // FIXME: 'single' is only supported on ARM so far.
00212     return Triple.getArch() == llvm::Triple::arm ||
00213            Triple.getArch() == llvm::Triple::armeb ||
00214            Triple.getArch() == llvm::Triple::thumb ||
00215            Triple.getArch() == llvm::Triple::thumbeb;
00216   } else if (Model == "posix")
00217     return true;
00218 
00219   return false;
00220 }
00221 
00222 std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
00223                                          types::ID InputType) const {
00224   switch (getTriple().getArch()) {
00225   default:
00226     return getTripleString();
00227 
00228   case llvm::Triple::x86_64: {
00229     llvm::Triple Triple = getTriple();
00230     if (!Triple.isOSBinFormatMachO())
00231       return getTripleString();
00232 
00233     if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
00234       // x86_64h goes in the triple. Other -march options just use the
00235       // vanilla triple we already have.
00236       StringRef MArch = A->getValue();
00237       if (MArch == "x86_64h")
00238         Triple.setArchName(MArch);
00239     }
00240     return Triple.getTriple();
00241   }
00242   case llvm::Triple::aarch64: {
00243     llvm::Triple Triple = getTriple();
00244     if (!Triple.isOSBinFormatMachO())
00245       return getTripleString();
00246 
00247     // FIXME: older versions of ld64 expect the "arm64" component in the actual
00248     // triple string and query it to determine whether an LTO file can be
00249     // handled. Remove this when we don't care any more.
00250     Triple.setArchName("arm64");
00251     return Triple.getTriple();
00252   }
00253   case llvm::Triple::arm:
00254   case llvm::Triple::armeb:
00255   case llvm::Triple::thumb:
00256   case llvm::Triple::thumbeb: {
00257     // FIXME: Factor into subclasses.
00258     llvm::Triple Triple = getTriple();
00259     bool IsBigEndian = getTriple().getArch() == llvm::Triple::armeb ||
00260                        getTriple().getArch() == llvm::Triple::thumbeb;
00261 
00262     // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
00263     // '-mbig-endian'/'-EB'.
00264     if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
00265                                  options::OPT_mbig_endian)) {
00266       if (A->getOption().matches(options::OPT_mlittle_endian))
00267         IsBigEndian = false;
00268       else
00269         IsBigEndian = true;
00270     }
00271 
00272     // Thumb2 is the default for V7 on Darwin.
00273     //
00274     // FIXME: Thumb should just be another -target-feaure, not in the triple.
00275     StringRef Suffix = Triple.isOSBinFormatMachO()
00276       ? tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMCPUForMArch(Args, Triple))
00277       : tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMTargetCPU(Args, Triple));
00278     bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") ||
00279       Suffix.startswith("v7em") ||
00280       (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO());
00281     // FIXME: this is invalid for WindowsCE
00282     if (getTriple().isOSWindows())
00283       ThumbDefault = true;
00284     std::string ArchName;
00285     if (IsBigEndian)
00286       ArchName = "armeb";
00287     else
00288       ArchName = "arm";
00289 
00290     // Assembly files should start in ARM mode.
00291     if (InputType != types::TY_PP_Asm &&
00292         Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault))
00293     {
00294       if (IsBigEndian)
00295         ArchName = "thumbeb";
00296       else
00297         ArchName = "thumb";
00298     }
00299     Triple.setArchName(ArchName + Suffix.str());
00300 
00301     return Triple.getTriple();
00302   }
00303   }
00304 }
00305 
00306 std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args, 
00307                                                    types::ID InputType) const {
00308   return ComputeLLVMTriple(Args, InputType);
00309 }
00310 
00311 void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
00312                                           ArgStringList &CC1Args) const {
00313   // Each toolchain should provide the appropriate include flags.
00314 }
00315 
00316 void ToolChain::addClangTargetOptions(const ArgList &DriverArgs,
00317                                       ArgStringList &CC1Args) const {
00318 }
00319 
00320 void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
00321 
00322 ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
00323   const ArgList &Args) const
00324 {
00325   if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
00326     StringRef Value = A->getValue();
00327     if (Value == "compiler-rt")
00328       return ToolChain::RLT_CompilerRT;
00329     if (Value == "libgcc")
00330       return ToolChain::RLT_Libgcc;
00331     getDriver().Diag(diag::err_drv_invalid_rtlib_name)
00332       << A->getAsString(Args);
00333   }
00334 
00335   return GetDefaultRuntimeLibType();
00336 }
00337 
00338 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
00339   if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
00340     StringRef Value = A->getValue();
00341     if (Value == "libc++")
00342       return ToolChain::CST_Libcxx;
00343     if (Value == "libstdc++")
00344       return ToolChain::CST_Libstdcxx;
00345     getDriver().Diag(diag::err_drv_invalid_stdlib_name)
00346       << A->getAsString(Args);
00347   }
00348 
00349   return ToolChain::CST_Libstdcxx;
00350 }
00351 
00352 /// \brief Utility function to add a system include directory to CC1 arguments.
00353 /*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
00354                                             ArgStringList &CC1Args,
00355                                             const Twine &Path) {
00356   CC1Args.push_back("-internal-isystem");
00357   CC1Args.push_back(DriverArgs.MakeArgString(Path));
00358 }
00359 
00360 /// \brief Utility function to add a system include directory with extern "C"
00361 /// semantics to CC1 arguments.
00362 ///
00363 /// Note that this should be used rarely, and only for directories that
00364 /// historically and for legacy reasons are treated as having implicit extern
00365 /// "C" semantics. These semantics are *ignored* by and large today, but its
00366 /// important to preserve the preprocessor changes resulting from the
00367 /// classification.
00368 /*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
00369                                                    ArgStringList &CC1Args,
00370                                                    const Twine &Path) {
00371   CC1Args.push_back("-internal-externc-isystem");
00372   CC1Args.push_back(DriverArgs.MakeArgString(Path));
00373 }
00374 
00375 void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
00376                                                 ArgStringList &CC1Args,
00377                                                 const Twine &Path) {
00378   if (llvm::sys::fs::exists(Path))
00379     addExternCSystemInclude(DriverArgs, CC1Args, Path);
00380 }
00381 
00382 /// \brief Utility function to add a list of system include directories to CC1.
00383 /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
00384                                              ArgStringList &CC1Args,
00385                                              ArrayRef<StringRef> Paths) {
00386   for (ArrayRef<StringRef>::iterator I = Paths.begin(), E = Paths.end();
00387        I != E; ++I) {
00388     CC1Args.push_back("-internal-isystem");
00389     CC1Args.push_back(DriverArgs.MakeArgString(*I));
00390   }
00391 }
00392 
00393 void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
00394                                              ArgStringList &CC1Args) const {
00395   // Header search paths should be handled by each of the subclasses.
00396   // Historically, they have not been, and instead have been handled inside of
00397   // the CC1-layer frontend. As the logic is hoisted out, this generic function
00398   // will slowly stop being called.
00399   //
00400   // While it is being called, replicate a bit of a hack to propagate the
00401   // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
00402   // header search paths with it. Once all systems are overriding this
00403   // function, the CC1 flag and this line can be removed.
00404   DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
00405 }
00406 
00407 void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
00408                                     ArgStringList &CmdArgs) const {
00409   CXXStdlibType Type = GetCXXStdlibType(Args);
00410 
00411   switch (Type) {
00412   case ToolChain::CST_Libcxx:
00413     CmdArgs.push_back("-lc++");
00414     break;
00415 
00416   case ToolChain::CST_Libstdcxx:
00417     CmdArgs.push_back("-lstdc++");
00418     break;
00419   }
00420 }
00421 
00422 void ToolChain::AddCCKextLibArgs(const ArgList &Args,
00423                                  ArgStringList &CmdArgs) const {
00424   CmdArgs.push_back("-lcc_kext");
00425 }
00426 
00427 bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args,
00428                                               ArgStringList &CmdArgs) const {
00429   // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
00430   // (to keep the linker options consistent with gcc and clang itself).
00431   if (!isOptimizationLevelFast(Args)) {
00432     // Check if -ffast-math or -funsafe-math.
00433     Arg *A =
00434         Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
00435                         options::OPT_funsafe_math_optimizations,
00436                         options::OPT_fno_unsafe_math_optimizations);
00437 
00438     if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
00439         A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
00440       return false;
00441   }
00442   // If crtfastmath.o exists add it to the arguments.
00443   std::string Path = GetFilePath("crtfastmath.o");
00444   if (Path == "crtfastmath.o") // Not found.
00445     return false;
00446 
00447   CmdArgs.push_back(Args.MakeArgString(Path));
00448   return true;
00449 }