diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticDriverKinds.td | 3 | ||||
-rw-r--r-- | clang/include/clang/Driver/CLCompatOptions.td | 14 | ||||
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 93 | ||||
-rw-r--r-- | clang/test/Driver/cl-inputs.c | 22 | ||||
-rw-r--r-- | clang/test/Driver/cl-options.c | 2 |
5 files changed, 110 insertions, 24 deletions
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 68e13584ed3..266e2f0f76b 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -133,6 +133,9 @@ def warn_drv_assuming_mfloat_abi_is : Warning< "unknown platform, assuming -mfloat-abi=%0">; def warn_ignoring_ftabstop_value : Warning< "ignoring invalid -ftabstop value '%0', using default value %1">; +def warn_drv_overriding_t_option : Warning< + "overriding '%0' option with '%1'">, + InGroup<DiagGroup<"overriding-t-option">>; def warn_drv_treating_input_as_cxx : Warning< "treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">, InGroup<Deprecated>; diff --git a/clang/include/clang/Driver/CLCompatOptions.td b/clang/include/clang/Driver/CLCompatOptions.td index d3494da5d74..5a3ad805ce4 100644 --- a/clang/include/clang/Driver/CLCompatOptions.td +++ b/clang/include/clang/Driver/CLCompatOptions.td @@ -81,6 +81,16 @@ def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">, Alias<fsyntax_only>; +// Non-aliases: + +def _SLASH_Tc : CLJoinedOrSeparate<"Tc">, HelpText<"Specify a C source file">, + MetaVarName<"<filename>">; +def _SLASH_TC : CLFlag<"TC">, HelpText<"Treat all source files as C">; +def _SLASH_Tp : CLJoinedOrSeparate<"Tp">, HelpText<"Specify a C++ source file">, + MetaVarName<"<filename>">; +def _SLASH_TP : CLFlag<"TP">, HelpText<"Treat all source files as C++">; + + // Ignored: def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">; @@ -114,10 +124,6 @@ def _SLASH_MTd : CLFlag<"MTd">; def _SLASH_Oi : CLFlag<"Oi">; def _SLASH_RTC : CLJoined<"RTC">; def _SLASH_showIncludes : CLJoined<"showIncludes">; -def _SLASH_Tc : CLJoined<"Tc">; -def _SLASH_TC : CLFlag<"TC">; -def _SLASH_Tp : CLJoined<"Tp">; -def _SLASH_TP : CLFlag<"TP">; def _SLASH_w : CLJoined<"w">; def _SLASH_Zc : CLJoined<"Zc:">; def _SLASH_ZI : CLFlag<"ZI">; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 4f9cd3e38a0..84e5fe2cfbb 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -943,6 +943,41 @@ void Driver::BuildUniversalActions(const ToolChain &TC, } } +/// \brief Check that the file referenced by Value exists. If it doesn't, +/// issue a diagnostic and return false. +static bool DiagnoseInputExistance(const Driver &D, const DerivedArgList &Args, + StringRef Value) { + if (!D.getCheckInputsExist()) + return true; + + // stdin always exists. + if (Value == "-") + return true; + + SmallString<64> Path(Value); + if (Arg *WorkDir = Args.getLastArg(options::OPT_working_directory)) { + if (!llvm::sys::path::is_absolute(Path.str())) { + SmallString<64> Directory(WorkDir->getValue()); + llvm::sys::path::append(Directory, Value); + Path.assign(Directory); + } + } + + if (llvm::sys::fs::exists(Twine(Path))) + return true; + + D.Diag(clang::diag::err_drv_no_such_file) << Path.str(); + return false; +} + +static Arg* MakeInputArg(const DerivedArgList &Args, OptTable *Opts, + StringRef Value) { + unsigned Index = Args.getBaseArgs().MakeIndex(Value); + Arg *A = Opts->ParseOneArg(Args, Index); + A->claim(); + return A; +} + // Construct a the list of inputs and their types. void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args, InputList &Inputs) const { @@ -952,6 +987,29 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args, types::ID InputType = types::TY_Nothing; Arg *InputTypeArg = 0; + // The /TC and /TP options set the input type to C or C++ globally. + if (Arg *TCTP = Args.getLastArg(options::OPT__SLASH_TC, + options::OPT__SLASH_TP)) { + InputTypeArg = TCTP; + unsigned opposite; + + if (TCTP->getOption().matches(options::OPT__SLASH_TC)) { + InputType = types::TY_C; + opposite = options::OPT__SLASH_TP; + } else { + InputType = types::TY_CXX; + opposite = options::OPT__SLASH_TC; + } + + if (Arg *OppositeArg = Args.getLastArg(opposite)) { + Diag(clang::diag::warn_drv_overriding_t_option) + << OppositeArg->getSpelling() << InputTypeArg->getSpelling(); + } + + // No driver mode exposes -x and /TC or /TP; we don't support mixing them. + assert(!Args.hasArg(options::OPT_x) && "-x and /TC or /TP is not allowed"); + } + for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) { Arg *A = *it; @@ -1020,24 +1078,23 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args, Ty = InputType; } - // Check that the file exists, if enabled. - if (CheckInputsExist && memcmp(Value, "-", 2) != 0) { - SmallString<64> Path(Value); - if (Arg *WorkDir = Args.getLastArg(options::OPT_working_directory)) { - if (!llvm::sys::path::is_absolute(Path.str())) { - SmallString<64> Directory(WorkDir->getValue()); - llvm::sys::path::append(Directory, Value); - Path.assign(Directory); - } - } - - if (!llvm::sys::fs::exists(Twine(Path))) - Diag(clang::diag::err_drv_no_such_file) << Path.str(); - else - Inputs.push_back(std::make_pair(Ty, A)); - } else + if (DiagnoseInputExistance(*this, Args, Value)) Inputs.push_back(std::make_pair(Ty, A)); + } else if (A->getOption().matches(options::OPT__SLASH_Tc)) { + StringRef Value = A->getValue(); + if (DiagnoseInputExistance(*this, Args, Value)) { + Arg *InputArg = MakeInputArg(Args, Opts, A->getValue()); + Inputs.push_back(std::make_pair(types::TY_C, InputArg)); + } + A->claim(); + } else if (A->getOption().matches(options::OPT__SLASH_Tp)) { + StringRef Value = A->getValue(); + if (DiagnoseInputExistance(*this, Args, Value)) { + Arg *InputArg = MakeInputArg(Args, Opts, A->getValue()); + Inputs.push_back(std::make_pair(types::TY_CXX, InputArg)); + } + A->claim(); } else if (A->getOption().hasFlag(options::LinkerInput)) { // Just treat as object type, we could make a special type for this if // necessary. @@ -1060,9 +1117,7 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &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(); + Arg *A = MakeInputArg(Args, Opts, "-"); Inputs.push_back(std::make_pair(types::TY_C, A)); } } diff --git a/clang/test/Driver/cl-inputs.c b/clang/test/Driver/cl-inputs.c new file mode 100644 index 00000000000..1918e4cba92 --- /dev/null +++ b/clang/test/Driver/cl-inputs.c @@ -0,0 +1,22 @@ +// Don't attempt slash switches on msys bash.
+// REQUIRES: shell-preserves-root
+
+// Note: %s must be preceded by --, otherwise it may be interpreted as a
+// command-line option, e.g. on Mac where %s is commonly under /Users.
+
+// RUN: %clang_cl /TC -### -- %s 2>&1 | FileCheck -check-prefix=TC %s
+// TC: "-x" "c"
+
+// RUN: %clang_cl /TP -### -- %s 2>&1 | FileCheck -check-prefix=TP %s
+// TP: "-x" "c++"
+
+// RUN: %clang_cl -### /Tc%s 2>&1 | FileCheck -check-prefix=Tc %s
+// RUN: %clang_cl -### /TP /Tc%s 2>&1 | FileCheck -check-prefix=Tc %s
+// Tc: "-x" "c"
+
+// RUN: %clang_cl -### /Tp%s 2>&1 | FileCheck -check-prefix=Tp %s
+// RUN: %clang_cl -### /TC /Tp%s 2>&1 | FileCheck -check-prefix=Tp %s
+// Tp: "-x" "c++"
+
+// RUN: %clang_cl /TP /TC -### -- %s 2>&1 | FileCheck -check-prefix=WARN %s
+// WARN: overriding '/TP' option with '/TC'
diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 44d32350adb..ca286f739d9 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -90,5 +90,5 @@ // (/Zs is for syntax-only) // RUN: %clang_cl /Zs /EHsc /Fdfoo /Fobar /fp:precise /Gd /GL /GL- -- %s 2>&1 // RUN: %clang_cl /Zs /Gm /Gm- /GS /Gy /Gy- /GZ /MD /MT /MDd /MTd /Oi -- %s 2>&1 -// RUN: %clang_cl /Zs /RTC1 /Tcfoo /TC /Tpbar /TP /wfoo /Zc:wchar_t- -- %s 2>&1 +// RUN: %clang_cl /Zs /RTC1 /wfoo /Zc:wchar_t- -- %s 2>&1 // RUN: %clang_cl /Zs /ZI /Zi /showIncludes -- %s 2>&1 |