aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2011-07-12 19:35:15 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2011-07-12 19:35:15 +0000
commitbb52786da8d055568eef6e5694288c1258bc8c2a (patch)
treed873a59365c239ada903f2dd16ba184ec07487b0
parent0d516767a3af70538a40a297577960034e6ad66f (diff)
Implement -MG. Fixes PR9613
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134996 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td2
-rw-r--r--include/clang/Driver/CC1Options.td1
-rw-r--r--include/clang/Frontend/DependencyOutputOptions.h2
-rw-r--r--lib/Driver/Tools.cpp10
-rw-r--r--lib/Frontend/CompilerInvocation.cpp1
-rw-r--r--lib/Frontend/DependencyFile.cpp39
-rw-r--r--lib/Lex/PPDirectives.cpp9
-rw-r--r--lib/Lex/Pragma.cpp2
-rw-r--r--test/Driver/mg.c5
10 files changed, 64 insertions, 9 deletions
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 409c6a2016..e33b67ef7a 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -86,6 +86,8 @@ def err_drv_objc_gc_arr : Error<
"cannot specify both '-fobjc-arc' and '%0'">;
def err_arc_nonfragile_abi : Error<
"-fobjc-arc is not supported with fragile abi">;
+def err_drv_mg_requires_m_or_mm : Error<
+ "option '-MG' requires '-M' or '-MM'">;
def warn_c_kext : Warning<
"ignoring -fapple-kext which is valid for c++ and objective-c++ only">;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 3514ccace2..38d6a80016 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -178,7 +178,7 @@ def ext_empty_fnmacro_arg : Extension<
def err_pp_invalid_directive : Error<"invalid preprocessing directive">;
def err_pp_hash_error : Error<"#error%0">;
-def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal;
+def warn_pp_file_not_found : Warning<"'%0' file not found">, DefaultFatal;
def err_pp_error_opening_file : Error<
"error opening file '%0': %1">, DefaultFatal;
def err_pp_empty_filename : Error<"empty filename">;
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 6befc8cd07..8cadbe92da 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -208,6 +208,7 @@ def MQ : Separate<"-MQ">, HelpText<"Specify target to quote for dependency">;
def MT : Separate<"-MT">, HelpText<"Specify target for dependency">;
def MP : Flag<"-MP">,
HelpText<"Create phony target for each dependency (other than main file)">;
+def MG : Flag<"-MG">, HelpText<"Add missing headers to dependency list">;
//===----------------------------------------------------------------------===//
// Diagnostic Options
diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h
index 35aa6c6aac..1e22c227fc 100644
--- a/include/clang/Frontend/DependencyOutputOptions.h
+++ b/include/clang/Frontend/DependencyOutputOptions.h
@@ -24,6 +24,7 @@ public:
unsigned UsePhonyTargets : 1; ///< Include phony targets for each
/// dependency, which can avoid some 'make'
/// problems.
+ unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
/// The file to write dependency output to.
std::string OutputFile;
@@ -43,6 +44,7 @@ public:
IncludeSystemHeaders = 0;
ShowHeaderIncludes = 0;
UsePhonyTargets = 0;
+ AddMissingHeaderDeps = 0;
}
};
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 9b3e49480e..eb17609d6c 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -242,6 +242,13 @@ void Clang::AddPreprocessingOptions(const Driver &D,
CmdArgs.push_back("-sys-header-deps");
}
+ if (Args.hasArg(options::OPT_MG)) {
+ if (!A || A->getOption().matches(options::OPT_MD) ||
+ A->getOption().matches(options::OPT_MMD))
+ D.Diag(clang::diag::err_drv_mg_requires_m_or_mm);
+ CmdArgs.push_back("-MG");
+ }
+
Args.AddLastArg(CmdArgs, options::OPT_MP);
// Convert all -MQ <target> args to -MT <quoted target>
@@ -1354,8 +1361,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
types::ID InputType = Inputs[0].getType();
if (!Args.hasArg(options::OPT_fallow_unsupported)) {
Arg *Unsupported;
- if ((Unsupported = Args.getLastArg(options::OPT_MG)) ||
- (Unsupported = Args.getLastArg(options::OPT_iframework)))
+ if ((Unsupported = Args.getLastArg(options::OPT_iframework)))
D.Diag(clang::diag::err_drv_clang_unsupported)
<< Unsupported->getOption().getName();
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 02a5088f93..05b3377b3e 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1048,6 +1048,7 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file);
+ Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG);
}
static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index dde3454aba..1edd09b06c 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -17,6 +17,7 @@
#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Lex/DirectoryLookup.h"
+#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/StringSet.h"
@@ -34,9 +35,11 @@ class DependencyFileCallback : public PPCallbacks {
llvm::raw_ostream *OS;
bool IncludeSystemHeaders;
bool PhonyTarget;
+ bool AddMissingHeaderDeps;
private:
bool FileMatchesDepCriteria(const char *Filename,
SrcMgr::CharacteristicKind FileType);
+ void AddFilename(llvm::StringRef Filename);
void OutputDependencyFile();
public:
@@ -45,10 +48,19 @@ public:
const DependencyOutputOptions &Opts)
: PP(_PP), Targets(Opts.Targets), OS(_OS),
IncludeSystemHeaders(Opts.IncludeSystemHeaders),
- PhonyTarget(Opts.UsePhonyTargets) {}
+ PhonyTarget(Opts.UsePhonyTargets),
+ AddMissingHeaderDeps(Opts.AddMissingHeaderDeps) {}
virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType);
+ virtual void InclusionDirective(SourceLocation HashLoc,
+ const Token &IncludeTok,
+ llvm::StringRef FileName,
+ bool IsAngled,
+ const FileEntry *File,
+ SourceLocation EndLoc,
+ llvm::StringRef SearchPath,
+ llvm::StringRef RelativePath);
virtual void EndOfMainFile() {
OutputDependencyFile();
@@ -73,6 +85,16 @@ void clang::AttachDependencyFileGen(Preprocessor &PP,
return;
}
+ // Disable the "file not found" diagnostic if the -MG option was given.
+ // FIXME: Ideally this would live in the driver, but we don't have the ability
+ // to remap individual diagnostics there without creating a DiagGroup, in
+ // which case we would need to prevent the group name from showing up in
+ // diagnostics.
+ if (Opts.AddMissingHeaderDeps) {
+ PP.getDiagnostics().setDiagnosticMapping(diag::warn_pp_file_not_found,
+ diag::MAP_IGNORE, SourceLocation());
+ }
+
PP.addPPCallbacks(new DependencyFileCallback(&PP, OS, Opts));
}
@@ -116,7 +138,22 @@ void DependencyFileCallback::FileChanged(SourceLocation Loc,
Filename = Filename.substr(1);
}
+ AddFilename(Filename);
+}
+
+void DependencyFileCallback::InclusionDirective(SourceLocation HashLoc,
+ const Token &IncludeTok,
+ llvm::StringRef FileName,
+ bool IsAngled,
+ const FileEntry *File,
+ SourceLocation EndLoc,
+ llvm::StringRef SearchPath,
+ llvm::StringRef RelativePath) {
+ if (AddMissingHeaderDeps && !File)
+ AddFilename(FileName);
+}
+void DependencyFileCallback::AddFilename(llvm::StringRef Filename) {
if (FilesSet.insert(Filename))
Files.push_back(Filename);
}
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index efa188f752..4af5fabe5c 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -1180,16 +1180,17 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
const FileEntry *File = LookupFile(
Filename, isAngled, LookupFrom, CurDir,
Callbacks ? &SearchPath : NULL, Callbacks ? &RelativePath : NULL);
- if (File == 0) {
- Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
- return;
- }
// Notify the callback object that we've seen an inclusion directive.
if (Callbacks)
Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled, File,
End, SearchPath, RelativePath);
+ if (File == 0) {
+ Diag(FilenameTok, diag::warn_pp_file_not_found) << Filename;
+ return;
+ }
+
// The #included file will be considered to be a system header if either it is
// in a system include directory, or if the #includer is a system include
// header.
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index bd2ac1b6fb..e6b28c1331 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -368,7 +368,7 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
const DirectoryLookup *CurDir;
const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir, NULL, NULL);
if (File == 0) {
- Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
+ Diag(FilenameTok, diag::warn_pp_file_not_found) << Filename;
return;
}
diff --git a/test/Driver/mg.c b/test/Driver/mg.c
new file mode 100644
index 0000000000..4f438142f4
--- /dev/null
+++ b/test/Driver/mg.c
@@ -0,0 +1,5 @@
+// RUN: %clang -M -MG -include nonexistent-preinclude.h %s > %t
+// RUN: fgrep nonexistent-preinclude.h %t
+// RUN: fgrep nonexistent-ppinclude.h %t
+
+#include "nonexistent-ppinclude.h"