aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2012-11-15 05:36:36 +0000
committerNick Lewycky <nicholas@mxc.ca>2012-11-15 05:36:36 +0000
commit5bab9ae87c41148ee2f92d312945c1e9303222e8 (patch)
tree256d66a02ba4783bdf0aa56a9858a19d92decd7e
parent5d1cf4f292cb060b1973eb197607fc6d5716bd12 (diff)
Revert r167567, restoring the ability of clang to run gcc in cases where it
can't handle the input file type. This resulted in PR14338. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168024 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Driver/Driver.h5
-rw-r--r--include/clang/Driver/Types.h3
-rw-r--r--lib/Driver/Driver.cpp16
-rw-r--r--lib/Driver/ToolChains.cpp99
-rw-r--r--lib/Driver/Tools.cpp622
-rw-r--r--lib/Driver/Tools.h64
-rw-r--r--lib/Driver/Types.cpp23
-rw-r--r--lib/Driver/WindowsToolChain.cpp7
8 files changed, 804 insertions, 35 deletions
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 8d752a497d..b752ce6a34 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -363,6 +363,11 @@ public:
/// GCC goes to extra lengths here to be a bit more robust.
std::string GetTemporaryPath(StringRef Prefix, const char *Suffix) const;
+ /// ShouldUseClangCompilar - Should the clang compiler be used to
+ /// handle this action.
+ bool ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
+ const llvm::Triple &ArchName) const;
+
bool IsUsingLTO(const ArgList &Args) const;
private:
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
index e6e4abc2ba..d28ca888d3 100644
--- a/include/clang/Driver/Types.h
+++ b/include/clang/Driver/Types.h
@@ -56,6 +56,9 @@ namespace types {
/// types).
bool canLipoType(ID Id);
+ /// isAcceptedByClang - Can clang handle this input type.
+ bool isAcceptedByClang(ID Id);
+
/// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
bool isCXX(ID Id);
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 464df333f7..68471ec04c 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -1731,6 +1731,22 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
return *TC;
}
+bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
+ const llvm::Triple &Triple) const {
+ // Check if user requested no clang, or clang doesn't understand this type (we
+ // only handle single inputs for now).
+ if (JA.size() != 1 ||
+ !types::isAcceptedByClang((*JA.begin())->getType()))
+ return false;
+
+ // Otherwise make sure this is an action clang understands.
+ if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
+ !isa<CompileJobAction>(JA))
+ return false;
+
+ return true;
+}
+
/// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the
/// grouped values as integers. Numbers which are not provided are set to 0.
///
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index a34751260d..819907b664 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -177,6 +177,12 @@ void Generic_ELF::anchor() {}
Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
Action::ActionClass Key = JA.getKind();
+
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) {
+ // FIXME: This seems like a hacky way to choose clang frontend.
+ Key = Action::AnalyzeJobClass;
+ }
+
bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
options::OPT_no_integrated_as,
IsIntegratedAssemblerDefault());
@@ -188,11 +194,13 @@ Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA,
case Action::BindArchClass:
llvm_unreachable("Invalid tool kind.");
case Action::PreprocessJobClass:
+ T = new tools::darwin::Preprocess(*this); break;
case Action::AnalyzeJobClass:
case Action::MigrateJobClass:
+ T = new tools::Clang(*this); break;
case Action::PrecompileJobClass:
case Action::CompileJobClass:
- T = new tools::Clang(*this); break;
+ T = new tools::darwin::Compile(*this); break;
case Action::AssembleJobClass: {
if (UseIntegratedAs)
T = new tools::ClangAs(*this);
@@ -1326,7 +1334,11 @@ Generic_GCC::~Generic_GCC() {
Tool &Generic_GCC::SelectTool(const Compilation &C,
const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
Tool *&T = Tools[Key];
if (!T) {
@@ -1335,11 +1347,14 @@ Tool &Generic_GCC::SelectTool(const Compilation &C,
case Action::BindArchClass:
llvm_unreachable("Invalid tool kind.");
case Action::PreprocessJobClass:
+ T = new tools::gcc::Preprocess(*this); break;
case Action::PrecompileJobClass:
+ T = new tools::gcc::Precompile(*this); break;
case Action::AnalyzeJobClass:
case Action::MigrateJobClass:
- case Action::CompileJobClass:
T = new tools::Clang(*this); break;
+ case Action::CompileJobClass:
+ T = new tools::gcc::Compile(*this); break;
case Action::AssembleJobClass:
T = new tools::gcc::Assemble(*this); break;
case Action::LinkJobClass:
@@ -1389,18 +1404,27 @@ Hexagon_TC::~Hexagon_TC() {
Tool &Hexagon_TC::SelectTool(const Compilation &C,
const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
+ Action::ActionClass Key;
+ // if (JA.getKind () == Action::CompileJobClass)
+ // Key = JA.getKind ();
+ // else
+
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
+ // if ((JA.getKind () == Action::CompileJobClass)
+ // && (JA.getType () != types::TY_LTO_BC)) {
+ // Key = JA.getKind ();
+ // }
+
Tool *&T = Tools[Key];
if (!T) {
switch (Key) {
case Action::InputClass:
case Action::BindArchClass:
assert(0 && "Invalid tool kind.");
- case Action::PreprocessJobClass:
- case Action::PrecompileJobClass:
case Action::AnalyzeJobClass:
- case Action::MigrateJobClass:
- case Action::CompileJobClass:
T = new tools::Clang(*this); break;
case Action::AssembleJobClass:
T = new tools::hexagon::Assemble(*this); break;
@@ -1484,7 +1508,12 @@ OpenBSD::OpenBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Arg
Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
+
bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
options::OPT_no_integrated_as,
IsIntegratedAssemblerDefault());
@@ -1519,7 +1548,12 @@ Bitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
Tool &Bitrig::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
+
bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
options::OPT_no_integrated_as,
IsIntegratedAssemblerDefault());
@@ -1606,7 +1640,12 @@ FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Arg
Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
+
bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
options::OPT_no_integrated_as,
IsIntegratedAssemblerDefault());
@@ -1650,7 +1689,12 @@ NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
Tool &NetBSD::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
+
bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
options::OPT_no_integrated_as,
IsIntegratedAssemblerDefault());
@@ -1685,7 +1729,11 @@ Minix::Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
Tool *&T = Tools[Key];
if (!T) {
@@ -1722,7 +1770,11 @@ AuroraUX::AuroraUX(const Driver &D, const llvm::Triple& Triple,
Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
Tool *&T = Tools[Key];
if (!T) {
@@ -1755,7 +1807,11 @@ Solaris::Solaris(const Driver &D, const llvm::Triple& Triple,
Tool &Solaris::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
Tool *&T = Tools[Key];
if (!T) {
@@ -2128,7 +2184,12 @@ bool Linux::HasNativeLLVMSupport() const {
Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
+
bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
options::OPT_no_integrated_as,
IsIntegratedAssemblerDefault());
@@ -2346,7 +2407,11 @@ DragonFly::DragonFly(const Driver &D, const llvm::Triple& Triple, const ArgList
Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const {
- Action::ActionClass Key = JA.getKind();
+ Action::ActionClass Key;
+ if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
Tool *&T = Tools[Key];
if (!T) {
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 9ab35ff83c..b1e450d21c 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -257,7 +257,7 @@ void Clang::AddPreprocessingOptions(Compilation &C,
A->getOption().matches(options::OPT_MM)) {
DepFile = "-";
} else {
- DepFile = getDependencyFileName(Args, Inputs);
+ DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);
C.addFailureResultFile(DepFile);
}
CmdArgs.push_back("-dependency-file");
@@ -1713,10 +1713,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Set the main file name, so that debug info works even with
// -save-temps.
CmdArgs.push_back("-main-file-name");
- CmdArgs.push_back(getBaseInputName(Args, Inputs));
+ CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
// Some flags which affect the language (via preprocessor
- // defines).
+ // defines). See darwin::CC1::AddCPPArgs.
if (Args.hasArg(options::OPT_static))
CmdArgs.push_back("-static-define");
@@ -3636,14 +3636,38 @@ llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) {
.Default(llvm::Triple::UnknownArch);
}
-const char *Clang::getBaseInputName(const ArgList &Args,
- const InputInfoList &Inputs) {
+const char *darwin::CC1::getCC1Name(types::ID Type) const {
+ switch (Type) {
+ default:
+ llvm_unreachable("Unexpected type for Darwin CC1 tool.");
+ case types::TY_Asm:
+ case types::TY_C: case types::TY_CHeader:
+ case types::TY_PP_C: case types::TY_PP_CHeader:
+ return "cc1";
+ case types::TY_ObjC: case types::TY_ObjCHeader:
+ case types::TY_PP_ObjC: case types::TY_PP_ObjC_Alias:
+ case types::TY_PP_ObjCHeader:
+ return "cc1obj";
+ case types::TY_CXX: case types::TY_CXXHeader:
+ case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
+ return "cc1plus";
+ case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
+ case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXX_Alias:
+ case types::TY_PP_ObjCXXHeader:
+ return "cc1objplus";
+ }
+}
+
+void darwin::CC1::anchor() {}
+
+const char *darwin::CC1::getBaseInputName(const ArgList &Args,
+ const InputInfoList &Inputs) {
return Args.MakeArgString(
llvm::sys::path::filename(Inputs[0].getBaseInput()));
}
-const char *Clang::getBaseInputStem(const ArgList &Args,
- const InputInfoList &Inputs) {
+const char *darwin::CC1::getBaseInputStem(const ArgList &Args,
+ const InputInfoList &Inputs) {
const char *Str = getBaseInputName(Args, Inputs);
if (const char *End = strrchr(Str, '.'))
@@ -3652,8 +3676,9 @@ const char *Clang::getBaseInputStem(const ArgList &Args,
return Str;
}
-const char *Clang::getDependencyFileName(const ArgList &Args,
- const InputInfoList &Inputs) {
+const char *
+darwin::CC1::getDependencyFileName(const ArgList &Args,
+ const InputInfoList &Inputs) {
// FIXME: Think about this more.
std::string Res;
@@ -3661,11 +3686,588 @@ const char *Clang::getDependencyFileName(const ArgList &Args,
std::string Str(OutputOpt->getValue());
Res = Str.substr(0, Str.rfind('.'));
} else {
- Res = getBaseInputStem(Args, Inputs);
+ Res = darwin::CC1::getBaseInputStem(Args, Inputs);
}
return Args.MakeArgString(Res + ".d");
}
+void darwin::CC1::RemoveCC1UnsupportedArgs(ArgStringList &CmdArgs) const {
+ for (ArgStringList::iterator it = CmdArgs.begin(), ie = CmdArgs.end();
+ it != ie;) {
+
+ StringRef Option = *it;
+ bool RemoveOption = false;
+
+ // Erase both -fmodule-cache-path and its argument.
+ if (Option.equals("-fmodule-cache-path") && it+2 != ie) {
+ it = CmdArgs.erase(it, it+2);
+ ie = CmdArgs.end();
+ continue;
+ }
+
+ // Remove unsupported -f options.
+ if (Option.startswith("-f")) {
+ // Remove -f/-fno- to reduce the number of cases.
+ if (Option.startswith("-fno-"))
+ Option = Option.substr(5);
+ else
+ Option = Option.substr(2);
+ RemoveOption = llvm::StringSwitch<bool>(Option)
+ .Case("altivec", true)
+ .Case("modules", true)
+ .Case("diagnostics-show-note-include-stack", true)
+ .Default(false);
+ }
+
+ // Handle machine specific options.
+ if (Option.startswith("-m")) {
+ RemoveOption = llvm::StringSwitch<bool>(Option)
+ .Case("-mthumb", true)
+ .Case("-mno-thumb", true)
+ .Case("-mno-fused-madd", true)
+ .Case("-mlong-branch", true)
+ .Case("-mlongcall", true)
+ .Case("-mcpu=G4", true)
+ .Case("-mcpu=G5", true)
+ .Default(false);
+ }
+
+ // Handle warning options.
+ if (Option.startswith("-W")) {
+ // Remove -W/-Wno- to reduce the number of cases.
+ if (Option.startswith("-Wno-"))
+ Option = Option.substr(5);
+ else
+ Option = Option.substr(2);
+
+ RemoveOption = llvm::StringSwitch<bool>(Option)
+ .Case("address-of-temporary", true)
+ .Case("ambiguous-member-template", true)
+ .Case("analyzer-incompatible-plugin", true)
+ .Case("array-bounds", true)
+ .Case("array-bounds-pointer-arithmetic", true)
+ .Case("bind-to-temporary-copy", true)
+ .Case("bitwise-op-parentheses", true)
+ .Case("bool-conversions", true)
+ .Case("builtin-macro-redefined", true)
+ .Case("c++-hex-floats", true)
+ .Case("c++0x-compat", true)
+ .Case("c++0x-extensions", true)
+ .Case("c++0x-narrowing", true)
+ .Case("c++11-compat", true)
+ .Case("c++11-extensions", true)
+ .Case("c++11-narrowing", true)
+ .Case("conditional-uninitialized", true)
+ .Case("constant-conversion", true)
+ .Case("conversion-null", true)
+ .Case("CFString-literal", true)
+ .Case("constant-logical-operand", true)
+ .Case("custom-atomic-properties", true)
+ .Case("default-arg-special-member", true)
+ .Case("delegating-ctor-cycles", true)
+ .Case("delete-non-virtual-dtor", true)
+ .Case("deprecated-implementations", true)
+ .Case("deprecated-writable-strings", true)
+ .Case("distributed-object-modifiers", true)
+ .Case("duplicate-method-arg", true)
+ .Case("dynamic-class-memaccess", true)
+ .Case("enum-compare", true)
+ .Case("enum-conversion", true)
+ .Case("exit-time-destructors", true)
+ .Case("gnu", true)
+ .Case("gnu-designator", true)
+ .Case("header-hygiene", true)
+ .Case("idiomatic-parentheses", true)
+ .Case("ignored-qualifiers", true)
+ .Case("implicit-atomic-properties", true)
+ .Case("incompatible-pointer-types", true)
+ .Case("incomplete-implementation", true)
+ .Case("int-conversion", true)
+ .Case("initializer-overrides", true)
+ .Case("invalid-noreturn", true)
+ .Case("invalid-token-paste", true)
+ .Case("language-extension-token", true)
+ .Case("literal-conversion", true)
+ .Case("literal-range", true)
+ .Case("local-type-template-args", true)
+ .Case("logical-op-parentheses", true)
+ .Case("method-signatures", true)
+ .Case("microsoft", true)
+ .Case("mismatched-tags", true)
+ .Case("missing-method-return-type", true)
+ .Case("non-pod-varargs", true)
+ .Case("nonfragile-abi2", true)
+ .Case("null-arithmetic", true)
+ .Case("null-dereference", true)
+ .Case("out-of-line-declaration", true)
+ .Case("overriding-method-mismatch", true)
+ .Case("readonly-setter-attrs", true)
+ .Case("return-stack-address", true)
+ .Case("self-assign", true)
+ .Case("semicolon-before-method-body", true)
+ .Case("sentinel", true)
+ .Case("shift-overflow", true)
+ .Case("shift-sign-overflow", true)
+ .Case("sign-conversion", true)
+ .Case("sizeof-array-argument", true)
+ .Case("sizeof-pointer-memaccess", true)
+ .Case("string-compare", true)
+ .Case("super-class-method-mismatch", true)
+ .Case("tautological-compare", true)
+ .Case("typedef-redefinition", true)
+ .Case("typename-missing", true)
+ .Case("undefined-reinterpret-cast", true)
+ .Case("unknown-warning-option", true)
+ .Case("unnamed-type-template-args", true)
+ .Case("unneeded-internal-declaration", true)
+ .Case("unneeded-member-function", true)
+ .Case("unused-comparison", true)
+ .Case("unused-exception-parameter", true)
+ .Case("unused-member-function", true)
+ .Case("unused-result", true)
+ .Case("vector-conversions", true)
+ .Case("vla", true)
+ .Case("used-but-marked-unused", true)
+ .Case("weak-vtables", true)
+ .Default(false);
+ } // if (Option.startswith("-W"))
+ if (RemoveOption) {
+ it = CmdArgs.erase(it);
+ ie = CmdArgs.end();
+ } else {
+ ++it;
+ }
+ }
+}
+
+void darwin::CC1::AddCC1Args(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ const Driver &D = getToolChain().getDriver();
+
+ CheckCodeGenerationOptions(D, Args);
+
+ // Derived from cc1 spec.
+ if ((!Args.hasArg(options::OPT_mkernel) ||
+ (getDarwinToolChain().isTargetIPhoneOS() &&
+ !getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) &&
+ !Args.hasArg(options::OPT_static) &&
+ !Args.hasArg(options::OPT_mdynamic_no_pic))
+ CmdArgs.push_back("-fPIC");
+
+ if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
+ getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
+ if (!Args.hasArg(options::OPT_fbuiltin_strcat))
+ CmdArgs.push_back("-fno-builtin-strcat");
+ if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
+ CmdArgs.push_back("-fno-builtin-strcpy");
+ }
+
+ if (Args.hasArg(options::OPT_g_Flag) &&
+ !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols))
+ CmdArgs.push_back("-feliminate-unused-debug-symbols");
+}
+
+void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
+ const InputInfoList &Inputs,
+ const ArgStringList &OutputArgs) const {
+ const Driver &D = getToolChain().getDriver();
+
+ // Derived from cc1_options spec.
+ if (Args.hasArg(options::OPT_fast) ||
+ Args.hasArg(options::OPT_fastf) ||
+ Args.hasArg(options::OPT_fastcp))
+ CmdArgs.push_back("-O3");
+
+ if (Arg *A = Args.getLastArg(options::OPT_pg))
+ if (Args.hasArg(options::OPT_fomit_frame_pointer))
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << A->getAsString(Args) << "-fomit-frame-pointer";
+
+ AddCC1Args(Args, CmdArgs);
+
+ if (!Args.hasArg(options::OPT_Q))
+ CmdArgs.push_back("-quiet");
+
+ CmdArgs.push_back("-dumpbase");
+ CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
+
+ Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
+
+ Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
+ Args.AddAllArgs(CmdArgs, options::OPT_a_Group);
+
+ // FIXME: The goal is to use the user provided -o if that is our
+ // final output, otherwise to drive from the original input
+ // name. Find a clean way to go about this.
+ if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) &&
+ Args.hasArg(options::OPT_o)) {
+ Arg *OutputOpt = Args.getLastArg(options::OPT_o);
+ CmdArgs.push_back("-auxbase-strip");
+ CmdArgs.push_back(OutputOpt->getValue());
+ } else {
+ CmdArgs.push_back("-auxbase");
+ CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs));
+ }
+
+ Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
+
+ Args.AddAllArgs(CmdArgs, options::OPT_O);
+ // FIXME: -Wall is getting some special treatment. Investigate.
+ Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
+ Args.AddLastArg(CmdArgs, options::OPT_w);
+ Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
+ options::OPT_trigraphs);
+ if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
+ // Honor -std-default.
+ Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
+ "-std=", /*Joined=*/true);
+ }
+
+ if (Args.hasArg(options::OPT_v))
+ CmdArgs.push_back("-version");
+ if (Args.hasArg(options::OPT_pg) &&
+ getToolChain().SupportsProfiling())
+ CmdArgs.push_back("-p");
+ Args.AddLastArg(CmdArgs, options::OPT_p);
+
+ // The driver treats -fsyntax-only specially.
+ if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
+ getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
+ // Removes -fbuiltin-str{cat,cpy}; these aren't recognized by cc1 but are
+ // used to inhibit the default -fno-builtin-str{cat,cpy}.
+ //
+ // FIXME: Should we grow a better way to deal with "removing" args?
+ for (arg_iterator it = Args.filtered_begin(options::OPT_f_Group,
+ options::OPT_fsyntax_only),
+ ie = Args.filtered_end(); it != ie; ++it) {
+ if (!(*it)->getOption().matches(options::OPT_fbuiltin_strcat) &&
+ !(*it)->getOption().matches(options::OPT_fbuiltin_strcpy)) {
+ (*it)->claim();
+ (*it)->render(Args, 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");
+
+ // FIXME: This isn't correct.
+ //Args.AddLastArg(CmdArgs, options::OPT__help)
+ //Args.AddLastArg(CmdArgs, options::OPT__targetHelp)
+
+ CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
+
+ // FIXME: Still don't get what is happening here. Investigate.
+ Args.AddAllArgs(CmdArgs, options::OPT__param);
+
+ if (Args.hasArg(options::OPT_fmudflap) ||
+ Args.hasArg(options::OPT_fmudflapth)) {
+ CmdArgs.push_back("-fno-builtin");
+ CmdArgs.push_back("-fno-merge-constants");
+ }
+
+ if (Args.hasArg(options::OPT_coverage)) {
+ CmdArgs.push_back("-fprofile-arcs");
+ CmdArgs.push_back("-ftest-coverage");
+ }
+
+ if (types::isCXX(Inputs[0].getType()))
+ CmdArgs.push_back("-D__private_extern__=extern");
+}
+
+void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
+ const InputInfoList &Inputs,
+ const ArgStringList &OutputArgs) const {
+ // Derived from cpp_options
+ AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
+
+ CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
+
+ AddCC1Args(Args, CmdArgs);
+
+ // NOTE: The code below has some commonality with cpp_options, but
+ // in classic gcc style ends up sending things in different
+ // orders. This may be a good merge candidate once we drop pedantic
+ // compatibility.
+
+ Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
+ Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
+ options::OPT_trigraphs);
+ if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
+ // Honor -std-default.
+ Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
+ "-std=", /*Joined=*/true);
+ }
+ Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
+ Args.AddLastArg(CmdArgs, options::OPT_w);
+
+ // 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");
+
+ Args.AddAllArgs(CmdArgs, options::OPT_O);
+ Args.AddAllArgs(CmdArgs, options::OPT_undef);
+ if (Args.hasArg(options::OPT_save_temps))
+ CmdArgs.push_back("-fpch-preprocess");
+}
+
+void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args,
+ ArgStringList &CmdArgs,
+ const InputInfoList &Inputs) const {
+ const Driver &D = getToolChain().getDriver();
+
+ CheckPreprocessingOptions(D, Args);
+
+ // Derived from cpp_unique_options.
+ // -{C,CC} only with -E is checked in CheckPreprocessingOptions().
+ Args.AddLastArg(CmdArgs, options::OPT_C);
+ Args.AddLastArg(CmdArgs, options::OPT_CC);
+ if (!Args.hasArg(options::OPT_Q))
+ CmdArgs.push_back("-quiet");
+ Args.AddAllArgs(CmdArgs, options::OPT_nostdinc);
+ Args.AddAllArgs(CmdArgs, options::OPT_nostdincxx);
+ Args.AddLastArg(CmdArgs, options::OPT_v);
+ Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
+ Args.AddLastArg(CmdArgs, options::OPT_P);
+
+ // FIXME: Handle %I properly.
+ if (getToolChain().getArch() == llvm::Triple::x86_64) {
+ CmdArgs.push_back("-imultilib");
+ CmdArgs.push_back("x86_64");
+ }
+
+ if (Args.hasArg(options::OPT_MD)) {
+ CmdArgs.push_back("-MD");
+ CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
+ }
+
+ if (Args.hasArg(options::OPT_MMD)) {
+ CmdArgs.push_back("-MMD");
+ CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
+ }
+
+ Args.AddLastArg(CmdArgs, options::OPT_M);
+ Args.AddLastArg(CmdArgs, options::OPT_MM);
+ Args.AddAllArgs(CmdArgs, options::OPT_MF);
+ Args.AddLastArg(CmdArgs, options::OPT_MG);
+ Args.AddLastArg(CmdArgs, options::OPT_MP);
+ Args.AddAllArgs(CmdArgs, options::OPT_MQ);
+ Args.AddAllArgs(CmdArgs, options::OPT_MT);
+ if (!Args.hasArg(options::OPT_M) && !Args.hasArg(options::OPT_MM) &&
+ (Args.hasArg(options::OPT_MD) || Args.hasArg(options::OPT_MMD))) {
+ if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
+ CmdArgs.push_back("-MQ");
+ CmdArgs.push_back(OutputOpt->getValue());
+ }
+ }
+
+ Args.AddLastArg(CmdArgs, options::OPT_remap);
+ if (Args.hasArg(options::OPT_g3))
+ CmdArgs.push_back("-dD");
+ Args.AddLastArg(CmdArgs, options::OPT_H);
+
+ AddCPPArgs(Args, CmdArgs);
+
+ Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U, options::OPT_A);
+ Args.AddAllArgs(CmdArgs, options::OPT_i_Group);
+
+ for (InputInfoList::const_iterator
+ it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+ const InputInfo &II = *it;
+
+ CmdArgs.push_back(II.getFilename());
+ }
+
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
+ options::OPT_Xpreprocessor);
+
+ if (Args.hasArg(options::OPT_fmudflap)) {
+ CmdArgs.push_back("-D_MUDFLAP");
+ CmdArgs.push_back("-include");
+ CmdArgs.push_back("mf-runtime.h");
+ }
+
+ if (Args.hasArg(options::OPT_fmudflapth)) {
+ CmdArgs.push_back("-D_MUDFLAP");
+ CmdArgs.push_back("-D_MUDFLAPTH");
+ CmdArgs.push_back("-include");
+ CmdArgs.push_back("mf-runtime.h");
+ }
+}
+
+void darwin::CC1::AddCPPArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ // Derived from cpp spec.
+
+ if (Args.hasArg(options::OPT_static)) {
+ // The gcc spec is broken here, it refers to dynamic but
+ // that has been translated. Start by being bug compatible.
+
+ // if (!Args.hasArg(arglist.parser.dynamicOption))
+ CmdArgs.push_back("-D__STATIC__");
+ } else
+ CmdArgs.push_back("-D__DYNAMIC__");
+
+ if (Args.hasArg(options::OPT_pthread))
+ CmdArgs.push_back("-D_REENTRANT");
+}
+
+void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ ArgStringList CmdArgs;
+
+ assert(Inputs.size() == 1 && "Unexpected number of inputs!");
+
+ CmdArgs.push_back("-E");
+
+ if (Args.hasArg(options::OPT_traditional) ||
+ Args.hasArg(options::OPT_traditional_cpp))
+ CmdArgs.push_back("-traditional-cpp");
+
+ ArgStringList OutputArgs;
+ assert(Output.isFilename() && "Unexpected CC1 output.");
+ OutputArgs.push_back("-o");
+ OutputArgs.push_back(Output.getFilename());
+
+ if (Args.hasArg(options::OPT_E) || getToolChain().getDriver().CCCIsCPP) {
+ AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
+ } else {
+ AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
+ CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
+ }
+
+ Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
+
+ RemoveCC1UnsupportedArgs(CmdArgs);
+
+ const char *CC1Name = getCC1Name(Inputs[0].getType());
+ const char *Exec =
+ Args.MakeArgString(getToolChain().GetProgramPath(CC1Name));
+ C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
+ 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!");
+
+ // Silence warning about unused --serialize-diagnostics
+ Args.ClaimAllArgs(options::OPT__serialize_diags);
+
+ types::ID InputType = Inputs[0].getType();
+ if (const Arg *A = Args.getLastArg(options::OPT_traditional))
+ D.Diag(diag::err_drv_argument_only_allowed_with)
+ << A->getAsString(Args) << "-E";
+
+ if (JA.getType() == types::TY_LLVM_IR ||
+ JA.getType() == types::TY_LTO_IR)
+ CmdArgs.push_back("-emit-llvm");
+ else if (JA.getType() == types::TY_LLVM_BC ||
+ JA.getType() == types::TY_LTO_BC)
+ CmdArgs.push_back("-emit-llvm-bc");
+ else if (Output.getType() == types::TY_AST)
+ D.Diag(diag::err_drv_no_ast_support)
+ << getToolChain().getTripleString();
+ else if (JA.getType() != types::TY_PP_Asm &&
+ JA.getType() != types::TY_PCH)
+ D.Diag(diag::err_drv_invalid_gcc_output_type)
+ << getTypeName(JA.getType());
+
+ ArgStringList OutputArgs;
+ if (Output.getType() != types::TY_PCH) {
+ OutputArgs.push_back("-o");
+ if (Output.isNothing())
+ OutputArgs.push_back("/dev/null");
+ else
+ OutputArgs.push_back(Output.getFilename());
+ }
+
+ // There is no need for this level of compatibility, but it makes
+ // diffing easier.
+ bool OutputArgsEarly = (Args.hasArg(options::OPT_fsyntax_only) ||
+ Args.hasArg(options::OPT_S));
+
+ if (types::getPreprocessedType(InputType) != types::TY_INVALID) {
+ AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
+ if (OutputArgsEarly) {
+ AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
+ } else {
+ AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
+ CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
+ }
+ } else {
+ CmdArgs.push_back("-fpreprocessed");
+
+ for (InputInfoList::const_iterator
+ it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+ const InputInfo &II = *it;