1 //===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "ToolChains.h"
12 #include "clang/Basic/CharInfo.h"
13 #include "clang/Basic/Version.h"
14 #include "clang/Driver/Compilation.h"
15 #include "clang/Driver/Driver.h"
16 #include "clang/Driver/DriverDiagnostic.h"
17 #include "clang/Driver/Options.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/Config/llvm-config.h"
20 #include "llvm/Option/Arg.h"
21 #include "llvm/Option/ArgList.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/Process.h"
27 // Include the necessary headers to interface with the Windows registry and
29 #if defined(LLVM_ON_WIN32)
34 #define WIN32_LEAN_AND_MEAN
42 using namespace clang::driver;
43 using namespace clang::driver::toolchains;
44 using namespace clang;
45 using namespace llvm::opt;
47 MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple& Triple,
49 : ToolChain(D, Triple, Args) {
50 getProgramPaths().push_back(getDriver().getInstalledDir());
51 if (getDriver().getInstalledDir() != getDriver().Dir)
52 getProgramPaths().push_back(getDriver().Dir);
55 Tool *MSVCToolChain::buildLinker() const {
56 return new tools::visualstudio::Linker(*this);
59 Tool *MSVCToolChain::buildAssembler() const {
60 if (getTriple().isOSBinFormatMachO())
61 return new tools::darwin::Assembler(*this);
62 getDriver().Diag(clang::diag::err_no_external_assembler);
66 bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
70 bool MSVCToolChain::IsUnwindTablesDefault() const {
71 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
72 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
73 // how to generate them yet.
74 return getArch() == llvm::Triple::x86_64;
77 bool MSVCToolChain::isPICDefault() const {
78 return getArch() == llvm::Triple::x86_64;
81 bool MSVCToolChain::isPIEDefault() const {
85 bool MSVCToolChain::isPICDefaultForced() const {
86 return getArch() == llvm::Triple::x86_64;
90 static bool readFullStringValue(HKEY hkey, const char *valueName,
92 // FIXME: We should be using the W versions of the registry functions, but
93 // doing so requires UTF8 / UTF16 conversions similar to how we handle command
94 // line arguments. The UTF8 conversion functions are not exposed publicly
95 // from LLVM though, so in order to do this we will probably need to create
96 // a registry abstraction in LLVMSupport that is Windows only.
100 // First just query for the required size.
101 result = RegQueryValueEx(hkey, valueName, NULL, &type, NULL, &valueSize);
102 if (result != ERROR_SUCCESS || type != REG_SZ)
104 std::vector<BYTE> buffer(valueSize);
105 result = RegQueryValueEx(hkey, valueName, NULL, NULL, &buffer[0], &valueSize);
106 if (result == ERROR_SUCCESS)
107 value.assign(reinterpret_cast<const char *>(buffer.data()));
112 /// \brief Read registry string.
113 /// This also supports a means to look for high-versioned keys by use
114 /// of a $VERSION placeholder in the key path.
115 /// $VERSION in the key path is a placeholder for the version number,
116 /// causing the highest value path to be searched for and used.
117 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
118 /// There can be additional characters in the component. Only the numeric
119 /// characters are compared. This function only searches HKLM.
120 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
121 std::string &value, std::string *phValue) {
125 HKEY hRootKey = HKEY_LOCAL_MACHINE;
128 bool returnValue = false;
130 const char *placeHolder = strstr(keyPath, "$VERSION");
131 std::string bestName;
132 // If we have a $VERSION placeholder, do the highest-version search.
134 const char *keyEnd = placeHolder - 1;
135 const char *nextKey = placeHolder;
136 // Find end of previous key.
137 while ((keyEnd > keyPath) && (*keyEnd != '\\'))
139 // Find end of key containing $VERSION.
140 while (*nextKey && (*nextKey != '\\'))
142 size_t partialKeyLength = keyEnd - keyPath;
143 char partialKey[256];
144 if (partialKeyLength > sizeof(partialKey))
145 partialKeyLength = sizeof(partialKey);
146 strncpy(partialKey, keyPath, partialKeyLength);
147 partialKey[partialKeyLength] = '\0';
149 lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
151 if (lResult == ERROR_SUCCESS) {
153 double bestValue = 0.0;
154 DWORD index, size = sizeof(keyName) - 1;
155 for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
156 NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
157 const char *sp = keyName;
158 while (*sp && !isDigit(*sp))
162 const char *ep = sp + 1;
163 while (*ep && (isDigit(*ep) || (*ep == '.')))
166 strncpy(numBuf, sp, sizeof(numBuf) - 1);
167 numBuf[sizeof(numBuf) - 1] = '\0';
168 double dvalue = strtod(numBuf, NULL);
169 if (dvalue > bestValue) {
170 // Test that InstallDir is indeed there before keeping this index.
171 // Open the chosen key path remainder.
173 // Append rest of key.
174 bestName.append(nextKey);
175 lResult = RegOpenKeyEx(hTopKey, bestName.c_str(), 0,
176 KEY_READ | KEY_WOW64_32KEY, &hKey);
177 if (lResult == ERROR_SUCCESS) {
178 lResult = readFullStringValue(hKey, valueName, value);
179 if (lResult == ERROR_SUCCESS) {
188 size = sizeof(keyName) - 1;
190 RegCloseKey(hTopKey);
194 RegOpenKeyEx(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
195 if (lResult == ERROR_SUCCESS) {
196 lResult = readFullStringValue(hKey, valueName, value);
197 if (lResult == ERROR_SUCCESS)
208 // Convert LLVM's ArchType
209 // to the corresponding name of Windows SDK libraries subfolder
210 static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch) {
212 case llvm::Triple::x86:
214 case llvm::Triple::x86_64:
216 case llvm::Triple::arm:
223 // Find the most recent version of Universal CRT or Windows 10 SDK.
224 // vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
225 // directory by name and uses the last one of the list.
226 // So we compare entry names lexicographically to find the greatest one.
227 static bool getWindows10SDKVersion(const std::string &SDKPath,
228 std::string &SDKVersion) {
232 llvm::SmallString<128> IncludePath(SDKPath);
233 llvm::sys::path::append(IncludePath, "Include");
234 for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
235 DirIt != DirEnd && !EC; DirIt.increment(EC)) {
236 if (!llvm::sys::fs::is_directory(DirIt->path()))
238 StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
239 // If WDK is installed, there could be subfolders like "wdf" in the
240 // "Include" directory.
241 // Allow only directories which names start with "10.".
242 if (!CandidateName.startswith("10."))
244 if (CandidateName > SDKVersion)
245 SDKVersion = CandidateName;
248 return !SDKVersion.empty();
251 /// \brief Get Windows SDK installation directory.
252 bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
253 std::string &WindowsSDKIncludeVersion,
254 std::string &WindowsSDKLibVersion) const {
255 std::string RegistrySDKVersion;
256 // Try the Windows registry.
257 if (!getSystemRegistryString(
258 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
259 "InstallationFolder", Path, &RegistrySDKVersion))
261 if (Path.empty() || RegistrySDKVersion.empty())
264 WindowsSDKIncludeVersion.clear();
265 WindowsSDKLibVersion.clear();
267 std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
271 // Windows SDK 8.x installs libraries in a folder whose names depend on the
272 // version of the OS you're targeting. By default choose the newest, which
273 // usually corresponds to the version of the OS you've installed the SDK on.
274 const char *Tests[] = {"winv6.3", "win8", "win7"};
275 for (const char *Test : Tests) {
276 llvm::SmallString<128> TestPath(Path);
277 llvm::sys::path::append(TestPath, "Lib", Test);
278 if (llvm::sys::fs::exists(TestPath.c_str())) {
279 WindowsSDKLibVersion = Test;
283 return !WindowsSDKLibVersion.empty();
286 if (!getWindows10SDKVersion(Path, WindowsSDKIncludeVersion))
288 WindowsSDKLibVersion = WindowsSDKIncludeVersion;
291 // Unsupported SDK version
295 // Gets the library path required to link against the Windows SDK.
296 bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
299 std::string windowsSDKIncludeVersion;
300 std::string windowsSDKLibVersion;
303 if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
304 windowsSDKLibVersion))
307 llvm::SmallString<128> libPath(sdkPath);
308 llvm::sys::path::append(libPath, "Lib");
311 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
312 case llvm::Triple::x86:
314 case llvm::Triple::x86_64:
315 llvm::sys::path::append(libPath, "x64");
317 case llvm::Triple::arm:
318 // It is not necessary to link against Windows SDK 7.x when targeting ARM.
324 const StringRef archName = getWindowsSDKArch(getArch());
325 if (archName.empty())
327 llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
330 path = libPath.str();
334 // Check if the Include path of a specified version of Visual Studio contains
335 // specific header files. If not, they are probably shipped with Universal CRT.
336 bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT(
337 std::string &VisualStudioDir) const {
338 llvm::SmallString<128> TestPath(VisualStudioDir);
339 llvm::sys::path::append(TestPath, "VC\\include\\stdlib.h");
341 return !llvm::sys::fs::exists(TestPath);
344 bool MSVCToolChain::getUniversalCRTSdkDir(std::string &Path,
345 std::string &UCRTVersion) const {
346 // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
347 // for the specific key "KitsRoot10". So do we.
348 if (!getSystemRegistryString(
349 "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
353 return getWindows10SDKVersion(Path, UCRTVersion);
356 bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
357 std::string UniversalCRTSdkPath;
358 std::string UCRTVersion;
361 if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
364 StringRef ArchName = getWindowsSDKArch(getArch());
365 if (ArchName.empty())
368 llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
369 llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
371 Path = LibPath.str();
375 // Get the location to use for Visual Studio binaries. The location priority
376 // is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
377 // system (as reported by the registry).
378 bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath,
379 std::string &path) const {
382 SmallString<128> BinDir;
384 // First check the environment variables that vsvars32.bat sets.
385 llvm::Optional<std::string> VcInstallDir =
386 llvm::sys::Process::GetEnv("VCINSTALLDIR");
387 if (VcInstallDir.hasValue()) {
388 BinDir = VcInstallDir.getValue();
389 llvm::sys::path::append(BinDir, "bin");
391 // Next walk the PATH, trying to find a cl.exe in the path. If we find one,
392 // use that. However, make sure it's not clang's cl.exe.
393 llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
394 if (OptPath.hasValue()) {
395 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
396 SmallVector<StringRef, 8> PathSegments;
397 llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
399 for (StringRef PathSegment : PathSegments) {
400 if (PathSegment.empty())
403 SmallString<128> FilePath(PathSegment);
404 llvm::sys::path::append(FilePath, "cl.exe");
405 if (llvm::sys::fs::can_execute(FilePath.c_str()) &&
406 !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) {
407 // If we found it on the PATH, use it exactly as is with no
415 std::string installDir;
416 // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the
417 // registry then we have no choice but to fail.
418 if (!getVisualStudioInstallDir(installDir))
421 // Regardless of what binary we're ultimately trying to find, we make sure
422 // that this is a Visual Studio directory by checking for cl.exe. We use
423 // cl.exe instead of other binaries like link.exe because programs such as
424 // GnuWin32 also have a utility called link.exe, so cl.exe is the least
427 llvm::sys::path::append(BinDir, "VC", "bin");
428 SmallString<128> ClPath(BinDir);
429 llvm::sys::path::append(ClPath, "cl.exe");
431 if (!llvm::sys::fs::can_execute(ClPath.c_str()))
439 case llvm::Triple::x86:
441 case llvm::Triple::x86_64:
442 llvm::sys::path::append(BinDir, "amd64");
444 case llvm::Triple::arm:
445 llvm::sys::path::append(BinDir, "arm");
448 // Whatever this is, Visual Studio doesn't have a toolchain for it.
455 // Get Visual Studio installation directory.
456 bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const {
457 // First check the environment variables that vsvars32.bat sets.
458 const char *vcinstalldir = getenv("VCINSTALLDIR");
461 path = path.substr(0, path.find("\\VC"));
465 std::string vsIDEInstallDir;
466 std::string vsExpressIDEInstallDir;
467 // Then try the windows registry.
469 getSystemRegistryString("SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
470 "InstallDir", vsIDEInstallDir, nullptr);
471 if (hasVCDir && !vsIDEInstallDir.empty()) {
472 path = vsIDEInstallDir.substr(0, vsIDEInstallDir.find("\\Common7\\IDE"));
476 bool hasVCExpressDir =
477 getSystemRegistryString("SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
478 "InstallDir", vsExpressIDEInstallDir, nullptr);
479 if (hasVCExpressDir && !vsExpressIDEInstallDir.empty()) {
480 path = vsExpressIDEInstallDir.substr(
481 0, vsIDEInstallDir.find("\\Common7\\IDE"));
485 // Try the environment.
486 const char *vs120comntools = getenv("VS120COMNTOOLS");
487 const char *vs100comntools = getenv("VS100COMNTOOLS");
488 const char *vs90comntools = getenv("VS90COMNTOOLS");
489 const char *vs80comntools = getenv("VS80COMNTOOLS");
491 const char *vscomntools = nullptr;
493 // Find any version we can
495 vscomntools = vs120comntools;
496 else if (vs100comntools)
497 vscomntools = vs100comntools;
498 else if (vs90comntools)
499 vscomntools = vs90comntools;
500 else if (vs80comntools)
501 vscomntools = vs80comntools;
503 if (vscomntools && *vscomntools) {
504 const char *p = strstr(vscomntools, "\\Common7\\Tools");
505 path = p ? std::string(vscomntools, p) : vscomntools;
511 void MSVCToolChain::AddSystemIncludeWithSubfolder(
512 const ArgList &DriverArgs, ArgStringList &CC1Args,
513 const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
514 const Twine &subfolder3) const {
515 llvm::SmallString<128> path(folder);
516 llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
517 addSystemInclude(DriverArgs, CC1Args, path);
520 void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
521 ArgStringList &CC1Args) const {
522 if (DriverArgs.hasArg(options::OPT_nostdinc))
525 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
526 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
530 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
533 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
534 if (const char *cl_include_dir = getenv("INCLUDE")) {
535 SmallVector<StringRef, 8> Dirs;
536 StringRef(cl_include_dir)
537 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
538 for (StringRef Dir : Dirs)
539 addSystemInclude(DriverArgs, CC1Args, Dir);
546 // When built with access to the proper Windows APIs, try to actually find
547 // the correct include paths first.
548 if (getVisualStudioInstallDir(VSDir)) {
549 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
551 if (useUniversalCRT(VSDir)) {
552 std::string UniversalCRTSdkPath;
553 std::string UCRTVersion;
554 if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
555 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
556 "Include", UCRTVersion, "ucrt");
560 std::string WindowsSDKDir;
562 std::string windowsSDKIncludeVersion;
563 std::string windowsSDKLibVersion;
564 if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
565 windowsSDKLibVersion)) {
567 // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
568 // Anyway, llvm::sys::path::append is able to manage it.
569 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
570 "include", windowsSDKIncludeVersion,
572 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
573 "include", windowsSDKIncludeVersion,
575 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
576 "include", windowsSDKIncludeVersion,
579 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
583 addSystemInclude(DriverArgs, CC1Args, VSDir);
588 // As a fallback, select default install paths.
589 // FIXME: Don't guess drives and paths like this on Windows.
590 const StringRef Paths[] = {
591 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
592 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
593 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
594 "C:/Program Files/Microsoft Visual Studio 8/VC/include",
595 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
597 addSystemIncludes(DriverArgs, CC1Args, Paths);
600 void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
601 ArgStringList &CC1Args) const {
602 // FIXME: There should probably be logic here to find libc++ on Windows.
606 MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
607 types::ID InputType) const {
608 std::string TripleStr =
609 ToolChain::ComputeEffectiveClangTriple(Args, InputType);
610 llvm::Triple Triple(TripleStr);
612 tools::visualstudio::getMSVCVersion(/*D=*/nullptr, Triple, Args,
613 /*IsWindowsMSVC=*/true);
617 MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
618 MSVT.getSubminor().getValueOr(0));
620 if (Triple.getEnvironment() == llvm::Triple::MSVC) {
621 StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
623 Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
625 Triple.setEnvironmentName(
626 (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
628 return Triple.getTriple();
631 SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
632 SanitizerMask Res = ToolChain::getSupportedSanitizers();
633 Res |= SanitizerKind::Address;
637 llvm::opt::DerivedArgList *
638 MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
639 const char *BoundArch) const {
640 DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
641 const OptTable &Opts = getDriver().getOpts();
643 // /Oy and /Oy- only has an effect under X86-32.
644 bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
646 // The -O[12xd] flag actually expands to several flags. We must desugar the
647 // flags so that options embedded can be negated. For example, the '-O2' flag
648 // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
649 // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
652 // Note that this expansion logic only applies to the *last* of '[12xd]'.
654 // First step is to search for the character we'd like to expand.
655 const char *ExpandChar = nullptr;
656 for (Arg *A : Args) {
657 if (!A->getOption().matches(options::OPT__SLASH_O))
659 StringRef OptStr = A->getValue();
660 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
661 const char &OptChar = *(OptStr.data() + I);
662 if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
663 ExpandChar = OptStr.data() + I;
667 // The -O flag actually takes an amalgam of other options. For example,
668 // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
669 for (Arg *A : Args) {
670 if (!A->getOption().matches(options::OPT__SLASH_O)) {
675 StringRef OptStr = A->getValue();
676 for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
677 const char &OptChar = *(OptStr.data() + I);
685 if (&OptChar == ExpandChar) {
686 if (OptChar == 'd') {
687 DAL->AddFlagArg(A, Opts.getOption(options::OPT_O0));
689 if (OptChar == '1') {
690 DAL->AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
691 } else if (OptChar == '2' || OptChar == 'x') {
692 DAL->AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
693 DAL->AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
695 if (SupportsForcingFramePointer)
697 Opts.getOption(options::OPT_fomit_frame_pointer));
698 if (OptChar == '1' || OptChar == '2')
700 Opts.getOption(options::OPT_ffunction_sections));
705 if (I + 1 != E && isdigit(OptStr[I + 1]))
711 if (I + 1 != E && OptStr[I + 1] == '-') {
713 DAL->AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
715 DAL->AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
719 DAL->AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
722 DAL->AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
725 bool OmitFramePointer = true;
726 if (I + 1 != E && OptStr[I + 1] == '-') {
727 OmitFramePointer = false;
730 if (SupportsForcingFramePointer) {
731 if (OmitFramePointer)
733 Opts.getOption(options::OPT_fomit_frame_pointer));
736 A, Opts.getOption(options::OPT_fno_omit_frame_pointer));