1 //===- ModuleDepCollector.h - Callbacks to collect deps ---------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_MODULE_DEP_COLLECTOR_H
11 #define LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_MODULE_DEP_COLLECTOR_H
12 
13 #include "clang/Basic/LLVM.h"
14 #include "clang/Basic/SourceManager.h"
15 #include "clang/Frontend/Utils.h"
16 #include "clang/Lex/HeaderSearch.h"
17 #include "clang/Lex/PPCallbacks.h"
18 #include "clang/Serialization/ASTReader.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/StringSet.h"
21 #include "llvm/Support/raw_ostream.h"
22 
23 #include <string>
24 
25 namespace clang {
26 namespace tooling {
27 namespace dependencies {
28 
29 class DependencyConsumer;
30 
31 struct ModuleDeps {
32   std::string ModuleName;
33   std::string ClangModuleMapFile;
34   std::string ModulePCMPath;
35   std::string ContextHash;
36   llvm::StringSet<> FileDeps;
37   llvm::StringSet<> ClangModuleDeps;
38   bool ImportedByMainFile = false;
39 };
40 
41 class ModuleDepCollector;
42 
43 class ModuleDepCollectorPP final : public PPCallbacks {
44 public:
45   ModuleDepCollectorPP(CompilerInstance &I, ModuleDepCollector &MDC)
46       : Instance(I), MDC(MDC) {}
47 
48   void FileChanged(SourceLocation Loc, FileChangeReason Reason,
49                    SrcMgr::CharacteristicKind FileType,
50                    FileID PrevFID) override;
51   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
52                           StringRef FileName, bool IsAngled,
53                           CharSourceRange FilenameRange, const FileEntry *File,
54                           StringRef SearchPath, StringRef RelativePath,
55                           const Module *Imported,
56                           SrcMgr::CharacteristicKind FileType) override;
57 
58   void EndOfMainFile() override;
59 
60 private:
61   CompilerInstance &Instance;
62   ModuleDepCollector &MDC;
63   llvm::DenseSet<const Module *> DirectDeps;
64 
65   void handleTopLevelModule(const Module *M);
66   void addAllSubmoduleDeps(const Module *M, ModuleDeps &MD);
67   void addModuleDep(const Module *M, ModuleDeps &MD);
68 
69   void addDirectDependencies(const Module *Mod);
70 };
71 
72 class ModuleDepCollector final : public DependencyCollector {
73 public:
74   ModuleDepCollector(CompilerInstance &I, DependencyConsumer &C);
75 
76   void attachToPreprocessor(Preprocessor &PP) override;
77   void attachToASTReader(ASTReader &R) override;
78 
79 private:
80   friend ModuleDepCollectorPP;
81 
82   CompilerInstance &Instance;
83   DependencyConsumer &Consumer;
84   std::string MainFile;
85   std::string ContextHash;
86   std::vector<std::string> MainDeps;
87   std::unordered_map<std::string, ModuleDeps> Deps;
88 };
89 
90 } // end namespace dependencies
91 } // end namespace tooling
92 } // end namespace clang
93 
94 #endif // LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_MODULE_DEP_COLLECTOR_H
95