1 //===--- MSVC.h - MSVC ToolChain Implementations ----------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H 10 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H 11 12 #include "Cuda.h" 13 #include "clang/Basic/DebugInfoOptions.h" 14 #include "clang/Driver/Compilation.h" 15 #include "clang/Driver/Tool.h" 16 #include "clang/Driver/ToolChain.h" 17 18 namespace clang { 19 namespace driver { 20 namespace tools { 21 22 /// Visual studio tools. 23 namespace visualstudio { 24 class LLVM_LIBRARY_VISIBILITY Linker : public Tool { 25 public: 26 Linker(const ToolChain &TC) 27 : Tool("visualstudio::Linker", "linker", TC, RF_Full, 28 llvm::sys::WEM_UTF16) {} 29 30 bool hasIntegratedCPP() const override { return false; } 31 bool isLinkJob() const override { return true; } 32 33 void ConstructJob(Compilation &C, const JobAction &JA, 34 const InputInfo &Output, const InputInfoList &Inputs, 35 const llvm::opt::ArgList &TCArgs, 36 const char *LinkingOutput) const override; 37 }; 38 39 class LLVM_LIBRARY_VISIBILITY Compiler : public Tool { 40 public: 41 Compiler(const ToolChain &TC) 42 : Tool("visualstudio::Compiler", "compiler", TC, RF_Full, 43 llvm::sys::WEM_UTF16) {} 44 45 bool hasIntegratedAssembler() const override { return true; } 46 bool hasIntegratedCPP() const override { return true; } 47 bool isLinkJob() const override { return false; } 48 49 void ConstructJob(Compilation &C, const JobAction &JA, 50 const InputInfo &Output, const InputInfoList &Inputs, 51 const llvm::opt::ArgList &TCArgs, 52 const char *LinkingOutput) const override; 53 54 std::unique_ptr<Command> GetCommand(Compilation &C, const JobAction &JA, 55 const InputInfo &Output, 56 const InputInfoList &Inputs, 57 const llvm::opt::ArgList &TCArgs, 58 const char *LinkingOutput) const; 59 }; 60 } // end namespace visualstudio 61 62 } // end namespace tools 63 64 namespace toolchains { 65 66 class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain { 67 public: 68 MSVCToolChain(const Driver &D, const llvm::Triple &Triple, 69 const llvm::opt::ArgList &Args); 70 71 llvm::opt::DerivedArgList * 72 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 73 Action::OffloadKind DeviceOffloadKind) const override; 74 75 bool IsIntegratedAssemblerDefault() const override; 76 bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override; 77 bool isPICDefault() const override; 78 bool isPIEDefault() const override; 79 bool isPICDefaultForced() const override; 80 81 /// Set CodeView as the default debug info format. Users can use -gcodeview 82 /// and -gdwarf to override the default. 83 codegenoptions::DebugInfoFormat getDefaultDebugFormat() const override { 84 return codegenoptions::DIF_CodeView; 85 } 86 87 /// Set the debugger tuning to "default", since we're definitely not tuning 88 /// for GDB. 89 llvm::DebuggerKind getDefaultDebuggerTuning() const override { 90 return llvm::DebuggerKind::Default; 91 } 92 93 enum class SubDirectoryType { 94 Bin, 95 Include, 96 Lib, 97 }; 98 std::string getSubDirectoryPath(SubDirectoryType Type, 99 llvm::Triple::ArchType TargetArch) const; 100 101 // Convenience overload. 102 // Uses the current target arch. 103 std::string getSubDirectoryPath(SubDirectoryType Type) const { 104 return getSubDirectoryPath(Type, getArch()); 105 } 106 107 enum class ToolsetLayout { 108 OlderVS, 109 VS2017OrNewer, 110 DevDivInternal, 111 }; 112 bool getIsVS2017OrNewer() const { return VSLayout == ToolsetLayout::VS2017OrNewer; } 113 114 void 115 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 116 llvm::opt::ArgStringList &CC1Args) const override; 117 void AddClangCXXStdlibIncludeArgs( 118 const llvm::opt::ArgList &DriverArgs, 119 llvm::opt::ArgStringList &CC1Args) const override; 120 121 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 122 llvm::opt::ArgStringList &CC1Args) const override; 123 124 bool getWindowsSDKLibraryPath(std::string &path) const; 125 /// Check if Universal CRT should be used if available 126 bool getUniversalCRTLibraryPath(std::string &path) const; 127 bool useUniversalCRT() const; 128 VersionTuple 129 computeMSVCVersion(const Driver *D, 130 const llvm::opt::ArgList &Args) const override; 131 132 std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, 133 types::ID InputType) const override; 134 SanitizerMask getSupportedSanitizers() const override; 135 136 void printVerboseInfo(raw_ostream &OS) const override; 137 138 bool FoundMSVCInstall() const { return !VCToolChainPath.empty(); } 139 140 protected: 141 void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs, 142 llvm::opt::ArgStringList &CC1Args, 143 const std::string &folder, 144 const Twine &subfolder1, 145 const Twine &subfolder2 = "", 146 const Twine &subfolder3 = "") const; 147 148 Tool *buildLinker() const override; 149 Tool *buildAssembler() const override; 150 private: 151 std::string VCToolChainPath; 152 ToolsetLayout VSLayout = ToolsetLayout::OlderVS; 153 CudaInstallationDetector CudaInstallation; 154 }; 155 156 } // end namespace toolchains 157 } // end namespace driver 158 } // end namespace clang 159 160 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSVC_H 161