diff options
Diffstat (limited to 'lib/Driver/Tools.cpp')
-rw-r--r-- | lib/Driver/Tools.cpp | 217 |
1 files changed, 135 insertions, 82 deletions
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index c9d0b26..808c31c 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -12,8 +12,8 @@ #include "clang/Driver/Action.h" #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" -#include "clang/Driver/Driver.h" // FIXME: Remove? -#include "clang/Driver/DriverDiagnostic.h" // FIXME: Remove? +#include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Job.h" #include "clang/Driver/HostInfo.h" @@ -22,9 +22,11 @@ #include "clang/Driver/Util.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/System/Process.h" #include "InputInfo.h" #include "ToolChains.h" @@ -32,13 +34,6 @@ using namespace clang::driver; using namespace clang::driver::tools; -static const char *MakeFormattedString(const ArgList &Args, - const llvm::format_object_base &Fmt) { - llvm::SmallString<256> Str; - llvm::raw_svector_ostream(Str) << Fmt; - return Args.MakeArgString(Str.str()); -} - /// CheckPreprocessingOptions - Perform some validation of preprocessing /// arguments that is shared with gcc. static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) { @@ -203,6 +198,10 @@ void Clang::AddPreprocessingOptions(const Driver &D, // those options. :( Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA, options::OPT_Xpreprocessor); + + // -I- is a deprecated GCC feature, reject it. + if (Arg *A = Args.getLastArg(options::OPT_I_)) + D.Diag(clang::diag::err_drv_I_dash_not_supported) << A->getAsString(Args); } /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting. @@ -417,8 +416,6 @@ void Clang::AddARMTargetArgs(const ArgList &Args, void Clang::AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { - // FIXME: This needs to change to use a clang-cc option, and set the attribute - // on functions. if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) || @@ -426,8 +423,6 @@ void Clang::AddX86TargetArgs(const ArgList &Args, Args.hasArg(options::OPT_fapple_kext)) CmdArgs.push_back("--disable-red-zone"); - // FIXME: This needs to change to use a clang-cc option, and set the attribute - // on functions. if (Args.hasFlag(options::OPT_msoft_float, options::OPT_mno_soft_float, false)) @@ -507,6 +502,57 @@ static bool needsExceptions(const ArgList &Args, types::ID InputType, } } +/// getEffectiveClangTriple - Get the "effective" target triple, which is the +/// triple for the target but with the OS version potentially modified for +/// Darwin's -mmacosx-version-min. +static std::string getEffectiveClangTriple(const Driver &D, + const ToolChain &TC, + const ArgList &Args) { + llvm::Triple Triple(getLLVMTriple(TC, Args)); + + if (Triple.getOS() != llvm::Triple::Darwin) { + // Diagnose use of -mmacosx-version-min and -miphoneos-version-min on + // non-Darwin. + if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ, + options::OPT_miphoneos_version_min_EQ)) + D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); + return Triple.getTriple(); + } + + // If -mmacosx-version-min=10.3.9 is specified, change the effective triple + // from being something like powerpc-apple-darwin9 to powerpc-apple-darwin7. + if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ)) { + unsigned Major, Minor, Micro; + bool HadExtra; + if (!Driver::GetReleaseVersion(A->getValue(Args), Major, Minor, Micro, + HadExtra) || HadExtra || + Major != 10) + D.Diag(clang::diag::err_drv_invalid_version_number) + << A->getAsString(Args); + + // Mangle the MacOS version min number into the Darwin number: e.g. 10.3.9 + // is darwin7.9. + llvm::SmallString<16> Str; + llvm::raw_svector_ostream(Str) << "darwin" << Minor + 4 << "." << Micro; + Triple.setOSName(Str.str()); + } else if (Arg *A = Args.getLastArg(options::OPT_miphoneos_version_min_EQ)) { + unsigned Major, Minor, Micro; + bool HadExtra; + if (!Driver::GetReleaseVersion(A->getValue(Args), Major, Minor, Micro, + HadExtra) || HadExtra) + D.Diag(clang::diag::err_drv_invalid_version_number) + << A->getAsString(Args); + + // Mangle the iPhoneOS version number into the Darwin number: e.g. 2.0 is 2 + // -> 9.2.0. + llvm::SmallString<16> Str; + llvm::raw_svector_ostream(Str) << "darwin9." << Major << "." << Minor; + Triple.setOSName(Str.str()); + } + + return Triple.getTriple(); +} + void Clang::ConstructJob(Compilation &C, const JobAction &JA, Job &Dest, const InputInfo &Output, @@ -518,12 +564,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, assert(Inputs.size() == 1 && "Unable to handle multiple inputs."); + // Add the "effective" target triple. CmdArgs.push_back("-triple"); + std::string TripleStr = getEffectiveClangTriple(D, getToolChain(), Args); + CmdArgs.push_back(Args.MakeArgString(TripleStr)); - const char *TripleStr = - Args.MakeArgString(getLLVMTriple(getToolChain(), Args)); - CmdArgs.push_back(TripleStr); - + // Select the appropriate action. if (isa<AnalyzeJobAction>(JA)) { assert(JA.getType() == types::TY_Plist && "Invalid output type."); CmdArgs.push_back("-analyze"); @@ -606,9 +652,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // issue is that llvm-gcc translates these options based on // the values in cc1, whereas we are processing based on // the driver arguments. - // - // FIXME: This is currently broken for -f flags when -fno - // variants are present. // This comes from the default translation the driver + cc1 // would do to enable flag_pic. @@ -661,8 +704,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("--debug-pass=Structure"); if (Args.hasArg(options::OPT_fdebug_pass_arguments)) CmdArgs.push_back("--debug-pass=Arguments"); - // FIXME: set --inline-threshhold=50 if (optimize_size || optimize - // < 3) + if (!Args.hasFlag(options::OPT_fmerge_all_constants, + options::OPT_fno_merge_all_constants)) + CmdArgs.push_back("--no-merge-all-constants"); // This is a coarse approximation of what llvm-gcc actually does, both // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more @@ -714,9 +758,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue(Args)); } - // FIXME: Add --stack-protector-buffer-size=<xxx> on - // -fstack-protect. - Arg *Unsupported; if ((Unsupported = Args.getLastArg(options::OPT_MG)) || (Unsupported = Args.getLastArg(options::OPT_MQ)) || @@ -726,8 +767,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_v); Args.AddLastArg(CmdArgs, options::OPT_P); - Args.AddLastArg(CmdArgs, options::OPT_mmacosx_version_min_EQ); - Args.AddLastArg(CmdArgs, options::OPT_miphoneos_version_min_EQ); Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout); // Special case debug options to only pass -g to clang. This is @@ -736,7 +775,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-g"); Args.AddLastArg(CmdArgs, options::OPT_nostdinc); - Args.AddLastArg(CmdArgs, options::OPT_nostdclanginc); + Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc); Args.AddLastArg(CmdArgs, options::OPT_isysroot); @@ -759,7 +798,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->render(Args, CmdArgs); } - Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group); + Args.AddAllArgs(CmdArgs, options::OPT_W_Group); + Args.AddLastArg(CmdArgs, options::OPT_pedantic); + Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors); Args.AddLastArg(CmdArgs, options::OPT_w); // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi} @@ -770,9 +811,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) { if (Std->getOption().matches(options::OPT_ansi)) if (types::isCXX(InputType)) - CmdArgs.push_back("-std=c++98"); + CmdArgs.push_back("-std=c++98"); else - CmdArgs.push_back("-std=c89"); + CmdArgs.push_back("-std=c89"); else Std->render(Args, CmdArgs); @@ -794,10 +835,21 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT__relocatable_pch, true)) CmdArgs.push_back("--relocatable-pch"); - if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) { - CmdArgs.push_back("-fconstant-string-class"); - CmdArgs.push_back(A->getValue(Args)); - } + if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) { + CmdArgs.push_back("-fconstant-string-class"); + CmdArgs.push_back(A->getValue(Args)); + } + + // Pass -fmessage-length=. + if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) { + A->render(Args, CmdArgs); + } else { + // If -fmessage-length=N was not specified, determine whether this is a + // terminal and, if so, implicitly define -fmessage-length appropriately. + unsigned N = llvm::sys::Process::StandardErrColumns(); + CmdArgs.push_back("-fmessage-length"); + CmdArgs.push_back(Args.MakeArgString(llvm::Twine(N))); + } // Forward -f options which we can pass directly. Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); @@ -805,7 +857,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); Args.AddLastArg(CmdArgs, options::OPT_fgnu_runtime); Args.AddLastArg(CmdArgs, options::OPT_flax_vector_conversions); - Args.AddLastArg(CmdArgs, options::OPT_fmessage_length_EQ); Args.AddLastArg(CmdArgs, options::OPT_fms_extensions); Args.AddLastArg(CmdArgs, options::OPT_fnext_runtime); Args.AddLastArg(CmdArgs, options::OPT_fno_caret_diagnostics); @@ -871,9 +922,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fsigned-char=0"); } - // -fno-pascal-strings is default, only pass non-default. If the - // -tool chain happened to translate to -mpascal-strings, we want to - // -back translate here. + // -fno-pascal-strings is default, only pass non-default. If the tool chain + // happened to translate to -mpascal-strings, we want to back translate here. // // FIXME: This is gross; that translation should be pulled from the // tool chain. @@ -905,9 +955,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasFlag(options::OPT_fdiagnostics_show_option, options::OPT_fno_diagnostics_show_option)) CmdArgs.push_back("-fdiagnostics-show-option"); - if (!Args.hasFlag(options::OPT_fcolor_diagnostics, - options::OPT_fno_color_diagnostics)) - CmdArgs.push_back("-fno-color-diagnostics"); + + // Color diagnostics are the default, unless the terminal doesn't support + // them. + if (Args.hasFlag(options::OPT_fcolor_diagnostics, + options::OPT_fno_color_diagnostics) && + llvm::sys::Process::StandardErrHasColors()) + CmdArgs.push_back("-fcolor-diagnostics"); + if (!Args.hasFlag(options::OPT_fshow_source_location, options::OPT_fno_show_source_location)) CmdArgs.push_back("-fno-show-source-location"); @@ -979,6 +1034,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, II.getInputArg().renderAsInput(Args, CmdArgs); } + Args.AddAllArgs(CmdArgs, options::OPT_undef); + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(C, "clang-cc")); Dest.addCommand(new Command(JA, Exec, CmdArgs)); @@ -1667,23 +1724,18 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, static bool isSourceSuffix(const char *Str) { // match: 'C', 'CPP', 'c', 'cc', 'cp', 'c++', 'cpp', 'cxx', 'm', // 'mm'. - switch (strlen(Str)) { - default: - return false; - case 1: - return (memcmp(Str, "C", 1) == 0 || - memcmp(Str, "c", 1) == 0 || - memcmp(Str, "m", 1) == 0); - case 2: - return (memcmp(Str, "cc", 2) == 0 || - memcmp(Str, "cp", 2) == 0 || - memcmp(Str, "mm", 2) == 0); - case 3: - return (memcmp(Str, "CPP", 3) == 0 || - memcmp(Str, "c++", 3) == 0 || - memcmp(Str, "cpp", 3) == 0 || - memcmp(Str, "cxx", 3) == 0); - } + return llvm::StringSwitch<bool>(Str) + .Case("C", true) + .Case("c", true) + .Case("m", true) + .Case("cc", true) + .Case("cp", true) + .Case("mm", true) + .Case("CPP", true) + .Case("c++", true) + .Case("cpp", true) + .Case("cxx", true) + .Default(false); } // FIXME: Can we tablegen this? @@ -1861,7 +1913,7 @@ void darwin::Link::AddLinkArgs(const ArgList &Args, // Adding all arguments doesn't make sense here but this is what // gcc does. Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ, - "-macosx_version_min"); + "-macosx_version_min"); Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ, "-iphoneos_version_min"); Args.AddLastArg(CmdArgs, options::OPT_nomultidefs); @@ -2137,10 +2189,10 @@ void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, } void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { + Job &Dest, const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { ArgStringList CmdArgs; Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, @@ -2167,15 +2219,15 @@ void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA, } void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { + Job &Dest, const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { const Driver &D = getToolChain().getHost().getDriver(); ArgStringList CmdArgs; if ((!Args.hasArg(options::OPT_nostdlib)) && - (!Args.hasArg(options::OPT_shared))) { + (!Args.hasArg(options::OPT_shared))) { CmdArgs.push_back("-e"); CmdArgs.push_back("_start"); } @@ -2212,14 +2264,13 @@ void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o"))); } else { CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o"))); -// CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o"))); } CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o"))); } - CmdArgs.push_back(MakeFormattedString(Args, - llvm::format("-L/opt/gcc4/lib/gcc/%s/4.2.4", - getToolChain().getTripleString().c_str()))); + CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/" + + getToolChain().getTripleString() + + "/4.2.4")); Args.AddAllArgs(CmdArgs, options::OPT_L); Args.AddAllArgs(CmdArgs, options::OPT_T_Group); @@ -2307,7 +2358,7 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, ArgStringList CmdArgs; if ((!Args.hasArg(options::OPT_nostdlib)) && - (!Args.hasArg(options::OPT_shared))) { + (!Args.hasArg(options::OPT_shared))) { CmdArgs.push_back("-e"); CmdArgs.push_back("__start"); } @@ -2345,9 +2396,11 @@ void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, } } - CmdArgs.push_back(MakeFormattedString(Args, - llvm::format("-L/usr/lib/gcc-lib/%s/3.3.5", - getToolChain().getTripleString().c_str()))); + std::string Triple = getToolChain().getTripleString(); + if (Triple.substr(0, 6) == "x86_64") + Triple.replace(0, 6, "amd64"); + CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + + "/3.3.5")); Args.AddAllArgs(CmdArgs, options::OPT_L); Args.AddAllArgs(CmdArgs, options::OPT_T_Group); @@ -2547,10 +2600,10 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA, // For now, DragonFly Assemble does just about the same as for // FreeBSD, but this may change soon. void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA, - Job &Dest, const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { + Job &Dest, const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { ArgStringList CmdArgs; // When building 32-bit code on DragonFly/pc64, we have to explicitly @@ -2678,7 +2731,7 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_pthread)) - CmdArgs.push_back("-lthread_xu"); + CmdArgs.push_back("-lpthread"); if (!Args.hasArg(options::OPT_nolibc)) { CmdArgs.push_back("-lc"); |