Gnu.h revision 341825
1317019Sdim//===--- Gnu.h - Gnu Tool and ToolChain Implementations ---------*- C++ -*-===// 2317019Sdim// 3317019Sdim// The LLVM Compiler Infrastructure 4317019Sdim// 5317019Sdim// This file is distributed under the University of Illinois Open Source 6317019Sdim// License. See LICENSE.TXT for details. 7317019Sdim// 8317019Sdim//===----------------------------------------------------------------------===// 9317019Sdim 10317019Sdim#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H 11317019Sdim#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H 12317019Sdim 13317019Sdim#include "Cuda.h" 14317019Sdim#include "clang/Driver/Tool.h" 15317019Sdim#include "clang/Driver/ToolChain.h" 16317019Sdim#include <set> 17317019Sdim 18317019Sdimnamespace clang { 19317019Sdimnamespace driver { 20317019Sdim 21317019Sdimstruct DetectedMultilibs { 22317019Sdim /// The set of multilibs that the detected installation supports. 23317019Sdim MultilibSet Multilibs; 24317019Sdim 25317019Sdim /// The primary multilib appropriate for the given flags. 26317019Sdim Multilib SelectedMultilib; 27317019Sdim 28317019Sdim /// On Biarch systems, this corresponds to the default multilib when 29317019Sdim /// targeting the non-default multilib. Otherwise, it is empty. 30317019Sdim llvm::Optional<Multilib> BiarchSibling; 31317019Sdim}; 32317019Sdim 33317019Sdimbool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple, 34317019Sdim StringRef Path, const llvm::opt::ArgList &Args, 35317019Sdim DetectedMultilibs &Result); 36317019Sdim 37317019Sdimnamespace tools { 38317019Sdim 39341825Sdim/// Base class for all GNU tools that provide the same behavior when 40317019Sdim/// it comes to response files support 41317019Sdimclass LLVM_LIBRARY_VISIBILITY GnuTool : public Tool { 42317019Sdim virtual void anchor(); 43317019Sdim 44317019Sdimpublic: 45317019Sdim GnuTool(const char *Name, const char *ShortName, const ToolChain &TC) 46317019Sdim : Tool(Name, ShortName, TC, RF_Full, llvm::sys::WEM_CurrentCodePage) {} 47317019Sdim}; 48317019Sdim 49317019Sdim/// Directly call GNU Binutils' assembler and linker. 50317019Sdimnamespace gnutools { 51317019Sdimclass LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { 52317019Sdimpublic: 53317019Sdim Assembler(const ToolChain &TC) : GnuTool("GNU::Assembler", "assembler", TC) {} 54317019Sdim 55317019Sdim bool hasIntegratedCPP() const override { return false; } 56317019Sdim 57317019Sdim void ConstructJob(Compilation &C, const JobAction &JA, 58317019Sdim const InputInfo &Output, const InputInfoList &Inputs, 59317019Sdim const llvm::opt::ArgList &TCArgs, 60317019Sdim const char *LinkingOutput) const override; 61317019Sdim}; 62317019Sdim 63317019Sdimclass LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { 64317019Sdimpublic: 65317019Sdim Linker(const ToolChain &TC) : GnuTool("GNU::Linker", "linker", TC) {} 66317019Sdim 67317019Sdim bool hasIntegratedCPP() const override { return false; } 68317019Sdim bool isLinkJob() const override { return true; } 69317019Sdim 70317019Sdim void ConstructJob(Compilation &C, const JobAction &JA, 71317019Sdim const InputInfo &Output, const InputInfoList &Inputs, 72317019Sdim const llvm::opt::ArgList &TCArgs, 73317019Sdim const char *LinkingOutput) const override; 74317019Sdim}; 75317019Sdim} // end namespace gnutools 76317019Sdim 77317019Sdim/// gcc - Generic GCC tool implementations. 78317019Sdimnamespace gcc { 79317019Sdimclass LLVM_LIBRARY_VISIBILITY Common : public GnuTool { 80317019Sdimpublic: 81317019Sdim Common(const char *Name, const char *ShortName, const ToolChain &TC) 82317019Sdim : GnuTool(Name, ShortName, TC) {} 83317019Sdim 84317019Sdim // A gcc tool has an "integrated" assembler that it will call to produce an 85317019Sdim // object. Let it use that assembler so that we don't have to deal with 86317019Sdim // assembly syntax incompatibilities. 87317019Sdim bool hasIntegratedAssembler() const override { return true; } 88317019Sdim void ConstructJob(Compilation &C, const JobAction &JA, 89317019Sdim const InputInfo &Output, const InputInfoList &Inputs, 90317019Sdim const llvm::opt::ArgList &TCArgs, 91317019Sdim const char *LinkingOutput) const override; 92317019Sdim 93317019Sdim /// RenderExtraToolArgs - Render any arguments necessary to force 94317019Sdim /// the particular tool mode. 95317019Sdim virtual void RenderExtraToolArgs(const JobAction &JA, 96317019Sdim llvm::opt::ArgStringList &CmdArgs) const = 0; 97317019Sdim}; 98317019Sdim 99317019Sdimclass LLVM_LIBRARY_VISIBILITY Preprocessor : public Common { 100317019Sdimpublic: 101317019Sdim Preprocessor(const ToolChain &TC) 102317019Sdim : Common("gcc::Preprocessor", "gcc preprocessor", TC) {} 103317019Sdim 104317019Sdim bool hasGoodDiagnostics() const override { return true; } 105317019Sdim bool hasIntegratedCPP() const override { return false; } 106317019Sdim 107317019Sdim void RenderExtraToolArgs(const JobAction &JA, 108317019Sdim llvm::opt::ArgStringList &CmdArgs) const override; 109317019Sdim}; 110317019Sdim 111317019Sdimclass LLVM_LIBRARY_VISIBILITY Compiler : public Common { 112317019Sdimpublic: 113317019Sdim Compiler(const ToolChain &TC) : Common("gcc::Compiler", "gcc frontend", TC) {} 114317019Sdim 115317019Sdim bool hasGoodDiagnostics() const override { return true; } 116317019Sdim bool hasIntegratedCPP() const override { return true; } 117317019Sdim 118317019Sdim void RenderExtraToolArgs(const JobAction &JA, 119317019Sdim llvm::opt::ArgStringList &CmdArgs) const override; 120317019Sdim}; 121317019Sdim 122317019Sdimclass LLVM_LIBRARY_VISIBILITY Linker : public Common { 123317019Sdimpublic: 124317019Sdim Linker(const ToolChain &TC) : Common("gcc::Linker", "linker (via gcc)", TC) {} 125317019Sdim 126317019Sdim bool hasIntegratedCPP() const override { return false; } 127317019Sdim bool isLinkJob() const override { return true; } 128317019Sdim 129317019Sdim void RenderExtraToolArgs(const JobAction &JA, 130317019Sdim llvm::opt::ArgStringList &CmdArgs) const override; 131317019Sdim}; 132317019Sdim} // end namespace gcc 133317019Sdim} // end namespace tools 134317019Sdim 135317019Sdimnamespace toolchains { 136317019Sdim 137317019Sdim/// Generic_GCC - A tool chain using the 'gcc' command to perform 138317019Sdim/// all subcommands; this relies on gcc translating the majority of 139317019Sdim/// command line options. 140317019Sdimclass LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain { 141317019Sdimpublic: 142341825Sdim /// Struct to store and manipulate GCC versions. 143317019Sdim /// 144317019Sdim /// We rely on assumptions about the form and structure of GCC version 145317019Sdim /// numbers: they consist of at most three '.'-separated components, and each 146317019Sdim /// component is a non-negative integer except for the last component. For 147317019Sdim /// the last component we are very flexible in order to tolerate release 148317019Sdim /// candidates or 'x' wildcards. 149317019Sdim /// 150317019Sdim /// Note that the ordering established among GCCVersions is based on the 151317019Sdim /// preferred version string to use. For example we prefer versions without 152317019Sdim /// a hard-coded patch number to those with a hard coded patch number. 153317019Sdim /// 154317019Sdim /// Currently this doesn't provide any logic for textual suffixes to patches 155317019Sdim /// in the way that (for example) Debian's version format does. If that ever 156317019Sdim /// becomes necessary, it can be added. 157317019Sdim struct GCCVersion { 158341825Sdim /// The unparsed text of the version. 159317019Sdim std::string Text; 160317019Sdim 161341825Sdim /// The parsed major, minor, and patch numbers. 162317019Sdim int Major, Minor, Patch; 163317019Sdim 164341825Sdim /// The text of the parsed major, and major+minor versions. 165317019Sdim std::string MajorStr, MinorStr; 166317019Sdim 167341825Sdim /// Any textual suffix on the patch number. 168317019Sdim std::string PatchSuffix; 169317019Sdim 170317019Sdim static GCCVersion Parse(StringRef VersionText); 171317019Sdim bool isOlderThan(int RHSMajor, int RHSMinor, int RHSPatch, 172317019Sdim StringRef RHSPatchSuffix = StringRef()) const; 173317019Sdim bool operator<(const GCCVersion &RHS) const { 174317019Sdim return isOlderThan(RHS.Major, RHS.Minor, RHS.Patch, RHS.PatchSuffix); 175317019Sdim } 176317019Sdim bool operator>(const GCCVersion &RHS) const { return RHS < *this; } 177317019Sdim bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); } 178317019Sdim bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); } 179317019Sdim }; 180317019Sdim 181341825Sdim /// This is a class to find a viable GCC installation for Clang to 182317019Sdim /// use. 183317019Sdim /// 184317019Sdim /// This class tries to find a GCC installation on the system, and report 185317019Sdim /// information about it. It starts from the host information provided to the 186317019Sdim /// Driver, and has logic for fuzzing that where appropriate. 187317019Sdim class GCCInstallationDetector { 188317019Sdim bool IsValid; 189317019Sdim llvm::Triple GCCTriple; 190317019Sdim const Driver &D; 191317019Sdim 192317019Sdim // FIXME: These might be better as path objects. 193317019Sdim std::string GCCInstallPath; 194317019Sdim std::string GCCParentLibPath; 195317019Sdim 196317019Sdim /// The primary multilib appropriate for the given flags. 197317019Sdim Multilib SelectedMultilib; 198317019Sdim /// On Biarch systems, this corresponds to the default multilib when 199317019Sdim /// targeting the non-default multilib. Otherwise, it is empty. 200317019Sdim llvm::Optional<Multilib> BiarchSibling; 201317019Sdim 202317019Sdim GCCVersion Version; 203317019Sdim 204317019Sdim // We retain the list of install paths that were considered and rejected in 205317019Sdim // order to print out detailed information in verbose mode. 206317019Sdim std::set<std::string> CandidateGCCInstallPaths; 207317019Sdim 208317019Sdim /// The set of multilibs that the detected installation supports. 209317019Sdim MultilibSet Multilibs; 210317019Sdim 211317019Sdim public: 212317019Sdim explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {} 213317019Sdim void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args, 214317019Sdim ArrayRef<std::string> ExtraTripleAliases = None); 215317019Sdim 216341825Sdim /// Check whether we detected a valid GCC install. 217317019Sdim bool isValid() const { return IsValid; } 218317019Sdim 219341825Sdim /// Get the GCC triple for the detected install. 220317019Sdim const llvm::Triple &getTriple() const { return GCCTriple; } 221317019Sdim 222341825Sdim /// Get the detected GCC installation path. 223317019Sdim StringRef getInstallPath() const { return GCCInstallPath; } 224317019Sdim 225341825Sdim /// Get the detected GCC parent lib path. 226317019Sdim StringRef getParentLibPath() const { return GCCParentLibPath; } 227317019Sdim 228341825Sdim /// Get the detected Multilib 229317019Sdim const Multilib &getMultilib() const { return SelectedMultilib; } 230317019Sdim 231341825Sdim /// Get the whole MultilibSet 232317019Sdim const MultilibSet &getMultilibs() const { return Multilibs; } 233317019Sdim 234317019Sdim /// Get the biarch sibling multilib (if it exists). 235317019Sdim /// \return true iff such a sibling exists 236317019Sdim bool getBiarchSibling(Multilib &M) const; 237317019Sdim 238341825Sdim /// Get the detected GCC version string. 239317019Sdim const GCCVersion &getVersion() const { return Version; } 240317019Sdim 241341825Sdim /// Print information about the detected GCC installation. 242317019Sdim void print(raw_ostream &OS) const; 243317019Sdim 244317019Sdim private: 245317019Sdim static void 246317019Sdim CollectLibDirsAndTriples(const llvm::Triple &TargetTriple, 247317019Sdim const llvm::Triple &BiarchTriple, 248317019Sdim SmallVectorImpl<StringRef> &LibDirs, 249317019Sdim SmallVectorImpl<StringRef> &TripleAliases, 250317019Sdim SmallVectorImpl<StringRef> &BiarchLibDirs, 251317019Sdim SmallVectorImpl<StringRef> &BiarchTripleAliases); 252317019Sdim 253341825Sdim void AddDefaultGCCPrefixes(const llvm::Triple &TargetTriple, 254341825Sdim SmallVectorImpl<std::string> &Prefixes, 255341825Sdim StringRef SysRoot); 256341825Sdim 257317019Sdim bool ScanGCCForMultilibs(const llvm::Triple &TargetTriple, 258317019Sdim const llvm::opt::ArgList &Args, 259317019Sdim StringRef Path, 260317019Sdim bool NeedsBiarchSuffix = false); 261317019Sdim 262317019Sdim void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch, 263317019Sdim const llvm::opt::ArgList &Args, 264317019Sdim const std::string &LibDir, 265317019Sdim StringRef CandidateTriple, 266317019Sdim bool NeedsBiarchSuffix = false); 267317019Sdim 268341825Sdim bool ScanGentooConfigs(const llvm::Triple &TargetTriple, 269341825Sdim const llvm::opt::ArgList &Args, 270341825Sdim const SmallVectorImpl<StringRef> &CandidateTriples, 271341825Sdim const SmallVectorImpl<StringRef> &BiarchTriples); 272317019Sdim 273317019Sdim bool ScanGentooGccConfig(const llvm::Triple &TargetTriple, 274317019Sdim const llvm::opt::ArgList &Args, 275317019Sdim StringRef CandidateTriple, 276317019Sdim bool NeedsBiarchSuffix = false); 277317019Sdim }; 278317019Sdim 279317019Sdimprotected: 280317019Sdim GCCInstallationDetector GCCInstallation; 281317019Sdim CudaInstallationDetector CudaInstallation; 282317019Sdim 283317019Sdimpublic: 284317019Sdim Generic_GCC(const Driver &D, const llvm::Triple &Triple, 285317019Sdim const llvm::opt::ArgList &Args); 286317019Sdim ~Generic_GCC() override; 287317019Sdim 288317019Sdim void printVerboseInfo(raw_ostream &OS) const override; 289317019Sdim 290322740Sdim bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override; 291317019Sdim bool isPICDefault() const override; 292317019Sdim bool isPIEDefault() const override; 293317019Sdim bool isPICDefaultForced() const override; 294317019Sdim bool IsIntegratedAssemblerDefault() const override; 295317019Sdim llvm::opt::DerivedArgList * 296317019Sdim TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 297317019Sdim Action::OffloadKind DeviceOffloadKind) const override; 298317019Sdim 299317019Sdimprotected: 300317019Sdim Tool *getTool(Action::ActionClass AC) const override; 301317019Sdim Tool *buildAssembler() const override; 302317019Sdim Tool *buildLinker() const override; 303317019Sdim 304317019Sdim /// \name ToolChain Implementation Helper Functions 305317019Sdim /// @{ 306317019Sdim 307341825Sdim /// Check whether the target triple's architecture is 64-bits. 308317019Sdim bool isTarget64Bit() const { return getTriple().isArch64Bit(); } 309317019Sdim 310341825Sdim /// Check whether the target triple's architecture is 32-bits. 311317019Sdim bool isTarget32Bit() const { return getTriple().isArch32Bit(); } 312317019Sdim 313341825Sdim // FIXME: This should be final, but the CrossWindows toolchain does weird 314341825Sdim // things that can't be easily generalized. 315317019Sdim void AddClangCXXStdlibIncludeArgs( 316317019Sdim const llvm::opt::ArgList &DriverArgs, 317317019Sdim llvm::opt::ArgStringList &CC1Args) const override; 318317019Sdim 319317019Sdim virtual void 320341825Sdim addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, 321341825Sdim llvm::opt::ArgStringList &CC1Args) const; 322341825Sdim virtual void 323317019Sdim addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, 324317019Sdim llvm::opt::ArgStringList &CC1Args) const; 325317019Sdim 326317019Sdim bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple, 327317019Sdim StringRef GCCMultiarchTriple, 328317019Sdim StringRef TargetMultiarchTriple, 329317019Sdim Twine IncludeSuffix, 330317019Sdim const llvm::opt::ArgList &DriverArgs, 331317019Sdim llvm::opt::ArgStringList &CC1Args) const; 332317019Sdim 333317019Sdim /// @} 334317019Sdim 335317019Sdimprivate: 336317019Sdim mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocess; 337317019Sdim mutable std::unique_ptr<tools::gcc::Compiler> Compile; 338317019Sdim}; 339317019Sdim 340317019Sdimclass LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC { 341317019Sdim virtual void anchor(); 342317019Sdim 343317019Sdimpublic: 344317019Sdim Generic_ELF(const Driver &D, const llvm::Triple &Triple, 345317019Sdim const llvm::opt::ArgList &Args) 346317019Sdim : Generic_GCC(D, Triple, Args) {} 347317019Sdim 348317019Sdim void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 349320970Sdim llvm::opt::ArgStringList &CC1Args, 350320970Sdim Action::OffloadKind DeviceOffloadKind) const override; 351317019Sdim}; 352317019Sdim 353317019Sdim} // end namespace toolchains 354317019Sdim} // end namespace driver 355317019Sdim} // end namespace clang 356317019Sdim 357317019Sdim#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H 358