diff options
Diffstat (limited to 'lib/Driver')
-rw-r--r-- | lib/Driver/Arg.cpp | 9 | ||||
-rw-r--r-- | lib/Driver/Compilation.cpp | 49 | ||||
-rw-r--r-- | lib/Driver/Driver.cpp | 8 | ||||
-rw-r--r-- | lib/Driver/OptTable.cpp | 6 | ||||
-rw-r--r-- | lib/Driver/ToolChains.cpp | 4 | ||||
-rw-r--r-- | lib/Driver/ToolChains.h | 2 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 38 |
7 files changed, 93 insertions, 23 deletions
diff --git a/lib/Driver/Arg.cpp b/lib/Driver/Arg.cpp index a09ba095f119..7e61a1d414e0 100644 --- a/lib/Driver/Arg.cpp +++ b/lib/Driver/Arg.cpp @@ -10,6 +10,7 @@ #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" #include "clang/Driver/Option.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" using namespace clang::driver; @@ -155,14 +156,12 @@ SeparateArg::SeparateArg(const Option *Opt, unsigned Index, unsigned _NumValues, void SeparateArg::render(const ArgList &Args, ArgStringList &Output) const { if (getOption().hasForceJoinedRender()) { assert(getNumValues() == 1 && "Cannot force joined render with > 1 args."); - // FIXME: Avoid std::string. - std::string Joined(getOption().getName()); - Joined += Args.getArgString(getIndex()); - Output.push_back(Args.MakeArgString(Joined.c_str())); + Output.push_back(Args.MakeArgString(llvm::StringRef(getOption().getName()) + + getValue(Args, 0))); } else { Output.push_back(Args.getArgString(getIndex())); for (unsigned i = 0; i < NumValues; ++i) - Output.push_back(Args.getArgString(getIndex() + 1 + i)); + Output.push_back(getValue(Args, i)); } } diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp index b819cda89c09..227f79a75b71 100644 --- a/lib/Driver/Compilation.cpp +++ b/lib/Driver/Compilation.cpp @@ -61,10 +61,21 @@ void Compilation::PrintJob(llvm::raw_ostream &OS, const Job &J, OS << " \"" << C->getExecutable() << '"'; for (ArgStringList::const_iterator it = C->getArguments().begin(), ie = C->getArguments().end(); it != ie; ++it) { - if (Quote) - OS << " \"" << *it << '"'; - else - OS << ' ' << *it; + OS << ' '; + if (!Quote) { + OS << *it; + continue; + } + + // Quote the argument and escape shell special characters; this isn't + // really complete but is good enough. + OS << '"'; + for (const char *s = *it; *s; ++s) { + if (*s == '"' || *s == '\\' || *s == '$') + OS << '\\'; + OS << *s; + } + OS << '"'; } OS << Terminator; } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) { @@ -123,8 +134,34 @@ int Compilation::ExecuteCommand(const Command &C, std::copy(C.getArguments().begin(), C.getArguments().end(), Argv+1); Argv[C.getArguments().size() + 1] = 0; - if (getDriver().CCCEcho || getArgs().hasArg(options::OPT_v)) - PrintJob(llvm::errs(), C, "\n", false); + if (getDriver().CCCEcho || getDriver().CCPrintOptions || + getArgs().hasArg(options::OPT_v)) { + llvm::raw_ostream *OS = &llvm::errs(); + + // Follow gcc implementation of CC_PRINT_OPTIONS; we could also cache the + // output stream. + if (getDriver().CCPrintOptions && getDriver().CCPrintOptionsFilename) { + std::string Error; + OS = new llvm::raw_fd_ostream(getDriver().CCPrintOptionsFilename, + Error, + llvm::raw_fd_ostream::F_Append); + if (!Error.empty()) { + getDriver().Diag(clang::diag::err_drv_cc_print_options_failure) + << Error; + FailingCommand = &C; + delete OS; + return 1; + } + } + + if (getDriver().CCPrintOptions) + *OS << "[Logging clang options]"; + + PrintJob(*OS, C, "\n", /*Quote=*/getDriver().CCPrintOptions); + + if (OS != &llvm::errs()) + delete OS; + } std::string Error; int Res = diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 3257ee55a7b9..acfff386f485 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -51,10 +51,10 @@ Driver::Driver(llvm::StringRef _Name, llvm::StringRef _Dir, DefaultImageName(_DefaultImageName), DriverTitle("clang \"gcc-compatible\" driver"), Host(0), - CCCGenericGCCName("gcc"), CCCIsCXX(false), CCCEcho(false), - CCCPrintBindings(false), CheckInputsExist(true), CCCUseClang(true), - CCCUseClangCXX(true), CCCUseClangCPP(true), CCCUsePCH(true), - SuppressMissingInputWarning(false) { + CCCGenericGCCName("gcc"), CCPrintOptionsFilename(0), CCCIsCXX(false), + CCCEcho(false), CCCPrintBindings(false), CCPrintOptions(false), + CheckInputsExist(true), CCCUseClang(true), CCCUseClangCXX(true), + CCCUseClangCPP(true), CCCUsePCH(true), SuppressMissingInputWarning(false) { if (IsProduction) { // In a "production" build, only use clang on architectures we expect to // work, and don't use clang C++. diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp index f69d5d806d28..de1e4592b342 100644 --- a/lib/Driver/OptTable.cpp +++ b/lib/Driver/OptTable.cpp @@ -167,11 +167,13 @@ Option *OptTable::CreateOption(unsigned id) const { if (info.Flags & RenderAsInput) Opt->setNoOptAsInput(true); if (info.Flags & RenderJoined) { - assert(info.Kind == Option::SeparateClass && "Invalid option."); + assert((info.Kind == Option::JoinedOrSeparateClass || + info.Kind == Option::SeparateClass) && "Invalid option."); Opt->setForceJoinedRender(true); } if (info.Flags & RenderSeparate) { - assert(info.Kind == Option::JoinedClass && "Invalid option."); + assert((info.Kind == Option::JoinedOrSeparateClass || + info.Kind == Option::JoinedClass) && "Invalid option."); Opt->setForceSeparateRender(true); } if (info.Flags & Unsupported) diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 2f8d714504ba..105eab06af5f 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -394,9 +394,9 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args, // this. Perhaps put under -pedantic? if (getTriple().getArch() == llvm::Triple::arm || getTriple().getArch() == llvm::Triple::thumb) - OSXVersion = 0; + OSXTarget = 0; else - iPhoneVersion = 0; + iPhoneOSTarget = 0; } if (OSXTarget) { diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 6dd64dec9ee3..0d5b2a3f4747 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -96,6 +96,8 @@ public: return TargetIsIPhoneOS; } + bool isTargetInitialized() const { return TargetInitialized; } + void getTargetVersion(unsigned (&Res)[3]) const { assert(TargetInitialized && "Target not initialized!"); Res[0] = TargetVersion[0]; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index bc521008cf7c..1c34df05b1c5 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -655,6 +655,12 @@ static std::string getEffectiveClangTriple(const Driver &D, } else { const toolchains::Darwin &DarwinTC( reinterpret_cast<const toolchains::Darwin&>(TC)); + + // If the target isn't initialized (e.g., an unknown Darwin platform, return + // the default triple). + if (!DarwinTC.isTargetInitialized()) + return Triple.getTriple(); + unsigned Version[3]; DarwinTC.getTargetVersion(Version); @@ -686,6 +692,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { + bool KernelOrKext = Args.hasArg(options::OPT_mkernel, + options::OPT_fapple_kext); const Driver &D = getToolChain().getDriver(); ArgStringList CmdArgs; @@ -870,7 +878,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.hasFlag(options::OPT_fasynchronous_unwind_tables, options::OPT_fno_asynchronous_unwind_tables, getToolChain().IsUnwindTablesDefault() && - !Args.hasArg(options::OPT_mkernel)); + !KernelOrKext); if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables, AsynchronousUnwindTables)) CmdArgs.push_back("-munwind-tables"); @@ -1029,12 +1037,22 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue(Args)); } + // -fhosted is default. + if (KernelOrKext || Args.hasFlag(options::OPT_ffreestanding, + options::OPT_fhosted, + false)) + CmdArgs.push_back("-ffreestanding"); + // Forward -f (flag) options which we can pass directly. Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_behavior); Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); - Args.AddLastArg(CmdArgs, options::OPT_ffreestanding); Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); - Args.AddLastArg(CmdArgs, options::OPT_flax_vector_conversions); + + // -flax-vector-conversions is default. + if (!Args.hasFlag(options::OPT_flax_vector_conversions, + options::OPT_fno_lax_vector_conversions)) + CmdArgs.push_back("-fno-lax-vector-conversions"); + Args.AddLastArg(CmdArgs, options::OPT_fno_caret_diagnostics); Args.AddLastArg(CmdArgs, options::OPT_fno_show_column); Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc_only); @@ -1080,6 +1098,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fblocks"); } + // -fno-access-control is default (for now). + if (Args.hasFlag(options::OPT_faccess_control, + options::OPT_fno_access_control, + false)) + CmdArgs.push_back("-faccess-control"); + // -fexceptions=0 is default. if (needsExceptions(Args, InputType, getToolChain().getTriple())) CmdArgs.push_back("-fexceptions"); @@ -1088,7 +1112,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fsjlj-exceptions"); // -frtti is default. - if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti)) + if (KernelOrKext || + !Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti)) CmdArgs.push_back("-fno-rtti"); // -fsigned-char is default. @@ -1101,6 +1126,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_threadsafe_statics)) CmdArgs.push_back("-fno-threadsafe-statics"); + // -fuse-cxa-atexit is default. + if (KernelOrKext || !Args.hasFlag(options::OPT_fuse_cxa_atexit, + options::OPT_fno_use_cxa_atexit)) + CmdArgs.push_back("-fno-use-cxa-atexit"); + // -fms-extensions=0 is default. if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, getToolChain().getTriple().getOS() == llvm::Triple::Win32)) |