summaryrefslogtreecommitdiffstats
path: root/lib/Driver/Tools.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/Tools.cpp')
-rw-r--r--lib/Driver/Tools.cpp504
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 {
OpenPOWER on IntegriCloud