Home | History | Annotate | Download | only in Driver
      1 //===--- ToolChains.h - ToolChain Implementations ---------------*- C++ -*-===//
      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 #ifndef CLANG_LIB_DRIVER_TOOLCHAINS_H_
     11 #define CLANG_LIB_DRIVER_TOOLCHAINS_H_
     12 
     13 #include "clang/Driver/Action.h"
     14 #include "clang/Driver/ToolChain.h"
     15 
     16 #include "llvm/ADT/DenseMap.h"
     17 #include "llvm/Support/Compiler.h"
     18 
     19 #include "Tools.h"
     20 
     21 namespace clang {
     22 namespace driver {
     23 namespace toolchains {
     24 
     25 /// Generic_GCC - A tool chain using the 'gcc' command to perform
     26 /// all subcommands; this relies on gcc translating the majority of
     27 /// command line options.
     28 class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {
     29 protected:
     30   mutable llvm::DenseMap<unsigned, Tool*> Tools;
     31 
     32 public:
     33   Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple);
     34   ~Generic_GCC();
     35 
     36   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
     37                            const ActionList &Inputs) const;
     38 
     39   virtual bool IsUnwindTablesDefault() const;
     40   virtual const char *GetDefaultRelocationModel() const;
     41   virtual const char *GetForcedPicModel() const;
     42 };
     43 
     44 /// Darwin - The base Darwin tool chain.
     45 class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain {
     46 public:
     47   /// The host version.
     48   unsigned DarwinVersion[3];
     49 
     50 private:
     51   mutable llvm::DenseMap<unsigned, Tool*> Tools;
     52 
     53   /// Whether the information on the target has been initialized.
     54   //
     55   // FIXME: This should be eliminated. What we want to do is make this part of
     56   // the "default target for arguments" selection process, once we get out of
     57   // the argument translation business.
     58   mutable bool TargetInitialized;
     59 
     60   // FIXME: Remove this once there is a proper way to detect an ARC runtime
     61   // for the simulator.
     62  public:
     63   mutable enum {
     64     ARCSimulator_None,
     65     ARCSimulator_HasARCRuntime,
     66     ARCSimulator_NoARCRuntime
     67   } ARCRuntimeForSimulator;
     68 
     69   mutable enum {
     70     LibCXXSimulator_None,
     71     LibCXXSimulator_NotAvailable,
     72     LibCXXSimulator_Available
     73   } LibCXXForSimulator;
     74 
     75 private:
     76   /// Whether we are targeting iPhoneOS target.
     77   mutable bool TargetIsIPhoneOS;
     78 
     79   /// Whether we are targeting the iPhoneOS simulator target.
     80   mutable bool TargetIsIPhoneOSSimulator;
     81 
     82   /// The OS version we are targeting.
     83   mutable unsigned TargetVersion[3];
     84 
     85   /// The default macosx-version-min of this tool chain; empty until
     86   /// initialized.
     87   std::string MacosxVersionMin;
     88 
     89   bool hasARCRuntime() const;
     90 
     91 private:
     92   void AddDeploymentTarget(DerivedArgList &Args) const;
     93 
     94 public:
     95   Darwin(const HostInfo &Host, const llvm::Triple& Triple);
     96   ~Darwin();
     97 
     98   std::string ComputeEffectiveClangTriple(const ArgList &Args,
     99                                           types::ID InputType) const;
    100 
    101   /// @name Darwin Specific Toolchain API
    102   /// {
    103 
    104   // FIXME: Eliminate these ...Target functions and derive separate tool chains
    105   // for these targets and put version in constructor.
    106   void setTarget(bool IsIPhoneOS, unsigned Major, unsigned Minor,
    107                  unsigned Micro, bool IsIOSSim) const {
    108     assert((!IsIOSSim || IsIPhoneOS) && "Unexpected deployment target!");
    109 
    110     // FIXME: For now, allow reinitialization as long as values don't
    111     // change. This will go away when we move away from argument translation.
    112     if (TargetInitialized && TargetIsIPhoneOS == IsIPhoneOS &&
    113         TargetIsIPhoneOSSimulator == IsIOSSim &&
    114         TargetVersion[0] == Major && TargetVersion[1] == Minor &&
    115         TargetVersion[2] == Micro)
    116       return;
    117 
    118     assert(!TargetInitialized && "Target already initialized!");
    119     TargetInitialized = true;
    120     TargetIsIPhoneOS = IsIPhoneOS;
    121     TargetIsIPhoneOSSimulator = IsIOSSim;
    122     TargetVersion[0] = Major;
    123     TargetVersion[1] = Minor;
    124     TargetVersion[2] = Micro;
    125   }
    126 
    127   bool isTargetIPhoneOS() const {
    128     assert(TargetInitialized && "Target not initialized!");
    129     return TargetIsIPhoneOS;
    130   }
    131 
    132   bool isTargetIOSSimulator() const {
    133     assert(TargetInitialized && "Target not initialized!");
    134     return TargetIsIPhoneOSSimulator;
    135   }
    136 
    137   bool isTargetInitialized() const { return TargetInitialized; }
    138 
    139   void getTargetVersion(unsigned (&Res)[3]) const {
    140     assert(TargetInitialized && "Target not initialized!");
    141     Res[0] = TargetVersion[0];
    142     Res[1] = TargetVersion[1];
    143     Res[2] = TargetVersion[2];
    144   }
    145 
    146   /// getDarwinArchName - Get the "Darwin" arch name for a particular compiler
    147   /// invocation. For example, Darwin treats different ARM variations as
    148   /// distinct architectures.
    149   StringRef getDarwinArchName(const ArgList &Args) const;
    150 
    151   static bool isVersionLT(unsigned (&A)[3], unsigned (&B)[3]) {
    152     for (unsigned i=0; i < 3; ++i) {
    153       if (A[i] > B[i]) return false;
    154       if (A[i] < B[i]) return true;
    155     }
    156     return false;
    157   }
    158 
    159   bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
    160     assert(isTargetIPhoneOS() && "Unexpected call for OS X target!");
    161     unsigned B[3] = { V0, V1, V2 };
    162     return isVersionLT(TargetVersion, B);
    163   }
    164 
    165   bool isMacosxVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
    166     assert(!isTargetIPhoneOS() && "Unexpected call for iPhoneOS target!");
    167     unsigned B[3] = { V0, V1, V2 };
    168     return isVersionLT(TargetVersion, B);
    169   }
    170 
    171   /// AddLinkSearchPathArgs - Add the linker search paths to \arg CmdArgs.
    172   ///
    173   /// \param Args - The input argument list.
    174   /// \param CmdArgs [out] - The command argument list to append the paths
    175   /// (prefixed by -L) to.
    176   virtual void AddLinkSearchPathArgs(const ArgList &Args,
    177                                      ArgStringList &CmdArgs) const = 0;
    178 
    179   /// AddLinkARCArgs - Add the linker arguments to link the ARC runtime library.
    180   virtual void AddLinkARCArgs(const ArgList &Args,
    181                               ArgStringList &CmdArgs) const = 0;
    182 
    183   /// AddLinkRuntimeLibArgs - Add the linker arguments to link the compiler
    184   /// runtime library.
    185   virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
    186                                      ArgStringList &CmdArgs) const = 0;
    187 
    188   /// }
    189   /// @name ToolChain Implementation
    190   /// {
    191 
    192   virtual types::ID LookupTypeForExtension(const char *Ext) const;
    193 
    194   virtual bool HasNativeLLVMSupport() const;
    195 
    196   virtual void configureObjCRuntime(ObjCRuntime &runtime) const;
    197   virtual bool hasBlocksRuntime() const;
    198 
    199   virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args,
    200                                         const char *BoundArch) const;
    201 
    202   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
    203                            const ActionList &Inputs) const;
    204 
    205   virtual bool IsBlocksDefault() const {
    206     // Always allow blocks on Darwin; users interested in versioning are
    207     // expected to use /usr/include/Blocks.h.
    208     return true;
    209   }
    210   virtual bool IsIntegratedAssemblerDefault() const {
    211 #ifdef DISABLE_DEFAULT_INTEGRATED_ASSEMBLER
    212     return false;
    213 #else
    214     // Default integrated assembler to on for x86.
    215     return (getTriple().getArch() == llvm::Triple::x86 ||
    216             getTriple().getArch() == llvm::Triple::x86_64);
    217 #endif
    218   }
    219   virtual bool IsStrictAliasingDefault() const {
    220 #ifdef DISABLE_DEFAULT_STRICT_ALIASING
    221     return false;
    222 #else
    223     return ToolChain::IsStrictAliasingDefault();
    224 #endif
    225   }
    226 
    227   virtual bool IsObjCDefaultSynthPropertiesDefault() const {
    228     return false;
    229   }
    230 
    231   virtual bool IsObjCNonFragileABIDefault() const {
    232     // Non-fragile ABI is default for everything but i386.
    233     return getTriple().getArch() != llvm::Triple::x86;
    234   }
    235   virtual bool IsObjCLegacyDispatchDefault() const {
    236     // This is only used with the non-fragile ABI.
    237 
    238     // Legacy dispatch is used everywhere except on x86_64.
    239     return getTriple().getArch() != llvm::Triple::x86_64;
    240   }
    241   virtual bool UseObjCMixedDispatch() const {
    242     // This is only used with the non-fragile ABI and non-legacy dispatch.
    243 
    244     // Mixed dispatch is used everywhere except OS X before 10.6.
    245     return !(!isTargetIPhoneOS() && isMacosxVersionLT(10, 6));
    246   }
    247   virtual bool IsUnwindTablesDefault() const;
    248   virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
    249     // Stack protectors default to on for user code on 10.5,
    250     // and for everything in 10.6 and beyond
    251     return !isTargetIPhoneOS() &&
    252       (!isMacosxVersionLT(10, 6) ||
    253          (!isMacosxVersionLT(10, 5) && !KernelOrKext));
    254   }
    255   virtual const char *GetDefaultRelocationModel() const;
    256   virtual const char *GetForcedPicModel() const;
    257 
    258   virtual bool SupportsProfiling() const;
    259 
    260   virtual bool SupportsObjCGC() const;
    261 
    262   virtual bool UseDwarfDebugFlags() const;
    263 
    264   virtual bool UseSjLjExceptions() const;
    265 
    266   /// }
    267 };
    268 
    269 /// DarwinClang - The Darwin toolchain used by Clang.
    270 class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
    271 private:
    272   void AddGCCLibexecPath(unsigned darwinVersion);
    273 
    274 public:
    275   DarwinClang(const HostInfo &Host, const llvm::Triple& Triple);
    276 
    277   /// @name Darwin ToolChain Implementation
    278   /// {
    279 
    280   virtual void AddLinkSearchPathArgs(const ArgList &Args,
    281                                     ArgStringList &CmdArgs) const;
    282 
    283   virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
    284                                      ArgStringList &CmdArgs) const;
    285   void AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
    286                          const char *DarwinStaticLib) const;
    287 
    288   virtual void AddCXXStdlibLibArgs(const ArgList &Args,
    289                                    ArgStringList &CmdArgs) const;
    290 
    291   virtual void AddCCKextLibArgs(const ArgList &Args,
    292                                 ArgStringList &CmdArgs) const;
    293 
    294   virtual void AddLinkARCArgs(const ArgList &Args,
    295                               ArgStringList &CmdArgs) const;
    296   /// }
    297 };
    298 
    299 /// Darwin_Generic_GCC - Generic Darwin tool chain using gcc.
    300 class LLVM_LIBRARY_VISIBILITY Darwin_Generic_GCC : public Generic_GCC {
    301 public:
    302   Darwin_Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple)
    303     : Generic_GCC(Host, Triple) {}
    304 
    305   std::string ComputeEffectiveClangTriple(const ArgList &Args,
    306                                           types::ID InputType) const;
    307 
    308   virtual const char *GetDefaultRelocationModel() const { return "pic"; }
    309 };
    310 
    311 class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {
    312  public:
    313   Generic_ELF(const HostInfo &Host, const llvm::Triple& Triple)
    314     : Generic_GCC(Host, Triple) {}
    315 
    316   virtual bool IsIntegratedAssemblerDefault() const {
    317     // Default integrated assembler to on for x86.
    318     return (getTriple().getArch() == llvm::Triple::x86 ||
    319             getTriple().getArch() == llvm::Triple::x86_64);
    320   }
    321 };
    322 
    323 class LLVM_LIBRARY_VISIBILITY AuroraUX : public Generic_GCC {
    324 public:
    325   AuroraUX(const HostInfo &Host, const llvm::Triple& Triple);
    326 
    327   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
    328                            const ActionList &Inputs) const;
    329 };
    330 
    331 class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF {
    332 public:
    333   OpenBSD(const HostInfo &Host, const llvm::Triple& Triple);
    334 
    335   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
    336                            const ActionList &Inputs) const;
    337 };
    338 
    339 class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
    340 public:
    341   FreeBSD(const HostInfo &Host, const llvm::Triple& Triple);
    342 
    343   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
    344                            const ActionList &Inputs) const;
    345 };
    346 
    347 class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF {
    348   const llvm::Triple ToolTriple;
    349 
    350 public:
    351   NetBSD(const HostInfo &Host, const llvm::Triple& Triple,
    352          const llvm::Triple& ToolTriple);
    353 
    354   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
    355                            const ActionList &Inputs) const;
    356 };
    357 
    358 class LLVM_LIBRARY_VISIBILITY Minix : public Generic_GCC {
    359 public:
    360   Minix(const HostInfo &Host, const llvm::Triple& Triple);
    361 
    362   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
    363                            const ActionList &Inputs) const;
    364 };
    365 
    366 class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
    367 public:
    368   DragonFly(const HostInfo &Host, const llvm::Triple& Triple);
    369 
    370   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
    371                            const ActionList &Inputs) const;
    372 };
    373 
    374 class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
    375 public:
    376   Linux(const HostInfo &Host, const llvm::Triple& Triple);
    377 
    378   virtual bool HasNativeLLVMSupport() const;
    379 
    380   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
    381                            const ActionList &Inputs) const;
    382 
    383   std::string Linker;
    384   std::vector<std::string> ExtraOpts;
    385 };
    386 
    387 
    388 /// TCEToolChain - A tool chain using the llvm bitcode tools to perform
    389 /// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
    390 class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain {
    391 public:
    392   TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple);
    393   ~TCEToolChain();
    394 
    395   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
    396                            const ActionList &Inputs) const;
    397   bool IsMathErrnoDefault() const;
    398   bool IsUnwindTablesDefault() const;
    399   const char* GetDefaultRelocationModel() const;
    400   const char* GetForcedPicModel() const;
    401 
    402 private:
    403   mutable llvm::DenseMap<unsigned, Tool*> Tools;
    404 
    405 };
    406 
    407 class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain {
    408   mutable llvm::DenseMap<unsigned, Tool*> Tools;
    409 
    410 public:
    411   Windows(const HostInfo &Host, const llvm::Triple& Triple);
    412 
    413   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
    414                            const ActionList &Inputs) const;
    415 
    416   virtual bool IsIntegratedAssemblerDefault() const;
    417   virtual bool IsUnwindTablesDefault() const;
    418   virtual const char *GetDefaultRelocationModel() const;
    419   virtual const char *GetForcedPicModel() const;
    420 };
    421 
    422 } // end namespace toolchains
    423 } // end namespace driver
    424 } // end namespace clang
    425 
    426 #endif
    427