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 "clang/Driver/ToolChain.h"
00011 
00012 #include "clang/Driver/Action.h"
00013 #include "clang/Driver/Arg.h"
00014 #include "clang/Driver/ArgList.h"
00015 #include "clang/Driver/Driver.h"
00016 #include "clang/Driver/DriverDiagnostic.h"
00017 #include "clang/Driver/ObjCRuntime.h"
00018 #include "clang/Driver/Options.h"
00019 #include "llvm/ADT/StringSwitch.h"
00020 #include "llvm/Support/ErrorHandling.h"
00021 using namespace clang::driver;
00022 using namespace clang;
00023 
00024 ToolChain::ToolChain(const Driver &D, const llvm::Triple &T)
00025   : D(D), Triple(T) {
00026 }
00027 
00028 ToolChain::~ToolChain() {
00029 }
00030 
00031 const Driver &ToolChain::getDriver() const {
00032  return D;
00033 }
00034 
00035 std::string ToolChain::GetFilePath(const char *Name) const {
00036   return D.GetFilePath(Name, *this);
00037 
00038 }
00039 
00040 std::string ToolChain::GetProgramPath(const char *Name, bool WantFile) const {
00041   return D.GetProgramPath(Name, *this, WantFile);
00042 }
00043 
00044 types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
00045   return types::lookupTypeForExtension(Ext);
00046 }
00047 
00048 bool ToolChain::HasNativeLLVMSupport() const {
00049   return false;
00050 }
00051 
00052 void ToolChain::configureObjCRuntime(ObjCRuntime &runtime) const {
00053   switch (runtime.getKind()) {
00054   case ObjCRuntime::NeXT:
00055     // Assume a minimal NeXT runtime.
00056     runtime.HasARC = false;
00057     runtime.HasWeak = false;
00058     runtime.HasSubscripting = false;
00059     runtime.HasTerminate = false;
00060     return;
00061 
00062   case ObjCRuntime::GNU:
00063     // Assume a maximal GNU runtime.
00064     runtime.HasARC = true;
00065     runtime.HasWeak = true;
00066     runtime.HasSubscripting = false; // to be added
00067     runtime.HasTerminate = false; // to be added
00068     return;
00069   }
00070   llvm_unreachable("invalid runtime kind!");
00071 }
00072 
00073 /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
00074 //
00075 // FIXME: tblgen this.
00076 static const char *getARMTargetCPU(const ArgList &Args,
00077                                    const llvm::Triple &Triple) {
00078   // For Darwin targets, the -arch option (which is translated to a
00079   // corresponding -march option) should determine the architecture
00080   // (and the Mach-O slice) regardless of any -mcpu options.
00081   if (!Triple.isOSDarwin()) {
00082     // FIXME: Warn on inconsistent use of -mcpu and -march.
00083     // If we have -mcpu=, use that.
00084     if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
00085       return A->getValue(Args);
00086   }
00087 
00088   StringRef MArch;
00089   if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
00090     // Otherwise, if we have -march= choose the base CPU for that arch.
00091     MArch = A->getValue(Args);
00092   } else {
00093     // Otherwise, use the Arch from the triple.
00094     MArch = Triple.getArchName();
00095   }
00096 
00097   return llvm::StringSwitch<const char *>(MArch)
00098     .Cases("armv2", "armv2a","arm2")
00099     .Case("armv3", "arm6")
00100     .Case("armv3m", "arm7m")
00101     .Cases("armv4", "armv4t", "arm7tdmi")
00102     .Cases("armv5", "armv5t", "arm10tdmi")
00103     .Cases("armv5e", "armv5te", "arm1026ejs")
00104     .Case("armv5tej", "arm926ej-s")
00105     .Cases("armv6", "armv6k", "arm1136jf-s")
00106     .Case("armv6j", "arm1136j-s")
00107     .Cases("armv6z", "armv6zk", "arm1176jzf-s")
00108     .Case("armv6t2", "arm1156t2-s")
00109     .Cases("armv7", "armv7a", "armv7-a", "cortex-a8")
00110     .Cases("armv7r", "armv7-r", "cortex-r4")
00111     .Cases("armv7m", "armv7-m", "cortex-m3")
00112     .Case("ep9312", "ep9312")
00113     .Case("iwmmxt", "iwmmxt")
00114     .Case("xscale", "xscale")
00115     .Cases("armv6m", "armv6-m", "cortex-m0")
00116     // If all else failed, return the most base CPU LLVM supports.
00117     .Default("arm7tdmi");
00118 }
00119 
00120 /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
00121 /// CPU.
00122 //
00123 // FIXME: This is redundant with -mcpu, why does LLVM use this.
00124 // FIXME: tblgen this, or kill it!
00125 static const char *getLLVMArchSuffixForARM(StringRef CPU) {
00126   return llvm::StringSwitch<const char *>(CPU)
00127     .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t")
00128     .Cases("arm720t", "arm9", "arm9tdmi", "v4t")
00129     .Cases("arm920", "arm920t", "arm922t", "v4t")
00130     .Cases("arm940t", "ep9312","v4t")
00131     .Cases("arm10tdmi",  "arm1020t", "v5")
00132     .Cases("arm9e",  "arm926ej-s",  "arm946e-s", "v5e")
00133     .Cases("arm966e-s",  "arm968e-s",  "arm10e", "v5e")
00134     .Cases("arm1020e",  "arm1022e",  "xscale", "iwmmxt", "v5e")
00135     .Cases("arm1136j-s",  "arm1136jf-s",  "arm1176jz-s", "v6")
00136     .Cases("arm1176jzf-s",  "mpcorenovfp",  "mpcore", "v6")
00137     .Cases("arm1156t2-s",  "arm1156t2f-s", "v6t2")
00138     .Cases("cortex-a8", "cortex-a9", "v7")
00139     .Case("cortex-m3", "v7m")
00140     .Case("cortex-m4", "v7m")
00141     .Case("cortex-m0", "v6m")
00142     .Default("");
00143 }
00144 
00145 std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, 
00146                                          types::ID InputType) const {
00147   switch (getTriple().getArch()) {
00148   default:
00149     return getTripleString();
00150 
00151   case llvm::Triple::arm:
00152   case llvm::Triple::thumb: {
00153     // FIXME: Factor into subclasses.
00154     llvm::Triple Triple = getTriple();
00155 
00156     // Thumb2 is the default for V7 on Darwin.
00157     //
00158     // FIXME: Thumb should just be another -target-feaure, not in the triple.
00159     StringRef Suffix =
00160       getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
00161     bool ThumbDefault = (Suffix == "v7" && getTriple().isOSDarwin());
00162     std::string ArchName = "arm";
00163 
00164     // Assembly files should start in ARM mode.
00165     if (InputType != types::TY_PP_Asm &&
00166         Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault))
00167       ArchName = "thumb";
00168     Triple.setArchName(ArchName + Suffix.str());
00169 
00170     return Triple.getTriple();
00171   }
00172   }
00173 }
00174 
00175 std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args, 
00176                                                    types::ID InputType) const {
00177   // Diagnose use of Darwin OS deployment target arguments on non-Darwin.
00178   if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ,
00179                                options::OPT_miphoneos_version_min_EQ,
00180                                options::OPT_mios_simulator_version_min_EQ))
00181     getDriver().Diag(diag::err_drv_clang_unsupported)
00182       << A->getAsString(Args);
00183 
00184   return ComputeLLVMTriple(Args, InputType);
00185 }
00186 
00187 void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
00188                                           ArgStringList &CC1Args) const {
00189   // Each toolchain should provide the appropriate include flags.
00190 }
00191 
00192 ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
00193   const ArgList &Args) const
00194 {
00195   if (Arg *A = Args.getLastArg(options::OPT_rtlib_EQ)) {
00196     StringRef Value = A->getValue(Args);
00197     if (Value == "compiler-rt")
00198       return ToolChain::RLT_CompilerRT;
00199     if (Value == "libgcc")
00200       return ToolChain::RLT_Libgcc;
00201     getDriver().Diag(diag::err_drv_invalid_rtlib_name)
00202       << A->getAsString(Args);
00203   }
00204 
00205   return GetDefaultRuntimeLibType();
00206 }
00207 
00208 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
00209   if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
00210     StringRef Value = A->getValue(Args);
00211     if (Value == "libc++")
00212       return ToolChain::CST_Libcxx;
00213     if (Value == "libstdc++")
00214       return ToolChain::CST_Libstdcxx;
00215     getDriver().Diag(diag::err_drv_invalid_stdlib_name)
00216       << A->getAsString(Args);
00217   }
00218 
00219   return ToolChain::CST_Libstdcxx;
00220 }
00221 
00222 /// \brief Utility function to add a system include directory to CC1 arguments.
00223 /*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs,
00224                                             ArgStringList &CC1Args,
00225                                             const Twine &Path) {
00226   CC1Args.push_back("-internal-isystem");
00227   CC1Args.push_back(DriverArgs.MakeArgString(Path));
00228 }
00229 
00230 /// \brief Utility function to add a system include directory with extern "C"
00231 /// semantics to CC1 arguments.
00232 ///
00233 /// Note that this should be used rarely, and only for directories that
00234 /// historically and for legacy reasons are treated as having implicit extern
00235 /// "C" semantics. These semantics are *ignored* by and large today, but its
00236 /// important to preserve the preprocessor changes resulting from the
00237 /// classification.
00238 /*static*/ void ToolChain::addExternCSystemInclude(const ArgList &DriverArgs,
00239                                                    ArgStringList &CC1Args,
00240                                                    const Twine &Path) {
00241   CC1Args.push_back("-internal-externc-isystem");
00242   CC1Args.push_back(DriverArgs.MakeArgString(Path));
00243 }
00244 
00245 /// \brief Utility function to add a list of system include directories to CC1.
00246 /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
00247                                              ArgStringList &CC1Args,
00248                                              ArrayRef<StringRef> Paths) {
00249   for (ArrayRef<StringRef>::iterator I = Paths.begin(), E = Paths.end();
00250        I != E; ++I) {
00251     CC1Args.push_back("-internal-isystem");
00252     CC1Args.push_back(DriverArgs.MakeArgString(*I));
00253   }
00254 }
00255 
00256 void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
00257                                              ArgStringList &CC1Args) const {
00258   // Header search paths should be handled by each of the subclasses.
00259   // Historically, they have not been, and instead have been handled inside of
00260   // the CC1-layer frontend. As the logic is hoisted out, this generic function
00261   // will slowly stop being called.
00262   //
00263   // While it is being called, replicate a bit of a hack to propagate the
00264   // '-stdlib=' flag down to CC1 so that it can in turn customize the C++
00265   // header search paths with it. Once all systems are overriding this
00266   // function, the CC1 flag and this line can be removed.
00267   DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
00268 }
00269 
00270 void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
00271                                     ArgStringList &CmdArgs) const {
00272   CXXStdlibType Type = GetCXXStdlibType(Args);
00273 
00274   switch (Type) {
00275   case ToolChain::CST_Libcxx:
00276     CmdArgs.push_back("-lc++");
00277     break;
00278 
00279   case ToolChain::CST_Libstdcxx:
00280     CmdArgs.push_back("-lstdc++");
00281     break;
00282   }
00283 }
00284 
00285 void ToolChain::AddCCKextLibArgs(const ArgList &Args,
00286                                  ArgStringList &CmdArgs) const {
00287   CmdArgs.push_back("-lcc_kext");
00288 }