mirror of
https://github.com/intel/llvm.git
synced 2026-01-24 00:20:25 +08:00
Implement -MG. Fixes PR9613
llvm-svn: 134996
This commit is contained in:
@@ -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">;
|
||||
|
||||
@@ -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">;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
5
clang/test/Driver/mg.c
Normal file
5
clang/test/Driver/mg.c
Normal file
@@ -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"
|
||||
Reference in New Issue
Block a user