clang-cl: Implement the /Tc, /TC, /Tp and /TP options.
These are used to specify source files, and whether to treat source files as C or C++. Differential Revision: http://llvm-reviews.chandlerc.com/D1290 llvm-svn: 187760
This commit is contained in:
parent
428ad10623
commit
6ee64d52cf
5 changed files with 110 additions and 24 deletions
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -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">;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
clang/test/Driver/cl-inputs.c
Normal file
22
clang/test/Driver/cl-inputs.c
Normal file
|
|
@ -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'
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue