23 #include "llvm/ADT/StringSet.h"
24 #include "llvm/Support/FileSystem.h"
25 #include "llvm/Support/Path.h"
26 #include "llvm/Support/raw_ostream.h"
29 using namespace clang;
32 struct DepCollectorPPCallbacks :
public PPCallbacks {
36 : DepCollector(L), PP(PP) {}
38 void LexedFileChanged(
FileID FID, LexedFileChangeReason Reason,
47 if (std::optional<StringRef>
Filename =
50 llvm::sys::path::remove_leading_dotslash(*
Filename),
58 llvm::sys::path::remove_leading_dotslash(SkippedFile.
getName());
66 StringRef FileName,
bool IsAngled,
69 StringRef RelativePath,
const Module *SuggestedModule,
86 llvm::sys::path::remove_leading_dotslash(
File->getName());
93 void EndOfMainFile()
override {
103 bool IsSystem)
override {
116 : DepCollector(L), FileMgr(FileMgr) {}
117 bool needsInputFileVisitation()
override {
return true; }
118 bool needsSystemInputFileVisitation()
override {
121 void visitModuleFile(StringRef
Filename,
127 bool visitInputFile(StringRef
Filename,
bool IsSystem,
128 bool IsOverridden,
bool IsExplicitModule)
override {
129 if (IsOverridden || IsExplicitModule)
146 bool FromModule,
bool IsSystem,
154 StringRef SearchPath;
158 llvm::sys::path::native(TmpPath);
159 std::transform(TmpPath.begin(), TmpPath.end(), TmpPath.begin(), ::tolower);
160 SearchPath = TmpPath.str();
165 if (Seen.insert(SearchPath).second) {
166 Dependencies.push_back(std::string(
Filename));
177 bool IsSystem,
bool IsModuleFile,
185 PP.
addPPCallbacks(std::make_unique<DepCollectorPPCallbacks>(*
this, PP));
187 std::make_unique<DepCollectorMMCallbacks>(*
this));
191 std::make_unique<DepCollectorASTListener>(*
this, R.
getFileManager()));
196 : OutputFile(Opts.OutputFile),
197 DependencyFilter(Opts.DependencyFilter), Targets(Opts.Targets),
198 IncludeSystemHeaders(Opts.IncludeSystemHeaders),
199 PhonyTarget(Opts.UsePhonyTargets),
200 AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), SeenMissingHeader(
false),
201 IncludeModuleFiles(Opts.IncludeModuleFiles),
202 OutputFormat(Opts.OutputFormat), InputFileIndex(0) {
203 for (
const auto &ExtraDep : Opts.
ExtraDeps) {
211 if (AddMissingHeaderDeps)
218 bool IsSystem,
bool IsModuleFile,
222 if (AddMissingHeaderDeps)
224 SeenMissingHeader =
true;
227 if (IsModuleFile && !IncludeModuleFiles)
233 if (DependencyFilter.size() &&
234 DependencyFilter.compare(0, DependencyFilter.size(),
Filename.data(),
235 DependencyFilter.size()) == 0)
239 if (IncludeSystemHeaders)
301 llvm::sys::path::native(
Filename.str(), NativePath);
307 if (NativePath.find_first_of(
" #${}^!") != StringRef::npos)
308 OS <<
'\"' << NativePath <<
'\"';
314 for (
unsigned i = 0, e = NativePath.size(); i != e; ++i) {
315 if (NativePath[i] ==
'#')
317 else if (NativePath[i] ==
' ') {
320 while (j > 0 && NativePath[--j] ==
'\\')
322 }
else if (NativePath[i] ==
'$')
329 if (SeenMissingHeader) {
335 llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::OF_TextWithCRLF);
337 Diags.
Report(diag::err_fe_error_opening) << OutputFile << EC.message();
349 const unsigned MaxColumns = 75;
350 unsigned Columns = 0;
352 for (StringRef
Target : Targets) {
353 unsigned N =
Target.size();
356 }
else if (Columns + N + 2 > MaxColumns) {
373 for (StringRef
File : Files) {
374 if (
File ==
"<stdin>")
379 unsigned N =
File.size();
380 if (Columns + (N + 1) + 2 > MaxColumns) {
391 if (PhonyTarget && !Files.empty()) {
393 for (
auto I = Files.begin(), E = Files.end(); I != E; ++I) {
394 if (Index++ == InputFileIndex)
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...
static bool isSpecialFilename(StringRef Filename)
Defines the clang::FileManager interface and associated types.
llvm::MachO::FileType FileType
llvm::MachO::Target Target
Defines the PPCallbacks interface.
Defines the clang::Preprocessor interface.
Defines the SourceManager interface.
Abstract interface for callback invocations by the ASTReader.
Reads an AST files chain containing the contents of a translation unit.
FileManager & getFileManager() const
void addListener(std::unique_ptr< ASTReaderListener > L)
Add an AST callback listener.
Represents a character-granular source range.
An interface for collecting the dependencies of a compilation.
virtual 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.
bool addDependency(StringRef Filename)
Return true if the filename was added to the list of dependencies, false otherwise.
virtual void attachToPreprocessor(Preprocessor &PP)
virtual void finishedMainFile(DiagnosticsEngine &Diags)
Called when the end of the main file is reached.
ArrayRef< std::string > getDependencies() const
virtual void attachToASTReader(ASTReader &R)
virtual ~DependencyCollector()
virtual bool needSystemDependencies()
Return true if system files should be passed to sawDependency().
virtual bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem, bool IsModuleFile, bool IsMissing)
Called when a new file is seen.
void outputDependencyFile(llvm::raw_ostream &OS)
void attachToPreprocessor(Preprocessor &PP) override
void finishedMainFile(DiagnosticsEngine &Diags) override
Called when the end of the main file is reached.
bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem, bool IsModuleFile, bool IsMissing) final
Called when a new file is seen.
DependencyFileGenerator(const DependencyOutputOptions &Opts)
DependencyOutputOptions - Options for controlling the compiler dependency file generation.
std::vector< std::pair< std::string, ExtraDepKind > > ExtraDeps
A list of extra dependencies (filename and kind) to be used for every target.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
StringRef getName() const
The name of this FileEntry.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
Record the location of an inclusion directive, such as an #include or #import statement.
A mechanism to observe the actions of the module map parser as it reads module map files.
void addModuleMapCallbacks(std::unique_ptr< ModuleMapCallbacks > Callback)
Add a module map callback.
Describes a module or submodule.
This interface provides a way to observe the actions of the preprocessor as it does its thing.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
SourceManager & getSourceManager() const
HeaderSearch & getHeaderSearchInfo() const
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
DiagnosticsEngine & getDiagnostics() const
void SetSuppressIncludeNotFoundError(bool Suppress)
Encodes a location in the source.
std::optional< StringRef > getNonBuiltinFilenameForID(FileID FID) const
Returns the filename for the provided FileID, unless it's a built-in buffer that's not represented by...
Token - This structure provides full information about a lexed token.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
ModuleKind
Specifies the kind of module that has been loaded.
The JSON file list parser is used to communicate input to InstallAPI.
DependencyOutputFormat
DependencyOutputFormat - Format for the compiler dependency file.