[clang-cl] Remove the /fallback option

As discussed in
https://lists.llvm.org/pipermail/cfe-dev/2021-January/067524.html

It doesn't appear to be used, isn't really maintained, and adds some
complexity to the code. Let's remove it.

Differential revision: https://reviews.llvm.org/D95876
This commit is contained in:
Hans Wennborg 2021-02-02 14:10:26 +01:00
parent 225ccf0c50
commit 6625680a58
20 changed files with 21 additions and 450 deletions

View File

@ -76,7 +76,8 @@ Modified Compiler Flags
Removed Compiler Flags Removed Compiler Flags
------------------------- -------------------------
- ... - The clang-cl ``/fallback`` flag, which made clang-cl invoke Microsoft Visual
C++ on files it couldn't compile itself, has been removed.
New Pragmas in Clang New Pragmas in Clang
-------------------- --------------------

View File

@ -3501,7 +3501,6 @@ Execute ``clang-cl /?`` to see a list of supported options:
/execution-charset:<value> /execution-charset:<value>
Runtime encoding, supports only UTF-8 Runtime encoding, supports only UTF-8
/E Preprocess to stdout /E Preprocess to stdout
/fallback Fall back to cl.exe if clang-cl fails to compile
/FA Output assembly code file during compilation /FA Output assembly code file during compilation
/Fa<file or directory> Output assembly code to this file during compilation (with /FA) /Fa<file or directory> Output assembly code to this file during compilation (with /FA)
/Fe<file or directory> Set output executable file or directory (ends in / or \) /Fe<file or directory> Set output executable file or directory (ends in / or \)
@ -3847,18 +3846,6 @@ This could lead to very subtle bugs. Using ``-fvisibility-inlines-hidden`` can
lead to the same issue. To avoid it in this case, make `S::foo()` or lead to the same issue. To avoid it in this case, make `S::foo()` or
`internal()` non-inline, or mark them `dllimport/dllexport` explicitly. `internal()` non-inline, or mark them `dllimport/dllexport` explicitly.
The /fallback Option
^^^^^^^^^^^^^^^^^^^^
When clang-cl is run with the ``/fallback`` option, it will first try to
compile files itself. For any file that it fails to compile, it will fall back
and try to compile the file by invoking cl.exe.
This option is intended to be used as a temporary means to build projects where
clang-cl cannot successfully compile all the files. clang-cl may fail to compile
a file either because it cannot generate code for some C++ feature, or because
it cannot parse some Microsoft language extension.
Finding Clang runtime libraries Finding Clang runtime libraries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -210,9 +210,6 @@ def warn_drv_yc_multiple_inputs_clang_cl : Warning<
"support for '/Yc' with more than one source file not implemented yet; flag ignored">, "support for '/Yc' with more than one source file not implemented yet; flag ignored">,
InGroup<ClangClPch>; InGroup<ClangClPch>;
def err_drv_dllexport_inlines_and_fallback : Error<
"option '/Zc:dllexportInlines-' is ABI-changing and not compatible with '/fallback'">;
def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">; def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">;
def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">; def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">;
def err_drv_invalid_value_with_suggestion : Error<"invalid value '%1' in '%0','%2'">; def err_drv_invalid_value_with_suggestion : Error<"invalid value '%1' in '%0','%2'">;
@ -392,9 +389,6 @@ def err_test_module_file_extension_format : Error<
"-ftest-module-file-extension argument '%0' is not of the required form " "-ftest-module-file-extension argument '%0' is not of the required form "
"'blockname:major:minor:hashed:user info'">; "'blockname:major:minor:hashed:user info'">;
def warn_drv_invoking_fallback : Warning<"falling back to %0">,
InGroup<Fallback>;
def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">, def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">,
InGroup<DiagGroup<"slash-u-filename">>; InGroup<DiagGroup<"slash-u-filename">>;
def note_use_dashdash : Note<"Use '--' to treat subsequent arguments as filenames">; def note_use_dashdash : Note<"Use '--' to treat subsequent arguments as filenames">;

View File

@ -753,7 +753,6 @@ def Visibility : DiagGroup<"visibility">;
def ZeroLengthArray : DiagGroup<"zero-length-array">; def ZeroLengthArray : DiagGroup<"zero-length-array">;
def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">; def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">;
def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">; def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">;
def Fallback : DiagGroup<"fallback">;
def MisleadingIndentation : DiagGroup<"misleading-indentation">; def MisleadingIndentation : DiagGroup<"misleading-indentation">;
// This covers both the deprecated case (in C++98) // This covers both the deprecated case (in C++98)

View File

@ -78,7 +78,6 @@ ENUM_DIAGOPT(VerifyIgnoreUnexpected, DiagnosticLevelMask, 4,
/// -verify. /// -verify.
DIAGOPT(ElideType, 1, 0) /// Elide identical types in template diffing DIAGOPT(ElideType, 1, 0) /// Elide identical types in template diffing
DIAGOPT(ShowTemplateTree, 1, 0) /// Print a template tree when diffing DIAGOPT(ShowTemplateTree, 1, 0) /// Print a template tree when diffing
DIAGOPT(CLFallbackMode, 1, 0) /// Format for clang-cl fallback mode
VALUE_DIAGOPT(ErrorLimit, 32, 0) /// Limit # errors emitted. VALUE_DIAGOPT(ErrorLimit, 32, 0) /// Limit # errors emitted.
/// Limit depth of macro expansion backtrace. /// Limit depth of macro expansion backtrace.

View File

@ -241,26 +241,6 @@ public:
void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment) override; void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment) override;
}; };
/// Like Command, but with a fallback which is executed in case
/// the primary command crashes.
class FallbackCommand : public Command {
public:
FallbackCommand(const Action &Source_, const Tool &Creator_,
ResponseFileSupport ResponseSupport, const char *Executable_,
const llvm::opt::ArgStringList &Arguments_,
ArrayRef<InputInfo> Inputs, ArrayRef<InputInfo> Outputs,
std::unique_ptr<Command> Fallback_);
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
CrashReportInfo *CrashInfo = nullptr) const override;
int Execute(ArrayRef<Optional<StringRef>> Redirects, std::string *ErrMsg,
bool *ExecutionFailed) const override;
private:
std::unique_ptr<Command> Fallback;
};
/// Like Command, but always pretends that the wrapped command succeeded. /// Like Command, but always pretends that the wrapped command succeeded.
class ForceSuccessCommand : public Command { class ForceSuccessCommand : public Command {
public: public:

View File

@ -4756,8 +4756,8 @@ def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">,
HelpText<"File for serializing diagnostics in a binary format">; HelpText<"File for serializing diagnostics in a binary format">;
def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">, def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">,
HelpText<"Change diagnostic formatting to match IDE and command line tools">, Values<"clang,msvc,msvc-fallback,vi">, HelpText<"Change diagnostic formatting to match IDE and command line tools">, Values<"clang,msvc,vi">,
NormalizedValuesScope<"DiagnosticOptions">, NormalizedValues<["Clang", "MSVC", "MSVC", "Vi"]>, NormalizedValuesScope<"DiagnosticOptions">, NormalizedValues<["Clang", "MSVC", "Vi"]>,
MarshallingInfoString<DiagnosticOpts<"Format">, "Clang">, AutoNormalizeEnum; MarshallingInfoString<DiagnosticOpts<"Format">, "Clang">, AutoNormalizeEnum;
def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">, def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">,
HelpText<"Print diagnostic category">, Values<"none,id,name">, HelpText<"Print diagnostic category">, Values<"none,id,name">,
@ -5711,8 +5711,6 @@ def _SLASH_FA : CLFlag<"FA">,
def _SLASH_Fa : CLJoined<"Fa">, def _SLASH_Fa : CLJoined<"Fa">,
HelpText<"Set assembly output file name (with /FA)">, HelpText<"Set assembly output file name (with /FA)">,
MetaVarName<"<file or dir/>">; MetaVarName<"<file or dir/>">;
def _SLASH_fallback : CLCompileFlag<"fallback">,
HelpText<"Fall back to cl.exe if clang-cl fails to compile">;
def _SLASH_FI : CLJoinedOrSeparate<"FI">, def _SLASH_FI : CLJoinedOrSeparate<"FI">,
HelpText<"Include file before parsing">, Alias<include_>; HelpText<"Include file before parsing">, Alias<include_>;
def _SLASH_Fe : CLJoined<"Fe">, def _SLASH_Fe : CLJoined<"Fe">,

View File

@ -50,8 +50,7 @@ public:
/// TextDiagnostic logic requires. /// TextDiagnostic logic requires.
static void printDiagnosticLevel(raw_ostream &OS, static void printDiagnosticLevel(raw_ostream &OS,
DiagnosticsEngine::Level Level, DiagnosticsEngine::Level Level,
bool ShowColors, bool ShowColors);
bool CLFallbackMode = false);
/// Pretty-print a diagnostic message to a raw_ostream. /// Pretty-print a diagnostic message to a raw_ostream.
/// ///

View File

@ -414,50 +414,6 @@ void CC1Command::setEnvironment(llvm::ArrayRef<const char *> NewEnvironment) {
"The CC1Command doesn't support changing the environment vars!"); "The CC1Command doesn't support changing the environment vars!");
} }
FallbackCommand::FallbackCommand(const Action &Source_, const Tool &Creator_,
ResponseFileSupport ResponseSupport,
const char *Executable_,
const llvm::opt::ArgStringList &Arguments_,
ArrayRef<InputInfo> Inputs,
ArrayRef<InputInfo> Outputs,
std::unique_ptr<Command> Fallback_)
: Command(Source_, Creator_, ResponseSupport, Executable_, Arguments_,
Inputs, Outputs),
Fallback(std::move(Fallback_)) {}
void FallbackCommand::Print(raw_ostream &OS, const char *Terminator,
bool Quote, CrashReportInfo *CrashInfo) const {
Command::Print(OS, "", Quote, CrashInfo);
OS << " ||";
Fallback->Print(OS, Terminator, Quote, CrashInfo);
}
static bool ShouldFallback(int ExitCode) {
// FIXME: We really just want to fall back for internal errors, such
// as when some symbol cannot be mangled, when we should be able to
// parse something but can't, etc.
return ExitCode != 0;
}
int FallbackCommand::Execute(ArrayRef<llvm::Optional<StringRef>> Redirects,
std::string *ErrMsg, bool *ExecutionFailed) const {
int PrimaryStatus = Command::Execute(Redirects, ErrMsg, ExecutionFailed);
if (!ShouldFallback(PrimaryStatus))
return PrimaryStatus;
// Clear ExecutionFailed and ErrMsg before falling back.
if (ErrMsg)
ErrMsg->clear();
if (ExecutionFailed)
*ExecutionFailed = false;
const Driver &D = getCreator().getToolChain().getDriver();
D.Diag(diag::warn_drv_invoking_fallback) << Fallback->getExecutable();
int SecondaryStatus = Fallback->Execute(Redirects, ErrMsg, ExecutionFailed);
return SecondaryStatus;
}
ForceSuccessCommand::ForceSuccessCommand( ForceSuccessCommand::ForceSuccessCommand(
const Action &Source_, const Tool &Creator_, const Action &Source_, const Tool &Creator_,
ResponseFileSupport ResponseSupport, const char *Executable_, ResponseFileSupport ResponseSupport, const char *Executable_,

View File

@ -6551,23 +6551,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Input.getInputArg().renderAsInput(Args, CmdArgs); Input.getInputArg().renderAsInput(Args, CmdArgs);
} }
// Finally add the compile command to the compilation. if (D.CC1Main && !D.CCGenDiagnostics) {
if (Args.hasArg(options::OPT__SLASH_fallback) &&
Output.getType() == types::TY_Object &&
(InputType == types::TY_C || InputType == types::TY_CXX)) {
auto CLCommand =
getCLFallback()->GetCommand(C, JA, Output, Inputs, Args, LinkingOutput);
C.addCommand(std::make_unique<FallbackCommand>(
JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs,
Output, std::move(CLCommand)));
} else if (Args.hasArg(options::OPT__SLASH_fallback) &&
isa<PrecompileJobAction>(JA)) {
// In /fallback builds, run the main compilation even if the pch generation
// fails, so that the main compilation's fallback to cl.exe runs.
C.addCommand(std::make_unique<ForceSuccessCommand>(
JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs,
Output));
} else if (D.CC1Main && !D.CCGenDiagnostics) {
// Invoke the CC1 directly in this process // Invoke the CC1 directly in this process
C.addCommand(std::make_unique<CC1Command>(JA, *this, C.addCommand(std::make_unique<CC1Command>(JA, *this,
ResponseFileSupport::AtFileUTF8(), ResponseFileSupport::AtFileUTF8(),
@ -6933,11 +6917,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
if (Args.hasFlag(options::OPT__SLASH_Zc_dllexportInlines_, if (Args.hasFlag(options::OPT__SLASH_Zc_dllexportInlines_,
options::OPT__SLASH_Zc_dllexportInlines, options::OPT__SLASH_Zc_dllexportInlines,
false)) { false)) {
if (Args.hasArg(options::OPT__SLASH_fallback)) { CmdArgs.push_back("-fno-dllexport-inlines");
D.Diag(clang::diag::err_drv_dllexport_inlines_and_fallback);
} else {
CmdArgs.push_back("-fno-dllexport-inlines");
}
} }
Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg); Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
@ -7006,10 +6986,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) { if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) {
CmdArgs.push_back("-fdiagnostics-format"); CmdArgs.push_back("-fdiagnostics-format");
if (Args.hasArg(options::OPT__SLASH_fallback)) CmdArgs.push_back("msvc");
CmdArgs.push_back("msvc-fallback");
else
CmdArgs.push_back("msvc");
} }
if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) { if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
@ -7029,13 +7006,6 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
} }
} }
visualstudio::Compiler *Clang::getCLFallback() const {
if (!CLFallback)
CLFallback.reset(new visualstudio::Compiler(getToolChain()));
return CLFallback.get();
}
const char *Clang::getBaseInputName(const ArgList &Args, const char *Clang::getBaseInputName(const ArgList &Args,
const InputInfo &Input) { const InputInfo &Input) {
return Args.MakeArgString(llvm::sys::path::filename(Input.getBaseInput())); return Args.MakeArgString(llvm::sys::path::filename(Input.getBaseInput()));

View File

@ -88,10 +88,6 @@ private:
codegenoptions::DebugInfoKind *DebugInfoKind, codegenoptions::DebugInfoKind *DebugInfoKind,
bool *EmitCodeView) const; bool *EmitCodeView) const;
visualstudio::Compiler *getCLFallback() const;
mutable std::unique_ptr<visualstudio::Compiler> CLFallback;
mutable std::unique_ptr<llvm::raw_fd_ostream> CompilationDatabase = nullptr; mutable std::unique_ptr<llvm::raw_fd_ostream> CompilationDatabase = nullptr;
void DumpCompilationDatabase(Compilation &C, StringRef Filename, void DumpCompilationDatabase(Compilation &C, StringRef Filename,
StringRef Target, StringRef Target,

View File

@ -655,145 +655,6 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
C.addCommand(std::move(LinkCmd)); C.addCommand(std::move(LinkCmd));
} }
void visualstudio::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
}
std::unique_ptr<Command> visualstudio::Compiler::GetCommand(
Compilation &C, const JobAction &JA, const InputInfo &Output,
const InputInfoList &Inputs, const ArgList &Args,
const char *LinkingOutput) const {
ArgStringList CmdArgs;
CmdArgs.push_back("/nologo");
CmdArgs.push_back("/c"); // Compile only.
CmdArgs.push_back("/W0"); // No warnings.
// The goal is to be able to invoke this tool correctly based on
// any flag accepted by clang-cl.
// These are spelled the same way in clang and cl.exe,.
Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
// Optimization level.
if (Arg *A = Args.getLastArg(options::OPT_fbuiltin, options::OPT_fno_builtin))
CmdArgs.push_back(A->getOption().getID() == options::OPT_fbuiltin ? "/Oi"
: "/Oi-");
if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
if (A->getOption().getID() == options::OPT_O0) {
CmdArgs.push_back("/Od");
} else {
CmdArgs.push_back("/Og");
StringRef OptLevel = A->getValue();
if (OptLevel == "s" || OptLevel == "z")
CmdArgs.push_back("/Os");
else
CmdArgs.push_back("/Ot");
CmdArgs.push_back("/Ob2");
}
}
if (Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
options::OPT_fno_omit_frame_pointer))
CmdArgs.push_back(A->getOption().getID() == options::OPT_fomit_frame_pointer
? "/Oy"
: "/Oy-");
if (!Args.hasArg(options::OPT_fwritable_strings))
CmdArgs.push_back("/GF");
// Flags for which clang-cl has an alias.
// FIXME: How can we ensure this stays in sync with relevant clang-cl options?
if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
/*Default=*/false))
CmdArgs.push_back("/GR-");
if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS,
/*Default=*/false))
CmdArgs.push_back("/GS-");
if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
options::OPT_fno_function_sections))
CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
? "/Gy"
: "/Gy-");
if (Arg *A = Args.getLastArg(options::OPT_fdata_sections,
options::OPT_fno_data_sections))
CmdArgs.push_back(
A->getOption().getID() == options::OPT_fdata_sections ? "/Gw" : "/Gw-");
if (Args.hasArg(options::OPT_fsyntax_only))
CmdArgs.push_back("/Zs");
if (Args.hasArg(options::OPT_g_Flag, options::OPT_gline_tables_only,
options::OPT__SLASH_Z7))
CmdArgs.push_back("/Z7");
std::vector<std::string> Includes =
Args.getAllArgValues(options::OPT_include);
for (const auto &Include : Includes)
CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
// Flags that can simply be passed through.
Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX);
Args.AddAllArgs(CmdArgs, options::OPT__SLASH_GX_);
Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
Args.AddAllArgs(CmdArgs, options::OPT__SLASH_Zl);
// The order of these flags is relevant, so pick the last one.
if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
A->render(Args, CmdArgs);
// Use MSVC's default threadsafe statics behaviour unless there was a flag.
if (Arg *A = Args.getLastArg(options::OPT_fthreadsafe_statics,
options::OPT_fno_threadsafe_statics)) {
CmdArgs.push_back(A->getOption().getID() == options::OPT_fthreadsafe_statics
? "/Zc:threadSafeInit"
: "/Zc:threadSafeInit-");
}
// Control Flow Guard checks
if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
StringRef GuardArgs = A->getValue();
if (GuardArgs.equals_lower("cf") || GuardArgs.equals_lower("cf,nochecks")) {
// MSVC doesn't yet support the "nochecks" modifier.
CmdArgs.push_back("/guard:cf");
} else if (GuardArgs.equals_lower("cf-")) {
CmdArgs.push_back("/guard:cf-");
}
}
// Pass through all unknown arguments so that the fallback command can see
// them too.
Args.AddAllArgs(CmdArgs, options::OPT_UNKNOWN);
// Input filename.
assert(Inputs.size() == 1);
const InputInfo &II = Inputs[0];
assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
if (II.isFilename())
CmdArgs.push_back(II.getFilename());
else
II.getInputArg().renderAsInput(Args, CmdArgs);
// Output filename.
assert(Output.getType() == types::TY_Object);
const char *Fo =
Args.MakeArgString(std::string("/Fo") + Output.getFilename());
CmdArgs.push_back(Fo);
std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe");
return std::make_unique<Command>(
JA, *this, ResponseFileSupport::AtFileUTF16(), Args.MakeArgString(Exec),
CmdArgs, Inputs, Output);
}
MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple, MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args) const ArgList &Args)
: ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args), : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args),

View File

@ -34,27 +34,6 @@ public:
const llvm::opt::ArgList &TCArgs, const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override; const char *LinkingOutput) const override;
}; };
class LLVM_LIBRARY_VISIBILITY Compiler : public Tool {
public:
Compiler(const ToolChain &TC)
: Tool("visualstudio::Compiler", "compiler", TC) {}
bool hasIntegratedAssembler() const override { return true; }
bool hasIntegratedCPP() const override { return true; }
bool isLinkJob() const override { return false; }
void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override;
std::unique_ptr<Command> GetCommand(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const;
};
} // end namespace visualstudio } // end namespace visualstudio
} // end namespace tools } // end namespace tools

View File

@ -1666,9 +1666,6 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Opts.DiagnosticSerializationFile = A->getValue(); Opts.DiagnosticSerializationFile = A->getValue();
Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor); Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor);
if (Args.getLastArgValue(OPT_fdiagnostics_format) == "msvc-fallback")
Opts.CLFallbackMode = true;
Opts.VerifyDiagnostics = Args.hasArg(OPT_verify) || Args.hasArg(OPT_verify_EQ); Opts.VerifyDiagnostics = Args.hasArg(OPT_verify) || Args.hasArg(OPT_verify_EQ);
if (Args.hasArg(OPT_verify)) if (Args.hasArg(OPT_verify))
Opts.VerifyPrefixes.push_back("expected"); Opts.VerifyPrefixes.push_back("expected");

View File

@ -684,8 +684,7 @@ void TextDiagnostic::emitDiagnosticMessage(
OS.resetColor(); OS.resetColor();
if (DiagOpts->ShowLevel) if (DiagOpts->ShowLevel)
printDiagnosticLevel(OS, Level, DiagOpts->ShowColors, printDiagnosticLevel(OS, Level, DiagOpts->ShowColors);
DiagOpts->CLFallbackMode);
printDiagnosticMessage(OS, printDiagnosticMessage(OS,
/*IsSupplemental*/ Level == DiagnosticsEngine::Note, /*IsSupplemental*/ Level == DiagnosticsEngine::Note,
Message, OS.tell() - StartOfLocationInfo, Message, OS.tell() - StartOfLocationInfo,
@ -695,8 +694,7 @@ void TextDiagnostic::emitDiagnosticMessage(
/*static*/ void /*static*/ void
TextDiagnostic::printDiagnosticLevel(raw_ostream &OS, TextDiagnostic::printDiagnosticLevel(raw_ostream &OS,
DiagnosticsEngine::Level Level, DiagnosticsEngine::Level Level,
bool ShowColors, bool ShowColors) {
bool CLFallbackMode) {
if (ShowColors) { if (ShowColors) {
// Print diagnostic category in bold and color // Print diagnostic category in bold and color
switch (Level) { switch (Level) {
@ -713,22 +711,13 @@ TextDiagnostic::printDiagnosticLevel(raw_ostream &OS,
switch (Level) { switch (Level) {
case DiagnosticsEngine::Ignored: case DiagnosticsEngine::Ignored:
llvm_unreachable("Invalid diagnostic type"); llvm_unreachable("Invalid diagnostic type");
case DiagnosticsEngine::Note: OS << "note"; break; case DiagnosticsEngine::Note: OS << "note: "; break;
case DiagnosticsEngine::Remark: OS << "remark"; break; case DiagnosticsEngine::Remark: OS << "remark: "; break;
case DiagnosticsEngine::Warning: OS << "warning"; break; case DiagnosticsEngine::Warning: OS << "warning: "; break;
case DiagnosticsEngine::Error: OS << "error"; break; case DiagnosticsEngine::Error: OS << "error: "; break;
case DiagnosticsEngine::Fatal: OS << "fatal error"; break; case DiagnosticsEngine::Fatal: OS << "fatal error: "; break;
} }
// In clang-cl /fallback mode, print diagnostics as "error(clang):". This
// makes it more clear whether a message is coming from clang or cl.exe,
// and it prevents MSBuild from concluding that the build failed just because
// there is an "error:" in the output.
if (CLFallbackMode)
OS << "(clang)";
OS << ": ";
if (ShowColors) if (ShowColors)
OS.resetColor(); OS.resetColor();
} }

View File

@ -133,8 +133,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
// diagnostics in a context that lacks language options, a source manager, or // diagnostics in a context that lacks language options, a source manager, or
// other infrastructure necessary when emitting more rich diagnostics. // other infrastructure necessary when emitting more rich diagnostics.
if (!Info.getLocation().isValid()) { if (!Info.getLocation().isValid()) {
TextDiagnostic::printDiagnosticLevel(OS, Level, DiagOpts->ShowColors, TextDiagnostic::printDiagnosticLevel(OS, Level, DiagOpts->ShowColors);
DiagOpts->CLFallbackMode);
TextDiagnostic::printDiagnosticMessage( TextDiagnostic::printDiagnosticMessage(
OS, /*IsSupplemental=*/Level == DiagnosticsEngine::Note, OS, /*IsSupplemental=*/Level == DiagnosticsEngine::Note,
DiagMessageStream.str(), OS.tell() - StartOfLocationInfo, DiagMessageStream.str(), OS.tell() - StartOfLocationInfo,

View File

@ -1,95 +0,0 @@
// 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 --target=i686-pc-win32 /fallback /Dfoo=bar /Ubaz /Ifoo /O0 /Ox /GR /GR- /GS /GS- /Gy /Gy- \
// RUN: /Gw /Gw- /LD /LDd /EHs /EHs- /Zl /MD /MDd /MTd /MT /guard:cf /guard:cf- /FImyheader.h /Zi \
// RUN: -garbage -moregarbage \
// RUN: -### -- %s 2>&1 \
// RUN: | FileCheck %s
// CHECK: "-fdiagnostics-format" "msvc-fallback"
// CHECK: ||
// CHECK: cl.exe
// CHECK: "/nologo"
// CHECK: "/c"
// CHECK: "/W0"
// CHECK: "-D" "foo=bar"
// CHECK: "-U" "baz"
// CHECK: "-I" "foo"
// CHECK: "/Oi"
// CHECK: "/Og"
// CHECK: "/Ot"
// CHECK: "/Ob2"
// CHECK: "/Oy"
// CHECK: "/GF"
// CHECK: "/GR-"
// CHECK: "/GS-"
// CHECK: "/Gy-"
// CHECK: "/Gw-"
// CHECK: "/Z7"
// CHECK: "/FImyheader.h"
// CHECK: "/LD"
// CHECK: "/LDd"
// CHECK: "/EHs"
// CHECK: "/EHs-"
// CHECK: "/Zl"
// CHECK: "/MT"
// CHECK: "/guard:cf-"
// CHECK: "-garbage"
// CHECK: "-moregarbage"
// CHECK: "/Tc" "{{.*cl-fallback.c}}"
// CHECK: "/Fo{{.*cl-fallback.*.obj}}"
// RUN: %clang_cl /fallback /GR- -### -- %s 2>&1 | FileCheck -check-prefix=GR %s
// GR: cl.exe
// GR: "/GR-"
// RUN: %clang_cl /fallback /GS- -### -- %s 2>&1 | FileCheck -check-prefix=GS %s
// GS: cl.exe
// GS: "/GS-"
// RUN: %clang_cl /fallback /Zc:threadSafeInit -### -- %s 2>&1 | FileCheck -check-prefix=ThreadSafe %s
// ThreadSafe: /Zc:threadSafeInit
// RUN: %clang_cl /fallback /Zc:threadSafeInit- -### -- %s 2>&1 | FileCheck -check-prefix=NonThreadSafe %s
// NonThreadSafe: /Zc:threadSafeInit-
// RUN: %clang_cl /fallback /Od -### -- %s 2>&1 | FileCheck -check-prefix=O0 %s
// O0: cl.exe
// O0: "/Od"
// RUN: %clang_cl --target=i686-pc-win32 /fallback /O1 -### -- %s 2>&1 | FileCheck -check-prefix=O1 %s
// O1: cl.exe
// O1: "/Og" "/Os" "/Ob2" "/Oy" "/GF" "/Gy"
// RUN: %clang_cl --target=i686-pc-win32 /fallback /O2 -### -- %s 2>&1 | FileCheck -check-prefix=O2 %s
// O2: cl.exe
// O2: "/Oi" "/Og" "/Ot" "/Ob2" "/Oy" "/GF" "/Gy"
// RUN: %clang_cl --target=i686-pc-win32 /fallback /Os -### -- %s 2>&1 | FileCheck -check-prefix=Os %s
// Os: cl.exe
// Os: "/Os"
// RUN: %clang_cl --target=i686-pc-win32 /fallback /Ox -### -- %s 2>&1 | FileCheck -check-prefix=Ox %s
// Ox: cl.exe
// Ox: "/Oi" "/Og" "/Ot" "/Ob2" "/Oy" "/GF"
// Only fall back when actually compiling, not for e.g. /P (preprocess).
// RUN: %clang_cl /fallback /P -### -- %s 2>&1 | FileCheck -check-prefix=P %s
// P-NOT: ||
// P-NOT: "cl.exe"
// RUN: not %clang_cl /fallback /c -- %s 2>&1 | \
// RUN: FileCheck -check-prefix=ErrWarn %s
// ErrWarn: warning: falling back to {{.*}}cl.exe
// RUN: %clang_cl /fallback /c /GR /GR- -### -- %s 2>&1 | \
// RUN: FileCheck -check-prefix=NO_RTTI %s
// NO_RTTI: "-cc1"
// NO_RTTI: ||
// NO_RTTI: cl.exe
// NO_RTTI: "/GR-"
// Don't fall back on non-C or C++ files.
// RUN: %clang_cl /fallback -### -- %S/Inputs/file.ll 2>&1 | FileCheck -check-prefix=LL %s
// LL: file.ll
// LL-NOT: ||
// LL-NOT: "cl.exe"
#error "This fails to compile."

View File

@ -530,8 +530,6 @@
// NoDllExportInlines: "-fno-dllexport-inlines" // NoDllExportInlines: "-fno-dllexport-inlines"
// RUN: %clang_cl /Zc:dllexportInlines /c -### -- %s 2>&1 | FileCheck -check-prefix=DllExportInlines %s // RUN: %clang_cl /Zc:dllexportInlines /c -### -- %s 2>&1 | FileCheck -check-prefix=DllExportInlines %s
// DllExportInlines-NOT: "-fno-dllexport-inlines" // DllExportInlines-NOT: "-fno-dllexport-inlines"
// RUN: %clang_cl /fallback /Zc:dllexportInlines- /c -### -- %s 2>&1 | FileCheck -check-prefix=DllExportInlinesFallback %s
// DllExportInlinesFallback: error: option '/Zc:dllexportInlines-' is ABI-changing and not compatible with '/fallback'
// RUN: %clang_cl /Zi /c -### -- %s 2>&1 | FileCheck -check-prefix=Zi %s // RUN: %clang_cl /Zi /c -### -- %s 2>&1 | FileCheck -check-prefix=Zi %s
// Zi: "-gcodeview" // Zi: "-gcodeview"

View File

@ -333,39 +333,6 @@
// uses the last one. This is true for e.g. /Fo too, so not warning on this // uses the last one. This is true for e.g. /Fo too, so not warning on this
// is self-consistent with clang-cl's flag handling. // is self-consistent with clang-cl's flag handling.
// Interaction with /fallback
// /Yc /fallback => /Yc not passed on (but /FI is)
// RUN: %clang_cl -Werror /Ycpchfile.h /FIpchfile.h /Fpfoo.pch /fallback /c -### -- %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-YC-FALLBACK %s
// Note that in /fallback builds, if creation of the pch fails the main compile
// does still run so that /fallback can have an effect (this part is not tested)
// CHECK-YC-FALLBACK: cc1
// CHECK-YC-FALLBACK: -emit-obj
// CHECK-YC-FALLBACK: -include-pch
// CHECK-YC-FALLBACK: foo.pch
// CHECK-YC-FALLBACK: ||
// CHECK-YC-FALLBACK: cl.exe
// CHECK-YC-FALLBACK-NOT: -include-pch
// CHECK-YC-FALLBACK-NOT: /Ycpchfile.h
// CHECK-YC-FALLBACK: /FIpchfile.h
// CHECK-YC-FALLBACK-NOT: /Fpfoo.pch
// /Yu /fallback => /Yu not passed on (but /FI is)
// RUN: %clang_cl -Werror /Yupchfile.h /FIpchfile.h /Fpfoo.pch /fallback /c -### -- %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-YU-FALLBACK %s
// CHECK-YU-FALLBACK-NOT: -emit-pch
// CHECK-YU-FALLBACK: cc1
// CHECK-YU-FALLBACK: -emit-obj
// CHECK-YU-FALLBACK: -include-pch
// CHECK-YU-FALLBACK: foo.pch
// CHECK-YU-FALLBACK: ||
// CHECK-YU-FALLBACK: cl.exe
// CHECK-YU-FALLBACK-NOT: -include-pch
// CHECK-YU-FALLBACK-NOT: /Yupchfile.h
// CHECK-YU-FALLBACK: /FIpchfile.h
// CHECK-YU-FALLBACK-NOT: /Fpfoo.pch
// /FI without /Yu => pch file not used, even if it exists (different from // /FI without /Yu => pch file not used, even if it exists (different from
// -include, which picks up .gch files if they exist). // -include, which picks up .gch files if they exist).
// RUN: touch %t.pch // RUN: touch %t.pch

View File

@ -20,11 +20,11 @@
// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fno-show-column -fmsc-version=1900 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2015_ORIG // RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fno-show-column -fmsc-version=1900 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2015_ORIG
// //
// RUN: %clang -fsyntax-only -fno-show-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=NO_COLUMN // RUN: %clang -fsyntax-only -fno-show-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=NO_COLUMN
//
// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1300 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010-FALLBACK
// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fms-compatibility-version=13.00 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010-FALLBACK
// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1800 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2013-FALLBACK
// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1900 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2015-FALLBACK
@ -42,7 +42,4 @@
// VI: {{.*}} +36:8: warning: extra tokens at end of #endif directive [-Wextra-tokens] // VI: {{.*}} +36:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
// MSVC2015_ORIG: {{.*}}(36): warning: extra tokens at end of #endif directive [-Wextra-tokens] // MSVC2015_ORIG: {{.*}}(36): warning: extra tokens at end of #endif directive [-Wextra-tokens]
// NO_COLUMN: {{.*}}:36: warning: extra tokens at end of #endif directive [-Wextra-tokens] // NO_COLUMN: {{.*}}:36: warning: extra tokens at end of #endif directive [-Wextra-tokens]
// MSVC2010-FALLBACK: {{.*}}(36,7) : error(clang): extra tokens at end of #endif directive
// MSVC2013-FALLBACK: {{.*}}(36,8) : error(clang): extra tokens at end of #endif directive
// MSVC2015-FALLBACK: {{.*}}(36,8): error(clang): extra tokens at end of #endif directive
int x; int x;