summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPawel Wodnicki <pawel@32bitmicro.com>2012-11-19 21:31:56 +0000
committerPawel Wodnicki <pawel@32bitmicro.com>2012-11-19 21:31:56 +0000
commitb595a356285f677a8ee8b513c65aa1c852f9059e (patch)
treeabea910719f3fe1e44225602c8b269250afa519f
parent0d7bc297f7165a7dbefdcad3b4043c275d35c13e (diff)
downloadclang-b595a356285f677a8ee8b513c65aa1c852f9059e.tar.gz
clang-b595a356285f677a8ee8b513c65aa1c852f9059e.tar.bz2
clang-b595a356285f677a8ee8b513c65aa1c852f9059e.tar.xz
Merging r168024 from trunk into 3.2 release branch
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/branches/release_32@168330 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 00894c4547..d42078461c 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");
@@ -3624,14 +3624,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, '.'))
@@ -3640,8 +3664,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;
@@ -3649,11 +3674,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;
+
+ // Reject AST inputs.
+ if (II.getType() == types::TY_AST) {
+ D.Diag(diag::err_drv_no_ast_support)
+ << getToolChain().getTripleString();
+ return;
+ }
+
+ CmdArgs.push_back(II.getFilename());
+ }
+
+ if (OutputArgsEarly) {
+ AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
+ } else {
+ AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
+ CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
+ }
+ }
+
+ if (Output.getType() == types::TY_PCH) {
+ assert(Output.isFilename() && "Invalid PCH output.");
+
+ CmdArgs.push_back("-o");
+ // NOTE: gcc uses a temp .s file for this, but there doesn't seem
+ // to be a good reason.
+ const char *TmpPath = C.getArgs().MakeArgString(
+ D.GetTemporaryPath("cc", "s"));
+ C.addTempFile(TmpPath);
+ CmdArgs.push_back(TmpPath);
+
+ // If we're emitting a pch file with the last 4 characters of ".pth"
+ // and falling back to llvm-gcc we want to use ".gch" instead.
+ std::string OutputFile(Output.getFilename());
+ size_t loc = OutputFile.rfind(".pth");
+ if (loc != std::string::npos)
+ OutputFile.replace(loc, 4, ".gch");
+ const char *Tmp = C.getArgs().MakeArgString("--output-pch="+OutputFile);
+ CmdArgs.push_back(Tmp);
+ }
+
+ 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::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index cef7d80d98..5898c660a4 100644
--- a/lib/Driver/Tools.h
+++ b/lib/Driver/Tools.h
@@ -31,13 +31,6 @@ namespace tools {
/// \brief Clang compiler tool.
class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
- static const char *getBaseInputName(const ArgList &Args,
- const InputInfoList &Inputs);
- static const char *getBaseInputStem(const ArgList &Args,
- const InputInfoList &Inputs);
- static const char *getDependencyFileName(const ArgList &Args,
- const InputInfoList &Inputs);
-
void AddPreprocessingOptions(Compilation &C,
const Driver &D,
const ArgList &Args,
@@ -225,6 +218,63 @@ namespace darwin {
const ToolChain &TC) : Tool(Name, ShortName, TC) {}
};
+ class LLVM_LIBRARY_VISIBILITY CC1 : public DarwinTool {
+ virtual void anchor();
+ public:
+ static const char *getBaseInputName(const ArgList &Args,
+ const InputInfoList &Input);
+ static const char *getBaseInputStem(const ArgList &Args,
+ const InputInfoList &Input);
+ static const char *getDependencyFileName(const ArgList &Args,
+ const InputInfoList &Inputs);
+
+ protected:
+ const char *getCC1Name(types::ID Type) const;
+
+ void AddCC1Args(const ArgList &Args, ArgStringList &CmdArgs) const;
+ void RemoveCC1UnsupportedArgs(ArgStringList &CmdArgs) const;
+ void AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
+ const InputInfoList &Inputs,
+ const ArgStringList &OutputArgs) const;
+ void AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
+ const InputInfoList &Inputs,
+ const ArgStringList &OutputArgs) const;
+ void AddCPPUniqueOptionsArgs(const ArgList &Args,
+ ArgStringList &CmdArgs,
+ const InputInfoList &Inputs) const;
+ void AddCPPArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+
+ public:
+ CC1(const char *Name, const char *ShortName,
+ const ToolChain &TC) : DarwinTool(Name, ShortName, TC) {}
+
+ virtual bool hasGoodDiagnostics() const { return true; }
+ virtual bool hasIntegratedCPP() const { return true; }
+ };
+
+ class LLVM_LIBRARY_VISIBILITY Preprocess : public CC1 {
+ public:
+ Preprocess(const ToolChain &TC) : CC1("darwin::Preprocess",
+ "gcc preprocessor", TC) {}
+
+ virtual void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const;
+ };
+
+ class LLVM_LIBRARY_VISIBILITY Compile : public CC1 {
+ public:
+ Compile(const ToolChain &TC) : CC1("darwin::Compile", "gcc frontend", TC) {}
+
+ virtual void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const;
+ };
+
class LLVM_LIBRARY_VISIBILITY Assemble : public DarwinTool {
public:
Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble",
diff --git a/lib/Driver/Types.cpp b/lib/Driver/Types.cpp
index c22638fef2..862025ed9a 100644
--- a/lib/Driver/Types.cpp
+++ b/lib/Driver/Types.cpp
@@ -71,6 +71,29 @@ bool types::canLipoType(ID Id) {
Id == TY_LTO_BC);
}
+bool types::isAcceptedByClang(ID Id) {
+ switch (Id) {
+ default:
+ return false;
+
+ case TY_Asm:
+ case TY_C: case TY_PP_C:
+ case TY_CL:
+ case TY_CUDA:
+ case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:
+ case TY_CXX: case TY_PP_CXX:
+ case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
+ case TY_CHeader: case TY_PP_CHeader:
+ case TY_CLHeader:
+ case TY_ObjCHeader: case TY_PP_ObjCHeader:
+ case TY_CXXHeader: case TY_PP_CXXHeader:
+ case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
+ case TY_AST:
+ case TY_LLVM_IR: case TY_LLVM_BC:
+ return true;
+ }
+}
+
bool types::isObjC(ID Id) {
switch (Id) {
default:
diff --git a/lib/Driver/WindowsToolChain.cpp b/lib/Driver/WindowsToolChain.cpp
index a93702e693..ac6518712f 100644
--- a/lib/Driver/WindowsToolChain.cpp
+++ b/lib/Driver/WindowsToolChain.cpp
@@ -37,7 +37,12 @@ Windows::Windows(const Driver &D, const llvm::Triple& Triple)
Tool &Windows::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());