summaryrefslogtreecommitdiffstats
path: root/lib/Driver/Driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/Driver.cpp')
-rw-r--r--lib/Driver/Driver.cpp117
1 files changed, 73 insertions, 44 deletions
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 5a5986b..fc4d86c 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -30,6 +30,7 @@
#include "clang/Basic/Version.h"
#include "llvm/Config/config.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -42,13 +43,6 @@
#include <map>
-#ifdef __CYGWIN__
-#include <cygwin/version.h>
-#if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<1007
-#define IS_CYGWIN15 1
-#endif
-#endif
-
using namespace clang::driver;
using namespace clang;
@@ -58,15 +52,17 @@ Driver::Driver(llvm::StringRef _ClangExecutable,
bool IsProduction, bool CXXIsProduction,
Diagnostic &_Diags)
: Opts(createDriverOptTable()), Diags(_Diags),
- ClangExecutable(_ClangExecutable), DefaultHostTriple(_DefaultHostTriple),
- DefaultImageName(_DefaultImageName),
+ ClangExecutable(_ClangExecutable), UseStdLib(true),
+ DefaultHostTriple(_DefaultHostTriple), DefaultImageName(_DefaultImageName),
DriverTitle("clang \"gcc-compatible\" driver"),
Host(0),
- CCPrintOptionsFilename(0), CCPrintHeadersFilename(0), CCCIsCXX(false),
- CCCEcho(false), CCCPrintBindings(false), CCPrintOptions(false),
- CCPrintHeaders(false), CCCGenericGCCName("gcc"),
- CheckInputsExist(true), CCCUseClang(true), CCCUseClangCXX(true),
- CCCUseClangCPP(true), CCCUsePCH(true), SuppressMissingInputWarning(false) {
+ CCPrintOptionsFilename(0), CCPrintHeadersFilename(0),
+ CCLogDiagnosticsFilename(0), CCCIsCXX(false),
+ CCCIsCPP(false),CCCEcho(false), CCCPrintBindings(false),
+ CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false),
+ CCCGenericGCCName(""), CheckInputsExist(true), CCCUseClang(true),
+ CCCUseClangCXX(true), CCCUseClangCPP(true), CCCUsePCH(true),
+ SuppressMissingInputWarning(false) {
if (IsProduction) {
// In a "production" build, only use clang on architectures we expect to
// work, and don't use clang C++.
@@ -100,11 +96,10 @@ Driver::~Driver() {
delete Host;
}
-InputArgList *Driver::ParseArgStrings(const char **ArgBegin,
- const char **ArgEnd) {
+InputArgList *Driver::ParseArgStrings(llvm::ArrayRef<const char *> ArgList) {
llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
unsigned MissingArgIndex, MissingArgCount;
- InputArgList *Args = getOpts().ParseArgs(ArgBegin, ArgEnd,
+ InputArgList *Args = getOpts().ParseArgs(ArgList.begin(), ArgList.end(),
MissingArgIndex, MissingArgCount);
// Check for missing argument error.
@@ -206,7 +201,7 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
return DAL;
}
-Compilation *Driver::BuildCompilation(int argc, const char **argv) {
+Compilation *Driver::BuildCompilation(llvm::ArrayRef<const char *> ArgList) {
llvm::PrettyStackTraceString CrashInfo("Compilation construction");
// FIXME: Handle environment options which effect driver behavior, somewhere
@@ -218,9 +213,7 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
// FIXME: This stuff needs to go into the Compilation, not the driver.
bool CCCPrintOptions = false, CCCPrintActions = false;
- const char **Start = argv + 1, **End = argv + argc;
-
- InputArgList *Args = ParseArgStrings(Start, End);
+ InputArgList *Args = ParseArgStrings(ArgList.slice(1));
// -no-canonical-prefixes is used very early in main.
Args->ClaimAllArgs(options::OPT_no_canonical_prefixes);
@@ -238,13 +231,6 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
CCCPrintActions = Args->hasArg(options::OPT_ccc_print_phases);
CCCPrintBindings = Args->hasArg(options::OPT_ccc_print_bindings);
CCCIsCXX = Args->hasArg(options::OPT_ccc_cxx) || CCCIsCXX;
- if (CCCIsCXX) {
-#ifdef IS_CYGWIN15
- CCCGenericGCCName = "g++-4";
-#else
- CCCGenericGCCName = "g++";
-#endif
- }
CCCEcho = Args->hasArg(options::OPT_ccc_echo);
if (const Arg *A = Args->getLastArg(options::OPT_ccc_gcc_name))
CCCGenericGCCName = A->getValue(*Args);
@@ -287,6 +273,10 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
A->claim();
PrefixDirs.push_back(A->getValue(*Args, 0));
}
+ if (const Arg *A = Args->getLastArg(options::OPT__sysroot_EQ))
+ SysRoot = A->getValue(*Args);
+ if (Args->hasArg(options::OPT_nostdlib))
+ UseStdLib = false;
Host = GetHostInfo(DefaultHostTriple.c_str());
@@ -593,7 +583,7 @@ static bool ContainsCompileAction(const Action *A) {
}
void Driver::BuildUniversalActions(const ToolChain &TC,
- const ArgList &Args,
+ const DerivedArgList &Args,
ActionList &Actions) const {
llvm::PrettyStackTraceString CrashInfo("Building universal build actions");
// Collect the list of architectures. Duplicates are allowed, but should only
@@ -688,7 +678,7 @@ void Driver::BuildUniversalActions(const ToolChain &TC,
}
}
-void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
+void Driver::BuildActions(const ToolChain &TC, const DerivedArgList &Args,
ActionList &Actions) const {
llvm::PrettyStackTraceString CrashInfo("Building compilation actions");
// Start by constructing the list of inputs and their types.
@@ -721,18 +711,23 @@ void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
//
// Otherwise emit an error but still use a valid type to avoid
// spurious errors (e.g., no inputs).
- if (!Args.hasArgNoClaim(options::OPT_E))
+ if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP)
Diag(clang::diag::err_drv_unknown_stdin_type);
Ty = types::TY_C;
} else {
- // Otherwise lookup by extension, and fallback to ObjectType if not
- // found. We use a host hook here because Darwin at least has its own
+ // Otherwise lookup by extension.
+ // Fallback is C if invoked as C preprocessor or Object otherwise.
+ // We use a host hook here because Darwin at least has its own
// idea of what .s is.
if (const char *Ext = strrchr(Value, '.'))
Ty = TC.LookupTypeForExtension(Ext + 1);
- if (Ty == types::TY_INVALID)
- Ty = types::TY_Object;
+ if (Ty == types::TY_INVALID) {
+ if (CCCIsCPP)
+ Ty = types::TY_C;
+ else
+ Ty = types::TY_Object;
+ }
// If the driver is invoked as C++ compiler (like clang++ or c++) it
// should autodetect some input files as C++ for g++ compatibility.
@@ -799,6 +794,15 @@ void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
}
}
+ if (CCCIsCPP && Inputs.empty()) {
+ // If called as standalone preprocessor, stdin is processed
+ // if no other input is present.
+ unsigned Index = Args.getBaseArgs().MakeIndex("-");
+ Arg *A = Opts->ParseOneArg(Args, Index);
+ A->claim();
+ Inputs.push_back(std::make_pair(types::TY_C, A));
+ }
+
if (!SuppressMissingInputWarning && Inputs.empty()) {
Diag(clang::diag::err_drv_no_input_files);
return;
@@ -811,7 +815,8 @@ void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
phases::ID FinalPhase;
// -{E,M,MM} only run the preprocessor.
- if ((FinalPhaseArg = Args.getLastArg(options::OPT_E)) ||
+ if (CCCIsCPP ||
+ (FinalPhaseArg = Args.getLastArg(options::OPT_E)) ||
(FinalPhaseArg = Args.getLastArg(options::OPT_M, options::OPT_MM))) {
FinalPhase = phases::Preprocess;
@@ -853,6 +858,10 @@ void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
// Claim here to avoid the more general unused warning.
InputArg->claim();
+ // Suppress all unused style warnings with -Qunused-arguments
+ if (Args.hasArg(options::OPT_Qunused_arguments))
+ continue;
+
// Special case '-E' warning on a previously preprocessed file to make
// more sense.
if (InitialPhase == phases::Compile && FinalPhase == phases::Preprocess &&
@@ -945,7 +954,8 @@ Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
} else if (Args.hasArg(options::OPT_emit_ast)) {
return new CompileJobAction(Input, types::TY_AST);
} else if (Args.hasArg(options::OPT_emit_llvm) ||
- Args.hasArg(options::OPT_flto) || HasO4) {
+ Args.hasFlag(options::OPT_flto, options::OPT_fno_lto, false) ||
+ HasO4) {
types::ID Output =
Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
return new CompileJobAction(Input, Output);
@@ -1064,14 +1074,17 @@ static const Tool &SelectToolForJob(Compilation &C, const ToolChain *TC,
bool HasStatic = (C.getArgs().hasArg(options::OPT_mkernel) ||
C.getArgs().hasArg(options::OPT_static) ||
C.getArgs().hasArg(options::OPT_fapple_kext));
- bool IsIADefault = (TC->IsIntegratedAssemblerDefault() && !HasStatic);
+ bool IsDarwin = TC->getTriple().getOS() == llvm::Triple::Darwin;
+ bool IsIADefault = TC->IsIntegratedAssemblerDefault() &&
+ !(HasStatic && IsDarwin);
if (C.getArgs().hasFlag(options::OPT_integrated_as,
options::OPT_no_integrated_as,
IsIADefault) &&
!C.getArgs().hasArg(options::OPT_save_temps) &&
isa<AssembleJobAction>(JA) &&
Inputs->size() == 1 && isa<CompileJobAction>(*Inputs->begin())) {
- const Tool &Compiler = TC->SelectTool(C,cast<JobAction>(**Inputs->begin()));
+ const Tool &Compiler = TC->SelectTool(
+ C, cast<JobAction>(**Inputs->begin()), (*Inputs)[0]->getInputs());
if (Compiler.hasIntegratedAssembler()) {
Inputs = &(*Inputs)[0]->getInputs();
ToolForJob = &Compiler;
@@ -1080,7 +1093,7 @@ static const Tool &SelectToolForJob(Compilation &C, const ToolChain *TC,
// Otherwise use the tool for the current job.
if (!ToolForJob)
- ToolForJob = &TC->SelectTool(C, *JA);
+ ToolForJob = &TC->SelectTool(C, *JA, *Inputs);
// See if we should use an integrated preprocessor. We do so when we have
// exactly one input, since this is the only use case we care about
@@ -1206,7 +1219,13 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
}
llvm::SmallString<128> BasePath(BaseInput);
- llvm::StringRef BaseName = llvm::sys::path::filename(BasePath);
+ llvm::StringRef BaseName;
+
+ // Dsymutil actions should use the full path.
+ if (isa<DsymutilJobAction>(JA))
+ BaseName = BasePath;
+ else
+ BaseName = llvm::sys::path::filename(BasePath);
// Determine what the derived output name should be.
const char *NamedOutput;
@@ -1243,7 +1262,12 @@ std::string Driver::GetFilePath(const char *Name, const ToolChain &TC) const {
// attempting to use this prefix when lokup up program paths.
for (Driver::prefix_list::const_iterator it = PrefixDirs.begin(),
ie = PrefixDirs.end(); it != ie; ++it) {
- llvm::sys::Path P(*it);
+ std::string Dir(*it);
+ if (Dir.empty())
+ continue;
+ if (Dir[0] == '=')
+ Dir = SysRoot + Dir.substr(1);
+ llvm::sys::Path P(Dir);
P.appendComponent(Name);
bool Exists;
if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
@@ -1253,7 +1277,12 @@ std::string Driver::GetFilePath(const char *Name, const ToolChain &TC) const {
const ToolChain::path_list &List = TC.getFilePaths();
for (ToolChain::path_list::const_iterator
it = List.begin(), ie = List.end(); it != ie; ++it) {
- llvm::sys::Path P(*it);
+ std::string Dir(*it);
+ if (Dir.empty())
+ continue;
+ if (Dir[0] == '=')
+ Dir = SysRoot + Dir.substr(1);
+ llvm::sys::Path P(Dir);
P.appendComponent(Name);
bool Exists;
if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
@@ -1323,7 +1352,7 @@ std::string Driver::GetTemporaryPath(const char *Suffix) const {
const HostInfo *Driver::GetHostInfo(const char *TripleStr) const {
llvm::PrettyStackTraceString CrashInfo("Constructing host");
- llvm::Triple Triple(TripleStr);
+ llvm::Triple Triple(llvm::Triple::normalize(TripleStr).c_str());
// TCE is an osless target
if (Triple.getArchName() == "tce")
OpenPOWER on IntegriCloud