clang  16.0.0git
ModuleDepCollector.cpp
Go to the documentation of this file.
1 //===- ModuleDepCollector.cpp - Callbacks to collect deps -------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
13 #include "clang/Lex/Preprocessor.h"
15 #include "llvm/Support/BLAKE3.h"
16 #include "llvm/Support/StringSaver.h"
17 
18 using namespace clang;
19 using namespace tooling;
20 using namespace dependencies;
21 
23  ASTReader &Reader,
24  const serialization::ModuleFile &MF) {
25  // Only preserve search paths that were used during the dependency scan.
26  std::vector<HeaderSearchOptions::Entry> Entries = Opts.UserEntries;
27  Opts.UserEntries.clear();
28 
29  llvm::BitVector SearchPathUsage(Entries.size());
31  std::function<void(const serialization::ModuleFile *)> VisitMF =
32  [&](const serialization::ModuleFile *MF) {
33  SearchPathUsage |= MF->SearchPathUsage;
34  Visited.insert(MF);
35  for (const serialization::ModuleFile *Import : MF->Imports)
36  if (!Visited.contains(Import))
37  VisitMF(Import);
38  };
39  VisitMF(&MF);
40 
41  for (auto Idx : SearchPathUsage.set_bits())
42  Opts.UserEntries.push_back(Entries[Idx]);
43 }
44 
45 static std::vector<std::string> splitString(std::string S, char Separator) {
46  SmallVector<StringRef> Segments;
47  StringRef(S).split(Segments, Separator, /*MaxSplit=*/-1, /*KeepEmpty=*/false);
48  std::vector<std::string> Result;
49  Result.reserve(Segments.size());
50  for (StringRef Segment : Segments)
51  Result.push_back(Segment.str());
52  return Result;
53 }
54 
55 void ModuleDepCollector::addOutputPaths(CompilerInvocation &CI,
56  ModuleDeps &Deps) {
57  // These are technically *inputs* to the compilation, but we populate them
58  // here in order to make \c getModuleContextHash() independent of
59  // \c lookupModuleOutput().
60  addModuleFiles(CI, Deps.ClangModuleDeps);
61 
66  Consumer.lookupModuleOutput(
68  if (!CI.getDependencyOutputOpts().OutputFile.empty()) {
74  '\0');
75  if (!CI.getDependencyOutputOpts().OutputFile.empty() &&
76  CI.getDependencyOutputOpts().Targets.empty()) {
77  // Fallback to -o as dependency target, as in the driver.
80  CI.getDependencyOutputOpts().Targets.push_back(std::string(Target));
81  }
82  }
83 }
84 
86 ModuleDepCollector::makeInvocationForModuleBuildWithoutOutputs(
87  const ModuleDeps &Deps,
88  llvm::function_ref<void(CompilerInvocation &)> Optimize) const {
89  // Make a deep copy of the original Clang invocation.
90  CompilerInvocation CI(OriginalInvocation);
91 
94 
95  // Remove options incompatible with explicit module build or are likely to
96  // differ between identical modules discovered from different translation
97  // units.
98  CI.getFrontendOpts().Inputs.clear();
99  CI.getFrontendOpts().OutputFile.clear();
100 
101  // TODO: Figure out better way to set options to their default value.
102  CI.getCodeGenOpts().MainFileName.clear();
103  CI.getCodeGenOpts().DwarfDebugFlags.clear();
104  if (!CI.getLangOpts()->ModulesCodegen) {
105  CI.getCodeGenOpts().DebugCompilationDir.clear();
107  }
108 
109  // Map output paths that affect behaviour to "-" so their existence is in the
110  // context hash. The final path will be computed in addOutputPaths.
113  if (!CI.getDependencyOutputOpts().OutputFile.empty())
115  CI.getDependencyOutputOpts().Targets.clear();
116 
118  CI.getLangOpts()->ModuleName = Deps.ID.ModuleName;
119  CI.getFrontendOpts().IsSystemModule = Deps.IsSystem;
120 
121  // Inputs
122  InputKind ModuleMapInputKind(CI.getFrontendOpts().DashX.getLanguage(),
123  InputKind::Format::ModuleMap);
124  CI.getFrontendOpts().Inputs.emplace_back(Deps.ClangModuleMapFile,
125  ModuleMapInputKind);
126 
127  auto CurrentModuleMapEntry =
128  ScanInstance.getFileManager().getFile(Deps.ClangModuleMapFile);
129  assert(CurrentModuleMapEntry && "module map file entry not found");
130 
131  auto DepModuleMapFiles = collectModuleMapFiles(Deps.ClangModuleDeps);
132  for (StringRef ModuleMapFile : Deps.ModuleMapFileDeps) {
133  // TODO: Track these as `FileEntryRef` to simplify the equality check below.
134  auto ModuleMapEntry = ScanInstance.getFileManager().getFile(ModuleMapFile);
135  assert(ModuleMapEntry && "module map file entry not found");
136 
137  // Don't report module maps describing eagerly-loaded dependency. This
138  // information will be deserialized from the PCM.
139  // TODO: Verify this works fine when modulemap for module A is eagerly
140  // loaded from A.pcm, and module map passed on the command line contains
141  // definition of a submodule: "explicit module A.Private { ... }".
142  if (EagerLoadModules && DepModuleMapFiles.contains(*ModuleMapEntry))
143  continue;
144 
145  // Don't report module map file of the current module unless it also
146  // describes a dependency (for symmetry).
147  if (*ModuleMapEntry == *CurrentModuleMapEntry &&
148  !DepModuleMapFiles.contains(*ModuleMapEntry))
149  continue;
150 
151  CI.getFrontendOpts().ModuleMapFiles.emplace_back(ModuleMapFile);
152  }
153 
154  // Report the prebuilt modules this module uses.
155  for (const auto &PrebuiltModule : Deps.PrebuiltModuleDeps)
156  CI.getFrontendOpts().ModuleFiles.push_back(PrebuiltModule.PCMFile);
157 
158  // Remove any macro definitions that are explicitly ignored.
159  if (!CI.getHeaderSearchOpts().ModulesIgnoreMacros.empty()) {
160  llvm::erase_if(
162  [&CI](const std::pair<std::string, bool> &Def) {
163  StringRef MacroDef = Def.first;
164  return CI.getHeaderSearchOpts().ModulesIgnoreMacros.contains(
165  llvm::CachedHashString(MacroDef.split('=').first));
166  });
167  // Remove the now unused option.
169  }
170 
171  Optimize(CI);
172 
173  // The original invocation probably didn't have strict context hash enabled.
174  // We will use the context hash of this invocation to distinguish between
175  // multiple incompatible versions of the same module and will use it when
176  // reporting dependencies to the clients. Let's make sure we're using
177  // **strict** context hash in order to prevent accidental sharing of
178  // incompatible modules (e.g. with differences in search paths).
180 
181  return CI;
182 }
183 
184 llvm::DenseSet<const FileEntry *> ModuleDepCollector::collectModuleMapFiles(
185  ArrayRef<ModuleID> ClangModuleDeps) const {
186  llvm::DenseSet<const FileEntry *> ModuleMapFiles;
187  for (const ModuleID &MID : ClangModuleDeps) {
188  ModuleDeps *MD = ModuleDepsByID.lookup(MID);
189  assert(MD && "Inconsistent dependency info");
190  // TODO: Track ClangModuleMapFile as `FileEntryRef`.
191  auto FE = ScanInstance.getFileManager().getFile(MD->ClangModuleMapFile);
192  assert(FE && "Missing module map file that was previously found");
193  ModuleMapFiles.insert(*FE);
194  }
195  return ModuleMapFiles;
196 }
197 
198 void ModuleDepCollector::addModuleMapFiles(
199  CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const {
200  if (EagerLoadModules)
201  return; // Only pcm is needed for eager load.
202 
203  for (const ModuleID &MID : ClangModuleDeps) {
204  ModuleDeps *MD = ModuleDepsByID.lookup(MID);
205  assert(MD && "Inconsistent dependency info");
206  CI.getFrontendOpts().ModuleMapFiles.push_back(MD->ClangModuleMapFile);
207  }
208 }
209 
210 void ModuleDepCollector::addModuleFiles(
211  CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const {
212  for (const ModuleID &MID : ClangModuleDeps) {
213  std::string PCMPath =
215  if (EagerLoadModules)
216  CI.getFrontendOpts().ModuleFiles.push_back(std::move(PCMPath));
217  else
219  {MID.ModuleName, std::move(PCMPath)});
220  }
221 }
222 
223 static bool needsModules(FrontendInputFile FIF) {
224  switch (FIF.getKind().getLanguage()) {
225  case Language::Unknown:
226  case Language::Asm:
227  case Language::LLVM_IR:
228  return false;
229  default:
230  return true;
231  }
232 }
233 
236 
237  if (llvm::any_of(CI.getFrontendOpts().Inputs, needsModules)) {
238  Preprocessor &PP = ScanInstance.getPreprocessor();
239  if (Module *CurrentModule = PP.getCurrentModuleImplementation())
240  if (Optional<FileEntryRef> CurrentModuleMap =
242  .getModuleMap()
243  .getModuleMapFileForUniquing(CurrentModule))
244  CI.getFrontendOpts().ModuleMapFiles.emplace_back(
245  CurrentModuleMap->getName());
246 
247  SmallVector<ModuleID> DirectDeps;
248  for (const auto &KV : ModularDeps)
249  if (KV.second->ImportedByMainFile)
250  DirectDeps.push_back(KV.second->ID);
251 
252  // TODO: Report module maps the same way it's done for modular dependencies.
253  addModuleMapFiles(CI, DirectDeps);
254 
255  addModuleFiles(CI, DirectDeps);
256 
257  for (const auto &KV : DirectPrebuiltModularDeps)
258  CI.getFrontendOpts().ModuleFiles.push_back(KV.second.PCMFile);
259  }
260 }
261 
262 static std::string getModuleContextHash(const ModuleDeps &MD,
263  const CompilerInvocation &CI,
264  bool EagerLoadModules) {
265  llvm::HashBuilder<llvm::TruncatedBLAKE3<16>,
266  llvm::support::endianness::native>
267  HashBuilder;
268  SmallString<32> Scratch;
269 
270  // Hash the compiler version and serialization version to ensure the module
271  // will be readable.
272  HashBuilder.add(getClangFullRepositoryVersion());
274 
275  // Hash the BuildInvocation without any input files.
277  CI.generateCC1CommandLine(DummyArgs, [&](const Twine &Arg) {
278  Scratch.clear();
279  StringRef Str = Arg.toStringRef(Scratch);
280  HashBuilder.add(Str);
281  return "<unused>";
282  });
283 
284  // Hash the module dependencies. These paths may differ even if the invocation
285  // is identical if they depend on the contents of the files in the TU -- for
286  // example, case-insensitive paths to modulemap files. Usually such a case
287  // would indicate a missed optimization to canonicalize, but it may be
288  // difficult to canonicalize all cases when there is a VFS.
289  for (const auto &ID : MD.ClangModuleDeps) {
290  HashBuilder.add(ID.ModuleName);
291  HashBuilder.add(ID.ContextHash);
292  }
293 
294  HashBuilder.add(EagerLoadModules);
295 
296  llvm::BLAKE3Result<16> Hash = HashBuilder.final();
297  std::array<uint64_t, 2> Words;
298  static_assert(sizeof(Hash) == sizeof(Words), "Hash must match Words");
299  std::memcpy(Words.data(), Hash.data(), sizeof(Hash));
300  return toString(llvm::APInt(sizeof(Words) * 8, Words), 36, /*Signed=*/false);
301 }
302 
303 void ModuleDepCollector::associateWithContextHash(const CompilerInvocation &CI,
304  ModuleDeps &Deps) {
305  Deps.ID.ContextHash = getModuleContextHash(Deps, CI, EagerLoadModules);
306  bool Inserted = ModuleDepsByID.insert({Deps.ID, &Deps}).second;
307  (void)Inserted;
308  assert(Inserted && "duplicate module mapping");
309 }
310 
312  FileChangeReason Reason,
314  FileID PrevFID) {
315  if (Reason != PPCallbacks::EnterFile)
316  return;
317 
318  // This has to be delayed as the context hash can change at the start of
319  // `CompilerInstance::ExecuteAction`.
320  if (MDC.ContextHash.empty()) {
321  MDC.ContextHash = MDC.ScanInstance.getInvocation().getModuleHash();
322  MDC.Consumer.handleContextHash(MDC.ContextHash);
323  }
324 
325  SourceManager &SM = MDC.ScanInstance.getSourceManager();
326 
327  // Dependency generation really does want to go all the way to the
328  // file entry for a source location to find out what is depended on.
329  // We do not want #line markers to affect dependency generation!
331  SM.getNonBuiltinFilenameForID(SM.getFileID(SM.getExpansionLoc(Loc))))
332  MDC.addFileDep(llvm::sys::path::remove_leading_dotslash(*Filename));
333 }
334 
336  SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
337  bool IsAngled, CharSourceRange FilenameRange, Optional<FileEntryRef> File,
338  StringRef SearchPath, StringRef RelativePath, const Module *Imported,
339  SrcMgr::CharacteristicKind FileType) {
340  if (!File && !Imported) {
341  // This is a non-modular include that HeaderSearch failed to find. Add it
342  // here as `FileChanged` will never see it.
343  MDC.addFileDep(FileName);
344  }
345  handleImport(Imported);
346 }
347 
349  ModuleIdPath Path,
350  const Module *Imported) {
351  handleImport(Imported);
352 }
353 
354 void ModuleDepCollectorPP::handleImport(const Module *Imported) {
355  if (!Imported)
356  return;
357 
358  const Module *TopLevelModule = Imported->getTopLevelModule();
359 
360  if (MDC.isPrebuiltModule(TopLevelModule))
361  MDC.DirectPrebuiltModularDeps.insert(
362  {TopLevelModule, PrebuiltModuleDep{TopLevelModule}});
363  else
364  DirectModularDeps.insert(TopLevelModule);
365 }
366 
368  FileID MainFileID = MDC.ScanInstance.getSourceManager().getMainFileID();
369  MDC.MainFile = std::string(MDC.ScanInstance.getSourceManager()
370  .getFileEntryForID(MainFileID)
371  ->getName());
372 
373  if (!MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude.empty())
374  MDC.addFileDep(MDC.ScanInstance.getPreprocessorOpts().ImplicitPCHInclude);
375 
376  for (const Module *M :
377  MDC.ScanInstance.getPreprocessor().getAffectingClangModules())
378  if (!MDC.isPrebuiltModule(M))
379  DirectModularDeps.insert(M);
380 
381  for (const Module *M : DirectModularDeps) {
382  // A top-level module might not be actually imported as a module when
383  // -fmodule-name is used to compile a translation unit that imports this
384  // module. In that case it can be skipped. The appropriate header
385  // dependencies will still be reported as expected.
386  if (!M->getASTFile())
387  continue;
388  handleTopLevelModule(M);
389  }
390 
391  MDC.Consumer.handleDependencyOutputOpts(*MDC.Opts);
392 
393  for (auto &&I : MDC.ModularDeps)
394  MDC.Consumer.handleModuleDependency(*I.second);
395 
396  for (auto &&I : MDC.FileDeps)
397  MDC.Consumer.handleFileDependency(I);
398 
399  for (auto &&I : MDC.DirectPrebuiltModularDeps)
400  MDC.Consumer.handlePrebuiltModuleDependency(I.second);
401 }
402 
403 ModuleID ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
404  assert(M == M->getTopLevelModule() && "Expected top level module!");
405 
406  // If this module has been handled already, just return its ID.
407  auto ModI = MDC.ModularDeps.insert({M, nullptr});
408  if (!ModI.second)
409  return ModI.first->second->ID;
410 
411  ModI.first->second = std::make_unique<ModuleDeps>();
412  ModuleDeps &MD = *ModI.first->second;
413 
414  MD.ID.ModuleName = M->getFullModuleName();
415  MD.ImportedByMainFile = DirectModularDeps.contains(M);
416  MD.ImplicitModulePCMPath = std::string(M->getASTFile()->getName());
417  MD.IsSystem = M->IsSystem;
418 
419  ModuleMap &ModMapInfo =
420  MDC.ScanInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
421 
423 
424  if (ModuleMap) {
425  SmallString<128> Path = ModuleMap->getNameAsRequested();
426  ModMapInfo.canonicalizeModuleMapPath(Path);
427  MD.ClangModuleMapFile = std::string(Path);
428  }
429 
431  MDC.ScanInstance.getASTReader()->getModuleManager().lookup(
432  M->getASTFile());
433  MDC.ScanInstance.getASTReader()->visitInputFiles(
434  *MF, true, true, [&](const serialization::InputFile &IF, bool isSystem) {
435  // __inferred_module.map is the result of the way in which an implicit
436  // module build handles inferred modules. It adds an overlay VFS with
437  // this file in the proper directory and relies on the rest of Clang to
438  // handle it like normal. With explicitly built modules we don't need
439  // to play VFS tricks, so replace it with the correct module map.
440  if (IF.getFile()->getName().endswith("__inferred_module.map")) {
441  MDC.addFileDep(MD, ModuleMap->getName());
442  return;
443  }
444  MDC.addFileDep(MD, IF.getFile()->getName());
445  });
446 
448  addAllSubmodulePrebuiltDeps(M, MD, SeenDeps);
449  addAllSubmoduleDeps(M, MD, SeenDeps);
450  addAllAffectingClangModules(M, MD, SeenDeps);
451 
452  MDC.ScanInstance.getASTReader()->visitTopLevelModuleMaps(
453  *MF, [&](FileEntryRef FE) {
454  if (FE.getNameAsRequested().endswith("__inferred_module.map"))
455  return;
456  MD.ModuleMapFileDeps.emplace_back(FE.getNameAsRequested());
457  });
458 
459  CompilerInvocation CI = MDC.makeInvocationForModuleBuildWithoutOutputs(
460  MD, [&](CompilerInvocation &BuildInvocation) {
461  if (MDC.OptimizeArgs)
463  *MDC.ScanInstance.getASTReader(), *MF);
464  });
465 
466  MDC.associateWithContextHash(CI, MD);
467 
468  // Finish the compiler invocation. Requires dependencies and the context hash.
469  MDC.addOutputPaths(CI, MD);
470 
471  MD.BuildArguments = CI.getCC1CommandLine();
472 
473  return MD.ID;
474 }
475 
476 static void forEachSubmoduleSorted(const Module *M,
477  llvm::function_ref<void(const Module *)> F) {
478  // Submodule order depends on order of header includes for inferred submodules
479  // we don't care about the exact order, so sort so that it's consistent across
480  // TUs to improve sharing.
482  M->submodule_end());
483  llvm::stable_sort(Submodules, [](const Module *A, const Module *B) {
484  return A->Name < B->Name;
485  });
486  for (const Module *SubM : Submodules)
487  F(SubM);
488 }
489 
490 void ModuleDepCollectorPP::addAllSubmodulePrebuiltDeps(
491  const Module *M, ModuleDeps &MD,
492  llvm::DenseSet<const Module *> &SeenSubmodules) {
493  addModulePrebuiltDeps(M, MD, SeenSubmodules);
494 
495  forEachSubmoduleSorted(M, [&](const Module *SubM) {
496  addAllSubmodulePrebuiltDeps(SubM, MD, SeenSubmodules);
497  });
498 }
499 
500 void ModuleDepCollectorPP::addModulePrebuiltDeps(
501  const Module *M, ModuleDeps &MD,
502  llvm::DenseSet<const Module *> &SeenSubmodules) {
503  for (const Module *Import : M->Imports)
504  if (Import->getTopLevelModule() != M->getTopLevelModule())
505  if (MDC.isPrebuiltModule(Import->getTopLevelModule()))
506  if (SeenSubmodules.insert(Import->getTopLevelModule()).second)
507  MD.PrebuiltModuleDeps.emplace_back(Import->getTopLevelModule());
508 }
509 
510 void ModuleDepCollectorPP::addAllSubmoduleDeps(
511  const Module *M, ModuleDeps &MD,
512  llvm::DenseSet<const Module *> &AddedModules) {
513  addModuleDep(M, MD, AddedModules);
514 
515  forEachSubmoduleSorted(M, [&](const Module *SubM) {
516  addAllSubmoduleDeps(SubM, MD, AddedModules);
517  });
518 }
519 
520 void ModuleDepCollectorPP::addModuleDep(
521  const Module *M, ModuleDeps &MD,
522  llvm::DenseSet<const Module *> &AddedModules) {
523  for (const Module *Import : M->Imports) {
524  if (Import->getTopLevelModule() != M->getTopLevelModule() &&
525  !MDC.isPrebuiltModule(Import)) {
526  ModuleID ImportID = handleTopLevelModule(Import->getTopLevelModule());
527  if (AddedModules.insert(Import->getTopLevelModule()).second)
528  MD.ClangModuleDeps.push_back(ImportID);
529  }
530  }
531 }
532 
533 void ModuleDepCollectorPP::addAllAffectingClangModules(
534  const Module *M, ModuleDeps &MD,
535  llvm::DenseSet<const Module *> &AddedModules) {
536  addAffectingClangModule(M, MD, AddedModules);
537 
538  for (const Module *SubM : M->submodules())
539  addAllAffectingClangModules(SubM, MD, AddedModules);
540 }
541 
542 void ModuleDepCollectorPP::addAffectingClangModule(
543  const Module *M, ModuleDeps &MD,
544  llvm::DenseSet<const Module *> &AddedModules) {
545  for (const Module *Affecting : M->AffectingClangModules) {
546  assert(Affecting == Affecting->getTopLevelModule() &&
547  "Not quite import not top-level module");
548  if (Affecting != M->getTopLevelModule() &&
549  !MDC.isPrebuiltModule(Affecting)) {
550  ModuleID ImportID = handleTopLevelModule(Affecting);
551  if (AddedModules.insert(Affecting).second)
552  MD.ClangModuleDeps.push_back(ImportID);
553  }
554  }
555 }
556 
558  std::unique_ptr<DependencyOutputOptions> Opts,
559  CompilerInstance &ScanInstance, DependencyConsumer &C,
560  CompilerInvocation OriginalCI, bool OptimizeArgs, bool EagerLoadModules)
561  : ScanInstance(ScanInstance), Consumer(C), Opts(std::move(Opts)),
562  OriginalInvocation(std::move(OriginalCI)), OptimizeArgs(OptimizeArgs),
563  EagerLoadModules(EagerLoadModules) {}
564 
566  PP.addPPCallbacks(std::make_unique<ModuleDepCollectorPP>(*this));
567 }
568 
570 
571 bool ModuleDepCollector::isPrebuiltModule(const Module *M) {
573  const auto &PrebuiltModuleFiles =
575  auto PrebuiltModuleFileIt = PrebuiltModuleFiles.find(Name);
576  if (PrebuiltModuleFileIt == PrebuiltModuleFiles.end())
577  return false;
578  assert("Prebuilt module came from the expected AST file" &&
579  PrebuiltModuleFileIt->second == M->getASTFile()->getName());
580  return true;
581 }
582 
583 static StringRef makeAbsoluteAndPreferred(CompilerInstance &CI, StringRef Path,
584  SmallVectorImpl<char> &Storage) {
585  if (llvm::sys::path::is_absolute(Path) &&
586  !llvm::sys::path::is_style_windows(llvm::sys::path::Style::native))
587  return Path;
588  Storage.assign(Path.begin(), Path.end());
589  CI.getFileManager().makeAbsolutePath(Storage);
590  llvm::sys::path::make_preferred(Storage);
591  return StringRef(Storage.data(), Storage.size());
592 }
593 
594 void ModuleDepCollector::addFileDep(StringRef Path) {
595  llvm::SmallString<256> Storage;
596  Path = makeAbsoluteAndPreferred(ScanInstance, Path, Storage);
597  FileDeps.push_back(std::string(Path));
598 }
599 
600 void ModuleDepCollector::addFileDep(ModuleDeps &MD, StringRef Path) {
601  llvm::SmallString<256> Storage;
602  Path = makeAbsoluteAndPreferred(ScanInstance, Path, Storage);
603  MD.FileDeps.insert(Path);
604 }
clang::FrontendOptions::ModuleMapFiles
std::vector< std::string > ModuleMapFiles
The list of module map files to load before processing the input.
Definition: FrontendOptions.h:471
clang::Module::getTopLevelModule
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Definition: Module.h:593
clang::CompilerInvocationValueBase::getCodeGenOpts
CodeGenOptions & getCodeGenOpts()
Definition: CompilerInvocation.h:159
clang::interp::APInt
llvm::APInt APInt
Definition: Integral.h:27
clang::FileEntryRef
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition: FileEntry.h:62
clang::serialization::InputFile::getFile
OptionalFileEntryRefDegradesToFileEntryPtr getFile() const
Definition: ModuleFile.h:105
clang::DiagnosticOptions::DiagnosticSerializationFile
std::string DiagnosticSerializationFile
The file to serialize diagnostics to (non-appending).
Definition: DiagnosticOptions.h:107
clang::ModuleMap::canonicalizeModuleMapPath
std::error_code canonicalizeModuleMapPath(SmallVectorImpl< char > &Path)
Canonicalize Path in a manner suitable for a module map file.
Definition: ModuleMap.cpp:1287
clang::tooling::dependencies::DependencyConsumer::handlePrebuiltModuleDependency
virtual void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD)=0
clang::DeclaratorContext::File
@ File
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::FrontendInputFile::getKind
InputKind getKind() const
Definition: FrontendOptions.h:241
clang::ModuleMap::getModuleMapFileForUniquing
Optional< FileEntryRef > getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module.
Definition: ModuleMap.cpp:1272
clang::FrontendOptions::ProgramAction
frontend::ActionKind ProgramAction
The frontend action to perform.
Definition: FrontendOptions.h:445
clang::tooling::dependencies::DependencyConsumer
Definition: DependencyScanningWorker.h:39
llvm::SmallVector
Definition: LLVM.h:38
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
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:219
clang::MultiVersionKind::Target
@ Target
clang::Preprocessor::getAffectingClangModules
const llvm::SmallSetVector< Module *, 2 > & getAffectingClangModules() const
Get the set of top-level clang modules that affected preprocessing, but were not imported.
Definition: Preprocessor.h:1341
clang::Module::submodule_begin
submodule_iterator submodule_begin()
Definition: Module.h:708
Filename
StringRef Filename
Definition: Format.cpp:2715
memcpy
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Definition: __clang_cuda_device_functions.h:1549
clang::FrontendInputFile
An input file for the front end.
Definition: FrontendOptions.h:218
clang::Module::Name
std::string Name
The name of this module.
Definition: Module.h:101
clang::tooling::dependencies::DependencyConsumer::handleModuleDependency
virtual void handleModuleDependency(ModuleDeps MD)=0
clang::PPCallbacks::EnterFile
@ EnterFile
Definition: PPCallbacks.h:40
MakeSupport.h
llvm::Optional< FileEntryRef >
clang::CompilerInvocationRefBase::getHeaderSearchOpts
HeaderSearchOptions & getHeaderSearchOpts()
Definition: CompilerInvocation.h:112
clang::serialization::VERSION_MAJOR
const unsigned VERSION_MAJOR
AST file major version number supported by this version of Clang.
Definition: ASTBitCodes.h:44
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:79
clang::tooling::dependencies::DependencyConsumer::lookupModuleOutput
virtual std::string lookupModuleOutput(const ModuleID &ID, ModuleOutputKind Kind)=0
clang::Language::Asm
@ Asm
Assembly: we accept this only so that we can preprocess it.
clang::Token
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
clang::InputKind
The kind of a file that we've been handed as an input.
Definition: FrontendOptions.h:148
clang::CompilerInvocation::resetNonModularOptions
void resetNonModularOptions()
Reset all of the options that are not considered when building a module.
Definition: CompilerInvocation.cpp:4714
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:637
clang::FrontendOptions::Inputs
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
Definition: FrontendOptions.h:426
Preprocessor.h
clang::tooling::dependencies::ModuleDepCollector::attachToPreprocessor
void attachToPreprocessor(Preprocessor &PP) override
Definition: ModuleDepCollector.cpp:565
clang::CompilerInstance::getFileManager
FileManager & getFileManager() const
Return the current file manager to the caller.
Definition: CompilerInstance.h:402
clang::Preprocessor::getCurrentModuleImplementation
Module * getCurrentModuleImplementation()
Retrieves the module whose implementation we're current compiling, if any.
Definition: Preprocessor.cpp:531
clang::Module
Describes a module or submodule.
Definition: Module.h:98
clang::FileEntryRef::getNameAsRequested
StringRef getNameAsRequested() const
The name of this FileEntry, as originally requested without applying any remappings for VFS 'use-exte...
Definition: FileEntry.h:73
clang::HeaderSearchOptions::ModulesStrictContextHash
unsigned ModulesStrictContextHash
Whether we should include all things that could impact the module in the hash.
Definition: HeaderSearchOptions.h:226
clang::CompilerInvocationValueBase::getFrontendOpts
FrontendOptions & getFrontendOpts()
Definition: CompilerInvocation.h:176
clang::FrontendOptions::OutputFile
std::string OutputFile
The output file, if any.
Definition: FrontendOptions.h:433
clang::tooling::dependencies::PrebuiltModuleDep
Modular dependency that has already been built prior to the dependency scan.
Definition: ModuleDepCollector.h:32
clang::serialization::InputFile
The input file that has been loaded from this AST file, along with bools indicating whether this was ...
Definition: ModuleFile.h:76
clang::threadSafety::sx::toString
std::string toString(const til::SExpr *E)
Definition: ThreadSafetyCommon.h:91
clang::Module::getTopLevelModuleName
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
Definition: Module.h:603
needsModules
static bool needsModules(FrontendInputFile FIF)
Definition: ModuleDepCollector.cpp:223
clang::SourceManager::getMainFileID
FileID getMainFileID() const
Returns the FileID of the main source file.
Definition: SourceManager.h:851
clang::tooling::dependencies::ModuleDepCollector::ModuleDepCollector
ModuleDepCollector(std::unique_ptr< DependencyOutputOptions > Opts, CompilerInstance &ScanInstance, DependencyConsumer &C, CompilerInvocation OriginalCI, bool OptimizeArgs, bool EagerLoadModules)
Definition: ModuleDepCollector.cpp:557
clang::CodeGenOptions::CoverageCompilationDir
std::string CoverageCompilationDir
The string to embed in coverage mapping as the current working directory.
Definition: CodeGenOptions.h:179
clang::InputKind::getLanguage
Language getLanguage() const
Definition: FrontendOptions.h:179
splitString
static std::vector< std::string > splitString(std::string S, char Separator)
Definition: ModuleDepCollector.cpp:45
llvm::SmallString< 128 >
clang::CompilerInvocationRefBase::getLangOpts
LangOptions * getLangOpts()
Definition: CompilerInvocation.h:104
clang::getClangFullRepositoryVersion
std::string getClangFullRepositoryVersion()
Retrieves the full repository version that is an amalgamation of the information in getClangRepositor...
Definition: Version.cpp:60
llvm::DenseSet
Definition: Sema.h:77
clang::CompilerInstance::getPreprocessor
Preprocessor & getPreprocessor() const
Return the current preprocessor.
Definition: CompilerInstance.h:442
clang::FrontendOptions::DashX
InputKind DashX
The input kind, either specified via -x argument or deduced from the input file name.
Definition: FrontendOptions.h:423
DependencyScanningWorker.h
clang::Module::getASTFile
OptionalFileEntryRefDegradesToFileEntryPtr getASTFile() const
The serialized AST file for this module, if one was created.
Definition: Module.h:608
clang::CompilerInvocation::generateCC1CommandLine
void generateCC1CommandLine(llvm::SmallVectorImpl< const char * > &Args, StringAllocator SA) const
Generate cc1-compatible command line arguments from this instance.
Definition: CompilerInvocation.cpp:4679
clang::CompilerInstance
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Definition: CompilerInstance.h:72
clang::HeaderSearchOptions::PrebuiltModuleFiles
std::map< std::string, std::string, std::less<> > PrebuiltModuleFiles
The mapping of module names to prebuilt module files.
Definition: HeaderSearchOptions.h:119
clang::serialization::VERSION_MINOR
const unsigned VERSION_MINOR
AST file minor version number supported by this version of Clang.
Definition: ASTBitCodes.h:54
clang::tooling::dependencies::ModuleOutputKind::DependencyTargets
@ DependencyTargets
The null-separated list of names to use as the targets in the dependency file, if any.
clang::ModuleMap
Definition: ModuleMap.h:75
clang::CompilerInstance::getPreprocessorOpts
PreprocessorOptions & getPreprocessorOpts()
Definition: CompilerInstance.h:306
clang::tooling::dependencies::ModuleOutputKind::DependencyFile
@ DependencyFile
The path of the dependency file (.d), if any.
clang::CompilerInvocation::clearImplicitModuleBuildOptions
void clearImplicitModuleBuildOptions()
Disable implicit modules and canonicalize options that are only used by implicit modules.
Definition: CompilerInvocation.cpp:4719
clang::Module::submodules
llvm::iterator_range< submodule_iterator > submodules()
Definition: Module.h:713
clang::quoteMakeTarget
void quoteMakeTarget(StringRef Target, SmallVectorImpl< char > &Res)
Quote target names for inclusion in GNU Make dependency files.
Definition: MakeSupport.cpp:11
clang::tooling::dependencies::ModuleOutputKind::DiagnosticSerializationFile
@ DiagnosticSerializationFile
The path of the serialized diagnostic file (.dia), if any.
ModuleDepCollector.h
clang::CompilerInvocationRefBase::getPreprocessorOpts
PreprocessorOptions & getPreprocessorOpts()
Definition: CompilerInvocation.h:126
clang::PPCallbacks::FileChangeReason
FileChangeReason
Definition: PPCallbacks.h:39
clang::HeaderSearchOptions::ModulesIgnoreMacros
llvm::SmallSetVector< llvm::CachedHashString, 16 > ModulesIgnoreMacros
The set of macro names that should be ignored for the purposes of computing the module hash.
Definition: HeaderSearchOptions.h:182
clang::FrontendOptions::IsSystemModule
unsigned IsSystemModule
When using -emit-module, treat the modulemap as a system module.
Definition: FrontendOptions.h:342
clang::CompilerInvocation::getModuleHash
std::string getModuleHash() const
Retrieve a module hash string that is suitable for uniquely identifying the conditions under which th...
Definition: CompilerInvocation.cpp:4583
clang::frontend::GenerateModule
@ GenerateModule
Generate pre-compiled module from a module map.
Definition: FrontendOptions.h:85
clang::Module::IsSystem
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
Definition: Module.h:293
clang::CompilerInvocationValueBase::getDependencyOutputOpts
DependencyOutputOptions & getDependencyOutputOpts()
Definition: CompilerInvocation.h:162
makeAbsoluteAndPreferred
static StringRef makeAbsoluteAndPreferred(CompilerInstance &CI, StringRef Path, SmallVectorImpl< char > &Storage)
Definition: ModuleDepCollector.cpp:583
clang::serialization::ModuleFile::SearchPathUsage
llvm::BitVector SearchPathUsage
The bit vector denoting usage of each header search entry (true = used).
Definition: ModuleFile.h:185
llvm::ArrayRef
Definition: LLVM.h:34
clang::Language::LLVM_IR
@ LLVM_IR
LLVM IR: we accept this so that we can run the optimizer on it, and compile it to assembly or object ...
clang::CompilerInstance::getInvocation
CompilerInvocation & getInvocation()
Definition: CompilerInstance.h:229
clang::tooling::dependencies::ModuleDepCollector::attachToASTReader
void attachToASTReader(ASTReader &R) override
Definition: ModuleDepCollector.cpp:569
clang::tooling::dependencies::ModuleDepCollectorPP::EndOfMainFile
void EndOfMainFile() override
Callback invoked when the end of the main file is reached.
Definition: ModuleDepCollector.cpp:367
getModuleContextHash
static std::string getModuleContextHash(const ModuleDeps &MD, const CompilerInvocation &CI, bool EagerLoadModules)
Definition: ModuleDepCollector.cpp:262
clang::CharSourceRange
Represents a character-granular source range.
Definition: SourceLocation.h:253
clang::tooling::dependencies::ModuleDepCollectorPP::InclusionDirective
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, Optional< FileEntryRef > File, StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override
Callback invoked whenever an inclusion directive of any kind (#include, #import, etc....
Definition: ModuleDepCollector.cpp:335
clang::tooling::dependencies::ModuleDepCollectorPP::moduleImport
void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, const Module *Imported) override
Callback invoked whenever there was an explicit module-import syntax.
Definition: ModuleDepCollector.cpp:348
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:349
clang::HeaderSearchOptions::UserEntries
std::vector< Entry > UserEntries
User specified include entries.
Definition: HeaderSearchOptions.h:103
clang::CodeGenOptions::DebugCompilationDir
std::string DebugCompilationDir
The string to embed in debug information as the current working directory.
Definition: CodeGenOptions.h:176
clang::DependencyOutputOptions::Targets
std::vector< std::string > Targets
A list of names to use as the targets in the dependency file; this list must contain at least one ent...
Definition: DependencyOutputOptions.h:64
clang::ASTReader
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:359
std
Definition: Format.h:4477
clang::FrontendOptions::ModuleFiles
std::vector< std::string > ModuleFiles
The list of additional prebuilt module files to load before processing the input.
Definition: FrontendOptions.h:475
clang::FileManager::makeAbsolutePath
bool makeAbsolutePath(SmallVectorImpl< char > &Path) const
Makes Path absolute taking into account FileSystemOptions and the working directory option.
Definition: FileManager.cpp:516
clang::Builtin::ID
ID
Definition: Builtins.h:52
clang
Definition: CalledOnceCheck.h:17
clang::Preprocessor::addPPCallbacks
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
Definition: Preprocessor.h:1159
clang::serialization::ModuleFile::Imports
llvm::SetVector< ModuleFile * > Imports
List of modules which this module depends on.
Definition: ModuleFile.h:508
clang::tooling::dependencies::ModuleOutputKind::ModuleFile
@ ModuleFile
The module file (.pcm). Required.
clang::DependencyOutputOptions::OutputFile
std::string OutputFile
The file to write dependency output to.
Definition: DependencyOutputOptions.h:54
optimizeHeaderSearchOpts
static void optimizeHeaderSearchOpts(HeaderSearchOptions &Opts, ASTReader &Reader, const serialization::ModuleFile &MF)
Definition: ModuleDepCollector.cpp:22
clang::Module::AffectingClangModules
llvm::SmallSetVector< Module *, 2 > AffectingClangModules
The set of top-level modules that affected the compilation of this module, but were not imported.
Definition: Module.h:353
clang::FileEntry::getName
StringRef getName() const
Definition: FileEntry.h:397
clang::FileID
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Definition: SourceLocation.h:38
clang::CompilerInvocation
Helper class for holding the data necessary to invoke the compiler.
Definition: CompilerInvocation.h:193
clang::tooling::dependencies::DependencyConsumer::handleContextHash
virtual void handleContextHash(std::string Hash)=0
clang::SourceManager::getFileEntryForID
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
Definition: SourceManager.h:1045
clang::SrcMgr::isSystem
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
Definition: SourceManager.h:88
clang::Module::submodule_end
submodule_iterator submodule_end()
Definition: Module.h:710
clang::FileManager::getFile
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
Definition: FileManager.cpp:197
CompilerInstance.h
clang::Language::Unknown
@ Unknown
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:311
clang::CompilerInstance::getASTReader
IntrusiveRefCntPtr< ASTReader > getASTReader() const
Definition: CompilerInstance.cpp:203
clang::CompilerInstance::getSourceManager
SourceManager & getSourceManager() const
Return the current source manager.
Definition: CompilerInstance.h:422
llvm::SmallVectorImpl< char >
clang::tooling::dependencies::ModuleID
This is used to identify a specific module.
Definition: ModuleDepCollector.h:44
clang::Preprocessor
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:129
SM
#define SM(sm)
Definition: Cuda.cpp:79
clang::Preprocessor::getHeaderSearchInfo
HeaderSearch & getHeaderSearchInfo() const
Definition: Preprocessor.h:1066
clang::tooling::dependencies::DependencyConsumer::handleFileDependency
virtual void handleFileDependency(StringRef Filename)=0
clang::tooling::dependencies::DependencyConsumer::handleDependencyOutputOpts
virtual void handleDependencyOutputOpts(const DependencyOutputOptions &Opts)=0
clang::tooling::dependencies::ModuleDepCollector::applyDiscoveredDependencies
void applyDiscoveredDependencies(CompilerInvocation &CI)
Apply any changes implied by the discovered dependencies to the given invocation, (e....
Definition: ModuleDepCollector.cpp:234
forEachSubmoduleSorted
static void forEachSubmoduleSorted(const Module *M, llvm::function_ref< void(const Module *)> F)
Definition: ModuleDepCollector.cpp:476
clang::LangOptions::ModuleName
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
Definition: LangOptions.h:427
clang::PreprocessorOptions::Macros
std::vector< std::pair< std::string, bool > > Macros
Definition: PreprocessorOptions.h:67
clang::HeaderSearch::getModuleMap
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:791
clang::serialization::ModuleFile
Information about a module that has been loaded by the ASTReader.
Definition: ModuleFile.h:122
clang::CodeGenOptions::DwarfDebugFlags
std::string DwarfDebugFlags
The string to embed in the debug information for the compile unit, if non-empty.
Definition: CodeGenOptions.h:183
clang::CompilerInstance::getHeaderSearchOpts
HeaderSearchOptions & getHeaderSearchOpts()
Definition: CompilerInstance.h:289
clang::CompilerInvocation::getCC1CommandLine
std::vector< std::string > getCC1CommandLine() const
Generate cc1-compatible command line arguments from this instance, wrapping the result as a std::vect...
Definition: CompilerInvocation.cpp:4700
clang::PreprocessorOptions::ImplicitPCHInclude
std::string ImplicitPCHInclude
The implicit PCH included at the start of the translation unit, or empty.
Definition: PreprocessorOptions.h:97
clang::CodeGenOptions::MainFileName
std::string MainFileName
The user provided name for the "main file", if non-empty.
Definition: CodeGenOptions.h:227
clang::HeaderSearchOptions
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
Definition: HeaderSearchOptions.h:68
clang::CompilerInvocationRefBase::getDiagnosticOpts
DiagnosticOptions & getDiagnosticOpts() const
Definition: CompilerInvocation.h:110