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.

llvm-svn: 168024
This commit is contained in:
Nick Lewycky 2012-11-15 05:36:36 +00:00
parent 03c3a2f5bb
commit 5cc9ebb723
8 changed files with 804 additions and 35 deletions

View File

@ -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:

View File

@ -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);

View File

@ -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.
///

View File

@ -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) {

View File

@ -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;
// 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,

View File

@ -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",

View File

@ -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:

View File

@ -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());