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
10 #include "clang/Tooling/DependencyScanning/ModuleDepCollector.h"
11
12 #include "clang/Frontend/CompilerInstance.h"
13 #include "clang/Lex/Preprocessor.h"
14 #include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h"
15
16 using namespace clang;
17 using namespace tooling;
18 using namespace dependencies;
19
20 void ModuleDepCollectorPP::FileChanged(SourceLocation Loc,
21 FileChangeReason Reason,
22 SrcMgr::CharacteristicKind FileType,
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!
32 Optional<FileEntryRef> File =
33 SM.getFileEntryRefForID(SM.getFileID(SM.getExpansionLoc(Loc)));
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
43 void ModuleDepCollectorPP::InclusionDirective(
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
62 void ModuleDepCollectorPP::EndOfMainFile() {
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
74 DependencyOutputOptions Opts;
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()
91 .getHeaderSearchInfo()
92 .getModuleMap()
93 .getContainingModuleMapFile(M);
94
95 MD.ClangModuleMapFile = ModuleMap ? ModuleMap->getName() : "";
96 MD.ModuleName = M->getFullModuleName();
97 MD.ModulePCMPath = M->getASTFile()->getName();
98 MD.ContextHash = MDC.ContextHash;
99 serialization::ModuleFile *MF =
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
126 ModuleDepCollector::ModuleDepCollector(CompilerInstance &I,
127 DependencyConsumer &C)
128 : Instance(I), Consumer(C), ContextHash(I.getInvocation().getModuleHash()) {
129 }
130
131 void ModuleDepCollector::attachToPreprocessor(Preprocessor &PP) {
132 PP.addPPCallbacks(std::make_unique<ModuleDepCollectorPP>(Instance, *this));
133 }
134
135 void ModuleDepCollector::attachToASTReader(ASTReader &R) {}
clang::serialization::InputFile::getFile
const FileEntry * getFile() const
Definition: ModuleFile.h:94
clang::Module::getTopLevelModule
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Definition: Module.h:457
clang::PPCallbacks::EnterFile
Definition: PPCallbacks.h:40
clang::Module::getASTFile
const FileEntry * getASTFile() const
The serialized AST file for this module, if one was created.
Definition: Module.h:472
clang::SrcMgr::CharacteristicKind
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Definition: SourceManager.h:77
clang::HeaderSearch::getModuleMap
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:652
clang::CompilerInstance::getASTReader
IntrusiveRefCntPtr< ASTReader > getASTReader() const
Definition: CompilerInstance.cpp:138
llvm::Optional
Definition: LLVM.h:37
clang::SourceManager::getFileEntryRefForID
Optional< FileEntryRef > getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
Definition: SourceManager.h:1028
clang::tooling::dependencies::ModuleDeps::ModuleName
std::string ModuleName
Definition: ModuleDepCollector.h:32
clang::tooling::dependencies::ModuleDeps::FileDeps
llvm::StringSet FileDeps
Definition: ModuleDepCollector.h:36
clang::Token
Token - This structure provides full information about a lexed token.
Definition: Token.h:34
clang::Module
Describes a module or submodule.
Definition: Module.h:64
clang::Module::getTopLevelModuleName
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
Definition: Module.h:467
clang::Module::getFullModuleName
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
clang::Preprocessor::getHeaderSearchInfo
HeaderSearch & getHeaderSearchInfo() const
Definition: Preprocessor.h:912
clang::SourceManager::getExpansionLoc
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
Definition: SourceManager.h:1159
clang::ModuleMap::getContainingModuleMapFile
const FileEntry * getContainingModuleMapFile(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
Definition: ModuleMap.cpp:1224
CompilerInstance.h
clang::tooling::dependencies::DependencyConsumer
Definition: DependencyScanningWorker.h:33
clang::tooling::dependencies::DependencyConsumer::handleModuleDependency
virtual void handleModuleDependency(ModuleDeps MD)=0
clang::Module::Imports
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
Definition: Module.h:288
clang::tooling::dependencies::ModuleDeps
Definition: ModuleDepCollector.h:31
clang::ModuleMap
Definition: ModuleMap.h:75
clang::CharSourceRange
Represents a character-granular source range.
Definition: SourceLocation.h:250
clang::tooling::dependencies::ModuleDeps::ClangModuleDeps
llvm::StringSet ClangModuleDeps
Definition: ModuleDepCollector.h:37
clang::SourceManager::getFileEntryForID
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
Definition: SourceManager.h:1015
Preprocessor.h
Defines the clang::Preprocessor interface.
clang::PPCallbacks::FileChangeReason
FileChangeReason
Definition: PPCallbacks.h:39
clang::serialization::ModuleFile
Information about a module that has been loaded by the ASTReader.
Definition: ModuleFile.h:107
clang::tooling::dependencies::ModuleDeps::ClangModuleMapFile
std::string ClangModuleMapFile
Definition: ModuleDepCollector.h:33
SM
const SourceManager & SM
Definition: Format.cpp:1685
ModuleDepCollector.h
clang::tooling::dependencies::ModuleDepCollectorPP::EndOfMainFile
void EndOfMainFile() override
Callback invoked when the end of the main file is reached.
Definition: ModuleDepCollector.cpp:62
clang::CompilerInstance
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Definition: CompilerInstance.h:72
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::FileEntry::getName
StringRef getName() const
Definition: FileManager.h:102
clang::tooling::dependencies::ModuleDeps::ContextHash
std::string ContextHash
Definition: ModuleDepCollector.h:35
clang::FileEntry
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:78
clang::tooling::dependencies::ModuleDepCollectorPP::FileChanged
void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID) override
Callback invoked whenever a source file is entered or exited.
Definition: ModuleDepCollector.cpp:20
clang::tooling::dependencies::ModuleDeps::ModulePCMPath
std::string ModulePCMPath
Definition: ModuleDepCollector.h:34
clang::DependencyOutputOptions
DependencyOutputOptions - Options for controlling the compiler dependency file generation.
Definition: DependencyOutputOptions.h:25
clang::serialization::InputFile
The input file that has been loaded from this AST file, along with bools indicating whether this was ...
Definition: ModuleFile.h:65
clang::FileID
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Definition: SourceLocation.h:38
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:21
clang::Module::submodules
llvm::iterator_range< submodule_iterator > submodules()
Definition: Module.h:568
clang::ASTReader
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:340
DependencyScanningWorker.h
clang::SourceManager::getMainFileID
FileID getMainFileID() const
Returns the FileID of the main source file.
Definition: SourceManager.h:807
clang::CompilerInstance::getSourceManager
SourceManager & getSourceManager() const
Return the current source manager.
Definition: CompilerInstance.h:424
clang::SourceManager::getFileID
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
Definition: SourceManager.h:1090
clang::tooling::dependencies::ModuleDepCollectorPP::InclusionDirective
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.
Definition: ModuleDepCollector.cpp:43
clang::CompilerInstance::getPreprocessor
Preprocessor & getPreprocessor() const
Return the current preprocessor.
Definition: CompilerInstance.h:444
clang::tooling::dependencies::ModuleDepCollector::attachToPreprocessor
void attachToPreprocessor(Preprocessor &PP) override
Definition: ModuleDepCollector.cpp:131
clang::tooling::dependencies::ModuleDepCollector::ModuleDepCollector
ModuleDepCollector(CompilerInstance &I, DependencyConsumer &C)
Definition: ModuleDepCollector.cpp:126
clang::tooling::dependencies::ModuleDepCollector::attachToASTReader
void attachToASTReader(ASTReader &R) override
Definition: ModuleDepCollector.cpp:135
clang::SrcMgr::isSystem
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
Definition: SourceManager.h:82
clang::Preprocessor::addPPCallbacks
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
Definition: Preprocessor.h:1005
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:596
clang::tooling::dependencies::DependencyConsumer::handleFileDependency
virtual void handleFileDependency(const DependencyOutputOptions &Opts, StringRef Filename)=0
clang::Preprocessor
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:128