clang: lib/Frontend/DependencyGraph.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

20#include "llvm/ADT/SetVector.h"

21#include "llvm/Support/GraphWriter.h"

22#include "llvm/Support/raw_ostream.h"

23

24using namespace clang;

25namespace DOT = llvm::DOT;

26

27namespace {

28class DependencyGraphCallback : public PPCallbacks {

29 const Preprocessor *PP;

30 std::string OutputFile;

31 std::string SysRoot;

32 llvm::SetVector AllFiles;

33 using DependencyMap =

34 llvm::DenseMap<FileEntryRef, SmallVector<FileEntryRef, 2>>;

35

36 DependencyMap Dependencies;

37

38private:

39 raw_ostream &writeNodeReference(raw_ostream &OS,

40 const FileEntry *Node);

41 void OutputGraphFile();

42

43public:

44 DependencyGraphCallback(const Preprocessor *_PP, StringRef OutputFile,

45 StringRef SysRoot)

46 : PP(_PP), OutputFile(OutputFile.str()), SysRoot(SysRoot.str()) {}

47

48 void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,

49 StringRef FileName, bool IsAngled,

50 CharSourceRange FilenameRange,

52 StringRef RelativePath, const Module *SuggestedModule,

53 bool ModuleImported,

55

56 void EmbedDirective(SourceLocation HashLoc, StringRef FileName, bool IsAngled,

58 const LexEmbedParametersResult &Params) override;

59

60 void EndOfMainFile() override {

61 OutputGraphFile();

62 }

63

64};

65}

66

68 StringRef SysRoot) {

69 PP.addPPCallbacks(std::make_unique(&PP, OutputFile,

70 SysRoot));

71}

72

73void DependencyGraphCallback::InclusionDirective(

76 StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule,

79 return;

80

83 SM.getFileEntryRefForID(SM.getFileID(SM.getExpansionLoc(HashLoc)));

84 if (!FromFile)

85 return;

86

87 Dependencies[*FromFile].push_back(*File);

88

89 AllFiles.insert(*File);

90 AllFiles.insert(*FromFile);

91}

92

93void DependencyGraphCallback::EmbedDirective(SourceLocation HashLoc, StringRef,

95 const LexEmbedParametersResult &) {

97 return;

98

101 SM.getFileEntryRefForID(SM.getFileID(SM.getExpansionLoc(HashLoc)));

102 if (!FromFile)

103 return;

104

105 Dependencies[*FromFile].push_back(*File);

106

107 AllFiles.insert(*File);

108 AllFiles.insert(*FromFile);

109}

110

111raw_ostream &

112DependencyGraphCallback::writeNodeReference(raw_ostream &OS,

113 const FileEntry *Node) {

114 OS << "header_" << Node->getUID();

115 return OS;

116}

117

118void DependencyGraphCallback::OutputGraphFile() {

119 std::error_code EC;

120 llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::OF_TextWithCRLF);

121 if (EC) {

123 << EC.message();

124 return;

125 }

126

127 OS << "digraph \"dependencies\" {\n";

128

129

130 for (unsigned I = 0, N = AllFiles.size(); I != N; ++I) {

131

132 OS.indent(2);

133 writeNodeReference(OS, AllFiles[I]);

134 OS << " [ shape=\"box\", label=\"";

135 StringRef FileName = AllFiles[I].getName();

136 FileName.consume_front(SysRoot);

137

138 OS << DOT::EscapeString(std::string(FileName)) << "\"];\n";

139 }

140

141

142 for (DependencyMap::iterator F = Dependencies.begin(),

143 FEnd = Dependencies.end();

144 F != FEnd; ++F) {

145 for (unsigned I = 0, N = F->second.size(); I != N; ++I) {

146 OS.indent(2);

147 writeNodeReference(OS, F->first);

148 OS << " -> ";

149 writeNodeReference(OS, F->second[I]);

150 OS << ";\n";

151 }

152 }

153 OS << "}\n";

154}

155

Defines the clang::FileManager interface and associated types.

llvm::MachO::FileType FileType

Defines the PPCallbacks interface.

Defines the clang::Preprocessor interface.

Defines the SourceManager interface.

Represents a character-granular source range.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

Describes a module or submodule.

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

void addPPCallbacks(std::unique_ptr< PPCallbacks > C)

SourceManager & getSourceManager() const

DiagnosticsEngine & getDiagnostics() const

Encodes a location in the source.

This class handles loading and caching of source files into memory.

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...

@ OS

Indicates that the tracking object is a descendant of a referenced-counted OSObject,...

The JSON file list parser is used to communicate input to InstallAPI.

CustomizableOptional< FileEntryRef > OptionalFileEntryRef

@ Module

Module linkage, which indicates that the entity can be referred to from other translation units withi...

void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile, StringRef SysRoot)

AttachDependencyGraphGen - Create a dependency graph generator, and attach it to the given preprocess...

Definition DependencyGraph.cpp:67