[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
-------------------------
- ...
- 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
--------------------

View File

@ -3501,7 +3501,6 @@ Execute ``clang-cl /?`` to see a list of supported options:
/execution-charset:<value>
Runtime encoding, supports only UTF-8
/E Preprocess to stdout
/fallback Fall back to cl.exe if clang-cl fails to compile
/FA Output assembly code file during compilation
/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 \)
@ -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
`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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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">,
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_int_value : Error<"invalid integral value '%1' in '%0'">;
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 "
"'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">,
InGroup<DiagGroup<"slash-u-filename">>;
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 GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">;
def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">;
def Fallback : DiagGroup<"fallback">;
def MisleadingIndentation : DiagGroup<"misleading-indentation">;
// This covers both the deprecated case (in C++98)

View File

@ -78,7 +78,6 @@ ENUM_DIAGOPT(VerifyIgnoreUnexpected, DiagnosticLevelMask, 4,
/// -verify.
DIAGOPT(ElideType, 1, 0) /// Elide identical types in template 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.
/// Limit depth of macro expansion backtrace.

View File

@ -241,26 +241,6 @@ public:
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.
class ForceSuccessCommand : public Command {
public:

View File

@ -4756,8 +4756,8 @@ def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">,
HelpText<"File for serializing diagnostics in a binary format">;
def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">,
HelpText<"Change diagnostic formatting to match IDE and command line tools">, Values<"clang,msvc,msvc-fallback,vi">,
NormalizedValuesScope<"DiagnosticOptions">, NormalizedValues<["Clang", "MSVC", "MSVC", "Vi"]>,
HelpText<"Change diagnostic formatting to match IDE and command line tools">, Values<"clang,msvc,vi">,
NormalizedValuesScope<"DiagnosticOptions">, NormalizedValues<["Clang", "MSVC", "Vi"]>,
MarshallingInfoString<DiagnosticOpts<"Format">, "Clang">, AutoNormalizeEnum;
def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">,
HelpText<"Print diagnostic category">, Values<"none,id,name">,
@ -5711,8 +5711,6 @@ def _SLASH_FA : CLFlag<"FA">,
def _SLASH_Fa : CLJoined<"Fa">,
HelpText<"Set assembly output file name (with /FA)">,
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">,
HelpText<"Include file before parsing">, Alias<include_>;
def _SLASH_Fe : CLJoined<"Fe">,

View File

@ -50,8 +50,7 @@ public:
/// TextDiagnostic logic requires.
static void printDiagnosticLevel(raw_ostream &OS,
DiagnosticsEngine::Level Level,
bool ShowColors,
bool CLFallbackMode = false);
bool ShowColors);
/// 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!");
}
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(
const Action &Source_, const Tool &Creator_,
ResponseFileSupport ResponseSupport, const char *Executable_,

View File

@ -6551,23 +6551,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Input.getInputArg().renderAsInput(Args, CmdArgs);
}
// Finally add the compile command to the compilation.
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) {
if (D.CC1Main && !D.CCGenDiagnostics) {
// Invoke the CC1 directly in this process
C.addCommand(std::make_unique<CC1Command>(JA, *this,
ResponseFileSupport::AtFileUTF8(),
@ -6933,11 +6917,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
if (Args.hasFlag(options::OPT__SLASH_Zc_dllexportInlines_,
options::OPT__SLASH_Zc_dllexportInlines,
false)) {
if (Args.hasArg(options::OPT__SLASH_fallback)) {
D.Diag(clang::diag::err_drv_dllexport_inlines_and_fallback);
} else {
CmdArgs.push_back("-fno-dllexport-inlines");
}
CmdArgs.push_back("-fno-dllexport-inlines");
}
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)) {
CmdArgs.push_back("-fdiagnostics-format");
if (Args.hasArg(options::OPT__SLASH_fallback))
CmdArgs.push_back("msvc-fallback");
else
CmdArgs.push_back("msvc");
CmdArgs.push_back("msvc");
}
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 InputInfo &Input) {
return Args.MakeArgString(llvm::sys::path::filename(Input.getBaseInput()));

View File

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

View File

@ -655,145 +655,6 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
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,
const ArgList &Args)
: ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args),

View File

@ -34,27 +34,6 @@ public:
const llvm::opt::ArgList &TCArgs,
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 tools

View File

@ -1666,9 +1666,6 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Opts.DiagnosticSerializationFile = A->getValue();
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);
if (Args.hasArg(OPT_verify))
Opts.VerifyPrefixes.push_back("expected");

View File

@ -684,8 +684,7 @@ void TextDiagnostic::emitDiagnosticMessage(
OS.resetColor();
if (DiagOpts->ShowLevel)
printDiagnosticLevel(OS, Level, DiagOpts->ShowColors,
DiagOpts->CLFallbackMode);
printDiagnosticLevel(OS, Level, DiagOpts->ShowColors);
printDiagnosticMessage(OS,
/*IsSupplemental*/ Level == DiagnosticsEngine::Note,
Message, OS.tell() - StartOfLocationInfo,
@ -695,8 +694,7 @@ void TextDiagnostic::emitDiagnosticMessage(
/*static*/ void
TextDiagnostic::printDiagnosticLevel(raw_ostream &OS,
DiagnosticsEngine::Level Level,
bool ShowColors,
bool CLFallbackMode) {
bool ShowColors) {
if (ShowColors) {
// Print diagnostic category in bold and color
switch (Level) {
@ -713,22 +711,13 @@ TextDiagnostic::printDiagnosticLevel(raw_ostream &OS,
switch (Level) {
case DiagnosticsEngine::Ignored:
llvm_unreachable("Invalid diagnostic type");
case DiagnosticsEngine::Note: OS << "note"; break;
case DiagnosticsEngine::Remark: OS << "remark"; break;
case DiagnosticsEngine::Warning: OS << "warning"; break;
case DiagnosticsEngine::Error: OS << "error"; break;
case DiagnosticsEngine::Fatal: OS << "fatal error"; break;
case DiagnosticsEngine::Note: OS << "note: "; break;
case DiagnosticsEngine::Remark: OS << "remark: "; break;
case DiagnosticsEngine::Warning: OS << "warning: "; break;
case DiagnosticsEngine::Error: OS << "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)
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
// other infrastructure necessary when emitting more rich diagnostics.
if (!Info.getLocation().isValid()) {
TextDiagnostic::printDiagnosticLevel(OS, Level, DiagOpts->ShowColors,
DiagOpts->CLFallbackMode);
TextDiagnostic::printDiagnosticLevel(OS, Level, DiagOpts->ShowColors);
TextDiagnostic::printDiagnosticMessage(
OS, /*IsSupplemental=*/Level == DiagnosticsEngine::Note,
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"
// RUN: %clang_cl /Zc:dllexportInlines /c -### -- %s 2>&1 | FileCheck -check-prefix=DllExportInlines %s
// 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
// 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
// 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
// -include, which picks up .gch files if they exist).
// 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 -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]
// 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]
// 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;