clang API Documentation
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 }