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(File->getName());
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 std::make_unique<DepCollectorMMCallbacks>(*
this));
177 R.
addListener(std::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) {
196 if (AddMissingHeaderDeps)
203 bool IsSystem,
bool IsModuleFile,
207 if (AddMissingHeaderDeps)
209 SeenMissingHeader =
true;
212 if (IsModuleFile && !IncludeModuleFiles)
218 if (IncludeSystemHeaders)
280 llvm::sys::path::native(Filename.str(), NativePath);
286 if (NativePath.find_first_of(
" #${}^!") != StringRef::npos)
287 OS <<
'\"' << NativePath <<
'\"';
293 for (
unsigned i = 0, e = NativePath.size(); i != e; ++i) {
294 if (NativePath[i] ==
'#')
296 else if (NativePath[i] ==
' ') {
299 while (j > 0 && NativePath[--j] ==
'\\')
301 }
else if (NativePath[i] ==
'$')
308 if (SeenMissingHeader) {
314 llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::OF_Text);
316 Diags.
Report(diag::err_fe_error_opening) << OutputFile << EC.message();
328 const unsigned MaxColumns = 75;
329 unsigned Columns = 0;
331 for (StringRef
Target : Targets) {
332 unsigned N =
Target.size();
335 }
else if (Columns + N + 2 > MaxColumns) {
352 for (StringRef File : Files) {
356 unsigned N = File.size();
357 if (Columns + (N + 1) + 2 > MaxColumns) {
368 if (PhonyTarget && !Files.empty()) {
370 for (
auto I = Files.begin(), E = Files.end(); I != E; ++I) {
371 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.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
const StringRef getName() const
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.
Optional< FileEntryRef > getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
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.
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...
ArrayRef< std::string > getDependencies() const
static bool isSpecialFilename(StringRef Filename)
Represents a character-granular source range.
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.