[Driver] Fix multiple bugs related to dependency file options: -M -MM -MD -MMD -MT -MQ

-M -o test.i => dependency file is test.d, not test.i
-MM -o test.i => dependency file is test.d, not test.i
-M -MMD => bogus warning -Wunused-command-line-argument
-M MT dummy => -w not rendered

llvm-svn: 371918
This commit is contained in:
Fangrui Song 2019-09-14 06:01:22 +00:00
parent 6fe3d36768
commit 55abd2b295
3 changed files with 60 additions and 36 deletions

View File

@ -3450,8 +3450,10 @@ Action *Driver::ConstructPhaseAction(
llvm_unreachable("link action invalid here.");
case phases::Preprocess: {
types::ID OutputTy;
// -{M, MM} alter the output type.
if (Args.hasArg(options::OPT_M, options::OPT_MM)) {
// -M and -MM specify the dependency file name by altering the output type,
// -if -MD and -MMD are not specified.
if (Args.hasArg(options::OPT_M, options::OPT_MM) &&
!Args.hasArg(options::OPT_MD, options::OPT_MMD)) {
OutputTy = types::TY_Dependencies;
} else {
OutputTy = Input->getType();

View File

@ -1061,7 +1061,6 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
ArgStringList &CmdArgs,
const InputInfo &Output,
const InputInfoList &Inputs) const {
Arg *A;
const bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
CheckPreprocessingOptions(D, Args);
@ -1070,9 +1069,20 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_CC);
// Handle dependency file generation.
if ((A = Args.getLastArg(options::OPT_M, options::OPT_MM)) ||
(A = Args.getLastArg(options::OPT_MD)) ||
(A = Args.getLastArg(options::OPT_MMD))) {
Arg *ArgM = Args.getLastArg(options::OPT_MM);
if (!ArgM)
ArgM = Args.getLastArg(options::OPT_M);
Arg *ArgMD = Args.getLastArg(options::OPT_MMD);
if (!ArgMD)
ArgMD = Args.getLastArg(options::OPT_MD);
// -M and -MM imply -w.
if (ArgM)
CmdArgs.push_back("-w");
else
ArgM = ArgMD;
if (ArgM) {
// Determine the output location.
const char *DepFile;
if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
@ -1080,8 +1090,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
C.addFailureResultFile(DepFile, &JA);
} else if (Output.getType() == types::TY_Dependencies) {
DepFile = Output.getFilename();
} else if (A->getOption().matches(options::OPT_M) ||
A->getOption().matches(options::OPT_MM)) {
} else if (!ArgMD) {
DepFile = "-";
} else {
DepFile = getDependencyFileName(Args, Inputs);
@ -1090,8 +1099,22 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-dependency-file");
CmdArgs.push_back(DepFile);
bool HasTarget = false;
for (const Arg *A : Args.filtered(options::OPT_MT, options::OPT_MQ)) {
HasTarget = true;
A->claim();
if (A->getOption().matches(options::OPT_MT)) {
A->render(Args, CmdArgs);
} else {
CmdArgs.push_back("-MT");
SmallString<128> Quoted;
QuoteTarget(A->getValue(), Quoted);
CmdArgs.push_back(Args.MakeArgString(Quoted));
}
}
// Add a default target if one wasn't specified.
if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
if (!HasTarget) {
const char *DepTarget;
// If user provided -o, that is the dependency target, except
@ -1108,17 +1131,14 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
DepTarget = Args.MakeArgString(llvm::sys::path::filename(P));
}
if (!A->getOption().matches(options::OPT_MD) && !A->getOption().matches(options::OPT_MMD)) {
CmdArgs.push_back("-w");
}
CmdArgs.push_back("-MT");
SmallString<128> Quoted;
QuoteTarget(DepTarget, Quoted);
CmdArgs.push_back(Args.MakeArgString(Quoted));
}
if (A->getOption().matches(options::OPT_M) ||
A->getOption().matches(options::OPT_MD))
if (ArgM->getOption().matches(options::OPT_M) ||
ArgM->getOption().matches(options::OPT_MD))
CmdArgs.push_back("-sys-header-deps");
if ((isa<PrecompileJobAction>(JA) &&
!Args.hasArg(options::OPT_fno_module_file_deps)) ||
@ -1127,8 +1147,8 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
}
if (Args.hasArg(options::OPT_MG)) {
if (!A || A->getOption().matches(options::OPT_MD) ||
A->getOption().matches(options::OPT_MMD))
if (!ArgM || ArgM->getOption().matches(options::OPT_MD) ||
ArgM->getOption().matches(options::OPT_MMD))
D.Diag(diag::err_drv_mg_requires_m_or_mm);
CmdArgs.push_back("-MG");
}
@ -1136,22 +1156,6 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_MP);
Args.AddLastArg(CmdArgs, options::OPT_MV);
// Convert all -MQ <target> args to -MT <quoted target>
for (const Arg *A : Args.filtered(options::OPT_MT, options::OPT_MQ)) {
A->claim();
if (A->getOption().matches(options::OPT_MQ)) {
CmdArgs.push_back("-MT");
SmallString<128> Quoted;
QuoteTarget(A->getValue(), Quoted);
CmdArgs.push_back(Args.MakeArgString(Quoted));
// -MT flag - no change
} else {
A->render(Args, CmdArgs);
}
}
// Add offload include arguments specific for CUDA. This must happen before
// we -I or -include anything else, because we must pick up the CUDA headers
// from the particular CUDA installation, rather than from e.g.

View File

@ -1,16 +1,34 @@
// RUN: %clang -M -MM %s 2>&1 | FileCheck /dev/null --implicit-check-not=warning
// RUN: %clang -M %s 2>&1 | FileCheck %s --implicit-check-not=warning
// RUN: %clang -MM %s 2>&1 | FileCheck %s --implicit-check-not=warning
// CHECK: m-and-mm.o:
// TEST-I: {{.*}}test.i:
// TEST: {{.*}}test:
// RUN: mkdir -p %t.dir
/// if -MD and -MMD are not specified, -o specifies the dependency file name.
// RUN: rm -f %t.dir/test.i
// RUN: %clang -M %s -o %t.dir/test.i
// RUN: FileCheck %s < %t.dir/test.i
// RUN: rm -f %t.dir/test.i
// RUN: %clang -MM %s -o %t.dir/test.i
// RUN: FileCheck %s < %t.dir/test.i
// RUN: rm -f %t.dir/test.d
// RUN: %clang -fsyntax-only -MD %s -o %t.dir/test.i
// RUN: test -f %t.dir/test.d
// RUN: FileCheck --check-prefix=TEST-I %s < %t.dir/test.d
// RUN: rm -f %t.dir/test.d
// RUN: %clang -M -MD %s -o %t.dir/test.i
// RUN: FileCheck --check-prefix=TEST-I %s < %t.dir/test.d
/// If the output file name does not have a suffix, just append `.d`.
// RUN: rm -f %t.dir/test.d
// RUN: %clang -fsyntax-only -MD %s -o %t.dir/test
// RUN: test -f %t.dir/test.d
// RUN: FileCheck --check-prefix=TEST %s < %t.dir/test.d
#warning "-M and -MM suppresses preprocessing, thus this warning shouldn't show up"
#warning "-M and -MM suppresses warnings, thus this warning shouldn't show up"
int main(void)
{
return 0;