[clang][NFC] Consolidating usage of "FinalPhase" in Driver::BuildActions.

I am working to remove this concept of the "FinalPhase" in the clang driver,
but it is used in a lot of different places to do argument handling for
different combinations of phase pipelines and arguments. I am trying to
consolidate most of the uses of "FinalPhase" into its own separate scope.
Eventually, in a subsequent patch I will move all of this stuff to a separate
function, and have more of the complication phase list construction setup into
types::getComplicationPhases.

Differential Revision: https://reviews.llvm.org/D65969

llvm-svn: 368393
This commit is contained in:
Puyan Lotfi 2019-08-09 04:55:09 +00:00
parent e9efaf3529
commit 82c51b18e4
1 changed files with 102 additions and 85 deletions

View File

@ -3157,17 +3157,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
return;
}
Arg *FinalPhaseArg;
phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
if (FinalPhase == phases::Link) {
if (Args.hasArg(options::OPT_emit_llvm))
Diag(clang::diag::err_drv_emit_llvm_link);
if (IsCLMode() && LTOMode != LTOK_None &&
!Args.getLastArgValue(options::OPT_fuse_ld_EQ).equals_lower("lld"))
Diag(clang::diag::err_drv_lto_without_lld);
}
// Reject -Z* at the top level, these options should never have been exposed
// by gcc.
if (Arg *A = Args.getLastArg(options::OPT_Z_Joined))
@ -3220,15 +3209,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
Args.eraseArg(options::OPT__SLASH_Yc);
YcArg = nullptr;
}
if (FinalPhase == phases::Preprocess || Args.hasArg(options::OPT__SLASH_Y_)) {
// If only preprocessing or /Y- is used, all pch handling is disabled.
// Rather than check for it everywhere, just remove clang-cl pch-related
// flags here.
Args.eraseArg(options::OPT__SLASH_Fp);
Args.eraseArg(options::OPT__SLASH_Yc);
Args.eraseArg(options::OPT__SLASH_Yu);
YcArg = YuArg = nullptr;
}
// Builder to be used to build offloading actions.
OffloadingActionBuilder OffloadBuilder(C, Args, Inputs);
@ -3237,70 +3217,115 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
HeaderModulePrecompileJobAction *HeaderModuleAction = nullptr;
ActionList LinkerInputs;
unsigned LastPLSize = 0;
phases::ID FinalPhase;
{
Arg *FinalPhaseArg;
FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
if (FinalPhase == phases::Link) {
if (Args.hasArg(options::OPT_emit_llvm))
Diag(clang::diag::err_drv_emit_llvm_link);
if (IsCLMode() && LTOMode != LTOK_None &&
!Args.getLastArgValue(options::OPT_fuse_ld_EQ).equals_lower("lld"))
Diag(clang::diag::err_drv_lto_without_lld);
}
if (FinalPhase == phases::Preprocess ||
Args.hasArg(options::OPT__SLASH_Y_)) {
// If only preprocessing or /Y- is used, all pch handling is disabled.
// Rather than check for it everywhere, just remove clang-cl pch-related
// flags here.
Args.eraseArg(options::OPT__SLASH_Fp);
Args.eraseArg(options::OPT__SLASH_Yc);
Args.eraseArg(options::OPT__SLASH_Yu);
YcArg = YuArg = nullptr;
}
unsigned LastPLSize = 0;
for (auto &I : Inputs) {
types::ID InputType = I.first;
const Arg *InputArg = I.second;
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PL;
types::getCompilationPhases(InputType, PL);
LastPLSize = PL.size();
// If the first step comes after the final phase we are doing as part of
// this compilation, warn the user about it.
phases::ID InitialPhase = PL[0];
if (InitialPhase > FinalPhase) {
if (InputArg->isClaimed())
continue;
// 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 when final phase determined by binary name, rather than
// by a command-line argument with a corresponding Arg.
if (CCCIsCPP())
Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
<< InputArg->getAsString(Args) << getPhaseName(InitialPhase);
// Special case '-E' warning on a previously preprocessed file to make
// more sense.
else if (InitialPhase == phases::Compile &&
(Args.getLastArg(options::OPT__SLASH_EP,
options::OPT__SLASH_P) ||
Args.getLastArg(options::OPT_E) ||
Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
getPreprocessedType(InputType) == types::TY_INVALID)
Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
<< InputArg->getAsString(Args) << !!FinalPhaseArg
<< (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
else
Diag(clang::diag::warn_drv_input_file_unused)
<< InputArg->getAsString(Args) << getPhaseName(InitialPhase)
<< !!FinalPhaseArg
<< (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
continue;
}
if (YcArg) {
// Add a separate precompile phase for the compile phase.
if (FinalPhase >= phases::Compile) {
const types::ID HeaderType = lookupHeaderTypeForSourceType(InputType);
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PCHPL;
types::getCompilationPhases(HeaderType, PCHPL);
// Build the pipeline for the pch file.
Action *ClangClPch = C.MakeAction<InputAction>(*InputArg, HeaderType);
for (phases::ID Phase : PCHPL)
ClangClPch = ConstructPhaseAction(C, Args, Phase, ClangClPch);
assert(ClangClPch);
Actions.push_back(ClangClPch);
// The driver currently exits after the first failed command. This
// relies on that behavior, to make sure if the pch generation fails,
// the main compilation won't run.
// FIXME: If the main compilation fails, the PCH generation should
// probably not be considered successful either.
}
}
}
// If we are linking, claim any options which are obviously only used for
// compilation.
// FIXME: Understand why the last Phase List length is used here.
if (FinalPhase == phases::Link && LastPLSize == 1) {
Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
Args.ClaimAllArgs(options::OPT_cl_compile_Group);
}
}
for (auto &I : Inputs) {
types::ID InputType = I.first;
const Arg *InputArg = I.second;
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PL;
types::getCompilationPhases(InputType, PL);
LastPLSize = PL.size();
// If the first step comes after the final phase we are doing as part of
// this compilation, warn the user about it.
phases::ID InitialPhase = PL[0];
if (InitialPhase > FinalPhase) {
if (InputArg->isClaimed())
continue;
// 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 when final phase determined by binary name, rather than
// by a command-line argument with a corresponding Arg.
if (CCCIsCPP())
Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
<< InputArg->getAsString(Args) << getPhaseName(InitialPhase);
// Special case '-E' warning on a previously preprocessed file to make
// more sense.
else if (InitialPhase == phases::Compile &&
FinalPhase == phases::Preprocess &&
getPreprocessedType(InputType) == types::TY_INVALID)
Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
<< InputArg->getAsString(Args) << !!FinalPhaseArg
<< (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
else
Diag(clang::diag::warn_drv_input_file_unused)
<< InputArg->getAsString(Args) << getPhaseName(InitialPhase)
<< !!FinalPhaseArg
<< (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
if (PL[0] > FinalPhase)
continue;
}
if (YcArg) {
// Add a separate precompile phase for the compile phase.
if (FinalPhase >= phases::Compile) {
const types::ID HeaderType = lookupHeaderTypeForSourceType(InputType);
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PCHPL;
types::getCompilationPhases(HeaderType, PCHPL);
// Build the pipeline for the pch file.
Action *ClangClPch =
C.MakeAction<InputAction>(*InputArg, HeaderType);
for (phases::ID Phase : PCHPL)
ClangClPch = ConstructPhaseAction(C, Args, Phase, ClangClPch);
assert(ClangClPch);
Actions.push_back(ClangClPch);
// The driver currently exits after the first failed command. This
// relies on that behavior, to make sure if the pch generation fails,
// the main compilation won't run.
// FIXME: If the main compilation fails, the PCH generation should
// probably not be considered successful either.
}
}
// Build the pipeline for this file.
Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
@ -3379,14 +3404,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
Actions.push_back(LA);
}
// If we are linking, claim any options which are obviously only used for
// compilation.
// FIXME: Understand why the last Phase List length is used here.
if (FinalPhase == phases::Link && LastPLSize == 1) {
Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
Args.ClaimAllArgs(options::OPT_cl_compile_Group);
}
// If --print-supported-cpus, -mcpu=? or -mtune=? is specified, build a custom
// Compile phase that prints out supported cpu models and quits.
if (Arg *A = Args.getLastArg(options::OPT_print_supported_cpus)) {