clang  10.0.0git
ModuleDepCollector.cpp
Go to the documentation of this file.
1 //===- ModuleDepCollector.cpp - 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 
11 
13 #include "clang/Lex/Preprocessor.h"
15 
16 using namespace clang;
17 using namespace tooling;
18 using namespace dependencies;
19 
21  FileChangeReason Reason,
23  FileID PrevFID) {
24  if (Reason != PPCallbacks::EnterFile)
25  return;
26 
27  SourceManager &SM = Instance.getSourceManager();
28 
29  // Dependency generation really does want to go all the way to the
30  // file entry for a source location to find out what is depended on.
31  // We do not want #line markers to affect dependency generation!
34  if (!File)
35  return;
36 
37  StringRef FileName =
38  llvm::sys::path::remove_leading_dotslash(File->getName());
39 
40  MDC.MainDeps.push_back(FileName);
41 }
42 
44  SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
45  bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
46  StringRef SearchPath, StringRef RelativePath, const Module *Imported,
47  SrcMgr::CharacteristicKind FileType) {
48  if (!File && !Imported) {
49  // This is a non-modular include that HeaderSearch failed to find. Add it
50  // here as `FileChanged` will never see it.
51  MDC.MainDeps.push_back(FileName);
52  }
53 
54  if (!Imported)
55  return;
56 
57  MDC.Deps[MDC.ContextHash + Imported->getTopLevelModule()->getFullModuleName()]
58  .ImportedByMainFile = true;
59  DirectDeps.insert(Imported->getTopLevelModule());
60 }
61 
63  FileID MainFileID = Instance.getSourceManager().getMainFileID();
64  MDC.MainFile =
65  Instance.getSourceManager().getFileEntryForID(MainFileID)->getName();
66 
67  for (const Module *M : DirectDeps) {
68  handleTopLevelModule(M);
69  }
70 
71  for (auto &&I : MDC.Deps)
72  MDC.Consumer.handleModuleDependency(I.second);
73 
75  for (auto &&I : MDC.MainDeps)
76  MDC.Consumer.handleFileDependency(Opts, I);
77 }
78 
79 void ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
80  assert(M == M->getTopLevelModule() && "Expected top level module!");
81 
82  auto ModI = MDC.Deps.insert(
83  std::make_pair(MDC.ContextHash + M->getFullModuleName(), ModuleDeps{}));
84 
85  if (!ModI.first->second.ModuleName.empty())
86  return;
87 
88  ModuleDeps &MD = ModI.first->second;
89 
90  const FileEntry *ModuleMap = Instance.getPreprocessor()
92  .getModuleMap()
94 
95  MD.ClangModuleMapFile = ModuleMap ? ModuleMap->getName() : "";
96  MD.ModuleName = M->getFullModuleName();
97  MD.ModulePCMPath = M->getASTFile()->getName();
98  MD.ContextHash = MDC.ContextHash;
100  MDC.Instance.getASTReader()->getModuleManager().lookup(M->getASTFile());
101  MDC.Instance.getASTReader()->visitInputFiles(
102  *MF, true, true, [&](const serialization::InputFile &IF, bool isSystem) {
103  MD.FileDeps.insert(IF.getFile()->getName());
104  });
105 
106  addAllSubmoduleDeps(M, MD);
107 }
108 
109 void ModuleDepCollectorPP::addAllSubmoduleDeps(const Module *M,
110  ModuleDeps &MD) {
111  addModuleDep(M, MD);
112 
113  for (const Module *SubM : M->submodules())
114  addAllSubmoduleDeps(SubM, MD);
115 }
116 
117 void ModuleDepCollectorPP::addModuleDep(const Module *M, ModuleDeps &MD) {
118  for (const Module *Import : M->Imports) {
119  if (Import->getTopLevelModule() != M->getTopLevelModule()) {
120  MD.ClangModuleDeps.insert(Import->getTopLevelModuleName());
121  handleTopLevelModule(Import->getTopLevelModule());
122  }
123  }
124 }
125 
128  : Instance(I), Consumer(C), ContextHash(I.getInvocation().getModuleHash()) {
129 }
130 
132  PP.addPPCallbacks(std::make_unique<ModuleDepCollectorPP>(Instance, *this));
133 }
134 
const FileEntry * getFile() const
Definition: ModuleFile.h:94
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Definition: Module.h:457
const FileEntry * getASTFile() const
The serialized AST file for this module, if one was created.
Definition: Module.h:472
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Definition: SourceManager.h:77
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:652
IntrusiveRefCntPtr< ASTReader > getASTReader() const
Optional< FileEntryRef > getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
Token - This structure provides full information about a lexed token.
Definition: Token.h:34
Describes a module or submodule.
Definition: Module.h:64
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
Definition: Module.h:467
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Definition: Module.cpp:213
HeaderSearch & getHeaderSearchInfo() const
Definition: Preprocessor.h:912
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
const FileEntry * getContainingModuleMapFile(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
Definition: ModuleMap.cpp:1224
virtual void handleModuleDependency(ModuleDeps MD)=0
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
Definition: Module.h:288
Represents a character-granular source range.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
Defines the clang::Preprocessor interface.
Information about a module that has been loaded by the ASTReader.
Definition: ModuleFile.h:107
const SourceManager & SM
Definition: Format.cpp:1685
void EndOfMainFile() override
Callback invoked when the end of the main file is reached.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Encodes a location in the source.
StringRef getName() const
Definition: FileManager.h:102
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:78
void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID) override
Callback invoked whenever a source file is entered or exited.
DependencyOutputOptions - Options for controlling the compiler dependency file generation.
The input file that has been loaded from this AST file, along with bools indicating whether this was ...
Definition: ModuleFile.h:65
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Dataflow Directional Tag Classes.
llvm::iterator_range< submodule_iterator > submodules()
Definition: Module.h:568
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:340
FileID getMainFileID() const
Returns the FileID of the main source file.
SourceManager & getSourceManager() const
Return the current source manager.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override
Callback invoked whenever an inclusion directive of any kind (#include, #import, etc.) has been processed, regardless of whether the inclusion will actually result in an inclusion.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
void attachToPreprocessor(Preprocessor &PP) override
ModuleDepCollector(CompilerInstance &I, DependencyConsumer &C)
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
Definition: SourceManager.h:82
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
This class handles loading and caching of source files into memory.
virtual void handleFileDependency(const DependencyOutputOptions &Opts, StringRef Filename)=0
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:128