diff options
Diffstat (limited to 'lib/Driver/Tools.cpp')
-rw-r--r-- | lib/Driver/Tools.cpp | 504 |
1 files changed, 392 insertions, 112 deletions
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 9f4a0bc..60803dd 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -34,14 +34,32 @@ #include "InputInfo.h" #include "ToolChains.h" +#ifdef __CYGWIN__ +#include <cygwin/version.h> +#if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<1007 +#define IS_CYGWIN15 1 +#endif +#endif + using namespace clang::driver; using namespace clang::driver::tools; +/// FindTargetProgramPath - Return path of the target specific version of +/// ProgName. If it doesn't exist, return path of ProgName itself. +static std::string FindTargetProgramPath(const ToolChain &TheToolChain, + const char *ProgName) { + std::string Executable(TheToolChain.getTripleString() + "-" + ProgName); + std::string Path(TheToolChain.GetProgramPath(Executable.c_str())); + if (Path != Executable) + return Path; + return TheToolChain.GetProgramPath(ProgName); +} + /// CheckPreprocessingOptions - Perform some validation of preprocessing /// arguments that is shared with gcc. static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) { if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC)) - if (!Args.hasArg(options::OPT_E)) + if (!Args.hasArg(options::OPT_E) && !D.CCCIsCPP) D.Diag(clang::diag::err_drv_argument_only_allowed_with) << A->getAsString(Args) << "-E"; } @@ -309,7 +327,7 @@ void Clang::AddPreprocessingOptions(const Driver &D, } } -/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting. +/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting. // // FIXME: tblgen this. static const char *getARMTargetCPU(const ArgList &Args, @@ -363,6 +381,8 @@ static const char *getARMTargetCPU(const ArgList &Args, return "iwmmxt"; if (MArch == "xscale") return "xscale"; + if (MArch == "armv6m" || MArch == "armv6-m") + return "cortex-m0"; // If all else failed, return the most base CPU LLVM supports. return "arm7tdmi"; @@ -420,10 +440,17 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) { } void Clang::AddARMTargetArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { + ArgStringList &CmdArgs, + bool KernelOrKext) const { const Driver &D = getToolChain().getDriver(); llvm::Triple Triple = getToolChain().getTriple(); + // Disable movt generation, if requested. +#ifdef DISABLE_ARM_DARWIN_USE_MOVT + CmdArgs.push_back("-backend-option"); + CmdArgs.push_back("-arm-darwin-use-movt=0"); +#endif + // Select the ABI to use. // // FIXME: Support -meabi. @@ -577,6 +604,28 @@ void Clang::AddARMTargetArgs(const ArgList &Args, } else D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); } + + // Setting -msoft-float effectively disables NEON because of the GCC + // implementation, although the same isn't true of VFP or VFP3. + if (FloatABI == "soft") { + CmdArgs.push_back("-target-feature"); + CmdArgs.push_back("-neon"); + } + + // Kernel code has more strict alignment requirements. + if (KernelOrKext) { + CmdArgs.push_back("-backend-option"); + CmdArgs.push_back("-arm-long-calls"); + + CmdArgs.push_back("-backend-option"); + CmdArgs.push_back("-arm-strict-align"); + + // The kext linker doesn't know how to deal with movw/movt. +#ifndef DISABLE_ARM_DARWIN_USE_MOVT + CmdArgs.push_back("-backend-option"); + CmdArgs.push_back("-arm-darwin-use-movt=0"); +#endif + } } void Clang::AddMIPSTargetArgs(const ArgList &Args, @@ -726,6 +775,11 @@ void Clang::AddX86TargetArgs(const ArgList &Args, CPUName = "x86-64"; else if (getToolChain().getArchName() == "i386") CPUName = "i486"; + } else if (getToolChain().getOS().startswith("freebsd")) { + if (getToolChain().getArchName() == "x86_64") + CPUName = "x86-64"; + else if (getToolChain().getArchName() == "i386") + CPUName = "i486"; } else if (getToolChain().getOS().startswith("netbsd")) { if (getToolChain().getArchName() == "x86_64") CPUName = "x86-64"; @@ -762,34 +816,112 @@ void Clang::AddX86TargetArgs(const ArgList &Args, } } -static bool needsExceptions(const ArgList &Args, types::ID InputType, - const llvm::Triple &Triple) { - // Handle -fno-exceptions. +static bool +shouldUseExceptionTablesForObjCExceptions(const ArgList &Args, + const llvm::Triple &Triple) { + // We use the zero-cost exception tables for Objective-C if the non-fragile + // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and + // later. + + if (Args.hasArg(options::OPT_fobjc_nonfragile_abi)) + return true; + + if (Triple.getOS() != llvm::Triple::Darwin) + return false; + + return (Triple.getDarwinMajorNumber() >= 9 && + (Triple.getArch() == llvm::Triple::x86_64 || + Triple.getArch() == llvm::Triple::arm)); +} + +/// addExceptionArgs - Adds exception related arguments to the driver command +/// arguments. There's a master flag, -fexceptions and also language specific +/// flags to enable/disable C++ and Objective-C exceptions. +/// This makes it possible to for example disable C++ exceptions but enable +/// Objective-C exceptions. +static void addExceptionArgs(const ArgList &Args, types::ID InputType, + const llvm::Triple &Triple, + bool KernelOrKext, bool IsRewriter, + ArgStringList &CmdArgs) { + if (KernelOrKext) + return; + + // Exceptions are enabled by default. + bool ExceptionsEnabled = true; + + // This keeps track of whether exceptions were explicitly turned on or off. + bool DidHaveExplicitExceptionFlag = false; + if (Arg *A = Args.getLastArg(options::OPT_fexceptions, options::OPT_fno_exceptions)) { if (A->getOption().matches(options::OPT_fexceptions)) - return true; - else - return false; + ExceptionsEnabled = true; + else + ExceptionsEnabled = false; + + DidHaveExplicitExceptionFlag = true; } - // Otherwise, C++ inputs use exceptions. - if (types::isCXX(InputType)) - return true; + bool ShouldUseExceptionTables = false; - // As do Objective-C non-fragile ABI inputs and all Objective-C inputs on - // x86_64 and ARM after SnowLeopard. - if (types::isObjC(InputType)) { - if (Args.hasArg(options::OPT_fobjc_nonfragile_abi)) - return true; - if (Triple.getOS() != llvm::Triple::Darwin) - return false; - return (Triple.getDarwinMajorNumber() >= 9 && - (Triple.getArch() == llvm::Triple::x86_64 || - Triple.getArch() == llvm::Triple::arm)); + // Exception tables and cleanups can be enabled with -fexceptions even if the + // language itself doesn't support exceptions. + if (ExceptionsEnabled && DidHaveExplicitExceptionFlag) + ShouldUseExceptionTables = true; + + // Obj-C exceptions are enabled by default, regardless of -fexceptions. This + // is not necessarily sensible, but follows GCC. + if (types::isObjC(InputType) && + Args.hasFlag(options::OPT_fobjc_exceptions, + options::OPT_fno_objc_exceptions, + true)) { + CmdArgs.push_back("-fobjc-exceptions"); + + ShouldUseExceptionTables |= + shouldUseExceptionTablesForObjCExceptions(Args, Triple); } - return false; + if (types::isCXX(InputType)) { + bool CXXExceptionsEnabled = ExceptionsEnabled; + + if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions, + options::OPT_fno_cxx_exceptions, + options::OPT_fexceptions, + options::OPT_fno_exceptions)) { + if (A->getOption().matches(options::OPT_fcxx_exceptions)) + CXXExceptionsEnabled = true; + else if (A->getOption().matches(options::OPT_fno_cxx_exceptions)) + CXXExceptionsEnabled = false; + } + + if (CXXExceptionsEnabled) { + CmdArgs.push_back("-fcxx-exceptions"); + + ShouldUseExceptionTables = true; + } + } + + if (ShouldUseExceptionTables) + CmdArgs.push_back("-fexceptions"); +} + +static bool ShouldDisableCFI(const ArgList &Args, + const ToolChain &TC) { + + // FIXME: Duplicated code with ToolChains.cpp + // FIXME: This doesn't belong here, but ideally we will support static soon + // anyway. + bool HasStatic = (Args.hasArg(options::OPT_mkernel) || + Args.hasArg(options::OPT_static) || + Args.hasArg(options::OPT_fapple_kext)); + bool IsIADefault = TC.IsIntegratedAssemblerDefault() && !HasStatic; + bool UseIntegratedAs = Args.hasFlag(options::OPT_integrated_as, + options::OPT_no_integrated_as, + IsIADefault); + bool UseCFI = Args.hasFlag(options::OPT_fdwarf2_cfi_asm, + options::OPT_fno_dwarf2_cfi_asm, + UseIntegratedAs); + return !UseCFI; } void Clang::ConstructJob(Compilation &C, const JobAction &JA, @@ -832,8 +964,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *A = Args.getLastArg(options::OPT_O_Group)) IsOpt = !A->getOption().matches(options::OPT_O0); if (Args.hasFlag(options::OPT_mrelax_all, - options::OPT_mno_relax_all, - !IsOpt)) + options::OPT_mno_relax_all, + !IsOpt)) CmdArgs.push_back("-mrelax-all"); // When using an integrated assembler, translate -Wa, and -Xassembler @@ -850,10 +982,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Value == "-force_cpusubtype_ALL") { // Do nothing, this is the default and we don't support anything else. } else if (Value == "-L") { - // We don't support -L yet, but it isn't important enough to error - // on. No one should really be using it for a semantic change. - D.Diag(clang::diag::warn_drv_unsupported_option_argument) - << A->getOption().getName() << Value; + CmdArgs.push_back("-msave-temp-labels"); } else { D.Diag(clang::diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Value; @@ -920,29 +1049,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Treat blocks as analysis entry points. CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks"); + CmdArgs.push_back("-analyzer-eagerly-assume"); + // Add default argument set. if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) { - types::ID InputType = Inputs[0].getType(); - - // Checks to perform for all language types. - CmdArgs.push_back("-analyzer-checker=core"); + CmdArgs.push_back("-analyzer-checker=deadcode"); + CmdArgs.push_back("-analyzer-checker=security"); + if (getToolChain().getTriple().getOS() != llvm::Triple::Win32) CmdArgs.push_back("-analyzer-checker=unix"); - if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple) - CmdArgs.push_back("-analyzer-checker=macosx"); - - // Checks to perform for Objective-C/Objective-C++. - if (types::isObjC(InputType)) { - // Enable all checkers in 'cocoa' package. - CmdArgs.push_back("-analyzer-checker=cocoa"); - } - // NOTE: Leaving -analyzer-check-objc-mem here is intentional. - // It also checks C code. - CmdArgs.push_back("-analyzer-check-objc-mem"); - - CmdArgs.push_back("-analyzer-eagerly-assume"); + if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple) + CmdArgs.push_back("-analyzer-checker=osx"); } // Set the output format. The default is plist, for (lame) historical @@ -1006,7 +1125,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } if (!Args.hasFlag(options::OPT_fmerge_all_constants, options::OPT_fno_merge_all_constants)) - CmdArgs.push_back("-no-merge-all-constants"); + CmdArgs.push_back("-fno-merge-all-constants"); // LLVM Code Generator Options. @@ -1015,6 +1134,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue(Args)); } + if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false)) + CmdArgs.push_back("-mrtd"); + // FIXME: Set --enable-unsafe-fp-math. if (Args.hasFlag(options::OPT_fno_omit_frame_pointer, options::OPT_fomit_frame_pointer)) @@ -1049,6 +1171,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().getTriple().getOS() != llvm::Triple::Darwin) CmdArgs.push_back("-mconstructor-aliases"); + // Darwin's kernel doesn't support guard variables; just die if we + // try to use them. + if (KernelOrKext && + getToolChain().getTriple().getOS() == llvm::Triple::Darwin) + CmdArgs.push_back("-fforbid-guard-variables"); + if (Args.hasArg(options::OPT_mms_bitfields)) { CmdArgs.push_back("-mms-bitfields"); } @@ -1085,7 +1213,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, case llvm::Triple::arm: case llvm::Triple::thumb: - AddARMTargetArgs(Args, CmdArgs); + AddARMTargetArgs(Args, CmdArgs, KernelOrKext); break; case llvm::Triple::mips: @@ -1150,6 +1278,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_P); Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout); + if (D.CCLogDiagnostics) { + CmdArgs.push_back("-diagnostic-log-file"); + CmdArgs.push_back(D.CCLogDiagnosticsFilename ? + D.CCLogDiagnosticsFilename : "-"); + } + // Special case debug options to only pass -g to clang. This is // wrong. Args.ClaimAllArgs(options::OPT_g_Group); @@ -1162,6 +1296,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions); + if (Args.hasArg(options::OPT_ftest_coverage) || + Args.hasArg(options::OPT_coverage)) + CmdArgs.push_back("-femit-coverage-notes"); + if (Args.hasArg(options::OPT_fprofile_arcs) || + Args.hasArg(options::OPT_coverage)) + CmdArgs.push_back("-femit-coverage-data"); + Args.AddLastArg(CmdArgs, options::OPT_nostdinc); Args.AddLastArg(CmdArgs, options::OPT_nostdincxx); Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc); @@ -1187,10 +1328,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, else if (A->getOption().matches(options::OPT_O) && A->getValue(Args)[0] == '\0') CmdArgs.push_back("-O2"); - else if (A->getOption().matches(options::OPT_O) && - A->getValue(Args)[0] == 'z' && - A->getValue(Args)[1] == '\0') - CmdArgs.push_back("-Os"); else A->render(Args, CmdArgs); } @@ -1231,6 +1368,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_trigraphs); } + // Map the bizarre '-Wwrite-strings' flag to a more sensible + // '-fconst-strings'; this better indicates its actual behavior. + if (Args.hasFlag(options::OPT_Wwrite_strings, options::OPT_Wno_write_strings, + false)) { + // For perfect compatibility with GCC, we do this even in the presence of + // '-w'. This flag names something other than a warning for GCC. + CmdArgs.push_back("-fconst-strings"); + } + + // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active + // during C++ compilation, which it is by default. GCC keeps this define even + // in the presence of '-w', match this behavior bug-for-bug. + if (types::isCXX(InputType) && + Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated, + true)) { + CmdArgs.push_back("-fdeprecated-macro"); + } + // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'. if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) { if (Asm->getOption().matches(options::OPT_fasm)) @@ -1239,6 +1394,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fno-gnu-keywords"); } + if (ShouldDisableCFI(Args, getToolChain())) + CmdArgs.push_back("-fno-dwarf2-cfi-asm"); + if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) { CmdArgs.push_back("-ftemplate-depth"); CmdArgs.push_back(A->getValue(Args)); @@ -1311,7 +1469,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); Args.AddLastArg(CmdArgs, options::OPT_flimit_debug_info); - Args.AddLastArg(CmdArgs, options::OPT_pg); + if (getToolChain().SupportsProfiling()) + Args.AddLastArg(CmdArgs, options::OPT_pg); // -flax-vector-conversions is default. if (!Args.hasFlag(options::OPT_flax_vector_conversions, @@ -1348,7 +1507,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue(Args)); } - Args.AddLastArg(CmdArgs, options::OPT_fwrapv); + // Forward -ftrap_function= options to the backend. + if (Arg *A = Args.getLastArg(options::OPT_ftrap_function_EQ)) { + llvm::StringRef FuncName = A->getValue(Args); + CmdArgs.push_back("-backend-option"); + CmdArgs.push_back(Args.MakeArgString("-trap-func=" + FuncName)); + } + + // -fno-strict-overflow implies -fwrapv if it isn't disabled, but + // -fstrict-overflow won't turn off an explicitly enabled -fwrapv. + if (Arg *A = Args.getLastArg(options::OPT_fwrapv, + options::OPT_fno_wrapv)) { + if (A->getOption().matches(options::OPT_fwrapv)) + CmdArgs.push_back("-fwrapv"); + } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow, + options::OPT_fno_strict_overflow)) { + if (A->getOption().matches(options::OPT_fno_strict_overflow)) + CmdArgs.push_back("-fwrapv"); + } Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings); Args.AddLastArg(CmdArgs, options::OPT_funroll_loops); @@ -1389,7 +1565,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fblocks=0 is default. if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks, - getToolChain().IsBlocksDefault())) { + getToolChain().IsBlocksDefault()) || + (Args.hasArg(options::OPT_fgnu_runtime) && + Args.hasArg(options::OPT_fobjc_nonfragile_abi) && + !Args.hasArg(options::OPT_fno_blocks))) { CmdArgs.push_back("-fblocks"); } @@ -1405,10 +1584,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, false)) CmdArgs.push_back("-fno-elide-constructors"); - // -fexceptions=0 is default. - if (!KernelOrKext && - needsExceptions(Args, InputType, getToolChain().getTriple())) - CmdArgs.push_back("-fexceptions"); + // Add exception args. + addExceptionArgs(Args, InputType, getToolChain().getTriple(), + KernelOrKext, IsRewriter, CmdArgs); if (getToolChain().UseSjLjExceptions()) CmdArgs.push_back("-fsjlj-exceptions"); @@ -1463,6 +1641,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_borland_extensions, false)) CmdArgs.push_back("-fborland-extensions"); + // -fno-delayed-template-parsing is default. + if (Args.hasFlag(options::OPT_fdelayed_template_parsing, + options::OPT_fno_delayed_template_parsing, + false)) + CmdArgs.push_back("-fdelayed-template-parsing"); + // -fgnu-keywords default varies depending on language; only pass if // specified. if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords, @@ -1539,17 +1723,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + // FIXME: Don't expose -fobjc-default-synthesize-properties as a top-level + // driver flag yet. This feature is still under active development + // and shouldn't be exposed as a user visible feature (which may change). + // Clang still supports this as a -cc1 option for development and testing. +#if 0 // -fobjc-default-synthesize-properties=0 is default. if (Args.hasFlag(options::OPT_fobjc_default_synthesize_properties, options::OPT_fno_objc_default_synthesize_properties, getToolChain().IsObjCDefaultSynthPropertiesDefault())) { CmdArgs.push_back("-fobjc-default-synthesize-properties"); } - - // -fno-objc-exceptions is default. - if (IsRewriter || Args.hasFlag(options::OPT_fobjc_exceptions, - options::OPT_fno_objc_exceptions)) - CmdArgs.push_back("-fobjc-exceptions"); +#endif } if (!Args.hasFlag(options::OPT_fassume_sane_operator_new, @@ -1613,6 +1798,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info, options::OPT_fno_diagnostics_fixit_info)) CmdArgs.push_back("-fno-diagnostics-fixit-info"); + + // Enable -fdiagnostics-show-name by default. + if (Args.hasFlag(options::OPT_fdiagnostics_show_name, + options::OPT_fno_diagnostics_show_name, false)) + CmdArgs.push_back("-fdiagnostics-show-name"); // Enable -fdiagnostics-show-option by default. if (Args.hasFlag(options::OPT_fdiagnostics_show_option, @@ -1625,6 +1815,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue(Args)); } + if (Arg *A = Args.getLastArg( + options::OPT_fdiagnostics_show_note_include_stack, + options::OPT_fno_diagnostics_show_note_include_stack)) { + if (A->getOption().matches( + options::OPT_fdiagnostics_show_note_include_stack)) + CmdArgs.push_back("-fdiagnostics-show-note-include-stack"); + else + CmdArgs.push_back("-fno-diagnostics-show-note-include-stack"); + } + // Color diagnostics are the default, unless the terminal doesn't support // them. if (Args.hasFlag(options::OPT_fcolor_diagnostics, @@ -1680,9 +1880,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } #endif + // Only allow -traditional or -traditional-cpp outside in preprocessing modes. if (Arg *A = Args.getLastArg(options::OPT_traditional, - options::OPT_traditional_cpp)) - D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); + options::OPT_traditional_cpp)) { + if (isa<PreprocessJobAction>(JA)) + CmdArgs.push_back("-traditional-cpp"); + else + D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); + } Args.AddLastArg(CmdArgs, options::OPT_dM); Args.AddLastArg(CmdArgs, options::OPT_dD); @@ -1762,6 +1967,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // care to warn the user about. Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group); Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group); + + // Disable warnings for clang -E -use-gold-plugin -emit-llvm foo.c + Args.ClaimAllArgs(options::OPT_use_gold_plugin); + Args.ClaimAllArgs(options::OPT_emit_llvm); } void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, @@ -1776,6 +1985,10 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, // Don't warn about "clang -w -c foo.s" Args.ClaimAllArgs(options::OPT_w); + // and "clang -emit-llvm -c foo.s" + Args.ClaimAllArgs(options::OPT_emit_llvm); + // and "clang -use-gold-plugin -c foo.s" + Args.ClaimAllArgs(options::OPT_use_gold_plugin); // Invoke ourselves in -cc1as mode. // @@ -1801,7 +2014,8 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, !IsOpt)) CmdArgs.push_back("-relax-all"); - // FIXME: Add -force_cpusubtype_ALL support, once we have it. + // Ignore explicit -force_cpusubtype_ALL option. + (void) Args.hasArg(options::OPT_force__cpusubtype__ALL); // FIXME: Add -g support, once we have it. @@ -1809,6 +2023,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); + Args.AddAllArgs(CmdArgs, options::OPT_mllvm); assert(Output.isFilename() && "Unexpected lipo output."); CmdArgs.push_back("-o"); @@ -1924,7 +2139,20 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, } } - const char *GCCName = getToolChain().getDriver().getCCCGenericGCCName().c_str(); + const std::string customGCCName = D.getCCCGenericGCCName(); + const char *GCCName; + if (!customGCCName.empty()) + GCCName = customGCCName.c_str(); + else if (D.CCCIsCXX) { +#ifdef IS_CYGWIN15 + // FIXME: Detect the version of Cygwin at runtime? + GCCName = "g++-4"; +#else + GCCName = "g++"; +#endif + } else + GCCName = "gcc"; + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); @@ -2038,10 +2266,6 @@ void darwin::CC1::AddCC1Args(const ArgList &Args, CmdArgs.push_back("-fno-builtin-strcpy"); } - // gcc has some code here to deal with when no -mmacosx-version-min - // and no -miphoneos-version-min is present, but this never happens - // due to tool chain specific argument translation. - if (Args.hasArg(options::OPT_g_Flag) && !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols)) CmdArgs.push_back("-feliminate-unused-debug-symbols"); @@ -2105,7 +2329,8 @@ void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs, if (Args.hasArg(options::OPT_v)) CmdArgs.push_back("-version"); - if (Args.hasArg(options::OPT_pg)) + if (Args.hasArg(options::OPT_pg) && + getToolChain().SupportsProfiling()) CmdArgs.push_back("-p"); Args.AddLastArg(CmdArgs, options::OPT_p); @@ -2128,6 +2353,9 @@ void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs, } else Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only); + // Claim Clang only -f options, they aren't worth warning about. + Args.ClaimAllArgs(options::OPT_f_clang_Group); + Args.AddAllArgs(CmdArgs, options::OPT_undef); if (Args.hasArg(options::OPT_Qn)) CmdArgs.push_back("-fno-ident"); @@ -2185,6 +2413,9 @@ void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs, // The driver treats -fsyntax-only specially. Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only); + // Claim Clang only -f options, they aren't worth warning about. + Args.ClaimAllArgs(options::OPT_f_clang_Group); + if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) && !Args.hasArg(options::OPT_fno_working_directory)) CmdArgs.push_back("-fworking-directory"); @@ -2316,7 +2547,7 @@ void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA, OutputArgs.push_back("-o"); OutputArgs.push_back(Output.getFilename()); - if (Args.hasArg(options::OPT_E)) { + if (Args.hasArg(options::OPT_E) || getToolChain().getDriver().CCCIsCPP) { AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs); } else { AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList()); @@ -2436,11 +2667,16 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, assert(Inputs.size() == 1 && "Unexpected number of inputs."); const InputInfo &Input = Inputs[0]; - // Bit of a hack, this is only used for original inputs. - // - // FIXME: This is broken for preprocessed .s inputs. - if (Input.isFilename() && - strcmp(Input.getFilename(), Input.getBaseInput()) == 0) { + // Determine the original source input. + const Action *SourceAction = &JA; + while (SourceAction->getKind() != Action::InputClass) { + assert(!SourceAction->getInputs().empty() && "unexpected root action!"); + SourceAction = SourceAction->getInputs()[0]; + } + + // Forward -g, assuming we are dealing with an actual assembly file. + if (SourceAction->getType() == types::TY_Asm || + SourceAction->getType() == types::TY_PP_Asm) { if (Args.hasArg(options::OPT_gstabs)) CmdArgs.push_back("--gstabs"); else if (Args.hasArg(options::OPT_g_Group)) @@ -2496,6 +2732,7 @@ void darwin::Link::AddLinkArgs(Compilation &C, const ArgList &Args, ArgStringList &CmdArgs) const { const Driver &D = getToolChain().getDriver(); + const toolchains::Darwin &DarwinTC = getDarwinToolChain(); unsigned Version[3] = { 0, 0, 0 }; if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { @@ -2515,7 +2752,7 @@ void darwin::Link::AddLinkArgs(Compilation &C, // will match the linker version detected at configure time. We need the // universal driver. if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle) && - !getDarwinToolChain().isTargetIPhoneOS()) { + !DarwinTC.isTargetIPhoneOS()) { // Don't pass -demangle to ld_classic. // // FIXME: This is a temporary workaround, ld should be handling this. @@ -2590,7 +2827,7 @@ void darwin::Link::AddLinkArgs(Compilation &C, Args.AddLastArg(CmdArgs, options::OPT_all__load); Args.AddAllArgs(CmdArgs, options::OPT_allowable__client); Args.AddLastArg(CmdArgs, options::OPT_bind__at__load); - if (getDarwinToolChain().isTargetIPhoneOS()) + if (DarwinTC.isTargetIPhoneOS()) Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal); Args.AddLastArg(CmdArgs, options::OPT_dead__strip); Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms); @@ -2602,15 +2839,27 @@ void darwin::Link::AddLinkArgs(Compilation &C, Args.AddAllArgs(CmdArgs, options::OPT_image__base); Args.AddAllArgs(CmdArgs, options::OPT_init); - // Adding all arguments doesn't make sense here but this is what gcc does. One - // of this should always be present thanks to argument translation. - assert((Args.hasArg(options::OPT_mmacosx_version_min_EQ) || - Args.hasArg(options::OPT_miphoneos_version_min_EQ)) && - "Missing version argument (lost in translation)?"); - Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ, - "-macosx_version_min"); - Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ, - "-iphoneos_version_min"); + // Add the deployment target. + unsigned TargetVersion[3]; + DarwinTC.getTargetVersion(TargetVersion); + + // If we had an explicit -mios-simulator-version-min argument, honor that, + // otherwise use the traditional deployment targets. We can't just check the + // is-sim attribute because existing code follows this path, and the linker + // may not handle the argument. + // + // FIXME: We may be able to remove this, once we can verify no one depends on + // it. + if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ)) + CmdArgs.push_back("-ios_simulator_version_min"); + else if (DarwinTC.isTargetIPhoneOS()) + CmdArgs.push_back("-iphoneos_version_min"); + else + CmdArgs.push_back("-macosx_version_min"); + CmdArgs.push_back(Args.MakeArgString(llvm::Twine(TargetVersion[0]) + "." + + llvm::Twine(TargetVersion[1]) + "." + + llvm::Twine(TargetVersion[2]))); + Args.AddLastArg(CmdArgs, options::OPT_nomultidefs); Args.AddLastArg(CmdArgs, options::OPT_multi__module); Args.AddLastArg(CmdArgs, options::OPT_single__module); @@ -2716,7 +2965,10 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, // Derived from startfile spec. if (Args.hasArg(options::OPT_dynamiclib)) { // Derived from darwin_dylib1 spec. - if (getDarwinToolChain().isTargetIPhoneOS()) { + if (getDarwinToolChain().isTargetIOSSimulator()) { + // The simulator doesn't have a versioned crt1 file. + CmdArgs.push_back("-ldylib1.o"); + } else if (getDarwinToolChain().isTargetIPhoneOS()) { if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) CmdArgs.push_back("-ldylib1.o"); } else { @@ -2729,7 +2981,10 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_bundle)) { if (!Args.hasArg(options::OPT_static)) { // Derived from darwin_bundle1 spec. - if (getDarwinToolChain().isTargetIPhoneOS()) { + if (getDarwinToolChain().isTargetIOSSimulator()) { + // The simulator doesn't have a versioned crt1 file. + CmdArgs.push_back("-lbundle1.o"); + } else if (getDarwinToolChain().isTargetIPhoneOS()) { if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) CmdArgs.push_back("-lbundle1.o"); } else { @@ -2738,7 +2993,8 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, } } } else { - if (Args.hasArg(options::OPT_pg)) { + if (Args.hasArg(options::OPT_pg) && + getToolChain().SupportsProfiling()) { if (Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_object) || Args.hasArg(options::OPT_preload)) { @@ -2755,7 +3011,10 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-lcrt0.o"); } else { // Derived from darwin_crt1 spec. - if (getDarwinToolChain().isTargetIPhoneOS()) { + if (getDarwinToolChain().isTargetIOSSimulator()) { + // The simulator doesn't have a versioned crt1 file. + CmdArgs.push_back("-lcrt1.o"); + } else if (getDarwinToolChain().isTargetIPhoneOS()) { if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1)) CmdArgs.push_back("-lcrt1.o"); else @@ -3150,6 +3409,9 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; + if (!D.SysRoot.empty()) + CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + if (Args.hasArg(options::OPT_static)) { CmdArgs.push_back("-Bstatic"); } else { @@ -3200,7 +3462,10 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, } Args.AddAllArgs(CmdArgs, options::OPT_L); - CmdArgs.push_back("-L/usr/lib"); + const ToolChain::path_list Paths = getToolChain().getFilePaths(); + for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end(); + i != e; ++i) + CmdArgs.push_back(Args.MakeArgString(llvm::StringRef("-L") + *i)); Args.AddAllArgs(CmdArgs, options::OPT_T_Group); Args.AddAllArgs(CmdArgs, options::OPT_e); Args.AddAllArgs(CmdArgs, options::OPT_s); @@ -3312,8 +3577,8 @@ void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); } - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("as")); + const char *Exec = Args.MakeArgString(FindTargetProgramPath(getToolChain(), + "as")); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } @@ -3325,6 +3590,9 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; + if (!D.SysRoot.empty()) + CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + if (Args.hasArg(options::OPT_static)) { CmdArgs.push_back("-Bstatic"); } else { @@ -3423,8 +3691,8 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, "crtn.o"))); } - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("ld")); + const char *Exec = Args.MakeArgString(FindTargetProgramPath(getToolChain(), + "ld")); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } @@ -3476,14 +3744,14 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA, // Silence warning for "clang -g foo.o -o foo" Args.ClaimAllArgs(options::OPT_g_Group); + // and "clang -emit-llvm foo.o -o foo" + Args.ClaimAllArgs(options::OPT_emit_llvm); // and for "clang -g foo.o -o foo". Other warning options are already // handled somewhere else. Args.ClaimAllArgs(options::OPT_w); - if (Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) { - CmdArgs.push_back("--sysroot"); - CmdArgs.push_back(A->getValue(Args)); - } + if (!D.SysRoot.empty()) + CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); if (Args.hasArg(options::OPT_pie)) CmdArgs.push_back("-pie"); @@ -3506,13 +3774,19 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-m"); if (ToolChain.getArch() == llvm::Triple::x86) CmdArgs.push_back("elf_i386"); - else if (ToolChain.getArch() == llvm::Triple::arm) + else if (ToolChain.getArch() == llvm::Triple::arm + || ToolChain.getArch() == llvm::Triple::thumb) CmdArgs.push_back("armelf_linux_eabi"); + else if (ToolChain.getArch() == llvm::Triple::ppc) + CmdArgs.push_back("elf32ppclinux"); + else if (ToolChain.getArch() == llvm::Triple::ppc64) + CmdArgs.push_back("elf64ppc"); else CmdArgs.push_back("elf_x86_64"); if (Args.hasArg(options::OPT_static)) { - if (ToolChain.getArch() == llvm::Triple::arm) + if (ToolChain.getArch() == llvm::Triple::arm + || ToolChain.getArch() == llvm::Triple::thumb) CmdArgs.push_back("-Bstatic"); else CmdArgs.push_back("-static"); @@ -3521,13 +3795,19 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA, } if (ToolChain.getArch() == llvm::Triple::arm || + ToolChain.getArch() == llvm::Triple::thumb || (!Args.hasArg(options::OPT_static) && !Args.hasArg(options::OPT_shared))) { CmdArgs.push_back("-dynamic-linker"); if (ToolChain.getArch() == llvm::Triple::x86) CmdArgs.push_back("/lib/ld-linux.so.2"); - else if (ToolChain.getArch() == llvm::Triple::arm) + else if (ToolChain.getArch() == llvm::Triple::arm || + ToolChain.getArch() == llvm::Triple::thumb) CmdArgs.push_back("/lib/ld-linux.so.3"); + else if (ToolChain.getArch() == llvm::Triple::ppc) + CmdArgs.push_back("/lib/ld.so.1"); + else if (ToolChain.getArch() == llvm::Triple::ppc64) + CmdArgs.push_back("/lib64/ld64.so.1"); else CmdArgs.push_back("/lib64/ld-linux-x86-64.so.2"); } @@ -3563,12 +3843,9 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA, const ToolChain::path_list Paths = ToolChain.getFilePaths(); - for (ToolChain::path_list::const_iterator i = Paths.begin(), - e = Paths.end(); - i != e; ++i) { - const std::string &s = *i; - CmdArgs.push_back(Args.MakeArgString(std::string("-L") + s)); - } + for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end(); + i != e; ++i) + CmdArgs.push_back(Args.MakeArgString(llvm::StringRef("-L") + *i)); AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs); @@ -3763,6 +4040,9 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; + if (!D.SysRoot.empty()) + CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + if (Args.hasArg(options::OPT_static)) { CmdArgs.push_back("-Bstatic"); } else { |