Home | History | Annotate | Download | only in Driver
      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/Basic/ObjCRuntime.h"
     12 #include "clang/Driver/Action.h"
     13 #include "clang/Driver/Driver.h"
     14 #include "clang/Driver/DriverDiagnostic.h"
     15 #include "clang/Driver/Options.h"
     16 #include "clang/Driver/SanitizerArgs.h"
     17 #include "clang/Driver/ToolChain.h"
     18 #include "llvm/ADT/SmallString.h"
     19 #include "llvm/ADT/StringSwitch.h"
     20 #include "llvm/Option/Arg.h"
     21 #include "llvm/Option/ArgList.h"
     22 #include "llvm/Option/Option.h"
     23 #include "llvm/Support/ErrorHandling.h"
     24 #include "llvm/Support/FileSystem.h"
     25 using namespace clang::driver;
     26 using namespace clang;
     27 using namespace llvm::opt;
     28 
     29 ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
     30                      const ArgList &A)
     31   : D(D), Triple(T), Args(A) {
     32 }
     33 
     34 ToolChain::~ToolChain() {
     35 }
     36 
     37 const Driver &ToolChain::getDriver() const {
     38  return D;
     39 }
     40 
     41 bool ToolChain::useIntegratedAs() const {
     42   return Args.hasFlag(options::OPT_fintegrated_as,
     43                       options::OPT_fno_integrated_as,
     44                       IsIntegratedAssemblerDefault());
     45 }
     46 
     47 const SanitizerArgs& ToolChain::getSanitizerArgs() const {
     48   if (!SanitizerArguments.get())
     49     SanitizerArguments.reset(new SanitizerArgs(*this, Args));
     50   return *SanitizerArguments.get();
     51 }
     52 
     53 std::string ToolChain::getDefaultUniversalArchName() const {
     54   // In universal driver terms, the arch name accepted by -arch isn't exactly
     55   // the same as the ones that appear in the triple. Roughly speaking, this is
     56   // an inverse of the darwin::getArchTypeForDarwinArchName() function, but the
     57   // only interesting special case is powerpc.
     58   switch (Triple.getArch()) {
     59   case llvm::Triple::ppc:
     60     return "ppc";
     61   case llvm::Triple::ppc64:
     62     return "ppc64";
     63   case llvm::Triple::ppc64le:
     64     return "ppc64le";
     65   default:
     66     return Triple.getArchName();
     67   }
     68 }
     69 
     70 bool ToolChain::IsUnwindTablesDefault() const {
     71   return false;
     72 }
     73 
     74 Tool *ToolChain::getClang() const {
     75   if (!Clang)
     76     Clang.reset(new tools::Clang(*this));
     77   return Clang.get();
     78 }
     79 
     80 Tool *ToolChain::buildAssembler() const {
     81   return new tools::ClangAs(*this);
     82 }
     83 
     84 Tool *ToolChain::buildLinker() const {
     85   llvm_unreachable("Linking is not supported by this toolchain");
     86 }
     87 
     88 Tool *ToolChain::getAssemble() const {
     89   if (!Assemble)
     90     Assemble.reset(buildAssembler());
     91   return Assemble.get();
     92 }
     93 
     94 Tool *ToolChain::getClangAs() const {
     95   if (!Assemble)
     96     Assemble.reset(new tools::ClangAs(*this));
     97   return Assemble.get();
     98 }
     99 
    100 Tool *ToolChain::getLink() const {
    101   if (!Link)
    102     Link.reset(buildLinker());
    103   return Link.get();
    104 }
    105 
    106 Tool *ToolChain::getTool(Action::ActionClass AC) const {
    107   switch (AC) {
    108   case Action::AssembleJobClass:
    109     return getAssemble();
    110 
    111   case Action::LinkJobClass:
    112     return getLink();
    113 
    114   case Action::InputClass:
    115   case Action::BindArchClass:
    116   case Action::LipoJobClass:
    117   case Action::DsymutilJobClass:
    118   case Action::VerifyDebugInfoJobClass:
    119     llvm_unreachable("Invalid tool kind.");
    120 
    121   case Action::CompileJobClass:
    122   case Action::PrecompileJobClass:
    123   case Action::PreprocessJobClass:
    124   case Action::AnalyzeJobClass:
    125   case Action::MigrateJobClass:
    126   case Action::VerifyPCHJobClass:
    127     return getClang();
    128   }
    129 
    130   llvm_unreachable("Invalid tool kind.");
    131 }
    132 
    133 Tool *ToolChain::SelectTool(const JobAction &JA) const {
    134   if (getDriver().ShouldUseClangCompiler(JA))
    135     return getClang();
    136   Action::ActionClass AC = JA.getKind();
    137   if (AC == Action::AssembleJobClass && useIntegratedAs())
    138     return getClangAs();
    139   return getTool(AC);
    140 }
    141 
    142 std::string ToolChain::GetFilePath(const char *Name) const {
    143   return D.GetFilePath(Name, *this);
    144 
    145 }
    146 
    147 std::string ToolChain::GetProgramPath(const char *Name) const {
    148   return D.GetProgramPath(Name, *this);
    149 }
    150 
    151 std::string ToolChain::GetLinkerPath() const {
    152   if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
    153     StringRef Suffix = A->getValue();
    154 
    155     // If we're passed -fuse-ld= with no argument, or with the argument ld,
    156     // then use whatever the default system linker is.
    157     if (Suffix.empty() || Suffix == "ld")
    158       return GetProgramPath("ld");
    159 
    160     llvm::SmallString<8> LinkerName("ld.");
    161     LinkerName.append(Suffix);
    162 
    163     std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
    164     if (llvm::sys::fs::exists(LinkerPath))
    165       return LinkerPath;
    166 
    167     getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
    168     return "";
    169   }
    170 
    171   return GetProgramPath("ld");
    172 }
    173 
    174 
    175 types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
    176   return types::lookupTypeForExtension(Ext);
    177 }
    178 
    179 bool ToolChain::HasNativeLLVMSupport() const {
    180   return false;
    181 }
    182 
    183 bool ToolChain::isCrossCompiling() const {
    184   llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
    185   switch (HostTriple.getArch()) {
    186   // The A32/T32/T16 instruction sets are not separate architectures in this
    187   // context.
    188   case llvm::Triple::arm:
    189   case llvm::Triple::armeb:
    190   case llvm::Triple::thumb:
    191   case llvm::Triple::thumbeb:
    192     return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
    193            getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
    194   default:
    195     return HostTriple.getArch() != getArch();
    196   }
    197 }
    198 
    199 ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const {
    200   return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC,
    201                      VersionTuple());
    202 }
    203 
    204 std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
    205                                          types::ID InputType) const {
    206   switch (getTriple().getArch()) {
    207   default:
    208     return getTripleString();
    209 
    210   case llvm::Triple::x86_64: {
    211     llvm::Triple Triple = getTriple();
    212     if (!Triple.isOSBinFormatMachO())
    213       return getTripleString();
    214 
    215     if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
    216       // x86_64h goes in the triple. Other -march options just use the
    217       // vanilla triple we already have.
    218       StringRef MArch = A->getValue();
    219       if (MArch == "x86_64h")
    220         Triple.setArchName(MArch);
    221     }
    222     return Triple.getTriple();
    223   }
    224   case llvm::Triple::arm:
    225   case llvm::Triple::armeb:
    226   case llvm::Triple::thumb:
    227   case llvm::Triple::thumbeb: {
    228     // FIXME: Factor into subclasses.
    229     llvm::Triple Triple = getTriple();
    230     bool IsBigEndian = getTriple().getArch() == llvm::Triple::armeb ||
    231                        getTriple().getArch() == llvm::Triple::thumbeb;
    232 
    233     // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
    234     // '-mbig-endian'/'-EB'.
    235     if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
    236                                  options::OPT_mbig_endian)) {
    237       if (A->getOption().matches(options::OPT_mlittle_endian))
    238         IsBigEndian = false;
    239       else
    240         IsBigEndian = true;
    241     }
    242 
    243     // Thumb2 is the default for V7 on Darwin.
    244     //
    245     // FIXME: Thumb should just be another -target-feaure, not in the triple.
    246     StringRef Suffix = Triple.isOSBinFormatMachO()
    247       ? tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMCPUForMArch(Args, Triple))
    248       : tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMTargetCPU(Args, Triple));
    249     bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") ||
    250       Suffix.startswith("v7em") ||
    251       (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO());
    252     // FIXME: this is invalid for WindowsCE
    253     if (getTriple().isOSWindows())
    254       ThumbDefault = true;
    255     std::string ArchName;
    256     if (IsBigEndian)
    257       ArchName = "armeb";
    258     else
    259       ArchName = "arm";
    260 
    261     // Assembly files should start in ARM mode.
    262     if (InputType != types::TY_PP_Asm &&
    263         Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault))
    264     {
    265       if (IsBigEndian)
    266         ArchName = "thumbeb";
    267       else
    268         ArchName = "thumb";
    269     }
    270     Triple.setArchName(ArchName + Suffix.str());
    271 
    272     return Triple.getTriple();
    273   }
    274   }
    275 }
    276 
    277 std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
    278                                                    types::ID InputType) const {
    279   return ComputeLLVMTriple(Args, InputType);
    280 }
    281 
    282 void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
    283                                           ArgStringList &CC1Args) const {
    284   // Each toolchain should provide the appropriate include flags.
    285 }
    286 
    287 void ToolChain::addClangTargetOptions(const ArgList &DriverArgs,
    288                                       ArgStringList &CC1Args) const {
    289 }
    290 
    291 void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
    292 
    293 ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
    294   const ArgList &Args) const
    295 {
    296   if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
    297     StringRef Value = A->getValue();
    298     if (Value == "compiler-rt")
    299       return ToolChain::RLT_CompilerRT;
    300     if (Value == "libgcc")
    301       return ToolChain::RLT_Libgcc;
    302     getDriver().Diag(diag::err_drv_invalid_rtlib_name)
    303       << A->getAsString(Args);
    304   }
    305 
    306   return GetDefaultRuntimeLibType();
    307 }
    308 
    309 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
    310   if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
    311     StringRef Value = A->getValue();
    312     if (Value == "libc++")
    313       return ToolChain::CST_Libcxx;
    314     if (Value == "libstdc++")
    315       return ToolChain::CST_Libstdcxx;
    316     getDriver().Diag(diag::err_drv_invalid_stdlib_name)
    317       << A->getAsString(Args);
    318   }
    319 
    320   return ToolChain::CST_Libstdcxx;
    321 }
    322 
    323 /// \brief Utility function to add a system include directory to CC1 arguments.
    324 /*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
    325                                             ArgStringList &CC1Args,
    326                                             const Twine &Path) {
    327   CC1Args.push_back("-internal-isystem");
    328   CC1Args.push_back(DriverArgs.MakeArgString(Path));
    329 }
    330 
    331 /// \brief Utility function to add a system include directory with extern "C"
    332 /// semantics to CC1 arguments.
    333 ///
    334 /// Note that this should be used rarely, and only for directories that
    335 /// historically and for legacy reasons are treated as having implicit extern
    336 /// "C" semantics. These semantics are *ignored* by and large today, but its
    337 /// important to preserve the preprocessor changes resulting from the
    338 /// classification.
    339 /*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
    340                                                    ArgStringList &CC1Args,
    341                                                    const Twine &Path) {
    342   CC1Args.push_back("-internal-externc-isystem");
    343   CC1Args.push_back(DriverArgs.MakeArgString(Path));
    344 }
    345 
    346 void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs,
    347                                                 ArgStringList &CC1Args,
    348                                                 const Twine &Path) {
    349   if (llvm::sys::fs::exists(Path))
    350     addExternCSystemInclude(DriverArgs, CC1Args, Path);
    351 }
    352 
    353 /// \brief Utility function to add a list of system include directories to CC1.
    354 /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
    355                                              ArgStringList &CC1Args,
    356                                              ArrayRef<StringRef> Paths) {
    357   for (ArrayRef<StringRef>::iterator I = Paths.begin(), E = Paths.end();
    358        I != E; ++I) {
    359     CC1Args.push_back("-internal-isystem");
    360     CC1Args.push_back(DriverArgs.MakeArgString(*I));
    361   }
    362 }
    363 
    364 void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
    365                                              ArgStringList &CC1Args) const {
    366   // Header search paths should be handled by each of the subclasses.
    367   // Historically, they have not been, and instead have been handled inside of
    368   // the CC1-layer frontend. As the logic is hoisted out, this generic function
    369   // will slowly stop being called.
    370   //
    371   // While it is being called, replicate a bit of a hack to propagate the
    372   // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
    373   // header search paths with it. Once all systems are overriding this
    374   // function, the CC1 flag and this line can be removed.
    375   DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
    376 }
    377 
    378 void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
    379                                     ArgStringList &CmdArgs) const {
    380   CXXStdlibType Type = GetCXXStdlibType(Args);
    381 
    382   switch (Type) {
    383   case ToolChain::CST_Libcxx:
    384     CmdArgs.push_back("-lc++");
    385     break;
    386 
    387   case ToolChain::CST_Libstdcxx:
    388     CmdArgs.push_back("-lstdc++");
    389     break;
    390   }
    391 }
    392 
    393 void ToolChain::AddCCKextLibArgs(const ArgList &Args,
    394                                  ArgStringList &CmdArgs) const {
    395   CmdArgs.push_back("-lcc_kext");
    396 }
    397 
    398 bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args,
    399                                               ArgStringList &CmdArgs) const {
    400   // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
    401   // (to keep the linker options consistent with gcc and clang itself).
    402   if (!isOptimizationLevelFast(Args)) {
    403     // Check if -ffast-math or -funsafe-math.
    404     Arg *A =
    405         Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
    406                         options::OPT_funsafe_math_optimizations,
    407                         options::OPT_fno_unsafe_math_optimizations);
    408 
    409     if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
    410         A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
    411       return false;
    412   }
    413   // If crtfastmath.o exists add it to the arguments.
    414   std::string Path = GetFilePath("crtfastmath.o");
    415   if (Path == "crtfastmath.o") // Not found.
    416     return false;
    417 
    418   CmdArgs.push_back(Args.MakeArgString(Path));
    419   return true;
    420 }
    421