21 #include "llvm/ADT/SetVector.h"
22 #include "llvm/Support/GraphWriter.h"
23 #include "llvm/Support/raw_ostream.h"
25 using namespace clang;
26 namespace DOT = llvm::DOT;
29 class DependencyGraphCallback :
public PPCallbacks {
31 std::string OutputFile;
33 llvm::SetVector<const FileEntry *> AllFiles;
37 DependencyMap Dependencies;
40 raw_ostream &writeNodeReference(raw_ostream &OS,
42 void OutputGraphFile();
45 DependencyGraphCallback(
const Preprocessor *_PP, StringRef OutputFile,
47 : PP(_PP), OutputFile(OutputFile.str()), SysRoot(SysRoot.str()) { }
50 StringRef FileName,
bool IsAngled,
52 StringRef SearchPath, StringRef RelativePath,
53 const Module *Imported)
override;
55 void EndOfMainFile()
override {
64 PP.
addPPCallbacks(llvm::make_unique<DependencyGraphCallback>(&PP, OutputFile,
68 void DependencyGraphCallback::InclusionDirective(
SourceLocation HashLoc,
69 const Token &IncludeTok,
75 StringRef RelativePath,
86 Dependencies[FromFile].push_back(File);
88 AllFiles.insert(File);
89 AllFiles.insert(FromFile);
93 DependencyGraphCallback::writeNodeReference(raw_ostream &OS,
95 OS <<
"header_" << Node->
getUID();
99 void DependencyGraphCallback::OutputGraphFile() {
101 llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_Text);
103 PP->getDiagnostics().Report(diag::err_fe_error_opening) << OutputFile
108 OS <<
"digraph \"dependencies\" {\n";
111 for (
unsigned I = 0, N = AllFiles.size(); I != N; ++I) {
114 writeNodeReference(OS, AllFiles[I]);
115 OS <<
" [ shape=\"box\", label=\"";
116 StringRef FileName = AllFiles[I]->getName();
117 if (FileName.startswith(SysRoot))
118 FileName = FileName.substr(SysRoot.size());
120 OS << DOT::EscapeString(FileName)
125 for (DependencyMap::iterator F = Dependencies.begin(),
126 FEnd = Dependencies.end();
128 for (
unsigned I = 0, N = F->second.size(); I != N; ++I) {
130 writeNodeReference(OS, F->first);
132 writeNodeReference(OS, F->second[I]);
Defines the clang::FileManager interface and associated types.
Defines the SourceManager interface.
This interface provides a way to observe the actions of the preprocessor as it does its thing...
Describes a module or submodule.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
Represents a character-granular source range.
Defines the clang::Preprocessor interface.
Record the location of an inclusion directive, such as an #include or #import statement.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
Cached information about one file (either on disk or in the virtual file system). ...
void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile, StringRef SysRoot)
ast_type_traits::DynTypedNode Node
Defines the PPCallbacks interface.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
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.