diff options
Diffstat (limited to 'lib/Driver')
-rw-r--r-- | lib/Driver/ArgList.cpp | 28 | ||||
-rw-r--r-- | lib/Driver/CC1AsOptions.cpp | 39 | ||||
-rw-r--r-- | lib/Driver/CC1Options.cpp | 2 | ||||
-rw-r--r-- | lib/Driver/CMakeLists.txt | 4 | ||||
-rw-r--r-- | lib/Driver/Driver.cpp | 65 | ||||
-rw-r--r-- | lib/Driver/Tool.cpp | 6 | ||||
-rw-r--r-- | lib/Driver/ToolChains.cpp | 20 | ||||
-rw-r--r-- | lib/Driver/ToolChains.h | 29 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 143 | ||||
-rw-r--r-- | lib/Driver/Tools.h | 123 |
10 files changed, 357 insertions, 102 deletions
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp index 95805b0..3d07431 100644 --- a/lib/Driver/ArgList.cpp +++ b/lib/Driver/ArgList.cpp @@ -9,12 +9,14 @@ #include "clang/Driver/ArgList.h" #include "clang/Driver/Arg.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Option.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" +using namespace clang; using namespace clang::driver; void arg_iterator::SkipToNextArg() { @@ -108,6 +110,32 @@ bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const { return Default; } +llvm::StringRef ArgList::getLastArgValue(OptSpecifier Id, + llvm::StringRef Default) const { + if (Arg *A = getLastArg(Id)) + return A->getValue(*this); + return Default; +} + +int ArgList::getLastArgIntValue(OptSpecifier Id, int Default, + clang::Diagnostic &Diags) const { + int Res = Default; + + if (Arg *A = getLastArg(Id)) { + if (llvm::StringRef(A->getValue(*this)).getAsInteger(10, Res)) + Diags.Report(diag::err_drv_invalid_int_value) + << A->getAsString(*this) << A->getValue(*this); + } + + return Res; +} + +std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const { + llvm::SmallVector<const char *, 16> Values; + AddAllArgValues(Values, Id); + return std::vector<std::string>(Values.begin(), Values.end()); +} + void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const { if (Arg *A = getLastArg(Id)) { A->claim(); diff --git a/lib/Driver/CC1AsOptions.cpp b/lib/Driver/CC1AsOptions.cpp new file mode 100644 index 0000000..90c69ff --- /dev/null +++ b/lib/Driver/CC1AsOptions.cpp @@ -0,0 +1,39 @@ +//===--- CC1AsOptions.cpp - Clang Assembler Options Table -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Driver/CC1AsOptions.h" +#include "clang/Driver/Option.h" +#include "clang/Driver/OptTable.h" +using namespace clang; +using namespace clang::driver; +using namespace clang::driver::options; +using namespace clang::driver::cc1asoptions; + +static const OptTable::Info CC1AsInfoTable[] = { +#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ + HELPTEXT, METAVAR) \ + { NAME, HELPTEXT, METAVAR, Option::KIND##Class, FLAGS, PARAM, \ + OPT_##GROUP, OPT_##ALIAS }, +#include "clang/Driver/CC1AsOptions.inc" +}; + +namespace { + +class CC1AsOptTable : public OptTable { +public: + CC1AsOptTable() + : OptTable(CC1AsInfoTable, + sizeof(CC1AsInfoTable) / sizeof(CC1AsInfoTable[0])) {} +}; + +} + +OptTable *clang::driver::createCC1AsOptTable() { + return new CC1AsOptTable(); +} diff --git a/lib/Driver/CC1Options.cpp b/lib/Driver/CC1Options.cpp index 0e98bb9..14cf090 100644 --- a/lib/Driver/CC1Options.cpp +++ b/lib/Driver/CC1Options.cpp @@ -1,4 +1,4 @@ -//===--- CC1Options.cpp - Clang CC1 Options Table -----------------------*-===// +//===--- CC1Options.cpp - Clang CC1 Options Table -------------------------===// // // The LLVM Compiler Infrastructure // diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt index 7efcd8a..5af754d 100644 --- a/lib/Driver/CMakeLists.txt +++ b/lib/Driver/CMakeLists.txt @@ -5,6 +5,7 @@ add_clang_library(clangDriver Arg.cpp ArgList.cpp CC1Options.cpp + CC1AsOptions.cpp Compilation.cpp Driver.cpp DriverOptions.cpp @@ -20,4 +21,5 @@ add_clang_library(clangDriver Types.cpp ) -add_dependencies(clangDriver ClangDiagnosticDriver ClangDriverOptions ClangCC1Options) +add_dependencies(clangDriver ClangDiagnosticDriver ClangDriverOptions + ClangCC1Options ClangCC1AsOptions) diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 7371a93..da83803 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -227,28 +227,31 @@ int Driver::ExecuteCompilation(const Compilation &C) const { // Remove temp files. C.CleanupFileList(C.getTempFiles()); - // If the compilation failed, remove result files as well. - if (Res != 0 && !C.getArgs().hasArg(options::OPT_save_temps)) + // If the command succeeded, we are done. + if (Res == 0) + return Res; + + // Otherwise, remove result files as well. + if (!C.getArgs().hasArg(options::OPT_save_temps)) C.CleanupFileList(C.getResultFiles(), true); // Print extra information about abnormal failures, if possible. - if (Res) { - // This is ad-hoc, but we don't want to be excessively noisy. If the result - // status was 1, assume the command failed normally. In particular, if it - // was the compiler then assume it gave a reasonable error code. Failures in - // other tools are less common, and they generally have worse diagnostics, - // so always print the diagnostic there. - const Action &Source = FailingCommand->getSource(); - - if (!FailingCommand->getCreator().hasGoodDiagnostics() || Res != 1) { - // FIXME: See FIXME above regarding result code interpretation. - if (Res < 0) - Diag(clang::diag::err_drv_command_signalled) - << Source.getClassName() << -Res; - else - Diag(clang::diag::err_drv_command_failed) - << Source.getClassName() << Res; - } + // + // This is ad-hoc, but we don't want to be excessively noisy. If the result + // status was 1, assume the command failed normally. In particular, if it was + // the compiler then assume it gave a reasonable error code. Failures in other + // tools are less common, and they generally have worse diagnostics, so always + // print the diagnostic there. + const Tool &FailingTool = FailingCommand->getCreator(); + + if (!FailingCommand->getCreator().hasGoodDiagnostics() || Res != 1) { + // FIXME: See FIXME above regarding result code interpretation. + if (Res < 0) + Diag(clang::diag::err_drv_command_signalled) + << FailingTool.getShortName() << -Res; + else + Diag(clang::diag::err_drv_command_failed) + << FailingTool.getShortName() << Res; } return Res; @@ -291,6 +294,14 @@ void Driver::PrintVersion(const Compilation &C, llvm::raw_ostream &OS) const { OS << "Thread model: " << "posix" << '\n'; } +/// PrintDiagnosticCategories - Implement the --print-diagnostic-categories +/// option. +static void PrintDiagnosticCategories(llvm::raw_ostream &OS) { + for (unsigned i = 1; // Skip the empty category. + const char *CategoryName = Diagnostic::getCategoryNameFromID(i); ++i) + OS << i << ',' << CategoryName << '\n'; +} + bool Driver::HandleImmediateArgs(const Compilation &C) { // The order these options are handled in in gcc is all over the place, but we // don't expect inconsistencies w.r.t. that to matter in practice. @@ -299,6 +310,11 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { llvm::outs() << CLANG_VERSION_STRING "\n"; return false; } + + if (C.getArgs().hasArg(options::OPT__print_diagnostic_categories)) { + PrintDiagnosticCategories(llvm::outs()); + return false; + } if (C.getArgs().hasArg(options::OPT__help) || C.getArgs().hasArg(options::OPT__help_hidden)) { @@ -889,9 +905,16 @@ static const Tool &SelectToolForJob(Compilation &C, const ToolChain *TC, // See if we should look for a compiler with an integrated assembler. We match // bottom up, so what we are actually looking for is an assembler job with a // compiler input. - if (C.getArgs().hasArg(options::OPT_integrated_as, + + // FIXME: This doesn't belong here, but ideally we will support static soon + // anyway. + bool HasStatic = (C.getArgs().hasArg(options::OPT_mkernel) || + C.getArgs().hasArg(options::OPT_static) || + C.getArgs().hasArg(options::OPT_fapple_kext)); + bool IsIADefault = (TC->IsIntegratedAssemblerDefault() && !HasStatic); + if (C.getArgs().hasFlag(options::OPT_integrated_as, options::OPT_no_integrated_as, - TC->IsIntegratedAssemblerDefault()) && + IsIADefault) && !C.getArgs().hasArg(options::OPT_save_temps) && isa<AssembleJobAction>(JA) && Inputs->size() == 1 && isa<CompileJobAction>(*Inputs->begin())) { diff --git a/lib/Driver/Tool.cpp b/lib/Driver/Tool.cpp index 781e0a7..fe01531 100644 --- a/lib/Driver/Tool.cpp +++ b/lib/Driver/Tool.cpp @@ -11,8 +11,10 @@ using namespace clang::driver; -Tool::Tool(const char *_Name, const ToolChain &TC) : Name(_Name), - TheToolChain(TC) { +Tool::Tool(const char *_Name, const char *_ShortName, + const ToolChain &TC) : Name(_Name), ShortName(_ShortName), + TheToolChain(TC) +{ } Tool::~Tool() { diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 1cd8ee1..abb55b0 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -11,6 +11,7 @@ #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" +#include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/HostInfo.h" @@ -190,6 +191,16 @@ Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const { else Key = JA.getKind(); + // FIXME: This doesn't belong here, but ideally we will support static soon + // anyway. + bool HasStatic = (C.getArgs().hasArg(options::OPT_mkernel) || + C.getArgs().hasArg(options::OPT_static) || + C.getArgs().hasArg(options::OPT_fapple_kext)); + bool IsIADefault = IsIntegratedAssemblerDefault() && !HasStatic; + bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as, + options::OPT_no_integrated_as, + IsIADefault); + Tool *&T = Tools[Key]; if (!T) { switch (Key) { @@ -203,8 +214,13 @@ Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA) const { case Action::PrecompileJobClass: case Action::CompileJobClass: T = new tools::darwin::Compile(*this); break; - case Action::AssembleJobClass: - T = new tools::darwin::Assemble(*this); break; + case Action::AssembleJobClass: { + if (UseIntegratedAs) + T = new tools::ClangAs(*this); + else + T = new tools::darwin::Assemble(*this); + break; + } case Action::LinkJobClass: T = new tools::darwin::Link(*this); break; case Action::LipoJobClass: diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 9acc950..ad975bf 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -25,7 +25,7 @@ namespace toolchains { /// Generic_GCC - A tool chain using the 'gcc' command to perform /// all subcommands; this relies on gcc translating the majority of /// command line options. -class VISIBILITY_HIDDEN Generic_GCC : public ToolChain { +class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain { protected: mutable llvm::DenseMap<unsigned, Tool*> Tools; @@ -44,7 +44,7 @@ public: }; /// Darwin - The base Darwin tool chain. -class VISIBILITY_HIDDEN Darwin : public ToolChain { +class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain { mutable llvm::DenseMap<unsigned, Tool*> Tools; /// Whether the information on the target has been initialized. @@ -56,7 +56,7 @@ class VISIBILITY_HIDDEN Darwin : public ToolChain { /// Whether we are targetting iPhoneOS target. mutable bool TargetIsIPhoneOS; - + /// The OS version we are targetting. mutable unsigned TargetVersion[3]; @@ -159,6 +159,11 @@ public: else return !isMacosxVersionLT(10, 6); } + virtual bool IsIntegratedAssemblerDefault() const { + // Default integrated assembler to on for x86. + return (getTriple().getArch() == llvm::Triple::x86 || + getTriple().getArch() == llvm::Triple::x86_64); + } virtual bool IsObjCNonFragileABIDefault() const { // Non-fragile ABI is default for everything but i386. return getTriple().getArch() != llvm::Triple::x86; @@ -193,7 +198,7 @@ public: }; /// DarwinClang - The Darwin toolchain used by Clang. -class VISIBILITY_HIDDEN DarwinClang : public Darwin { +class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { public: DarwinClang(const HostInfo &Host, const llvm::Triple& Triple, const unsigned (&DarwinVersion)[3]); @@ -211,7 +216,7 @@ public: }; /// DarwinGCC - The Darwin toolchain used by GCC. -class VISIBILITY_HIDDEN DarwinGCC : public Darwin { +class LLVM_LIBRARY_VISIBILITY DarwinGCC : public Darwin { /// GCC version to use. unsigned GCCVersion[3]; @@ -236,7 +241,7 @@ public: }; /// Darwin_Generic_GCC - Generic Darwin tool chain using gcc. -class VISIBILITY_HIDDEN Darwin_Generic_GCC : public Generic_GCC { +class LLVM_LIBRARY_VISIBILITY Darwin_Generic_GCC : public Generic_GCC { public: Darwin_Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple) : Generic_GCC(Host, Triple) {} @@ -244,35 +249,35 @@ public: virtual const char *GetDefaultRelocationModel() const { return "pic"; } }; -class VISIBILITY_HIDDEN AuroraUX : public Generic_GCC { +class LLVM_LIBRARY_VISIBILITY AuroraUX : public Generic_GCC { public: AuroraUX(const HostInfo &Host, const llvm::Triple& Triple); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; }; -class VISIBILITY_HIDDEN OpenBSD : public Generic_GCC { +class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_GCC { public: OpenBSD(const HostInfo &Host, const llvm::Triple& Triple); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; }; -class VISIBILITY_HIDDEN FreeBSD : public Generic_GCC { +class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_GCC { public: FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; }; -class VISIBILITY_HIDDEN DragonFly : public Generic_GCC { +class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_GCC { public: DragonFly(const HostInfo &Host, const llvm::Triple& Triple); virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; }; -class VISIBILITY_HIDDEN Linux : public Generic_GCC { +class LLVM_LIBRARY_VISIBILITY Linux : public Generic_GCC { public: Linux(const HostInfo &Host, const llvm::Triple& Triple); }; @@ -280,7 +285,7 @@ public: /// TCEToolChain - A tool chain using the llvm bitcode tools to perform /// all subcommands. See http://tce.cs.tut.fi for our peculiar target. -class VISIBILITY_HIDDEN TCEToolChain : public ToolChain { +class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain { public: TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple); ~TCEToolChain(); diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 5a3916d..918f0d9 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -21,7 +21,6 @@ #include "clang/Driver/Options.h" #include "clang/Driver/ToolChain.h" #include "clang/Driver/Util.h" -#include "clang/Frontend/DiagnosticOptions.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" @@ -769,6 +768,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-E"); } else if (isa<AssembleJobAction>(JA)) { CmdArgs.push_back("-emit-obj"); + + // At -O0, we use -mrelax-all by default. + bool IsOpt = false; + 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)) + CmdArgs.push_back("-mrelax-all"); } else if (isa<PrecompileJobAction>(JA)) { // Use PCH if the user requested it, except for C++ (for now). bool UsePCH = D.CCCUsePCH; @@ -911,8 +919,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss, options::OPT_fno_zero_initialized_in_bss)) CmdArgs.push_back("-mno-zero-initialized-in-bss"); - if (Args.hasArg(options::OPT_dA) || Args.hasArg(options::OPT_fverbose_asm)) + + // Decide whether to use verbose asm. Verbose assembly is the default on + // toolchains which have the integrated assembler on by default. + bool IsVerboseAsmDefault = getToolChain().IsIntegratedAssemblerDefault(); + if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm, + IsVerboseAsmDefault) || + Args.hasArg(options::OPT_dA)) CmdArgs.push_back("-masm-verbose"); + if (Args.hasArg(options::OPT_fdebug_pass_structure)) { CmdArgs.push_back("-mdebug-pass"); CmdArgs.push_back("Structure"); @@ -979,6 +994,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, false)) CmdArgs.push_back("-fmath-errno"); + // Explicitly error on some things we know we don't support and can't just + // ignore. + types::ID InputType = Inputs[0].getType(); Arg *Unsupported; if ((Unsupported = Args.getLastArg(options::OPT_MG)) || (Unsupported = Args.getLastArg(options::OPT_iframework)) || @@ -986,6 +1004,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, D.Diag(clang::diag::err_drv_clang_unsupported) << Unsupported->getOption().getName(); + if (types::isCXX(InputType) && + getToolChain().getTriple().getOS() == llvm::Triple::Darwin && + getToolChain().getTriple().getArch() == llvm::Triple::x86) { + if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext))) + D.Diag(clang::diag::err_drv_clang_unsupported_opt_cxx_darwin_i386) + << Unsupported->getOption().getName(); + } + Args.AddAllArgs(CmdArgs, options::OPT_v); Args.AddLastArg(CmdArgs, options::OPT_P); Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout); @@ -993,9 +1019,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Special case debug options to only pass -g to clang. This is // wrong. Args.ClaimAllArgs(options::OPT_g_Group); - Arg *Garg = Args.getLastArg(options::OPT_g_Group); - if (Garg && Garg != Args.getLastArg(options::OPT_g0)) - CmdArgs.push_back("-g"); + if (Arg *A = Args.getLastArg(options::OPT_g_Group)) + if (!A->getOption().matches(options::OPT_g0)) + CmdArgs.push_back("-g"); + + Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections); + Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections); Args.AddLastArg(CmdArgs, options::OPT_nostdinc); Args.AddLastArg(CmdArgs, options::OPT_nostdincxx); @@ -1009,7 +1038,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // preprocessor. // // FIXME: Support -fpreprocessed - types::ID InputType = Inputs[0].getType(); if (types::getPreprocessedType(InputType) != types::TY_INVALID) AddPreprocessingOptions(D, Args, CmdArgs, Output, Inputs); @@ -1018,7 +1046,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { if (A->getOption().matches(options::OPT_O4)) CmdArgs.push_back("-O3"); - else if (A->getValue(Args)[0] == '\0') + else if (A->getOption().matches(options::OPT_O) && + A->getValue(Args)[0] == '\0') CmdArgs.push_back("-O2"); else A->render(Args, CmdArgs); @@ -1059,6 +1088,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_trigraphs); } + // 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)) + CmdArgs.push_back("-fgnu-keywords"); + else + CmdArgs.push_back("-fno-gnu-keywords"); + } + if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) { CmdArgs.push_back("-ftemplate-depth"); CmdArgs.push_back(A->getValue(Args)); @@ -1083,20 +1120,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, else CmdArgs.push_back("19"); - CmdArgs.push_back("-fmacro-backtrace-limit"); - if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) + if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) { + CmdArgs.push_back("-fmacro-backtrace-limit"); CmdArgs.push_back(A->getValue(Args)); - else - CmdArgs.push_back(Args.MakeArgString( - llvm::Twine(DiagnosticOptions::DefaultMacroBacktraceLimit))); - - CmdArgs.push_back("-ftemplate-backtrace-limit"); - if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) + } + + if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) { + CmdArgs.push_back("-ftemplate-backtrace-limit"); CmdArgs.push_back(A->getValue(Args)); - else - CmdArgs.push_back(Args.MakeArgString( - llvm::Twine(DiagnosticOptions::DefaultTemplateBacktraceLimit))); - + } + // Pass -fmessage-length=. CmdArgs.push_back("-fmessage-length"); if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) { @@ -1265,6 +1298,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fobjc-dispatch-method=non-legacy"); } } + + // FIXME: -fobjc-nonfragile-abi2 is a transient option meant to expose + // features in testing. It will eventually be removed. + if (Args.hasArg(options::OPT_fobjc_nonfragile_abi2)) + CmdArgs.push_back("-fobjc-nonfragile-abi2"); } if (!Args.hasFlag(options::OPT_fassume_sane_operator_new, @@ -1320,6 +1358,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_diagnostics_show_option)) CmdArgs.push_back("-fdiagnostics-show-option"); + if (const Arg *A = + Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) { + CmdArgs.push_back("-fdiagnostics-show-category"); + CmdArgs.push_back(A->getValue(Args)); + } + // Color diagnostics are the default, unless the terminal doesn't support // them. if (Args.hasFlag(options::OPT_fcolor_diagnostics, @@ -1451,6 +1495,67 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group); } +void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, + Job &Dest, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const Driver &D = getToolChain().getDriver(); + ArgStringList CmdArgs; + + assert(Inputs.size() == 1 && "Unexpected number of inputs."); + const InputInfo &Input = Inputs[0]; + + // Invoke ourselves in -cc1as mode. + // + // FIXME: Implement custom jobs for internal actions. + CmdArgs.push_back("-cc1as"); + + // Add the "effective" target triple. + CmdArgs.push_back("-triple"); + std::string TripleStr = getEffectiveClangTriple(D, getToolChain(), Args); + CmdArgs.push_back(Args.MakeArgString(TripleStr)); + + // Set the output mode, we currently only expect to be used as a real + // assembler. + CmdArgs.push_back("-filetype"); + CmdArgs.push_back("obj"); + + // At -O0, we use -mrelax-all by default. + bool IsOpt = false; + 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)) + CmdArgs.push_back("-mrelax-all"); + + // FIXME: Add -force_cpusubtype_ALL support, once we have it. + + // FIXME: Add -g support, once we have it. + + // FIXME: Add -static support, once we have it. + + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, + options::OPT_Xassembler); + + assert(Output.isFilename() && "Unexpected lipo output."); + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + if (Input.isPipe()) { + CmdArgs.push_back("-"); + } else { + assert(Input.isFilename() && "Invalid input."); + CmdArgs.push_back(Input.getFilename()); + } + + const char *Exec = + Args.MakeArgString(getToolChain().GetProgramPath(C, "clang")); + Dest.addCommand(new Command(JA, *this, Exec, CmdArgs)); +} + void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, Job &Dest, const InputInfo &Output, diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h index 091fec3..d5e98dd 100644 --- a/lib/Driver/Tools.h +++ b/lib/Driver/Tools.h @@ -26,7 +26,8 @@ namespace toolchains { namespace tools { - class VISIBILITY_HIDDEN Clang : public Tool { + /// \brief Clang compiler tool. + class LLVM_LIBRARY_VISIBILITY Clang : public Tool { void AddPreprocessingOptions(const Driver &D, const ArgList &Args, ArgStringList &CmdArgs, @@ -38,7 +39,7 @@ namespace tools { void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; public: - Clang(const ToolChain &TC) : Tool("clang", TC) {} + Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } @@ -54,11 +55,32 @@ namespace tools { const char *LinkingOutput) const; }; + /// \brief Clang integrated assembler tool. + class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool { + public: + ClangAs(const ToolChain &TC) : Tool("clang::as", + "clang integrated assembler", TC) {} + + virtual bool acceptsPipedInput() const { return true; } + virtual bool canPipeOutput() const { return true; } + virtual bool hasGoodDiagnostics() const { return true; } + virtual bool hasIntegratedAssembler() const { return false; } + virtual bool hasIntegratedCPP() const { return false; } + + virtual void ConstructJob(Compilation &C, const JobAction &JA, + Job &Dest, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &TCArgs, + const char *LinkingOutput) const; + }; + /// gcc - Generic GCC tool implementations. namespace gcc { - class VISIBILITY_HIDDEN Common : public Tool { + class LLVM_LIBRARY_VISIBILITY Common : public Tool { public: - Common(const char *Name, const ToolChain &TC) : Tool(Name, TC) {} + Common(const char *Name, const char *ShortName, + const ToolChain &TC) : Tool(Name, ShortName, TC) {} virtual void ConstructJob(Compilation &C, const JobAction &JA, Job &Dest, @@ -74,9 +96,10 @@ namespace gcc { }; - class VISIBILITY_HIDDEN Preprocess : public Common { + class LLVM_LIBRARY_VISIBILITY Preprocess : public Common { public: - Preprocess(const ToolChain &TC) : Common("gcc::Preprocess", TC) {} + Preprocess(const ToolChain &TC) : Common("gcc::Preprocess", + "gcc preprocessor", TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } @@ -87,9 +110,10 @@ namespace gcc { ArgStringList &CmdArgs) const; }; - class VISIBILITY_HIDDEN Precompile : public Common { + class LLVM_LIBRARY_VISIBILITY Precompile : public Common { public: - Precompile(const ToolChain &TC) : Common("gcc::Precompile", TC) {} + Precompile(const ToolChain &TC) : Common("gcc::Precompile", + "gcc precompile", TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return false; } @@ -100,9 +124,10 @@ namespace gcc { ArgStringList &CmdArgs) const; }; - class VISIBILITY_HIDDEN Compile : public Common { + class LLVM_LIBRARY_VISIBILITY Compile : public Common { public: - Compile(const ToolChain &TC) : Common("gcc::Compile", TC) {} + Compile(const ToolChain &TC) : Common("gcc::Compile", + "gcc frontend", TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } @@ -113,9 +138,10 @@ namespace gcc { ArgStringList &CmdArgs) const; }; - class VISIBILITY_HIDDEN Assemble : public Common { + class LLVM_LIBRARY_VISIBILITY Assemble : public Common { public: - Assemble(const ToolChain &TC) : Common("gcc::Assemble", TC) {} + Assemble(const ToolChain &TC) : Common("gcc::Assemble", + "assembler (via gcc)", TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return false; } @@ -125,9 +151,10 @@ namespace gcc { ArgStringList &CmdArgs) const; }; - class VISIBILITY_HIDDEN Link : public Common { + class LLVM_LIBRARY_VISIBILITY Link : public Common { public: - Link(const ToolChain &TC) : Common("gcc::Link", TC) {} + Link(const ToolChain &TC) : Common("gcc::Link", + "linker (via gcc)", TC) {} virtual bool acceptsPipedInput() const { return false; } virtual bool canPipeOutput() const { return false; } @@ -139,7 +166,7 @@ namespace gcc { } // end namespace gcc namespace darwin { - class VISIBILITY_HIDDEN DarwinTool : public Tool { + class LLVM_LIBRARY_VISIBILITY DarwinTool : public Tool { protected: void AddDarwinArch(const ArgList &Args, ArgStringList &CmdArgs) const; @@ -148,10 +175,11 @@ namespace darwin { } public: - DarwinTool(const char *Name, const ToolChain &TC) : Tool(Name, TC) {} + DarwinTool(const char *Name, const char *ShortName, + const ToolChain &TC) : Tool(Name, ShortName, TC) {} }; - class VISIBILITY_HIDDEN CC1 : public DarwinTool { + class LLVM_LIBRARY_VISIBILITY CC1 : public DarwinTool { public: static const char *getBaseInputName(const ArgList &Args, const InputInfoList &Input); @@ -176,7 +204,8 @@ namespace darwin { void AddCPPArgs(const ArgList &Args, ArgStringList &CmdArgs) const; public: - CC1(const char *Name, const ToolChain &TC) : DarwinTool(Name, TC) {} + CC1(const char *Name, const char *ShortName, + const ToolChain &TC) : DarwinTool(Name, ShortName, TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } @@ -184,9 +213,10 @@ namespace darwin { virtual bool hasIntegratedCPP() const { return true; } }; - class VISIBILITY_HIDDEN Preprocess : public CC1 { + class LLVM_LIBRARY_VISIBILITY Preprocess : public CC1 { public: - Preprocess(const ToolChain &TC) : CC1("darwin::Preprocess", TC) {} + Preprocess(const ToolChain &TC) : CC1("darwin::Preprocess", + "gcc preprocessor", TC) {} virtual void ConstructJob(Compilation &C, const JobAction &JA, Job &Dest, @@ -196,9 +226,9 @@ namespace darwin { const char *LinkingOutput) const; }; - class VISIBILITY_HIDDEN Compile : public CC1 { + class LLVM_LIBRARY_VISIBILITY Compile : public CC1 { public: - Compile(const ToolChain &TC) : CC1("darwin::Compile", TC) {} + Compile(const ToolChain &TC) : CC1("darwin::Compile", "gcc frontend", TC) {} virtual void ConstructJob(Compilation &C, const JobAction &JA, Job &Dest, @@ -208,9 +238,10 @@ namespace darwin { const char *LinkingOutput) const; }; - class VISIBILITY_HIDDEN Assemble : public DarwinTool { + class LLVM_LIBRARY_VISIBILITY Assemble : public DarwinTool { public: - Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble", TC) {} + Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble", + "assembler", TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return false; } @@ -224,11 +255,11 @@ namespace darwin { const char *LinkingOutput) const; }; - class VISIBILITY_HIDDEN Link : public DarwinTool { + class LLVM_LIBRARY_VISIBILITY Link : public DarwinTool { void AddLinkArgs(const ArgList &Args, ArgStringList &CmdArgs) const; public: - Link(const ToolChain &TC) : DarwinTool("darwin::Link", TC) {} + Link(const ToolChain &TC) : DarwinTool("darwin::Link", "linker", TC) {} virtual bool acceptsPipedInput() const { return false; } virtual bool canPipeOutput() const { return false; } @@ -242,9 +273,9 @@ namespace darwin { const char *LinkingOutput) const; }; - class VISIBILITY_HIDDEN Lipo : public DarwinTool { + class LLVM_LIBRARY_VISIBILITY Lipo : public DarwinTool { public: - Lipo(const ToolChain &TC) : DarwinTool("darwin::Lipo", TC) {} + Lipo(const ToolChain &TC) : DarwinTool("darwin::Lipo", "lipo", TC) {} virtual bool acceptsPipedInput() const { return false; } virtual bool canPipeOutput() const { return false; } @@ -261,9 +292,10 @@ namespace darwin { /// openbsd -- Directly call GNU Binutils assembler and linker namespace openbsd { - class VISIBILITY_HIDDEN Assemble : public Tool { + class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { public: - Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", TC) {} + Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", "assembler", + TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } @@ -276,9 +308,9 @@ namespace openbsd { const ArgList &TCArgs, const char *LinkingOutput) const; }; - class VISIBILITY_HIDDEN Link : public Tool { + class LLVM_LIBRARY_VISIBILITY Link : public Tool { public: - Link(const ToolChain &TC) : Tool("openbsd::Link", TC) {} + Link(const ToolChain &TC) : Tool("openbsd::Link", "linker", TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } @@ -295,9 +327,10 @@ namespace openbsd { /// freebsd -- Directly call GNU Binutils assembler and linker namespace freebsd { - class VISIBILITY_HIDDEN Assemble : public Tool { + class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { public: - Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", TC) {} + Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", "assembler", + TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } @@ -310,9 +343,9 @@ namespace freebsd { const ArgList &TCArgs, const char *LinkingOutput) const; }; - class VISIBILITY_HIDDEN Link : public Tool { + class LLVM_LIBRARY_VISIBILITY Link : public Tool { public: - Link(const ToolChain &TC) : Tool("freebsd::Link", TC) {} + Link(const ToolChain &TC) : Tool("freebsd::Link", "linker", TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } @@ -329,9 +362,10 @@ namespace freebsd { /// auroraux -- Directly call GNU Binutils assembler and linker namespace auroraux { - class VISIBILITY_HIDDEN Assemble : public Tool { + class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { public: - Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", TC) {} + Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", "assembler", + TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } @@ -344,9 +378,9 @@ namespace auroraux { const ArgList &TCArgs, const char *LinkingOutput) const; }; - class VISIBILITY_HIDDEN Link : public Tool { + class LLVM_LIBRARY_VISIBILITY Link : public Tool { public: - Link(const ToolChain &TC) : Tool("auroraux::Link", TC) {} + Link(const ToolChain &TC) : Tool("auroraux::Link", "linker", TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } @@ -363,9 +397,10 @@ namespace auroraux { /// dragonfly -- Directly call GNU Binutils assembler and linker namespace dragonfly { - class VISIBILITY_HIDDEN Assemble : public Tool { + class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { public: - Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", TC) {} + Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", "assembler", + TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } @@ -378,9 +413,9 @@ namespace dragonfly { const ArgList &TCArgs, const char *LinkingOutput) const; }; - class VISIBILITY_HIDDEN Link : public Tool { + class LLVM_LIBRARY_VISIBILITY Link : public Tool { public: - Link(const ToolChain &TC) : Tool("dragonfly::Link", TC) {} + Link(const ToolChain &TC) : Tool("dragonfly::Link", "linker", TC) {} virtual bool acceptsPipedInput() const { return true; } virtual bool canPipeOutput() const { return true; } |