Skip to content

Commit 740f69b

Browse files
committed
[NFC][clang] Moving argument handling: Driver::BuildActions -> handleArguments
This patch simply moves code that already exists into a new function. Specifically I think it will make the BuildActions code for building a clang job pipeline easier to read and work with. Differential Revision: https://reviews.llvm.org/D66058 llvm-svn: 368881
1 parent 3555af7 commit 740f69b

File tree

2 files changed

+127
-114
lines changed

2 files changed

+127
-114
lines changed

clang/include/clang/Driver/Driver.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/Driver/Util.h"
1919
#include "llvm/ADT/StringMap.h"
2020
#include "llvm/ADT/StringRef.h"
21+
#include "llvm/Option/Arg.h"
2122
#include "llvm/Option/ArgList.h"
2223
#include "llvm/Support/StringSaver.h"
2324

@@ -250,9 +251,17 @@ class Driver {
250251

251252
// getFinalPhase - Determine which compilation mode we are in and record
252253
// which option we used to determine the final phase.
254+
// TODO: Much of what getFinalPhase returns are not actually true compiler
255+
// modes. Fold this functionality into Types::getCompilationPhases and
256+
// handleArguments.
253257
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL,
254258
llvm::opt::Arg **FinalPhaseArg = nullptr) const;
255259

260+
// handleArguments - All code related to claiming and printing diagnostics
261+
// related to arguments to the driver are done here.
262+
void handleArguments(Compilation &C, llvm::opt::DerivedArgList &Args,
263+
const InputList &Inputs, ActionList &Actions) const;
264+
256265
// Before executing jobs, sets up response files for commands that need them.
257266
void setUpResponseFiles(Compilation &C, Command &Cmd);
258267

clang/lib/Driver/Driver.cpp

Lines changed: 118 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -3148,6 +3148,123 @@ class OffloadingActionBuilder final {
31483148
};
31493149
} // anonymous namespace.
31503150

3151+
void Driver::handleArguments(Compilation &C, DerivedArgList &Args,
3152+
const InputList &Inputs,
3153+
ActionList &Actions) const {
3154+
3155+
// Ignore /Yc/Yu if both /Yc and /Yu passed but with different filenames.
3156+
Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3157+
Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3158+
if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3159+
Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3160+
Args.eraseArg(options::OPT__SLASH_Yc);
3161+
Args.eraseArg(options::OPT__SLASH_Yu);
3162+
YcArg = YuArg = nullptr;
3163+
}
3164+
if (YcArg && Inputs.size() > 1) {
3165+
Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3166+
Args.eraseArg(options::OPT__SLASH_Yc);
3167+
YcArg = nullptr;
3168+
}
3169+
3170+
Arg *FinalPhaseArg;
3171+
phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
3172+
3173+
if (FinalPhase == phases::Link) {
3174+
if (Args.hasArg(options::OPT_emit_llvm))
3175+
Diag(clang::diag::err_drv_emit_llvm_link);
3176+
if (IsCLMode() && LTOMode != LTOK_None &&
3177+
!Args.getLastArgValue(options::OPT_fuse_ld_EQ).equals_lower("lld"))
3178+
Diag(clang::diag::err_drv_lto_without_lld);
3179+
}
3180+
3181+
if (FinalPhase == phases::Preprocess || Args.hasArg(options::OPT__SLASH_Y_)) {
3182+
// If only preprocessing or /Y- is used, all pch handling is disabled.
3183+
// Rather than check for it everywhere, just remove clang-cl pch-related
3184+
// flags here.
3185+
Args.eraseArg(options::OPT__SLASH_Fp);
3186+
Args.eraseArg(options::OPT__SLASH_Yc);
3187+
Args.eraseArg(options::OPT__SLASH_Yu);
3188+
YcArg = YuArg = nullptr;
3189+
}
3190+
3191+
unsigned LastPLSize = 0;
3192+
for (auto &I : Inputs) {
3193+
types::ID InputType = I.first;
3194+
const Arg *InputArg = I.second;
3195+
3196+
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PL;
3197+
types::getCompilationPhases(InputType, PL);
3198+
LastPLSize = PL.size();
3199+
3200+
// If the first step comes after the final phase we are doing as part of
3201+
// this compilation, warn the user about it.
3202+
phases::ID InitialPhase = PL[0];
3203+
if (InitialPhase > FinalPhase) {
3204+
if (InputArg->isClaimed())
3205+
continue;
3206+
3207+
// Claim here to avoid the more general unused warning.
3208+
InputArg->claim();
3209+
3210+
// Suppress all unused style warnings with -Qunused-arguments
3211+
if (Args.hasArg(options::OPT_Qunused_arguments))
3212+
continue;
3213+
3214+
// Special case when final phase determined by binary name, rather than
3215+
// by a command-line argument with a corresponding Arg.
3216+
if (CCCIsCPP())
3217+
Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
3218+
<< InputArg->getAsString(Args) << getPhaseName(InitialPhase);
3219+
// Special case '-E' warning on a previously preprocessed file to make
3220+
// more sense.
3221+
else if (InitialPhase == phases::Compile &&
3222+
(Args.getLastArg(options::OPT__SLASH_EP,
3223+
options::OPT__SLASH_P) ||
3224+
Args.getLastArg(options::OPT_E) ||
3225+
Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
3226+
getPreprocessedType(InputType) == types::TY_INVALID)
3227+
Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
3228+
<< InputArg->getAsString(Args) << !!FinalPhaseArg
3229+
<< (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
3230+
else
3231+
Diag(clang::diag::warn_drv_input_file_unused)
3232+
<< InputArg->getAsString(Args) << getPhaseName(InitialPhase)
3233+
<< !!FinalPhaseArg
3234+
<< (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
3235+
continue;
3236+
}
3237+
3238+
if (YcArg) {
3239+
// Add a separate precompile phase for the compile phase.
3240+
if (FinalPhase >= phases::Compile) {
3241+
const types::ID HeaderType = lookupHeaderTypeForSourceType(InputType);
3242+
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PCHPL;
3243+
types::getCompilationPhases(HeaderType, PCHPL);
3244+
// Build the pipeline for the pch file.
3245+
Action *ClangClPch = C.MakeAction<InputAction>(*InputArg, HeaderType);
3246+
for (phases::ID Phase : PCHPL)
3247+
ClangClPch = ConstructPhaseAction(C, Args, Phase, ClangClPch);
3248+
assert(ClangClPch);
3249+
Actions.push_back(ClangClPch);
3250+
// The driver currently exits after the first failed command. This
3251+
// relies on that behavior, to make sure if the pch generation fails,
3252+
// the main compilation won't run.
3253+
// FIXME: If the main compilation fails, the PCH generation should
3254+
// probably not be considered successful either.
3255+
}
3256+
}
3257+
}
3258+
3259+
// If we are linking, claim any options which are obviously only used for
3260+
// compilation.
3261+
// FIXME: Understand why the last Phase List length is used here.
3262+
if (FinalPhase == phases::Link && LastPLSize == 1) {
3263+
Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
3264+
Args.ClaimAllArgs(options::OPT_cl_compile_Group);
3265+
}
3266+
}
3267+
31513268
void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
31523269
const InputList &Inputs, ActionList &Actions) const {
31533270
llvm::PrettyStackTraceString CrashInfo("Building compilation actions");
@@ -3195,20 +3312,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
31953312
}
31963313
}
31973314

3198-
// Ignore /Yc/Yu if both /Yc and /Yu passed but with different filenames.
3199-
Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc);
3200-
Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu);
3201-
if (YcArg && YuArg && strcmp(YcArg->getValue(), YuArg->getValue()) != 0) {
3202-
Diag(clang::diag::warn_drv_ycyu_different_arg_clang_cl);
3203-
Args.eraseArg(options::OPT__SLASH_Yc);
3204-
Args.eraseArg(options::OPT__SLASH_Yu);
3205-
YcArg = YuArg = nullptr;
3206-
}
3207-
if (YcArg && Inputs.size() > 1) {
3208-
Diag(clang::diag::warn_drv_yc_multiple_inputs_clang_cl);
3209-
Args.eraseArg(options::OPT__SLASH_Yc);
3210-
YcArg = nullptr;
3211-
}
3315+
handleArguments(C, Args, Inputs, Actions);
32123316

32133317
// Builder to be used to build offloading actions.
32143318
OffloadingActionBuilder OffloadBuilder(C, Args, Inputs);
@@ -3217,106 +3321,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
32173321
HeaderModulePrecompileJobAction *HeaderModuleAction = nullptr;
32183322
ActionList LinkerInputs;
32193323

3220-
{
3221-
Arg *FinalPhaseArg;
3222-
phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
3223-
3224-
if (FinalPhase == phases::Link) {
3225-
if (Args.hasArg(options::OPT_emit_llvm))
3226-
Diag(clang::diag::err_drv_emit_llvm_link);
3227-
if (IsCLMode() && LTOMode != LTOK_None &&
3228-
!Args.getLastArgValue(options::OPT_fuse_ld_EQ).equals_lower("lld"))
3229-
Diag(clang::diag::err_drv_lto_without_lld);
3230-
}
3231-
3232-
if (FinalPhase == phases::Preprocess ||
3233-
Args.hasArg(options::OPT__SLASH_Y_)) {
3234-
// If only preprocessing or /Y- is used, all pch handling is disabled.
3235-
// Rather than check for it everywhere, just remove clang-cl pch-related
3236-
// flags here.
3237-
Args.eraseArg(options::OPT__SLASH_Fp);
3238-
Args.eraseArg(options::OPT__SLASH_Yc);
3239-
Args.eraseArg(options::OPT__SLASH_Yu);
3240-
YcArg = YuArg = nullptr;
3241-
}
3242-
3243-
unsigned LastPLSize = 0;
3244-
for (auto &I : Inputs) {
3245-
types::ID InputType = I.first;
3246-
const Arg *InputArg = I.second;
3247-
3248-
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PL;
3249-
types::getCompilationPhases(InputType, PL);
3250-
LastPLSize = PL.size();
3251-
3252-
// If the first step comes after the final phase we are doing as part of
3253-
// this compilation, warn the user about it.
3254-
phases::ID InitialPhase = PL[0];
3255-
if (InitialPhase > FinalPhase) {
3256-
if (InputArg->isClaimed())
3257-
continue;
3258-
3259-
// Claim here to avoid the more general unused warning.
3260-
InputArg->claim();
3261-
3262-
// Suppress all unused style warnings with -Qunused-arguments
3263-
if (Args.hasArg(options::OPT_Qunused_arguments))
3264-
continue;
3265-
3266-
// Special case when final phase determined by binary name, rather than
3267-
// by a command-line argument with a corresponding Arg.
3268-
if (CCCIsCPP())
3269-
Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
3270-
<< InputArg->getAsString(Args) << getPhaseName(InitialPhase);
3271-
// Special case '-E' warning on a previously preprocessed file to make
3272-
// more sense.
3273-
else if (InitialPhase == phases::Compile &&
3274-
(Args.getLastArg(options::OPT__SLASH_EP,
3275-
options::OPT__SLASH_P) ||
3276-
Args.getLastArg(options::OPT_E) ||
3277-
Args.getLastArg(options::OPT_M, options::OPT_MM)) &&
3278-
getPreprocessedType(InputType) == types::TY_INVALID)
3279-
Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
3280-
<< InputArg->getAsString(Args) << !!FinalPhaseArg
3281-
<< (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
3282-
else
3283-
Diag(clang::diag::warn_drv_input_file_unused)
3284-
<< InputArg->getAsString(Args) << getPhaseName(InitialPhase)
3285-
<< !!FinalPhaseArg
3286-
<< (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
3287-
continue;
3288-
}
3289-
3290-
if (YcArg) {
3291-
// Add a separate precompile phase for the compile phase.
3292-
if (FinalPhase >= phases::Compile) {
3293-
const types::ID HeaderType = lookupHeaderTypeForSourceType(InputType);
3294-
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PCHPL;
3295-
types::getCompilationPhases(HeaderType, PCHPL);
3296-
// Build the pipeline for the pch file.
3297-
Action *ClangClPch = C.MakeAction<InputAction>(*InputArg, HeaderType);
3298-
for (phases::ID Phase : PCHPL)
3299-
ClangClPch = ConstructPhaseAction(C, Args, Phase, ClangClPch);
3300-
assert(ClangClPch);
3301-
Actions.push_back(ClangClPch);
3302-
// The driver currently exits after the first failed command. This
3303-
// relies on that behavior, to make sure if the pch generation fails,
3304-
// the main compilation won't run.
3305-
// FIXME: If the main compilation fails, the PCH generation should
3306-
// probably not be considered successful either.
3307-
}
3308-
}
3309-
}
3310-
3311-
// If we are linking, claim any options which are obviously only used for
3312-
// compilation.
3313-
// FIXME: Understand why the last Phase List length is used here.
3314-
if (FinalPhase == phases::Link && LastPLSize == 1) {
3315-
Args.ClaimAllArgs(options::OPT_CompileOnly_Group);
3316-
Args.ClaimAllArgs(options::OPT_cl_compile_Group);
3317-
}
3318-
}
3319-
33203324
for (auto &I : Inputs) {
33213325
types::ID InputType = I.first;
33223326
const Arg *InputArg = I.second;

0 commit comments

Comments
 (0)