clang  19.0.0git
FrontendAction.cpp
Go to the documentation of this file.
1 //===--- FrontendAction.cpp -----------------------------------------------===//
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 #include "clang/AST/ASTConsumer.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/AST/DeclGroup.h"
13 #include "clang/Basic/Builtins.h"
15 #include "clang/Basic/FileEntry.h"
17 #include "clang/Basic/Sarif.h"
18 #include "clang/Basic/Stack.h"
19 #include "clang/Frontend/ASTUnit.h"
26 #include "clang/Frontend/Utils.h"
27 #include "clang/Lex/HeaderSearch.h"
29 #include "clang/Lex/Preprocessor.h"
31 #include "clang/Parse/ParseAST.h"
37 #include "llvm/ADT/ScopeExit.h"
38 #include "llvm/Support/BuryPointer.h"
39 #include "llvm/Support/ErrorHandling.h"
40 #include "llvm/Support/FileSystem.h"
41 #include "llvm/Support/Path.h"
42 #include "llvm/Support/Timer.h"
43 #include "llvm/Support/raw_ostream.h"
44 #include <memory>
45 #include <system_error>
46 using namespace clang;
47 
48 LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)
49 
50 namespace {
51 
52 class DelegatingDeserializationListener : public ASTDeserializationListener {
54  bool DeletePrevious;
55 
56 public:
57  explicit DelegatingDeserializationListener(
58  ASTDeserializationListener *Previous, bool DeletePrevious)
59  : Previous(Previous), DeletePrevious(DeletePrevious) {}
60  ~DelegatingDeserializationListener() override {
61  if (DeletePrevious)
62  delete Previous;
63  }
64 
65  DelegatingDeserializationListener(const DelegatingDeserializationListener &) =
66  delete;
67  DelegatingDeserializationListener &
68  operator=(const DelegatingDeserializationListener &) = delete;
69 
70  void ReaderInitialized(ASTReader *Reader) override {
71  if (Previous)
72  Previous->ReaderInitialized(Reader);
73  }
74  void IdentifierRead(serialization::IdentifierID ID,
75  IdentifierInfo *II) override {
76  if (Previous)
77  Previous->IdentifierRead(ID, II);
78  }
79  void TypeRead(serialization::TypeIdx Idx, QualType T) override {
80  if (Previous)
81  Previous->TypeRead(Idx, T);
82  }
83  void DeclRead(GlobalDeclID ID, const Decl *D) override {
84  if (Previous)
85  Previous->DeclRead(ID, D);
86  }
87  void SelectorRead(serialization::SelectorID ID, Selector Sel) override {
88  if (Previous)
89  Previous->SelectorRead(ID, Sel);
90  }
91  void MacroDefinitionRead(serialization::PreprocessedEntityID PPID,
92  MacroDefinitionRecord *MD) override {
93  if (Previous)
94  Previous->MacroDefinitionRead(PPID, MD);
95  }
96 };
97 
98 /// Dumps deserialized declarations.
99 class DeserializedDeclsDumper : public DelegatingDeserializationListener {
100 public:
101  explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
102  bool DeletePrevious)
103  : DelegatingDeserializationListener(Previous, DeletePrevious) {}
104 
105  void DeclRead(GlobalDeclID ID, const Decl *D) override {
106  llvm::outs() << "PCH DECL: " << D->getDeclKindName();
107  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
108  llvm::outs() << " - ";
109  ND->printQualifiedName(llvm::outs());
110  }
111  llvm::outs() << "\n";
112 
113  DelegatingDeserializationListener::DeclRead(ID, D);
114  }
115 };
116 
117 /// Checks deserialized declarations and emits error if a name
118 /// matches one given in command-line using -error-on-deserialized-decl.
119 class DeserializedDeclsChecker : public DelegatingDeserializationListener {
120  ASTContext &Ctx;
121  std::set<std::string> NamesToCheck;
122 
123 public:
124  DeserializedDeclsChecker(ASTContext &Ctx,
125  const std::set<std::string> &NamesToCheck,
127  bool DeletePrevious)
128  : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
129  NamesToCheck(NamesToCheck) {}
130 
131  void DeclRead(GlobalDeclID ID, const Decl *D) override {
132  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
133  if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
134  unsigned DiagID
136  "%0 was deserialized");
137  Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID)
138  << ND;
139  }
140 
141  DelegatingDeserializationListener::DeclRead(ID, D);
142  }
143 };
144 
145 } // end anonymous namespace
146 
147 FrontendAction::FrontendAction() : Instance(nullptr) {}
148 
150 
152  std::unique_ptr<ASTUnit> AST) {
153  this->CurrentInput = CurrentInput;
154  CurrentASTUnit = std::move(AST);
155 }
156 
160  CI.getLangOpts().CurrentModule, SourceLocation(), /*AllowSearch*/false);
161 }
162 
163 std::unique_ptr<ASTConsumer>
164 FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
165  StringRef InFile) {
166  std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile);
167  if (!Consumer)
168  return nullptr;
169 
170  // Validate -add-plugin args.
171  bool FoundAllPlugins = true;
172  for (const std::string &Arg : CI.getFrontendOpts().AddPluginActions) {
173  bool Found = false;
174  for (const FrontendPluginRegistry::entry &Plugin :
175  FrontendPluginRegistry::entries()) {
176  if (Plugin.getName() == Arg)
177  Found = true;
178  }
179  if (!Found) {
180  CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << Arg;
181  FoundAllPlugins = false;
182  }
183  }
184  if (!FoundAllPlugins)
185  return nullptr;
186 
187  // If there are no registered plugins we don't need to wrap the consumer
188  if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())
189  return Consumer;
190 
191  // If this is a code completion run, avoid invoking the plugin consumers
192  if (CI.hasCodeCompletionConsumer())
193  return Consumer;
194 
195  // Collect the list of plugins that go before the main action (in Consumers)
196  // or after it (in AfterConsumers)
197  std::vector<std::unique_ptr<ASTConsumer>> Consumers;
198  std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers;
199  for (const FrontendPluginRegistry::entry &Plugin :
200  FrontendPluginRegistry::entries()) {
201  std::unique_ptr<PluginASTAction> P = Plugin.instantiate();
202  PluginASTAction::ActionType ActionType = P->getActionType();
203  if (ActionType == PluginASTAction::CmdlineAfterMainAction ||
205  // This is O(|plugins| * |add_plugins|), but since both numbers are
206  // way below 50 in practice, that's ok.
207  if (llvm::is_contained(CI.getFrontendOpts().AddPluginActions,
208  Plugin.getName())) {
211  else
213  }
214  }
215  if ((ActionType == PluginASTAction::AddBeforeMainAction ||
216  ActionType == PluginASTAction::AddAfterMainAction) &&
217  P->ParseArgs(
218  CI,
219  CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())])) {
220  std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile);
221  if (ActionType == PluginASTAction::AddBeforeMainAction) {
222  Consumers.push_back(std::move(PluginConsumer));
223  } else {
224  AfterConsumers.push_back(std::move(PluginConsumer));
225  }
226  }
227  }
228 
229  // Add to Consumers the main consumer, then all the plugins that go after it
230  Consumers.push_back(std::move(Consumer));
231  if (!AfterConsumers.empty()) {
232  // If we have plugins after the main consumer, which may be the codegen
233  // action, they likely will need the ASTContext, so don't clear it in the
234  // codegen action.
235  CI.getCodeGenOpts().ClearASTBeforeBackend = false;
236  for (auto &C : AfterConsumers)
237  Consumers.push_back(std::move(C));
238  }
239 
240  return std::make_unique<MultiplexConsumer>(std::move(Consumers));
241 }
242 
243 /// For preprocessed files, if the first line is the linemarker and specifies
244 /// the original source file name, use that name as the input file name.
245 /// Returns the location of the first token after the line marker directive.
246 ///
247 /// \param CI The compiler instance.
248 /// \param InputFile Populated with the filename from the line marker.
249 /// \param IsModuleMap If \c true, add a line note corresponding to this line
250 /// directive. (We need to do this because the directive will not be
251 /// visited by the preprocessor.)
253  std::string &InputFile,
254  bool IsModuleMap = false) {
255  auto &SourceMgr = CI.getSourceManager();
256  auto MainFileID = SourceMgr.getMainFileID();
257 
258  auto MainFileBuf = SourceMgr.getBufferOrNone(MainFileID);
259  if (!MainFileBuf)
260  return SourceLocation();
261 
262  std::unique_ptr<Lexer> RawLexer(
263  new Lexer(MainFileID, *MainFileBuf, SourceMgr, CI.getLangOpts()));
264 
265  // If the first line has the syntax of
266  //
267  // # NUM "FILENAME"
268  //
269  // we use FILENAME as the input file name.
270  Token T;
271  if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)
272  return SourceLocation();
273  if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||
274  T.getKind() != tok::numeric_constant)
275  return SourceLocation();
276 
277  unsigned LineNo;
278  SourceLocation LineNoLoc = T.getLocation();
279  if (IsModuleMap) {
280  llvm::SmallString<16> Buffer;
281  if (Lexer::getSpelling(LineNoLoc, Buffer, SourceMgr, CI.getLangOpts())
282  .getAsInteger(10, LineNo))
283  return SourceLocation();
284  }
285 
286  RawLexer->LexFromRawLexer(T);
287  if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
288  return SourceLocation();
289 
291  if (Literal.hadError)
292  return SourceLocation();
293  RawLexer->LexFromRawLexer(T);
294  if (T.isNot(tok::eof) && !T.isAtStartOfLine())
295  return SourceLocation();
296  InputFile = Literal.GetString().str();
297 
298  if (IsModuleMap)
300  LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile), false,
301  false, SrcMgr::C_User_ModuleMap);
302 
303  return T.getLocation();
304 }
305 
306 static SmallVectorImpl<char> &
307 operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
308  Includes.append(RHS.begin(), RHS.end());
309  return Includes;
310 }
311 
312 static void addHeaderInclude(StringRef HeaderName,
313  SmallVectorImpl<char> &Includes,
314  const LangOptions &LangOpts,
315  bool IsExternC) {
316  if (IsExternC && LangOpts.CPlusPlus)
317  Includes += "extern \"C\" {\n";
318  if (LangOpts.ObjC)
319  Includes += "#import \"";
320  else
321  Includes += "#include \"";
322 
323  Includes += HeaderName;
324 
325  Includes += "\"\n";
326  if (IsExternC && LangOpts.CPlusPlus)
327  Includes += "}\n";
328 }
329 
330 /// Collect the set of header includes needed to construct the given
331 /// module and update the TopHeaders file set of the module.
332 ///
333 /// \param Module The module we're collecting includes from.
334 ///
335 /// \param Includes Will be augmented with the set of \#includes or \#imports
336 /// needed to load all of the named headers.
337 static std::error_code collectModuleHeaderIncludes(
338  const LangOptions &LangOpts, FileManager &FileMgr, DiagnosticsEngine &Diag,
339  ModuleMap &ModMap, clang::Module *Module, SmallVectorImpl<char> &Includes) {
340  // Don't collect any headers for unavailable modules.
341  if (!Module->isAvailable())
342  return std::error_code();
343 
344  // Resolve all lazy header directives to header files.
345  ModMap.resolveHeaderDirectives(Module, /*File=*/std::nullopt);
346 
347  // If any headers are missing, we can't build this module. In most cases,
348  // diagnostics for this should have already been produced; we only get here
349  // if explicit stat information was provided.
350  // FIXME: If the name resolves to a file with different stat information,
351  // produce a better diagnostic.
352  if (!Module->MissingHeaders.empty()) {
353  auto &MissingHeader = Module->MissingHeaders.front();
354  Diag.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
355  << MissingHeader.IsUmbrella << MissingHeader.FileName;
356  return std::error_code();
357  }
358 
359  // Add includes for each of these headers.
360  for (auto HK : {Module::HK_Normal, Module::HK_Private}) {
361  for (Module::Header &H : Module->Headers[HK]) {
362  Module->addTopHeader(H.Entry);
363  // Use the path as specified in the module map file. We'll look for this
364  // file relative to the module build directory (the directory containing
365  // the module map file) so this will find the same file that we found
366  // while parsing the module map.
367  addHeaderInclude(H.PathRelativeToRootModuleDirectory, Includes, LangOpts,
368  Module->IsExternC);
369  }
370  }
371  // Note that Module->PrivateHeaders will not be a TopHeader.
372 
373  if (std::optional<Module::Header> UmbrellaHeader =
375  Module->addTopHeader(UmbrellaHeader->Entry);
376  if (Module->Parent)
377  // Include the umbrella header for submodules.
378  addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
379  Includes, LangOpts, Module->IsExternC);
380  } else if (std::optional<Module::DirectoryName> UmbrellaDir =
382  // Add all of the headers we find in this subdirectory.
383  std::error_code EC;
384  SmallString<128> DirNative;
385  llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative);
386 
387  llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
389  for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
390  Dir != End && !EC; Dir.increment(EC)) {
391  // Check whether this entry has an extension typically associated with
392  // headers.
393  if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path()))
394  .Cases(".h", ".H", ".hh", ".hpp", true)
395  .Default(false))
396  continue;
397 
398  auto Header = FileMgr.getOptionalFileRef(Dir->path());
399  // FIXME: This shouldn't happen unless there is a file system race. Is
400  // that worth diagnosing?
401  if (!Header)
402  continue;
403 
404  // If this header is marked 'unavailable' in this module, don't include
405  // it.
406  if (ModMap.isHeaderUnavailableInModule(*Header, Module))
407  continue;
408 
409  // Compute the relative path from the directory to this file.
410  SmallVector<StringRef, 16> Components;
411  auto PathIt = llvm::sys::path::rbegin(Dir->path());
412  for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt)
413  Components.push_back(*PathIt);
414  SmallString<128> RelativeHeader(
415  UmbrellaDir->PathRelativeToRootModuleDirectory);
416  for (auto It = Components.rbegin(), End = Components.rend(); It != End;
417  ++It)
418  llvm::sys::path::append(RelativeHeader, *It);
419 
420  std::string RelName = RelativeHeader.c_str();
421  Headers.push_back(std::make_pair(RelName, *Header));
422  }
423 
424  if (EC)
425  return EC;
426 
427  // Sort header paths and make the header inclusion order deterministic
428  // across different OSs and filesystems.
429  llvm::sort(Headers, llvm::less_first());
430  for (auto &H : Headers) {
431  // Include this header as part of the umbrella directory.
432  Module->addTopHeader(H.second);
433  addHeaderInclude(H.first, Includes, LangOpts, Module->IsExternC);
434  }
435  }
436 
437  // Recurse into submodules.
438  for (auto *Submodule : Module->submodules())
439  if (std::error_code Err = collectModuleHeaderIncludes(
440  LangOpts, FileMgr, Diag, ModMap, Submodule, Includes))
441  return Err;
442 
443  return std::error_code();
444 }
445 
446 static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem,
447  bool IsPreprocessed,
448  std::string &PresumedModuleMapFile,
449  unsigned &Offset) {
450  auto &SrcMgr = CI.getSourceManager();
452 
453  // Map the current input to a file.
454  FileID ModuleMapID = SrcMgr.getMainFileID();
455  OptionalFileEntryRef ModuleMap = SrcMgr.getFileEntryRefForID(ModuleMapID);
456  assert(ModuleMap && "MainFileID without FileEntry");
457 
458  // If the module map is preprocessed, handle the initial line marker;
459  // line directives are not part of the module map syntax in general.
460  Offset = 0;
461  if (IsPreprocessed) {
462  SourceLocation EndOfLineMarker =
463  ReadOriginalFileName(CI, PresumedModuleMapFile, /*IsModuleMap*/ true);
464  if (EndOfLineMarker.isValid())
465  Offset = CI.getSourceManager().getDecomposedLoc(EndOfLineMarker).second;
466  }
467 
468  // Load the module map file.
469  if (HS.loadModuleMapFile(*ModuleMap, IsSystem, ModuleMapID, &Offset,
470  PresumedModuleMapFile))
471  return true;
472 
473  if (SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset)
474  Offset = 0;
475 
476  // Infer framework module if possible.
477  if (HS.getModuleMap().canInferFrameworkModule(ModuleMap->getDir())) {
478  SmallString<128> InferredFrameworkPath = ModuleMap->getDir().getName();
479  llvm::sys::path::append(InferredFrameworkPath,
480  CI.getLangOpts().ModuleName + ".framework");
481  if (auto Dir =
482  CI.getFileManager().getOptionalDirectoryRef(InferredFrameworkPath))
483  (void)HS.getModuleMap().inferFrameworkModule(*Dir, IsSystem, nullptr);
484  }
485 
486  return false;
487 }
488 
490  StringRef ModuleMapFilename) {
491  if (CI.getLangOpts().CurrentModule.empty()) {
492  CI.getDiagnostics().Report(diag::err_missing_module_name);
493 
494  // FIXME: Eventually, we could consider asking whether there was just
495  // a single module described in the module map, and use that as a
496  // default. Then it would be fairly trivial to just "compile" a module
497  // map with a single module (the common case).
498  return nullptr;
499  }
500 
501  // Dig out the module definition.
504  /*AllowSearch=*/true);
505  if (!M) {
506  CI.getDiagnostics().Report(diag::err_missing_module)
507  << CI.getLangOpts().CurrentModule << ModuleMapFilename;
508 
509  return nullptr;
510  }
511 
512  // Check whether we can build this module at all.
514  CI.getDiagnostics()))
515  return nullptr;
516 
517  // Inform the preprocessor that includes from within the input buffer should
518  // be resolved relative to the build directory of the module map file.
520 
521  // If the module was inferred from a different module map (via an expanded
522  // umbrella module definition), track that fact.
523  // FIXME: It would be preferable to fill this in as part of processing
524  // the module map, rather than adding it after the fact.
525  StringRef OriginalModuleMapName = CI.getFrontendOpts().OriginalModuleMap;
526  if (!OriginalModuleMapName.empty()) {
527  auto OriginalModuleMap =
528  CI.getFileManager().getOptionalFileRef(OriginalModuleMapName,
529  /*openFile*/ true);
530  if (!OriginalModuleMap) {
531  CI.getDiagnostics().Report(diag::err_module_map_not_found)
532  << OriginalModuleMapName;
533  return nullptr;
534  }
535  if (*OriginalModuleMap != CI.getSourceManager().getFileEntryRefForID(
537  M->IsInferred = true;
538  auto FileCharacter =
540  FileID OriginalModuleMapFID = CI.getSourceManager().getOrCreateFileID(
541  *OriginalModuleMap, FileCharacter);
542  CI.getPreprocessor()
544  .getModuleMap()
545  .setInferredModuleAllowedBy(M, OriginalModuleMapFID);
546  }
547  }
548 
549  // If we're being run from the command-line, the module build stack will not
550  // have been filled in yet, so complete it now in order to allow us to detect
551  // module cycles.
552  SourceManager &SourceMgr = CI.getSourceManager();
553  if (SourceMgr.getModuleBuildStack().empty())
555  FullSourceLoc(SourceLocation(), SourceMgr));
556  return M;
557 }
558 
559 /// Compute the input buffer that should be used to build the specified module.
560 static std::unique_ptr<llvm::MemoryBuffer>
562  FileManager &FileMgr = CI.getFileManager();
563 
564  // Collect the set of #includes we need to build the module.
565  SmallString<256> HeaderContents;
566  std::error_code Err = std::error_code();
567  if (std::optional<Module::Header> UmbrellaHeader =
569  addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
570  HeaderContents, CI.getLangOpts(), M->IsExternC);
572  CI.getLangOpts(), FileMgr, CI.getDiagnostics(),
574  HeaderContents);
575 
576  if (Err) {
577  CI.getDiagnostics().Report(diag::err_module_cannot_create_includes)
578  << M->getFullModuleName() << Err.message();
579  return nullptr;
580  }
581 
582  return llvm::MemoryBuffer::getMemBufferCopy(
583  HeaderContents, Module::getModuleInputBufferName());
584 }
585 
587  const FrontendInputFile &RealInput) {
588  FrontendInputFile Input(RealInput);
589  assert(!Instance && "Already processing a source file!");
590  assert(!Input.isEmpty() && "Unexpected empty filename!");
591  setCurrentInput(Input);
592  setCompilerInstance(&CI);
593 
594  bool HasBegunSourceFile = false;
595  bool ReplayASTFile = Input.getKind().getFormat() == InputKind::Precompiled &&
597 
598  // If we fail, reset state since the client will not end up calling the
599  // matching EndSourceFile(). All paths that return true should release this.
600  auto FailureCleanup = llvm::make_scope_exit([&]() {
601  if (HasBegunSourceFile)
603  CI.setASTConsumer(nullptr);
604  CI.clearOutputFiles(/*EraseFiles=*/true);
605  CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
607  setCompilerInstance(nullptr);
608  });
609 
610  if (!BeginInvocation(CI))
611  return false;
612 
613  // If we're replaying the build of an AST file, import it and set up
614  // the initial state from its build.
615  if (ReplayASTFile) {
617 
618  // The AST unit populates its own diagnostics engine rather than ours.
620  new DiagnosticsEngine(Diags->getDiagnosticIDs(),
621  &Diags->getDiagnosticOptions()));
622  ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false);
623 
624  // FIXME: What if the input is a memory buffer?
625  StringRef InputFile = Input.getFile();
626 
627  std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
628  std::string(InputFile), CI.getPCHContainerReader(),
630  /*HeaderSearchOptions=*/nullptr);
631  if (!AST)
632  return false;
633 
634  // Options relating to how we treat the input (but not what we do with it)
635  // are inherited from the AST unit.
636  CI.getHeaderSearchOpts() = AST->getHeaderSearchOpts();
637  CI.getPreprocessorOpts() = AST->getPreprocessorOpts();
638  CI.getLangOpts() = AST->getLangOpts();
639 
640  // Set the shared objects, these are reset when we finish processing the
641  // file, otherwise the CompilerInstance will happily destroy them.
642  CI.setFileManager(&AST->getFileManager());
644  CI.getSourceManager().initializeForReplay(AST->getSourceManager());
645 
646  // Preload all the module files loaded transitively by the AST unit. Also
647  // load all module map files that were parsed as part of building the AST
648  // unit.
649  if (auto ASTReader = AST->getASTReader()) {
650  auto &MM = ASTReader->getModuleManager();
651  auto &PrimaryModule = MM.getPrimaryModule();
652 
653  for (serialization::ModuleFile &MF : MM)
654  if (&MF != &PrimaryModule)
655  CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName);
656 
657  ASTReader->visitTopLevelModuleMaps(PrimaryModule, [&](FileEntryRef FE) {
658  CI.getFrontendOpts().ModuleMapFiles.push_back(
659  std::string(FE.getName()));
660  });
661  }
662 
663  // Set up the input file for replay purposes.
664  auto Kind = AST->getInputKind();
665  if (Kind.getFormat() == InputKind::ModuleMap) {
666  Module *ASTModule =
667  AST->getPreprocessor().getHeaderSearchInfo().lookupModule(
668  AST->getLangOpts().CurrentModule, SourceLocation(),
669  /*AllowSearch*/ false);
670  assert(ASTModule && "module file does not define its own module");
671  Input = FrontendInputFile(ASTModule->PresumedModuleMapFile, Kind);
672  } else {
673  auto &OldSM = AST->getSourceManager();
674  FileID ID = OldSM.getMainFileID();
675  if (auto File = OldSM.getFileEntryRefForID(ID))
676  Input = FrontendInputFile(File->getName(), Kind);
677  else
678  Input = FrontendInputFile(OldSM.getBufferOrFake(ID), Kind);
679  }
680  setCurrentInput(Input, std::move(AST));
681  }
682 
683  // AST files follow a very different path, since they share objects via the
684  // AST unit.
685  if (Input.getKind().getFormat() == InputKind::Precompiled) {
686  assert(!usesPreprocessorOnly() && "this case was handled above");
687  assert(hasASTFileSupport() &&
688  "This action does not have AST file support!");
689 
691 
692  // FIXME: What if the input is a memory buffer?
693  StringRef InputFile = Input.getFile();
694 
695  std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
696  std::string(InputFile), CI.getPCHContainerReader(),
699 
700  if (!AST)
701  return false;
702 
703  // Inform the diagnostic client we are processing a source file.
704  CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
705  HasBegunSourceFile = true;
706 
707  // Set the shared objects, these are reset when we finish processing the
708  // file, otherwise the CompilerInstance will happily destroy them.
709  CI.setFileManager(&AST->getFileManager());
710  CI.setSourceManager(&AST->getSourceManager());
711  CI.setPreprocessor(AST->getPreprocessorPtr());
712  Preprocessor &PP = CI.getPreprocessor();
714  PP.getLangOpts());
715  CI.setASTContext(&AST->getASTContext());
716 
717  setCurrentInput(Input, std::move(AST));
718 
719  // Initialize the action.
720  if (!BeginSourceFileAction(CI))
721  return false;
722 
723  // Create the AST consumer.
724  CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));
725  if (!CI.hasASTConsumer())
726  return false;
727 
728  FailureCleanup.release();
729  return true;
730  }
731 
732  // Set up the file and source managers, if needed.
733  if (!CI.hasFileManager()) {
734  if (!CI.createFileManager()) {
735  return false;
736  }
737  }
738  if (!CI.hasSourceManager()) {
740  if (CI.getDiagnosticOpts().getFormat() == DiagnosticOptions::SARIF) {
741  static_cast<SARIFDiagnosticPrinter *>(&CI.getDiagnosticClient())
742  ->setSarifWriter(
743  std::make_unique<SarifDocumentWriter>(CI.getSourceManager()));
744  }
745  }
746 
747  // Set up embedding for any specified files. Do this before we load any
748  // source files, including the primary module map for the compilation.
749  for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
750  if (auto FE = CI.getFileManager().getOptionalFileRef(F, /*openFile*/true))
752  else
753  CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
754  }
757 
758  // IR files bypass the rest of initialization.
759  if (Input.getKind().getLanguage() == Language::LLVM_IR) {
760  if (!hasIRSupport()) {
761  CI.getDiagnostics().Report(diag::err_ast_action_on_llvm_ir)
762  << Input.getFile();
763  return false;
764  }
765 
766  // Inform the diagnostic client we are processing a source file.
767  CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
768  HasBegunSourceFile = true;
769 
770  // Initialize the action.
771  if (!BeginSourceFileAction(CI))
772  return false;
773 
774  // Initialize the main file entry.
775  if (!CI.InitializeSourceManager(CurrentInput))
776  return false;
777 
778  FailureCleanup.release();
779  return true;
780  }
781 
782  // If the implicit PCH include is actually a directory, rather than
783  // a single file, search for a suitable PCH file in that directory.
784  if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
785  FileManager &FileMgr = CI.getFileManager();
787  StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
788  std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
789  if (auto PCHDir = FileMgr.getOptionalDirectoryRef(PCHInclude)) {
790  std::error_code EC;
791  SmallString<128> DirNative;
792  llvm::sys::path::native(PCHDir->getName(), DirNative);
793  bool Found = false;
794  llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
795  for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
796  DirEnd;
797  Dir != DirEnd && !EC; Dir.increment(EC)) {
798  // Check whether this is an acceptable AST file.
800  Dir->path(), FileMgr, CI.getModuleCache(),
803  SpecificModuleCachePath, /*RequireStrictOptionMatches=*/true)) {
804  PPOpts.ImplicitPCHInclude = std::string(Dir->path());
805  Found = true;
806  break;
807  }
808  }
809 
810  if (!Found) {
811  CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
812  return false;
813  }
814  }
815  }
816 
817  // Set up the preprocessor if needed. When parsing model files the
818  // preprocessor of the original source is reused.
819  if (!isModelParsingAction())
821 
822  // Inform the diagnostic client we are processing a source file.
824  &CI.getPreprocessor());
825  HasBegunSourceFile = true;
826 
827  // Handle C++20 header units.
828  // Here, the user has the option to specify that the header name should be
829  // looked up in the pre-processor search paths (and the main filename as
830  // passed by the driver might therefore be incomplete until that look-up).
831  if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
832  !Input.getKind().isPreprocessed()) {
833  StringRef FileName = Input.getFile();
834  InputKind Kind = Input.getKind();
835  if (Kind.getHeaderUnitKind() != InputKind::HeaderUnit_Abs) {
836  assert(CI.hasPreprocessor() &&
837  "trying to build a header unit without a Pre-processor?");
839  // Relative searches begin from CWD.
840  auto Dir = CI.getFileManager().getOptionalDirectoryRef(".");
842  CWD.push_back({std::nullopt, *Dir});
845  /*Angled*/ Input.getKind().getHeaderUnitKind() ==
847  nullptr, nullptr, CWD, nullptr, nullptr, nullptr,
848  nullptr, nullptr, nullptr);
849  if (!FE) {
850  CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
851  << FileName;
852  return false;
853  }
854  // We now have the filename...
855  FileName = FE->getName();
856  // ... still a header unit, but now use the path as written.
858  Input = FrontendInputFile(FileName, Kind, Input.isSystem());
859  }
860  // Unless the user has overridden the name, the header unit module name is
861  // the pathname for the file.
862  if (CI.getLangOpts().ModuleName.empty())
863  CI.getLangOpts().ModuleName = std::string(FileName);
865  }
866 
867  if (!CI.InitializeSourceManager(Input))
868  return false;
869 
870  if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
871  Input.getKind().isPreprocessed() && !usesPreprocessorOnly()) {
872  // We have an input filename like foo.iih, but we want to find the right
873  // module name (and original file, to build the map entry).
874  // Check if the first line specifies the original source file name with a
875  // linemarker.
876  std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
877  ReadOriginalFileName(CI, PresumedInputFile);
878  // Unless the user overrides this, the module name is the name by which the
879  // original file was known.
880  if (CI.getLangOpts().ModuleName.empty())
881  CI.getLangOpts().ModuleName = std::string(PresumedInputFile);
883  }
884 
885  // For module map files, we first parse the module map and synthesize a
886  // "<module-includes>" buffer before more conventional processing.
887  if (Input.getKind().getFormat() == InputKind::ModuleMap) {
888  CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);
889 
890  std::string PresumedModuleMapFile;
891  unsigned OffsetToContents;
892  if (loadModuleMapForModuleBuild(CI, Input.isSystem(),
893  Input.isPreprocessed(),
894  PresumedModuleMapFile, OffsetToContents))
895  return false;
896 
897  auto *CurrentModule = prepareToBuildModule(CI, Input.getFile());
898  if (!CurrentModule)
899  return false;
900 
901  CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;
902 
903  if (OffsetToContents)
904  // If the module contents are in the same file, skip to them.
905  CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true);
906  else {
907  // Otherwise, convert the module description to a suitable input buffer.
908  auto Buffer = getInputBufferForModule(CI, CurrentModule);
909  if (!Buffer)
910  return false;
911 
912  // Reinitialize the main file entry to refer to the new input.
913  auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
914  auto &SourceMgr = CI.getSourceManager();
915  auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);
916  assert(BufferID.isValid() && "couldn't create module buffer ID");
917  SourceMgr.setMainFileID(BufferID);
918  }
919  }
920 
921  // Initialize the action.
922  if (!BeginSourceFileAction(CI))
923  return false;
924 
925  // If we were asked to load any module map files, do so now.
926  for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
929  *File, /*IsSystem*/false);
930  else
931  CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
932  }
933 
934  // If compiling implementation of a module, load its module map file now.
936 
937  // Add a module declaration scope so that modules from -fmodule-map-file
938  // arguments may shadow modules found implicitly in search paths.
939  CI.getPreprocessor()
941  .getModuleMap()
943 
944  // Create the AST context and consumer unless this is a preprocessor only
945  // action.
946  if (!usesPreprocessorOnly()) {
947  // Parsing a model file should reuse the existing ASTContext.
948  if (!isModelParsingAction())
949  CI.createASTContext();
950 
951  // For preprocessed files, check if the first line specifies the original
952  // source file name with a linemarker.
953  std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
954  if (Input.isPreprocessed())
955  ReadOriginalFileName(CI, PresumedInputFile);
956 
957  std::unique_ptr<ASTConsumer> Consumer =
958  CreateWrappedASTConsumer(CI, PresumedInputFile);
959  if (!Consumer)
960  return false;
961 
962  // FIXME: should not overwrite ASTMutationListener when parsing model files?
963  if (!isModelParsingAction())
964  CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
965 
966  if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
967  // Convert headers to PCH and chain them.
968  IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
969  source = createChainedIncludesSource(CI, FinalReader);
970  if (!source)
971  return false;
972  CI.setASTReader(static_cast<ASTReader *>(FinalReader.get()));
973  CI.getASTContext().setExternalSource(source);
974  } else if (CI.getLangOpts().Modules ||
975  !CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
976  // Use PCM or PCH.
977  assert(hasPCHSupport() && "This action does not have PCH support!");
978  ASTDeserializationListener *DeserialListener =
979  Consumer->GetASTDeserializationListener();
980  bool DeleteDeserialListener = false;
982  DeserialListener = new DeserializedDeclsDumper(DeserialListener,
983  DeleteDeserialListener);
984  DeleteDeserialListener = true;
985  }
987  DeserialListener = new DeserializedDeclsChecker(
988  CI.getASTContext(),
990  DeserialListener, DeleteDeserialListener);
991  DeleteDeserialListener = true;
992  }
993  if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
998  DeserialListener, DeleteDeserialListener);
999  if (!CI.getASTContext().getExternalSource())
1000  return false;
1001  }
1002  // If modules are enabled, create the AST reader before creating
1003  // any builtins, so that all declarations know that they might be
1004  // extended by an external source.
1005  if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1006  !CI.getASTContext().getExternalSource()) {
1007  CI.createASTReader();
1008  CI.getASTReader()->setDeserializationListener(DeserialListener,
1009  DeleteDeserialListener);
1010  }
1011  }
1012 
1013  CI.setASTConsumer(std::move(Consumer));
1014  if (!CI.hasASTConsumer())
1015  return false;
1016  }
1017 
1018  // Initialize built-in info as long as we aren't using an external AST
1019  // source.
1020  if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1021  !CI.getASTContext().getExternalSource()) {
1022  Preprocessor &PP = CI.getPreprocessor();
1024  PP.getLangOpts());
1025  } else {
1026  // FIXME: If this is a problem, recover from it by creating a multiplex
1027  // source.
1028  assert((!CI.getLangOpts().Modules || CI.getASTReader()) &&
1029  "modules enabled but created an external source that "
1030  "doesn't support modules");
1031  }
1032 
1033  // If we were asked to load any module files, do so now.
1034  for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) {
1035  serialization::ModuleFile *Loaded = nullptr;
1036  if (!CI.loadModuleFile(ModuleFile, Loaded))
1037  return false;
1038 
1039  if (Loaded && Loaded->StandardCXXModule)
1040  CI.getDiagnostics().Report(
1041  diag::warn_eagerly_load_for_standard_cplusplus_modules);
1042  }
1043 
1044  // If there is a layout overrides file, attach an external AST source that
1045  // provides the layouts from that file.
1046  if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
1047  CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
1049  Override(new LayoutOverrideSource(
1051  CI.getASTContext().setExternalSource(Override);
1052  }
1053 
1054  // Setup HLSL External Sema Source
1055  if (CI.getLangOpts().HLSL && CI.hasASTContext()) {
1057  new HLSLExternalSemaSource());
1058  if (auto *SemaSource = dyn_cast_if_present<ExternalSemaSource>(
1059  CI.getASTContext().getExternalSource())) {
1061  new MultiplexExternalSemaSource(SemaSource, HLSLSema.get()));
1062  CI.getASTContext().setExternalSource(MultiSema);
1063  } else
1064  CI.getASTContext().setExternalSource(HLSLSema);
1065  }
1066 
1067  FailureCleanup.release();
1068  return true;
1069 }
1070 
1073 
1074  if (CI.hasFrontendTimer()) {
1075  llvm::TimeRegion Timer(CI.getFrontendTimer());
1076  ExecuteAction();
1077  }
1078  else ExecuteAction();
1079 
1080  // If we are supposed to rebuild the global module index, do so now unless
1081  // there were any module-build failures.
1082  if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() &&
1083  CI.hasPreprocessor()) {
1084  StringRef Cache =
1086  if (!Cache.empty()) {
1087  if (llvm::Error Err = GlobalModuleIndex::writeIndex(
1089  // FIXME this drops the error on the floor, but
1090  // Index/pch-from-libclang.c seems to rely on dropping at least some of
1091  // the error conditions!
1092  consumeError(std::move(Err));
1093  }
1094  }
1095  }
1096 
1097  return llvm::Error::success();
1098 }
1099 
1102 
1103  // Inform the diagnostic client we are done with this source file.
1105 
1106  // Inform the preprocessor we are done.
1107  if (CI.hasPreprocessor())
1109 
1110  // Finalize the action.
1112 
1113  // Sema references the ast consumer, so reset sema first.
1114  //
1115  // FIXME: There is more per-file stuff we could just drop here?
1116  bool DisableFree = CI.getFrontendOpts().DisableFree;
1117  if (DisableFree) {
1118  CI.resetAndLeakSema();
1120  llvm::BuryPointer(CI.takeASTConsumer().get());
1121  } else {
1122  CI.setSema(nullptr);
1123  CI.setASTContext(nullptr);
1124  CI.setASTConsumer(nullptr);
1125  }
1126 
1127  if (CI.getFrontendOpts().ShowStats) {
1128  llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFileOrBufferName() << "':\n";
1129  CI.getPreprocessor().PrintStats();
1133  llvm::errs() << "\n";
1134  }
1135 
1136  // Cleanup the output streams, and erase the output files if instructed by the
1137  // FrontendAction.
1138  CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
1139 
1140  // The resources are owned by AST when the current file is AST.
1141  // So we reset the resources here to avoid users accessing it
1142  // accidently.
1143  if (isCurrentFileAST()) {
1144  if (DisableFree) {
1148  llvm::BuryPointer(std::move(CurrentASTUnit));
1149  } else {
1150  CI.setPreprocessor(nullptr);
1151  CI.setSourceManager(nullptr);
1152  CI.setFileManager(nullptr);
1153  }
1154  }
1155 
1156  setCompilerInstance(nullptr);
1158  CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
1159 }
1160 
1163 }
1164 
1165 //===----------------------------------------------------------------------===//
1166 // Utility Actions
1167 //===----------------------------------------------------------------------===//
1168 
1171  if (!CI.hasPreprocessor())
1172  return;
1173  // This is a fallback: If the client forgets to invoke this, we mark the
1174  // current stack as the bottom. Though not optimal, this could help prevent
1175  // stack overflow during deep recursion.
1177 
1178  // FIXME: Move the truncation aspect of this into Sema, we delayed this till
1179  // here so the source manager would be initialized.
1180  if (hasCodeCompletionSupport() &&
1183 
1184  // Use a code completion consumer?
1185  CodeCompleteConsumer *CompletionConsumer = nullptr;
1186  if (CI.hasCodeCompletionConsumer())
1187  CompletionConsumer = &CI.getCodeCompletionConsumer();
1188 
1189  if (!CI.hasSema())
1190  CI.createSema(getTranslationUnitKind(), CompletionConsumer);
1191 
1194 }
1195 
1196 void PluginASTAction::anchor() { }
1197 
1198 std::unique_ptr<ASTConsumer>
1200  StringRef InFile) {
1201  llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
1202 }
1203 
1205  return WrappedAction->PrepareToExecuteAction(CI);
1206 }
1207 std::unique_ptr<ASTConsumer>
1209  StringRef InFile) {
1210  return WrappedAction->CreateASTConsumer(CI, InFile);
1211 }
1213  return WrappedAction->BeginInvocation(CI);
1214 }
1216  WrappedAction->setCurrentInput(getCurrentInput());
1217  WrappedAction->setCompilerInstance(&CI);
1218  auto Ret = WrappedAction->BeginSourceFileAction(CI);
1219  // BeginSourceFileAction may change CurrentInput, e.g. during module builds.
1220  setCurrentInput(WrappedAction->getCurrentInput());
1221  return Ret;
1222 }
1224  WrappedAction->ExecuteAction();
1225 }
1228  WrappedAction->EndSourceFileAction();
1229 }
1231  return WrappedAction->shouldEraseOutputFiles();
1232 }
1233 
1235  return WrappedAction->usesPreprocessorOnly();
1236 }
1238  return WrappedAction->getTranslationUnitKind();
1239 }
1241  return WrappedAction->hasPCHSupport();
1242 }
1244  return WrappedAction->hasASTFileSupport();
1245 }
1247  return WrappedAction->hasIRSupport();
1248 }
1250  return WrappedAction->hasCodeCompletionSupport();
1251 }
1252 
1254  std::unique_ptr<FrontendAction> WrappedAction)
1255  : WrappedAction(std::move(WrappedAction)) {}
Defines the clang::ASTContext interface.
StringRef P
static char ID
Definition: Arena.cpp:183
Defines enum values for all the target-independent builtin functions.
Defines interfaces for clang::FileEntry and clang::FileEntryRef.
unsigned Offset
Definition: Format.cpp:2978
StringRef Filename
Definition: Format.cpp:2976
static std::error_code collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr, DiagnosticsEngine &Diag, ModuleMap &ModMap, clang::Module *Module, SmallVectorImpl< char > &Includes)
Collect the set of header includes needed to construct the given module and update the TopHeaders fil...
static Module * prepareToBuildModule(CompilerInstance &CI, StringRef ModuleMapFilename)
static SmallVectorImpl< char > & operator+=(SmallVectorImpl< char > &Includes, StringRef RHS)
static std::unique_ptr< llvm::MemoryBuffer > getInputBufferForModule(CompilerInstance &CI, Module *M)
Compute the input buffer that should be used to build the specified module.
static void addHeaderInclude(StringRef HeaderName, SmallVectorImpl< char > &Includes, const LangOptions &LangOpts, bool IsExternC)
static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem, bool IsPreprocessed, std::string &PresumedModuleMapFile, unsigned &Offset)
static SourceLocation ReadOriginalFileName(CompilerInstance &CI, std::string &InputFile, bool IsModuleMap=false)
For preprocessed files, if the first line is the linemarker and specifies the original source file na...
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Defines the clang::Preprocessor interface.
Defines clang::SarifDocumentWriter, clang::SarifRule, clang::SarifResult.
Defines utilities for dealing with stack allocation and stack space.
SourceLocation End
StateNode * Previous
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:185
FullSourceLoc getFullLoc(SourceLocation Loc) const
Definition: ASTContext.h:798
void setASTMutationListener(ASTMutationListener *Listener)
Attach an AST mutation listener to the AST context.
Definition: ASTContext.h:1212
void setExternalSource(IntrusiveRefCntPtr< ExternalASTSource > Source)
Attach an external AST source to the AST context.
Definition: ASTContext.cpp:947
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Definition: ASTContext.h:1203
DiagnosticsEngine & getDiagnostics() const
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:366
void visitTopLevelModuleMaps(serialization::ModuleFile &MF, llvm::function_ref< void(FileEntryRef)> Visitor)
Visit all the top-level module maps loaded when building the given module file.
Definition: ASTReader.cpp:9540
ModuleManager & getModuleManager()
Retrieve the module manager.
Definition: ASTReader.h:1773
static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr, const InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, StringRef ExistingModuleCachePath, bool RequireStrictOptionMatches=false)
Determine whether the given AST file is acceptable to load into a translation unit with the given lan...
Definition: ASTReader.cpp:5691
@ LoadPreprocessorOnly
Load options and the preprocessor state.
Definition: ASTUnit.h:675
@ LoadEverything
Load everything, including Sema.
Definition: ASTUnit.h:681
static std::unique_ptr< ASTUnit > LoadFromASTFile(const std::string &Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, const FileSystemOptions &FileSystemOpts, std::shared_ptr< HeaderSearchOptions > HSOpts, std::shared_ptr< LangOptions > LangOpts=nullptr, bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, bool AllowASTWithCompilerErrors=false, bool UserFilesAreVolatile=false, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=llvm::vfs::getRealFileSystem())
Create a ASTUnit from an AST file.
Definition: ASTUnit.cpp:800
void initializeBuiltins(IdentifierTable &Table, const LangOptions &LangOpts)
Mark the identifiers for all the builtins with their appropriate builtin ID # and mark any non-portab...
Definition: Builtins.cpp:128
Abstract interface for a consumer of code-completion information.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
void setFileManager(FileManager *Value)
Replace the current file manager and virtual file system.
CodeGenOptions & getCodeGenOpts()
void setSourceManager(SourceManager *Value)
setSourceManager - Replace the current source manager.
void createPCHExternalASTSource(StringRef Path, DisableValidationForModuleKind DisableValidation, bool AllowPCHWithCompilerErrors, void *DeserializationListener, bool OwnDeserializationListener)
Create an external AST source to read a PCH file and attach it to the AST context.
void createPreprocessor(TranslationUnitKind TUKind)
Create the preprocessor, using the invocation, file, and source managers, and replace any existing on...
void createSourceManager(FileManager &FileMgr)
Create the source manager and replace any existing one with it.
FileManager * createFileManager(IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
Create the file manager and replace any existing one with it.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
TargetInfo & getTarget() const
std::shared_ptr< LangOptions > getLangOptsPtr() const
FrontendOptions & getFrontendOpts()
PreprocessorOptions & getPreprocessorOpts()
bool InitializeSourceManager(const FrontendInputFile &Input)
InitializeSourceManager - Initialize the source manager to set InputFile as the main file.
InMemoryModuleCache & getModuleCache() const
CodeCompleteConsumer & getCodeCompletionConsumer() const
void setASTConsumer(std::unique_ptr< ASTConsumer > Value)
setASTConsumer - Replace the current AST consumer; the compiler instance takes ownership of Value.
IntrusiveRefCntPtr< ASTReader > getASTReader() const
FileSystemOptions & getFileSystemOpts()
void createASTContext()
Create the AST context.
ASTContext & getASTContext() const
SourceManager & getSourceManager() const
Return the current source manager.
void setASTContext(ASTContext *Value)
setASTContext - Replace the current AST context.
llvm::Timer & getFrontendTimer() const
void setASTReader(IntrusiveRefCntPtr< ASTReader > Reader)
void setSema(Sema *S)
Replace the current Sema; the compiler instance takes ownership of S.
FileManager & getFileManager() const
Return the current file manager to the caller.
bool hasCodeCompletionConsumer() const
TargetOptions & getTargetOpts()
DiagnosticConsumer & getDiagnosticClient() const
HeaderSearchOptions & getHeaderSearchOpts()
std::string getSpecificModuleCachePath(StringRef ModuleHash)
std::shared_ptr< HeaderSearchOptions > getHeaderSearchOptsPtr() const
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
void createCodeCompletionConsumer()
Create a code completion consumer using the invocation; note that this will cause the source manager ...
LangOptions & getLangOpts()
DiagnosticOptions & getDiagnosticOpts()
void clearOutputFiles(bool EraseFiles)
clearOutputFiles - Clear the output file list.
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
std::unique_ptr< ASTConsumer > takeASTConsumer()
takeASTConsumer - Remove the current AST consumer and give ownership to the caller.
bool shouldBuildGlobalModuleIndex() const
Indicates whether we should (re)build the global module index.
bool loadModuleFile(StringRef FileName, serialization::ModuleFile *&LoadedModuleFile)
void setPreprocessor(std::shared_ptr< Preprocessor > Value)
Replace the current preprocessor.
void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)
Create the Sema object to be used for parsing.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
SourceLocation getLocation() const
Definition: DeclBase.h:445
const char * getDeclKindName() const
Definition: DeclBase.cpp:123
virtual void EndSourceFile()
Callback to inform the diagnostic client that processing of a source file has ended.
Definition: Diagnostic.h:1783
virtual void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP=nullptr)
Callback to inform the diagnostic client that processing of a source file is beginning.
Definition: Diagnostic.h:1775
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:193
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1553
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:879
bool hasErrorOccurred() const
Definition: Diagnostic.h:849
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition: FileEntry.h:57
StringRef getName() const
The name of this FileEntry.
Definition: FileEntry.h:61
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
Definition: FileManager.h:53
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:240
llvm::vfs::FileSystem & getVirtualFileSystem() const
Definition: FileManager.h:251
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:175
virtual void EndSourceFile()
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
virtual bool shouldEraseOutputFiles()
Callback at the end of processing a single input, to determine if the output files should be erased o...
virtual bool hasIRSupport() const
Does this action support use with IR files?
virtual void EndSourceFileAction()
Callback at the end of processing a single input.
llvm::Error Execute()
Set the source manager's main input file, and run the action.
virtual bool hasASTFileSupport() const
Does this action support use with AST files?
const FrontendInputFile & getCurrentInput() const
Module * getCurrentModule() const
void setCurrentInput(const FrontendInputFile &CurrentInput, std::unique_ptr< ASTUnit > AST=nullptr)
virtual std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile)=0
Create the AST consumer object for this action, if supported.
virtual bool BeginSourceFileAction(CompilerInstance &CI)
Callback at the start of processing a single input.
virtual void ExecuteAction()=0
Callback to run the program action, using the initialized compiler instance.
void setCompilerInstance(CompilerInstance *Value)
virtual TranslationUnitKind getTranslationUnitKind()
For AST-based actions, the kind of translation unit we're handling.
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input)
Prepare the action for processing the input file Input.
virtual bool hasCodeCompletionSupport() const
Does this action support use with code completion?
StringRef getCurrentFileOrBufferName() const
virtual bool isModelParsingAction() const
Is this action invoked on a model file?
bool isCurrentFileAST() const
virtual bool usesPreprocessorOnly() const =0
Does this action only use the preprocessor?
friend class WrapperFrontendAction
virtual bool BeginInvocation(CompilerInstance &CI)
Callback before starting processing a single input, giving the opportunity to modify the CompilerInvo...
virtual bool hasPCHSupport() const
Does this action support use with PCH?
CompilerInstance & getCompilerInstance() const
An input file for the front end.
InputKind getKind() const
StringRef getFile() const
std::vector< std::string > ModuleFiles
The list of additional prebuilt module files to load before processing the input.
unsigned SkipFunctionBodies
Skip over function bodies to speed up parsing in cases you do not need them (e.g.
std::map< std::string, std::vector< std::string > > PluginArgs
Args to pass to the plugins.
unsigned ShowStats
Show frontend performance metrics and statistics.
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
std::string OriginalModuleMap
When the input is a module map, the original module map file from which that map was inferred,...
std::vector< std::string > ModulesEmbedFiles
The list of files to embed into the compiled module file.
unsigned ModulesEmbedAllFiles
Whether we should embed all used files into the PCM file.
std::vector< std::string > AddPluginActions
The list of plugin actions to run in addition to the normal action.
unsigned DisableFree
Disable memory freeing on exit.
std::string OverrideRecordLayoutsFile
File name of the file that will provide record layouts (in the format produced by -fdump-record-layou...
std::vector< std::string > ModuleMapFiles
The list of module map files to load before processing the input.
A SourceLocation and its associated SourceManager.
static llvm::Error writeIndex(FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, llvm::StringRef Path)
Write a global index into the given.
Encapsulates the information needed to find the file referenced by a #include or #include_next,...
Definition: HeaderSearch.h:253
Module * lookupModule(StringRef ModuleName, SourceLocation ImportLoc=SourceLocation(), bool AllowSearch=true, bool AllowExtraModuleMapSearch=false)
Lookup a module Search for a module with the given name.
StringRef getModuleCachePath() const
Retrieve the path to the module cache.
Definition: HeaderSearch.h:450
OptionalFileEntryRef LookupFile(StringRef Filename, SourceLocation IncludeLoc, bool isAngled, ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDir, ArrayRef< std::pair< OptionalFileEntryRef, DirectoryEntryRef >> Includers, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false, bool BuildSystemModule=false, bool OpenFile=true, bool CacheFailures=true)
Given a "foo" or <foo> reference, look up the indicated file, return null on failure.
bool loadModuleMapFile(FileEntryRef File, bool IsSystem, FileID ID=FileID(), unsigned *Offset=nullptr, StringRef OriginalModuleMapFile=StringRef())
Read the contents of the given module map file.
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:837
One of these records is kept for each identifier that is lexed.
void PrintStats() const
Print some statistics to stderr that indicate how well the hashing is doing.
The kind of a file that we've been handed as an input.
bool isPreprocessed() const
InputKind withHeaderUnit(HeaderUnitKind HU) const
bool isHeaderUnit() const
Format getFormat() const
HeaderUnitKind getHeaderUnitKind() const
Language getLanguage() const
@ CMK_None
Not compiling a module interface at all.
Definition: LangOptions.h:99
@ CMK_ModuleMap
Compiling a module from a module map.
Definition: LangOptions.h:102
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:482
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
Definition: LangOptions.h:530
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:537
An external AST source that overrides the layout of a specified set of record types.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
Definition: Lexer.h:78
static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)
getSpelling - This method is used to get the spelling of a token into a preallocated buffer,...
Definition: Lexer.cpp:452
Record the location of a macro definition.
void finishModuleDeclarationScope()
Creates a new declaration scope for module names, allowing previously defined modules to shadow defin...
Definition: ModuleMap.h:601
bool canInferFrameworkModule(const DirectoryEntry *Dir) const
Check whether a framework module can be inferred in the given directory.
Definition: ModuleMap.h:610
bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
Definition: ModuleMap.cpp:732
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
Definition: ModuleMap.cpp:1247
void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)
Definition: ModuleMap.cpp:1334
Describes a module or submodule.
Definition: Module.h:105
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system.
Definition: Module.h:285
Module * Parent
The parent of this module.
Definition: Module.h:154
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
Definition: Module.h:265
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
Definition: Module.h:343
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
Definition: Module.h:333
static StringRef getModuleInputBufferName()
Definition: Module.h:796
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
Definition: Module.h:339
llvm::iterator_range< submodule_iterator > submodules()
Definition: Module.h:783
OptionalDirectoryEntryRef Directory
The build directory of this module.
Definition: Module.h:159
std::optional< DirectoryName > getUmbrellaDirAsWritten() const
Retrieve the umbrella directory as written.
Definition: Module.h:692
std::string PresumedModuleMapFile
The presumed file name for the module map defining this module.
Definition: Module.h:163
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
Definition: Module.h:529
std::optional< Header > getUmbrellaHeaderAsWritten() const
Retrieve the umbrella header as written.
Definition: Module.h:700
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:244
void addTopHeader(FileEntryRef File)
Add a top-level header associated with this module.
Definition: Module.cpp:277
An abstract interface that should be implemented by external AST sources that also provide informatio...
This represents a decl that may have a name.
Definition: Decl.h:249
@ AddAfterMainAction
Execute the action after the main action.
@ AddBeforeMainAction
Execute the action before the main action.
@ CmdlineBeforeMainAction
Execute the action before the main action if on the command line.
@ CmdlineAfterMainAction
Execute the action after the main action if on the command line.
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Provide a default implementation which returns aborts; this method should never be called by Frontend...
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
std::set< std::string > DeserializedPCHDeclsToErrorOn
This is a set of names for decls that we do not want to be deserialized, and we emit an error if they...
std::vector< std::string > ChainedIncludes
Headers that will be converted to chained PCHs in memory.
std::string ImplicitPCHInclude
The implicit PCH included at the start of the translation unit, or empty.
DisableValidationForModuleKind DisablePCHOrModuleValidation
Whether to disable most of the normal validation performed on precompiled headers and module files.
bool DumpDeserializedPCHDecls
Dump declarations that are deserialized from PCH, for testing.
bool AllowPCHWithCompilerErrors
When true, a PCH with compiler errors will not be rejected.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:128
HeaderSearch & getHeaderSearchInfo() const
void setMainFileDir(DirectoryEntryRef Dir)
Set the directory in which the main file should be considered to have been found, if it is not a real...
IdentifierTable & getIdentifierTable()
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, const Module &M, DiagnosticsEngine &Diags)
Check that the given module is available, producing a diagnostic if not.
Module * getCurrentModuleImplementation()
Retrieves the module whose implementation we're current compiling, if any.
void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine)
Instruct the preprocessor to skip part of the main source file.
const LangOptions & getLangOpts() const
void EndSourceFile()
Inform the preprocessor callbacks that processing is complete.
Builtin::Context & getBuiltinInfo()
A (possibly-)qualified type.
Definition: Type.h:940
Smart pointer class that efficiently represents Objective-C method names.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
void setAllFilesAreTransient(bool Transient)
Specify that all files that are read during this compilation are transient.
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, bool IsFileEntry, bool IsFileExit, SrcMgr::CharacteristicKind FileKind)
Add a line note to the line table for the FileID and offset specified by Loc.
void setFileIsTransient(FileEntryRef SourceFile)
Specify that a file is transient.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
void PrintStats() const
Print statistics to stderr.
ModuleBuildStack getModuleBuildStack() const
Retrieve the module build stack.
FileID getMainFileID() const
Returns the FileID of the main source file.
void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc)
Push an entry to the module build stack.
void initializeForReplay(const SourceManager &Old)
Initialize this source manager suitably to replay the compilation described by Old.
FileID getOrCreateFileID(FileEntryRef SourceFile, SrcMgr::CharacteristicKind FileCharacter)
Get the FileID for SourceFile if it exists.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
Token - This structure provides full information about a lexed token.
Definition: Token.h:36
The type-property cache.
Definition: Type.cpp:4392
bool BeginSourceFileAction(CompilerInstance &CI) override
Callback at the start of processing a single input.
bool hasIRSupport() const override
Does this action support use with IR files?
bool PrepareToExecuteAction(CompilerInstance &CI) override
Prepare to execute the action on the given CompilerInstance.
bool hasASTFileSupport() const override
Does this action support use with AST files?
bool usesPreprocessorOnly() const override
Does this action only use the preprocessor?
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
bool hasCodeCompletionSupport() const override
Does this action support use with code completion?
bool shouldEraseOutputFiles() override
Callback at the end of processing a single input, to determine if the output files should be erased o...
TranslationUnitKind getTranslationUnitKind() override
For AST-based actions, the kind of translation unit we're handling.
void EndSourceFileAction() override
Callback at the end of processing a single input.
bool BeginInvocation(CompilerInstance &CI) override
Callback before starting processing a single input, giving the opportunity to modify the CompilerInvo...
bool hasPCHSupport() const override
Does this action support use with PCH?
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
std::unique_ptr< FrontendAction > WrappedAction
void EndSourceFile() override
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
Information about a module that has been loaded by the ASTReader.
Definition: ModuleFile.h:124
bool StandardCXXModule
Whether this module file is a standard C++ module.
Definition: ModuleFile.h:170
ModuleFile & getPrimaryModule()
Returns the primary module associated with the manager, that is, the first module loaded.
A type index; the type ID with the qualifier bits removed.
Definition: ASTBitCodes.h:84
uint32_t Literal
Literals are represented as positive integers.
Definition: CNFFormula.h:35
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
Definition: Interp.h:218
uint32_t SelectorID
An ID number that refers to an ObjC selector in an AST file.
Definition: ASTBitCodes.h:143
uint32_t PreprocessedEntityID
An ID number that refers to an entity in the detailed preprocessing record.
Definition: ASTBitCodes.h:158
uint32_t IdentifierID
An ID number that refers to an identifier in an AST file.
Definition: ASTBitCodes.h:62
The JSON file list parser is used to communicate input to InstallAPI.
void ParseAST(Preprocessor &pp, ASTConsumer *C, ASTContext &Ctx, bool PrintStats=false, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr, bool SkipFunctionBodies=false)
Parse the entire file specified, notifying the ASTConsumer as the file is parsed.
Definition: ParseAST.cpp:101
void noteBottomOfStack()
Call this once on each thread, as soon after starting the thread as feasible, to note the approximate...
Definition: Stack.cpp:40
IntrusiveRefCntPtr< ExternalSemaSource > createChainedIncludesSource(CompilerInstance &CI, IntrusiveRefCntPtr< ExternalSemaSource > &Reader)
The ChainedIncludesSource class converts headers to chained PCHs in memory, mainly for testing.
llvm::Registry< PluginASTAction > FrontendPluginRegistry
The frontend plugin registry.
TranslationUnitKind
Describes the kind of translation unit being processed.
Definition: LangOptions.h:1074
const FunctionProtoType * T
Definition: Format.h:5433