20 #include "llvm/ADT/StringExtras.h" 21 #include "llvm/ADT/StringSwitch.h" 22 #include "llvm/Config/llvm-config.h" 23 #include "llvm/Option/Arg.h" 24 #include "llvm/Option/ArgList.h" 25 #include "llvm/Support/ConvertUTF.h" 26 #include "llvm/Support/ErrorHandling.h" 27 #include "llvm/Support/FileSystem.h" 28 #include "llvm/Support/Host.h" 29 #include "llvm/Support/MemoryBuffer.h" 30 #include "llvm/Support/Path.h" 31 #include "llvm/Support/Process.h" 36 #if defined(LLVM_ON_WIN32) 41 #define WIN32_LEAN_AND_MEAN 51 #define USE_MSVC_SETUP_API 57 #include "llvm/Support/COM.h" 69 using namespace clang;
75 std::string &value, std::string *phValue);
83 llvm::sys::Process::GetEnv(
"VCToolsInstallDir")) {
86 Path = std::move(*VCToolsInstallDir);
91 llvm::sys::Process::GetEnv(
"VCINSTALLDIR")) {
96 Path = std::move(*VCInstallDir);
105 llvm::sys::Process::GetEnv(
"PATH")) {
107 llvm::StringRef(*PathEnv).split(PathEntries, llvm::sys::EnvPathSeparator);
108 for (llvm::StringRef PathEntry : PathEntries) {
109 if (PathEntry.empty())
115 ExeTestPath = PathEntry;
116 llvm::sys::path::append(ExeTestPath,
"cl.exe");
117 if (!llvm::sys::fs::exists(ExeTestPath))
122 ExeTestPath = PathEntry;
123 llvm::sys::path::append(ExeTestPath,
"link.exe");
124 if (!llvm::sys::fs::exists(ExeTestPath))
128 llvm::StringRef TestPath = PathEntry;
129 bool IsBin = llvm::sys::path::filename(TestPath).equals_lower(
"bin");
132 TestPath = llvm::sys::path::parent_path(TestPath);
133 IsBin = llvm::sys::path::filename(TestPath).equals_lower(
"bin");
136 llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath);
137 llvm::StringRef ParentFilename = llvm::sys::path::filename(ParentPath);
138 if (ParentFilename ==
"VC") {
143 if (ParentFilename ==
"x86ret" || ParentFilename ==
"x86chk" 144 || ParentFilename ==
"amd64ret" || ParentFilename ==
"amd64chk") {
155 llvm::StringRef ExpectedPrefixes[] = {
"",
"Host",
"bin",
"",
156 "MSVC",
"Tools",
"VC"};
158 auto It = llvm::sys::path::rbegin(PathEntry);
159 auto End = llvm::sys::path::rend(PathEntry);
160 for (llvm::StringRef Prefix : ExpectedPrefixes) {
163 if (!It->startswith(Prefix))
170 llvm::StringRef ToolChainPath(PathEntry);
171 for (
int i = 0; i < 3; ++i)
172 ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
174 Path = ToolChainPath;
192 #if !defined(USE_MSVC_SETUP_API) 198 llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::SingleThreaded);
206 struct SuppressCOMErrorsRAII {
207 static void __stdcall handler(HRESULT hr, IErrorInfo *perrinfo) {}
209 SuppressCOMErrorsRAII() { _set_com_error_handler(handler); }
211 ~SuppressCOMErrorsRAII() { _set_com_error_handler(_com_raise_error); }
213 } COMErrorSuppressor;
215 ISetupConfigurationPtr Query;
216 HR = Query.CreateInstance(__uuidof(SetupConfiguration));
220 IEnumSetupInstancesPtr EnumInstances;
221 HR = ISetupConfiguration2Ptr(Query)->EnumAllInstances(&EnumInstances);
225 ISetupInstancePtr Instance;
226 HR = EnumInstances->Next(1, &Instance,
nullptr);
230 ISetupInstancePtr NewestInstance;
233 bstr_t VersionString;
235 HR = Instance->GetInstallationVersion(VersionString.GetAddress());
238 HR = ISetupHelperPtr(Query)->ParseVersion(VersionString, &VersionNum);
241 if (!NewestVersionNum || (VersionNum > NewestVersionNum)) {
242 NewestInstance = Instance;
243 NewestVersionNum = VersionNum;
245 }
while ((HR = EnumInstances->Next(1, &Instance,
nullptr)) == S_OK);
251 HR = NewestInstance->ResolvePath(L
"VC", VCPathWide.GetAddress());
255 std::string VCRootPath;
256 llvm::convertWideToUTF8(std::wstring(VCPathWide), VCRootPath);
259 llvm::sys::path::append(ToolsVersionFilePath,
"Auxiliary",
"Build",
260 "Microsoft.VCToolsVersion.default.txt");
262 auto ToolsVersionFile = llvm::MemoryBuffer::getFile(ToolsVersionFilePath);
263 if (!ToolsVersionFile)
267 llvm::sys::path::append(ToolchainPath,
"Tools",
"MSVC",
268 ToolsVersionFile->get()->getBuffer().rtrim());
269 if (!llvm::sys::fs::is_directory(ToolchainPath))
272 Path = ToolchainPath.str();
283 std::string VSInstallPath;
285 "InstallDir", VSInstallPath,
nullptr) ||
287 "InstallDir", VSInstallPath,
nullptr)) {
288 if (!VSInstallPath.empty()) {
290 VSInstallPath.c_str(), VSInstallPath.find(R
"(\Common7\IDE)"))); 291 llvm::sys::path::append(VCPath, "VC");
310 llvm::sys::path::append(FilePath, Exe);
311 return llvm::sys::fs::can_execute(FilePath) ? FilePath.str() : Exe;
318 const char *LinkingOutput)
const {
319 ArgStringList CmdArgs;
326 Args.MakeArgString(std::string(
"-out:") + Output.
getFilename()));
328 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
330 CmdArgs.push_back(
"-defaultlib:libcmt");
332 if (!llvm::sys::Process::GetEnv(
"LIB")) {
337 CmdArgs.push_back(Args.MakeArgString(
339 TC.getSubDirectoryPath(
342 if (TC.useUniversalCRT()) {
343 std::string UniversalCRTLibPath;
344 if (TC.getUniversalCRTLibraryPath(UniversalCRTLibPath))
346 Args.MakeArgString(Twine(
"-libpath:") + UniversalCRTLibPath));
349 std::string WindowsSdkLibPath;
350 if (TC.getWindowsSDKLibraryPath(WindowsSdkLibPath))
352 Args.MakeArgString(std::string(
"-libpath:") + WindowsSdkLibPath));
356 for (
const auto &LibPath : Args.getAllArgValues(options::OPT_L))
357 CmdArgs.push_back(Args.MakeArgString(
"-libpath:" + LibPath));
359 CmdArgs.push_back(
"-nologo");
361 if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7,
362 options::OPT__SLASH_Zd))
363 CmdArgs.push_back(
"-debug");
365 bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
366 options::OPT_shared);
368 CmdArgs.push_back(Args.MakeArgString(
"-dll"));
371 llvm::sys::path::replace_extension(ImplibName,
"lib");
372 CmdArgs.push_back(Args.MakeArgString(std::string(
"-implib:") + ImplibName));
375 if (TC.getSanitizerArgs().needsAsanRt()) {
376 CmdArgs.push_back(Args.MakeArgString(
"-debug"));
377 CmdArgs.push_back(Args.MakeArgString(
"-incremental:no"));
378 if (TC.getSanitizerArgs().needsSharedRt() ||
379 Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
380 for (
const auto &Lib : {
"asan_dynamic",
"asan_dynamic_runtime_thunk"})
381 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
384 CmdArgs.push_back(Args.MakeArgString(
385 TC.getArch() == llvm::Triple::x86
386 ?
"-include:___asan_seh_interceptor" 387 :
"-include:__asan_seh_interceptor"));
390 CmdArgs.push_back(Args.MakeArgString(std::string(
"-wholearchive:") +
391 TC.getCompilerRT(Args,
"asan_dynamic_runtime_thunk")));
393 CmdArgs.push_back(TC.getCompilerRTArgString(Args,
"asan_dll_thunk"));
395 for (
const auto &Lib : {
"asan",
"asan_cxx"}) {
396 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
400 CmdArgs.push_back(Args.MakeArgString(std::string(
"-wholearchive:") +
401 TC.getCompilerRT(Args, Lib)));
406 Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
408 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
409 options::OPT_fno_openmp,
false)) {
410 CmdArgs.push_back(
"-nodefaultlib:vcomp.lib");
411 CmdArgs.push_back(
"-nodefaultlib:vcompd.lib");
412 CmdArgs.push_back(Args.MakeArgString(std::string(
"-libpath:") +
413 TC.getDriver().Dir +
"/../lib"));
414 switch (TC.getDriver().getOpenMPRuntime(Args)) {
416 CmdArgs.push_back(
"-defaultlib:libomp.lib");
419 CmdArgs.push_back(
"-defaultlib:libiomp5md.lib");
431 if (!Args.hasArg(options::OPT_nostdlib)) {
436 for (
const auto &Input : Inputs) {
437 if (Input.isFilename()) {
438 CmdArgs.push_back(Input.getFilename());
442 const Arg &A = Input.getInputArg();
445 if (A.getOption().matches(options::OPT_l)) {
446 StringRef Lib = A.getValue();
447 const char *LinkLibArg;
448 if (Lib.endswith(
".lib"))
449 LinkLibArg = Args.MakeArgString(Lib);
451 LinkLibArg = Args.MakeArgString(Lib +
".lib");
452 CmdArgs.push_back(LinkLibArg);
458 A.renderAsInput(Args, CmdArgs);
461 TC.addProfileRTLibs(Args, CmdArgs);
463 std::vector<const char *> Environment;
469 StringRef
Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ,
"link");
470 if (Linker.equals_lower(
"lld"))
473 if (Linker.equals_lower(
"link")) {
486 if (TC.getIsVS2017OrNewer() &&
487 llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
488 auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
491 std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
492 GetEnvironmentStringsW(), FreeEnvironmentStringsW);
494 goto SkipSettingEnvironment;
497 size_t EnvBlockLen = 0;
498 while (EnvBlockWide[EnvBlockLen] != L
'\0') {
500 EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
505 std::string EnvBlock;
506 if (!llvm::convertUTF16ToUTF8String(
508 EnvBlockLen *
sizeof(EnvBlockWide[0])),
510 goto SkipSettingEnvironment;
512 Environment.reserve(EnvCount);
517 for (
const char *
Cursor = EnvBlock.data(); *
Cursor !=
'\0';) {
518 llvm::StringRef EnvVar(
Cursor);
519 if (EnvVar.startswith_lower(
"path=")) {
521 constexpr
size_t PrefixLen = 5;
522 Environment.push_back(Args.MakeArgString(
523 EnvVar.substr(0, PrefixLen) +
524 TC.getSubDirectoryPath(SubDirectoryType::Bin) +
525 llvm::Twine(llvm::sys::EnvPathSeparator) +
526 TC.getSubDirectoryPath(SubDirectoryType::Bin, HostArch) +
527 (EnvVar.size() > PrefixLen
528 ? llvm::Twine(llvm::sys::EnvPathSeparator) +
529 EnvVar.substr(PrefixLen)
532 Environment.push_back(Args.MakeArgString(EnvVar));
534 Cursor += EnvVar.size() + 1 ;
537 SkipSettingEnvironment:;
540 linkPath = TC.GetProgramPath(Linker.str().c_str());
543 auto LinkCmd = llvm::make_unique<Command>(
544 JA, *
this, Args.MakeArgString(linkPath), CmdArgs, Inputs);
545 if (!Environment.empty())
546 LinkCmd->setEnvironment(Environment);
554 const char *LinkingOutput)
const {
555 C.
addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
558 std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
561 const char *LinkingOutput)
const {
562 ArgStringList CmdArgs;
563 CmdArgs.push_back(
"/nologo");
564 CmdArgs.push_back(
"/c");
565 CmdArgs.push_back(
"/W0");
571 Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
574 if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
575 CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ?
"/Oi" 577 if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
578 if (A->getOption().getID() == options::OPT_O0) {
579 CmdArgs.push_back(
"/Od");
581 CmdArgs.push_back(
"/Og");
583 StringRef OptLevel = A->getValue();
584 if (OptLevel ==
"s" || OptLevel ==
"z")
585 CmdArgs.push_back(
"/Os");
587 CmdArgs.push_back(
"/Ot");
589 CmdArgs.push_back(
"/Ob2");
592 if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
593 options::OPT_fno_omit_frame_pointer))
594 CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
597 if (!Args.hasArg(options::OPT_fwritable_strings))
598 CmdArgs.push_back(
"/GF");
603 if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
605 CmdArgs.push_back(
"/GR-");
607 if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
609 CmdArgs.push_back(
"/GS-");
611 if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
612 options::OPT_fno_function_sections))
613 CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
616 if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
617 options::OPT_fno_data_sections))
619 A->getOption().getID() == options::OPT_fdata_sections ?
"/Gw" :
"/Gw-");
620 if (Args.hasArg(options::OPT_fsyntax_only))
621 CmdArgs.push_back(
"/Zs");
622 if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
623 options::OPT__SLASH_Z7))
624 CmdArgs.push_back(
"/Z7");
626 std::vector<std::string> Includes =
627 Args.getAllArgValues(options::OPT_include);
628 for (
const auto &Include : Includes)
629 CmdArgs.push_back(Args.MakeArgString(std::string(
"/FI") + Include));
632 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
633 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
634 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX);
635 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
636 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
637 Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
640 if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
641 options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
642 A->render(Args, CmdArgs);
645 if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics,
646 options::OPT_fno_threadsafe_statics)) {
647 CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics
648 ?
"/Zc:threadSafeInit" 649 :
"/Zc:threadSafeInit-");
654 Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
657 assert(Inputs.size() == 1);
659 assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
660 CmdArgs.push_back(II.getType() == types::TY_C ?
"/Tc" :
"/Tp");
662 CmdArgs.push_back(II.getFilename());
664 II.getInputArg().renderAsInput(Args, CmdArgs);
667 assert(Output.
getType() == types::TY_Object);
669 Args.MakeArgString(std::string(
"/Fo") + Output.
getFilename());
670 CmdArgs.push_back(Fo);
673 return llvm::make_unique<Command>(JA, *
this, Args.MakeArgString(Exec),
679 :
ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
694 if (VCToolChainPath.empty())
719 return getArch() == llvm::Triple::x86_64;
723 return getArch() == llvm::Triple::x86_64;
731 return getArch() == llvm::Triple::x86_64;
735 ArgStringList &CC1Args)
const {
740 CudaInstallation.
print(OS);
747 using ArchType = llvm::Triple::ArchType;
751 case ArchType::x86_64:
762 using ArchType = llvm::Triple::ArchType;
768 case ArchType::x86_64:
779 using ArchType = llvm::Triple::ArchType;
783 case ArchType::x86_64:
798 llvm::Triple::ArchType TargetArch)
const {
799 const char *SubdirName;
800 const char *IncludeName;
804 IncludeName =
"include";
808 IncludeName =
"include";
820 const bool HostIsX64 =
821 llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
822 const char *
const HostName = HostIsX64 ?
"HostX64" :
"HostX86";
823 llvm::sys::path::append(Path,
"bin", HostName, SubdirName);
825 llvm::sys::path::append(Path,
"bin", SubdirName);
829 llvm::sys::path::append(Path, IncludeName);
832 llvm::sys::path::append(Path,
"lib", SubdirName);
839 static bool readFullStringValue(HKEY hkey,
const char *valueName,
840 std::string &value) {
841 std::wstring WideValueName;
842 if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
849 result = RegQueryValueExW(hkey, WideValueName.c_str(),
NULL, &
type,
NULL,
851 if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
853 std::vector<BYTE> buffer(valueSize);
854 result = RegQueryValueExW(hkey, WideValueName.c_str(),
NULL,
NULL, &buffer[0],
856 if (result == ERROR_SUCCESS) {
857 std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
858 valueSize /
sizeof(
wchar_t));
859 if (valueSize && WideValue.back() == L
'\0') {
860 WideValue.pop_back();
866 return llvm::convertWideToUTF8(WideValue, value);
881 std::string &value, std::string *phValue) {
885 HKEY hRootKey = HKEY_LOCAL_MACHINE;
888 bool returnValue =
false;
890 const char *placeHolder = strstr(keyPath,
"$VERSION");
891 std::string bestName;
894 const char *keyEnd = placeHolder - 1;
895 const char *nextKey = placeHolder;
897 while ((keyEnd > keyPath) && (*keyEnd !=
'\\'))
900 while (*nextKey && (*nextKey !=
'\\'))
902 size_t partialKeyLength = keyEnd - keyPath;
903 char partialKey[256];
904 if (partialKeyLength >=
sizeof(partialKey))
905 partialKeyLength =
sizeof(partialKey) - 1;
906 strncpy(partialKey, keyPath, partialKeyLength);
907 partialKey[partialKeyLength] =
'\0';
909 lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
911 if (lResult == ERROR_SUCCESS) {
913 double bestValue = 0.0;
914 DWORD index, size =
sizeof(keyName) - 1;
915 for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size,
NULL,
NULL,
918 const char *sp = keyName;
923 const char *ep = sp + 1;
924 while (*ep && (
isDigit(*ep) || (*ep ==
'.')))
927 strncpy(numBuf, sp,
sizeof(numBuf) - 1);
928 numBuf[
sizeof(numBuf) - 1] =
'\0';
929 double dvalue = strtod(numBuf,
NULL);
930 if (dvalue > bestValue) {
935 bestName.append(nextKey);
936 lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
937 KEY_READ | KEY_WOW64_32KEY, &hKey);
938 if (lResult == ERROR_SUCCESS) {
939 if (readFullStringValue(hKey, valueName, value)) {
948 size =
sizeof(keyName) - 1;
950 RegCloseKey(hTopKey);
954 RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
955 if (lResult == ERROR_SUCCESS) {
956 if (readFullStringValue(hKey, valueName, value))
972 std::string &SDKVersion) {
977 llvm::sys::path::append(IncludePath,
"Include");
978 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
979 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
980 if (!llvm::sys::fs::is_directory(DirIt->path()))
982 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
986 if (!CandidateName.startswith(
"10."))
988 if (CandidateName > SDKVersion)
989 SDKVersion = CandidateName;
992 return !SDKVersion.empty();
997 std::string &WindowsSDKIncludeVersion,
998 std::string &WindowsSDKLibVersion) {
999 std::string RegistrySDKVersion;
1002 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
1003 "InstallationFolder", Path, &RegistrySDKVersion))
1005 if (Path.empty() || RegistrySDKVersion.empty())
1008 WindowsSDKIncludeVersion.clear();
1009 WindowsSDKLibVersion.clear();
1011 std::sscanf(RegistrySDKVersion.c_str(),
"v%d.", &Major);
1018 const char *Tests[] = {
"winv6.3",
"win8",
"win7"};
1019 for (
const char *Test : Tests) {
1021 llvm::sys::path::append(TestPath,
"Lib", Test);
1022 if (llvm::sys::fs::exists(TestPath.c_str())) {
1023 WindowsSDKLibVersion = Test;
1027 return !WindowsSDKLibVersion.empty();
1032 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
1041 std::string sdkPath;
1043 std::string windowsSDKIncludeVersion;
1044 std::string windowsSDKLibVersion;
1048 windowsSDKLibVersion))
1052 llvm::sys::path::append(libPath,
"Lib");
1053 if (sdkMajor >= 8) {
1054 llvm::sys::path::append(libPath, windowsSDKLibVersion,
"um",
1059 case llvm::Triple::x86:
1061 case llvm::Triple::x86_64:
1062 llvm::sys::path::append(libPath,
"x64");
1064 case llvm::Triple::arm:
1072 path = libPath.str();
1081 llvm::sys::path::append(TestPath,
"stdlib.h");
1082 return !llvm::sys::fs::exists(TestPath);
1089 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots",
"KitsRoot10",
1097 std::string UniversalCRTSdkPath;
1098 std::string UCRTVersion;
1105 if (ArchName.empty())
1109 llvm::sys::path::append(LibPath,
"Lib", UCRTVersion,
"ucrt", ArchName);
1111 Path = LibPath.str();
1116 unsigned Major, Minor, Micro;
1117 Triple.getEnvironmentVersion(Major, Minor, Micro);
1118 if (Major || Minor || Micro)
1127 llvm::sys::path::append(ClExe,
"cl.exe");
1129 std::wstring ClExeWide;
1130 if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
1133 const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
1135 if (VersionSize == 0)
1139 if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
1140 VersionBlock.data()))
1143 VS_FIXEDFILEINFO *FileInfo =
nullptr;
1144 UINT FileInfoSize = 0;
1145 if (!::VerQueryValueW(VersionBlock.data(), L
"\\",
1146 reinterpret_cast<LPVOID *
>(&FileInfo), &FileInfoSize) ||
1147 FileInfoSize <
sizeof(*FileInfo))
1150 const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
1151 const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
1152 const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
1160 const ArgList &DriverArgs, ArgStringList &CC1Args,
1161 const std::string &folder,
const Twine &subfolder1,
const Twine &subfolder2,
1162 const Twine &subfolder3)
const {
1164 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
1169 ArgStringList &CC1Args)
const {
1170 if (DriverArgs.hasArg(options::OPT_nostdinc))
1173 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
1179 for (
const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
1182 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
1187 llvm::sys::Process::GetEnv(
"INCLUDE")) {
1189 StringRef(*cl_include_dir)
1190 .split(Dirs,
";", -1,
false);
1191 for (StringRef Dir : Dirs)
1199 if (!VCToolChainPath.empty()) {
1204 std::string UniversalCRTSdkPath;
1205 std::string UCRTVersion;
1208 "Include", UCRTVersion,
"ucrt");
1212 std::string WindowsSDKDir;
1214 std::string windowsSDKIncludeVersion;
1215 std::string windowsSDKLibVersion;
1217 windowsSDKLibVersion)) {
1222 "include", windowsSDKIncludeVersion,
1225 "include", windowsSDKIncludeVersion,
1228 "include", windowsSDKIncludeVersion,
1239 #if defined(LLVM_ON_WIN32) 1242 const StringRef Paths[] = {
1243 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
1244 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
1245 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
1246 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
1247 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include" 1254 ArgStringList &CC1Args)
const {
1259 const ArgList &Args)
const {
1260 bool IsWindowsMSVC =
getTriple().isWindowsMSVCEnvironment();
1264 if (MSVT.
empty() && IsWindowsMSVC)
1267 Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
1287 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
1288 StringRef ObjFmt = Triple.getEnvironmentName().split(
'-').second;
1290 Triple.setEnvironmentName((Twine(
"msvc") + MSVT.
getAsString()).str());
1292 Triple.setEnvironmentName(
1293 (Twine(
"msvc") + MSVT.
getAsString() + Twine(
'-') + ObjFmt).str());
1295 return Triple.getTriple();
1300 Res |= SanitizerKind::Address;
1305 bool SupportsForcingFramePointer,
1306 const char *ExpandChar,
const OptTable &Opts) {
1307 assert(A->getOption().matches(options::OPT__SLASH_O));
1309 StringRef OptStr = A->getValue();
1310 for (
size_t I = 0, E = OptStr.size(); I != E; ++I) {
1311 const char &OptChar = *(OptStr.data() + I);
1321 if (&OptChar != ExpandChar) {
1325 if (OptChar ==
'd') {
1326 DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
1328 if (OptChar ==
'1') {
1329 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"s");
1330 }
else if (OptChar ==
'2' || OptChar ==
'x') {
1331 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1332 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"2");
1334 if (SupportsForcingFramePointer &&
1335 !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
1336 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fomit_frame_pointer));
1337 if (OptChar ==
'1' || OptChar ==
'2')
1338 DAL.AddFlagArg(A, Opts.getOption(options::OPT_ffunction_sections));
1342 if (I + 1 != E && isdigit(OptStr[I + 1])) {
1343 switch (OptStr[I + 1]) {
1345 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
1348 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
1351 DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
1360 if (I + 1 != E && OptStr[I + 1] ==
'-') {
1362 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
1364 DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
1368 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"s");
1371 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O),
"2");
1374 bool OmitFramePointer =
true;
1375 if (I + 1 != E && OptStr[I + 1] ==
'-') {
1376 OmitFramePointer =
false;
1379 if (SupportsForcingFramePointer) {
1380 if (OmitFramePointer)
1382 Opts.getOption(options::OPT_fomit_frame_pointer));
1385 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
1400 const OptTable &Opts) {
1401 assert(A->getOption().matches(options::OPT_D));
1403 StringRef Val = A->getValue();
1404 size_t Hash = Val.find(
'#');
1405 if (Hash == StringRef::npos || Hash > Val.find(
'=')) {
1410 std::string NewVal = Val;
1412 DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
1415 llvm::opt::DerivedArgList *
1418 DerivedArgList *DAL =
new DerivedArgList(Args.getBaseArgs());
1422 bool SupportsForcingFramePointer =
getArch() == llvm::Triple::x86;
1433 const char *ExpandChar =
nullptr;
1434 for (Arg *A : Args.filtered(options::OPT__SLASH_O)) {
1435 StringRef OptStr = A->getValue();
1436 for (
size_t I = 0, E = OptStr.size(); I != E; ++I) {
1437 char OptChar = OptStr[I];
1438 char PrevChar = I > 0 ? OptStr[I - 1] :
'0';
1439 if (PrevChar ==
'b') {
1443 if (OptChar ==
'1' || OptChar ==
'2' || OptChar ==
'x' || OptChar ==
'd')
1444 ExpandChar = OptStr.data() + I;
1448 for (Arg *A : Args) {
1449 if (A->getOption().matches(options::OPT__SLASH_O)) {
1452 TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
1453 }
else if (A->getOption().matches(options::OPT_D)) {
struct ISetupInstance ISetupInstance
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
static bool getSystemRegistryString(const char *keyPath, const char *valueName, std::string &value, std::string *phValue)
Read registry string.
static VersionTuple getMSVCVersionFromTriple(const llvm::Triple &Triple)
Represents a version number in the form major[.minor[.subminor[.build]]].
static bool findVCToolChainViaRegistry(std::string &Path, MSVCToolChain::ToolsetLayout &VSLayout)
static bool getWindows10SDKVersionFromPath(const std::string &SDKPath, std::string &SDKVersion)
The base class of the type hierarchy.
DiagnosticBuilder Diag(unsigned DiagID) const
void print(raw_ostream &OS) const
Print information about the detected CUDA installation.
static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL, bool SupportsForcingFramePointer, const char *ExpandChar, const OptTable &Opts)
static std::string FindVisualStudioExecutable(const ToolChain &TC, const char *Exe)
static bool findVCToolChainViaEnvironment(std::string &Path, MSVCToolChain::ToolsetLayout &VSLayout)
static const char * llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch)
Optional< unsigned > getMinor() const
Retrieve the minor version number, if provided.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
An unknown OpenMP runtime.
static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL, const OptTable &Opts)
Defines version macros and version-related utility functions for Clang.
struct IEnumSetupInstances IEnumSetupInstances
bool IsCLMode() const
Whether the driver should follow cl.exe like behavior.
struct ISetupHelper ISetupHelper
void addCommand(std::unique_ptr< Command > C)
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero)...
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
static bool findVCToolChainViaSetupConfig(std::string &Path, MSVCToolChain::ToolsetLayout &VSLayout)
static bool getWindowsSDKDir(std::string &Path, int &Major, std::string &WindowsSDKIncludeVersion, std::string &WindowsSDKLibVersion)
Get Windows SDK installation directory.
static bool getUniversalCRTSdkDir(std::string &Path, std::string &UCRTVersion)
Dataflow Directional Tag Classes.
Optional< unsigned > getSubminor() const
Retrieve the subminor version number, if provided.
struct ISetupInstance2 ISetupInstance2
unsigned getMajor() const
Retrieve the major version number.
static VersionTuple getMSVCVersionFromExe(const std::string &BinDir)
std::string getAsString() const
Retrieve a string representation of the version number.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
Compilation - A set of tasks to perform for a single driver invocation.
const Driver & getDriver() const
struct ISetupConfiguration ISetupConfiguration
const llvm::opt::OptTable & getOpts() const
static const char * llvmArchToWindowsSDKArch(llvm::Triple::ArchType Arch)
static const char * llvmArchToDevDivInternalArch(llvm::Triple::ArchType Arch)
struct ISetupConfiguration2 ISetupConfiguration2