23 #include "llvm/ADT/StringSet.h" 24 #include "llvm/ADT/StringSwitch.h" 25 #include "llvm/Support/FileSystem.h" 26 #include "llvm/Support/Path.h" 27 #include "llvm/Support/raw_ostream.h" 29 using namespace clang;
32 struct DepCollectorPPCallbacks :
public PPCallbacks {
38 : DepCollector(L), SM(SM), Diags(Diags) {}
55 llvm::sys::path::remove_leading_dotslash(FE->
getName());
62 void FileSkipped(
const FileEntry &SkippedFile,
const Token &FilenameTok,
65 llvm::sys::path::remove_leading_dotslash(SkippedFile.
getName());
73 StringRef FileName,
bool IsAngled,
75 StringRef SearchPath, StringRef RelativePath,
85 void HasInclude(
SourceLocation Loc, StringRef SpelledFilename,
bool IsAngled,
91 llvm::sys::path::remove_leading_dotslash(File->
getName());
106 bool IsSystem)
override {
107 StringRef Filename = Entry.
getName();
118 bool needsInputFileVisitation()
override {
return true; }
119 bool needsSystemInputFileVisitation()
override {
122 void visitModuleFile(StringRef Filename,
128 bool visitInputFile(StringRef Filename,
bool IsSystem,
129 bool IsOverridden,
bool IsExplicitModule)
override {
130 if (IsOverridden || IsExplicitModule)
141 bool IsSystem,
bool IsModuleFile,
143 if (sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing))
144 addDependency(Filename);
148 if (Seen.insert(Filename).second) {
149 Dependencies.push_back(Filename);
156 return llvm::StringSwitch<bool>(
Filename)
157 .Case(
"<built-in>",
true)
158 .Case(
"<stdin>",
true)
163 bool IsSystem,
bool IsModuleFile,
166 (needSystemDependencies() || !IsSystem);
174 llvm::make_unique<DepCollectorMMCallbacks>(*
this));
177 R.
addListener(llvm::make_unique<DepCollectorASTListener>(*
this));
182 : OutputFile(Opts.OutputFile), Targets(Opts.Targets),
183 IncludeSystemHeaders(Opts.IncludeSystemHeaders),
184 PhonyTarget(Opts.UsePhonyTargets),
185 AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), SeenMissingHeader(
false),
186 IncludeModuleFiles(Opts.IncludeModuleFiles),
187 OutputFormat(Opts.OutputFormat), InputFileIndex(0) {
188 for (
const auto &ExtraDep : Opts.
ExtraDeps) {
195 if (Targets.empty()) {
201 if (AddMissingHeaderDeps)
208 bool IsSystem,
bool IsModuleFile,
212 if (AddMissingHeaderDeps)
214 SeenMissingHeader =
true;
217 if (IsModuleFile && !IncludeModuleFiles)
223 if (IncludeSystemHeaders)
285 llvm::sys::path::native(Filename.str(), NativePath);
291 if (NativePath.find_first_of(
" #${}^!") != StringRef::npos)
292 OS <<
'\"' << NativePath <<
'\"';
298 for (
unsigned i = 0, e = NativePath.size();
i != e; ++
i) {
299 if (NativePath[
i] ==
'#')
301 else if (NativePath[
i] ==
' ') {
304 while (j > 0 && NativePath[--j] ==
'\\')
306 }
else if (NativePath[
i] ==
'$')
313 if (SeenMissingHeader) {
319 llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_Text);
321 Diags.
Report(diag::err_fe_error_opening) << OutputFile << EC.message();
333 const unsigned MaxColumns = 75;
334 unsigned Columns = 0;
336 for (StringRef
Target : Targets) {
337 unsigned N =
Target.size();
340 }
else if (Columns + N + 2 > MaxColumns) {
357 for (StringRef File : Files) {
361 unsigned N = File.size();
362 if (Columns + (N + 1) + 2 > MaxColumns) {
373 if (PhonyTarget && !Files.empty()) {
375 for (
auto I = Files.begin(), E = Files.end(); I != E; ++I) {
376 if (Index++ == InputFileIndex)
DependencyFileGenerator(const DependencyOutputOptions &Opts)
Defines the clang::FileManager interface and associated types.
An interface for collecting the dependencies of a compilation.
Defines the SourceManager interface.
void finishedMainFile(DiagnosticsEngine &Diags) override
Called when the end of the main file is reached.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
This interface provides a way to observe the actions of the preprocessor as it does its thing...
bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem, bool IsModuleFile, bool IsMissing) final override
Called when a new file is seen.
virtual bool needSystemDependencies()
Return true if system files should be passed to sawDependency().
Token - This structure provides full information about a lexed token.
void outputDependencyFile(llvm::raw_ostream &OS)
Describes a module or submodule.
void SetSuppressIncludeNotFoundError(bool Suppress)
virtual void attachToASTReader(ASTReader &R)
HeaderSearch & getHeaderSearchInfo() const
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
Concrete class used by the front-end to report problems and issues.
void addModuleMapCallbacks(std::unique_ptr< ModuleMapCallbacks > Callback)
Add a module map callback.
ModuleKind
Specifies the kind of module that has been loaded.
void maybeAddDependency(StringRef Filename, bool FromModule, bool IsSystem, bool IsModuleFile, bool IsMissing)
Add a dependency Filename if it has not been seen before and sawDependency() returns true...
ArrayRef< std::string > getDependencies() const
static bool isSpecialFilename(StringRef Filename)
Represents a character-granular source range.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
bool addDependency(StringRef Filename)
Return true if the filename was added to the list of dependencies, false otherwise.
Defines the clang::Preprocessor interface.
A mechanism to observe the actions of the module map parser as it reads module map files...
Record the location of an inclusion directive, such as an #include or #import statement.
SourceManager & getSourceManager() const
void addListener(std::unique_ptr< ASTReaderListener > L)
Add an AST callback listener.
Encodes a location in the source.
StringRef getName() const
Cached information about one file (either on disk or in the virtual file system). ...
DependencyOutputOptions - Options for controlling the compiler dependency file generation.
std::vector< std::string > ExtraDeps
A list of filenames to be used as extra dependencies for every target.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Dataflow Directional Tag Classes.
virtual void finishedMainFile(DiagnosticsEngine &Diags)
Called when the end of the main file is reached.
Reads an AST files chain containing the contents of a translation unit.
void attachToPreprocessor(Preprocessor &PP) override
virtual ~DependencyCollector()
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
Abstract interface for callback invocations by the ASTReader.
virtual void attachToPreprocessor(Preprocessor &PP)
Defines the PPCallbacks interface.
DiagnosticsEngine & getDiagnostics() const
virtual bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem, bool IsModuleFile, bool IsMissing)
Called when a new file is seen.
static void PrintFilename(raw_ostream &OS, StringRef Filename, DependencyOutputFormat OutputFormat)
Print the filename, with escaping or quoting that accommodates the three most likely tools that use d...
DependencyOutputFormat
DependencyOutputFormat - Format for the compiler dependency file.
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
This class handles loading and caching of source files into memory.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.