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
12#include "clang/AST/DeclGroup.h"
17#include "clang/Basic/Sarif.h"
18#include "clang/Basic/Stack.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>
46using namespace clang;
47
48LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)
49
50namespace {
51
52class DelegatingDeserializationListener : public ASTDeserializationListener {
54 bool DeletePrevious;
55
56public:
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 }
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(serialization::DeclID 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 }
92 MacroDefinitionRecord *MD) override {
93 if (Previous)
94 Previous->MacroDefinitionRead(PPID, MD);
95 }
96};
97
98/// Dumps deserialized declarations.
99class DeserializedDeclsDumper : public DelegatingDeserializationListener {
100public:
101 explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
102 bool DeletePrevious)
103 : DelegatingDeserializationListener(Previous, DeletePrevious) {}
104
105 void DeclRead(serialization::DeclID 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.
119class DeserializedDeclsChecker : public DelegatingDeserializationListener {
120 ASTContext &Ctx;
121 std::set<std::string> NamesToCheck;
122
123public:
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(serialization::DeclID 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
147FrontendAction::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
163std::unique_ptr<ASTConsumer>
164FrontendAction::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
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 ||
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) {
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,
302
303 return T.getLocation();
304}
305
307operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
308 Includes.append(RHS.begin(), RHS.end());
309 return Includes;
310}
311
312static 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.
337static std::error_code collectModuleHeaderIncludes(
338 const LangOptions &LangOpts, FileManager &FileMgr, DiagnosticsEngine &Diag,
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,
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.
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
446static 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.
560static 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);
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.
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 assert(hasIRSupport() &&
761 "This action does not have IR file support!");
762
763 // Inform the diagnostic client we are processing a source file.
765 HasBegunSourceFile = true;
766
767 // Initialize the action.
768 if (!BeginSourceFileAction(CI))
769 return false;
770
771 // Initialize the main file entry.
772 if (!CI.InitializeSourceManager(CurrentInput))
773 return false;
774
775 FailureCleanup.release();
776 return true;
777 }
778
779 // If the implicit PCH include is actually a directory, rather than
780 // a single file, search for a suitable PCH file in that directory.
781 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
782 FileManager &FileMgr = CI.getFileManager();
784 StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
785 std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
786 if (auto PCHDir = FileMgr.getOptionalDirectoryRef(PCHInclude)) {
787 std::error_code EC;
788 SmallString<128> DirNative;
789 llvm::sys::path::native(PCHDir->getName(), DirNative);
790 bool Found = false;
791 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
792 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
793 DirEnd;
794 Dir != DirEnd && !EC; Dir.increment(EC)) {
795 // Check whether this is an acceptable AST file.
797 Dir->path(), FileMgr, CI.getModuleCache(),
800 SpecificModuleCachePath, /*RequireStrictOptionMatches=*/true)) {
801 PPOpts.ImplicitPCHInclude = std::string(Dir->path());
802 Found = true;
803 break;
804 }
805 }
806
807 if (!Found) {
808 CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
809 return false;
810 }
811 }
812 }
813
814 // Set up the preprocessor if needed. When parsing model files the
815 // preprocessor of the original source is reused.
818
819 // Inform the diagnostic client we are processing a source file.
821 &CI.getPreprocessor());
822 HasBegunSourceFile = true;
823
824 // Handle C++20 header units.
825 // Here, the user has the option to specify that the header name should be
826 // looked up in the pre-processor search paths (and the main filename as
827 // passed by the driver might therefore be incomplete until that look-up).
828 if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
829 !Input.getKind().isPreprocessed()) {
830 StringRef FileName = Input.getFile();
831 InputKind Kind = Input.getKind();
832 if (Kind.getHeaderUnitKind() != InputKind::HeaderUnit_Abs) {
833 assert(CI.hasPreprocessor() &&
834 "trying to build a header unit without a Pre-processor?");
836 // Relative searches begin from CWD.
837 auto Dir = CI.getFileManager().getOptionalDirectoryRef(".");
839 CWD.push_back({std::nullopt, *Dir});
842 /*Angled*/ Input.getKind().getHeaderUnitKind() ==
844 nullptr, nullptr, CWD, nullptr, nullptr, nullptr,
845 nullptr, nullptr, nullptr);
846 if (!FE) {
847 CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
848 << FileName;
849 return false;
850 }
851 // We now have the filename...
852 FileName = FE->getName();
853 // ... still a header unit, but now use the path as written.
855 Input = FrontendInputFile(FileName, Kind, Input.isSystem());
856 }
857 // Unless the user has overridden the name, the header unit module name is
858 // the pathname for the file.
859 if (CI.getLangOpts().ModuleName.empty())
860 CI.getLangOpts().ModuleName = std::string(FileName);
862 }
863
864 if (!CI.InitializeSourceManager(Input))
865 return false;
866
867 if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
869 // We have an input filename like foo.iih, but we want to find the right
870 // module name (and original file, to build the map entry).
871 // Check if the first line specifies the original source file name with a
872 // linemarker.
873 std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
874 ReadOriginalFileName(CI, PresumedInputFile);
875 // Unless the user overrides this, the module name is the name by which the
876 // original file was known.
877 if (CI.getLangOpts().ModuleName.empty())
878 CI.getLangOpts().ModuleName = std::string(PresumedInputFile);
880 }
881
882 // For module map files, we first parse the module map and synthesize a
883 // "<module-includes>" buffer before more conventional processing.
884 if (Input.getKind().getFormat() == InputKind::ModuleMap) {
885 CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);
886
887 std::string PresumedModuleMapFile;
888 unsigned OffsetToContents;
890 Input.isPreprocessed(),
891 PresumedModuleMapFile, OffsetToContents))
892 return false;
893
894 auto *CurrentModule = prepareToBuildModule(CI, Input.getFile());
895 if (!CurrentModule)
896 return false;
897
898 CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;
899
900 if (OffsetToContents)
901 // If the module contents are in the same file, skip to them.
902 CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true);
903 else {
904 // Otherwise, convert the module description to a suitable input buffer.
905 auto Buffer = getInputBufferForModule(CI, CurrentModule);
906 if (!Buffer)
907 return false;
908
909 // Reinitialize the main file entry to refer to the new input.
910 auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
911 auto &SourceMgr = CI.getSourceManager();
912 auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);
913 assert(BufferID.isValid() && "couldn't create module buffer ID");
914 SourceMgr.setMainFileID(BufferID);
915 }
916 }
917
918 // Initialize the action.
919 if (!BeginSourceFileAction(CI))
920 return false;
921
922 // If we were asked to load any module map files, do so now.
923 for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
926 *File, /*IsSystem*/false);
927 else
928 CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
929 }
930
931 // If compiling implementation of a module, load its module map file now.
933
934 // Add a module declaration scope so that modules from -fmodule-map-file
935 // arguments may shadow modules found implicitly in search paths.
936 CI.getPreprocessor()
938 .getModuleMap()
940
941 // Create the AST context and consumer unless this is a preprocessor only
942 // action.
943 if (!usesPreprocessorOnly()) {
944 // Parsing a model file should reuse the existing ASTContext.
946 CI.createASTContext();
947
948 // For preprocessed files, check if the first line specifies the original
949 // source file name with a linemarker.
950 std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
951 if (Input.isPreprocessed())
952 ReadOriginalFileName(CI, PresumedInputFile);
953
954 std::unique_ptr<ASTConsumer> Consumer =
955 CreateWrappedASTConsumer(CI, PresumedInputFile);
956 if (!Consumer)
957 return false;
958
959 // FIXME: should not overwrite ASTMutationListener when parsing model files?
961 CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
962
963 if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
964 // Convert headers to PCH and chain them.
965 IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
966 source = createChainedIncludesSource(CI, FinalReader);
967 if (!source)
968 return false;
969 CI.setASTReader(static_cast<ASTReader *>(FinalReader.get()));
970 CI.getASTContext().setExternalSource(source);
971 } else if (CI.getLangOpts().Modules ||
973 // Use PCM or PCH.
974 assert(hasPCHSupport() && "This action does not have PCH support!");
975 ASTDeserializationListener *DeserialListener =
976 Consumer->GetASTDeserializationListener();
977 bool DeleteDeserialListener = false;
979 DeserialListener = new DeserializedDeclsDumper(DeserialListener,
980 DeleteDeserialListener);
981 DeleteDeserialListener = true;
982 }
984 DeserialListener = new DeserializedDeclsChecker(
985 CI.getASTContext(),
987 DeserialListener, DeleteDeserialListener);
988 DeleteDeserialListener = true;
989 }
990 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
995 DeserialListener, DeleteDeserialListener);
997 return false;
998 }
999 // If modules are enabled, create the AST reader before creating
1000 // any builtins, so that all declarations know that they might be
1001 // extended by an external source.
1002 if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1004 CI.createASTReader();
1005 CI.getASTReader()->setDeserializationListener(DeserialListener,
1006 DeleteDeserialListener);
1007 }
1008 }
1009
1010 CI.setASTConsumer(std::move(Consumer));
1011 if (!CI.hasASTConsumer())
1012 return false;
1013 }
1014
1015 // Initialize built-in info as long as we aren't using an external AST
1016 // source.
1017 if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1019 Preprocessor &PP = CI.getPreprocessor();
1021 PP.getLangOpts());
1022 } else {
1023 // FIXME: If this is a problem, recover from it by creating a multiplex
1024 // source.
1025 assert((!CI.getLangOpts().Modules || CI.getASTReader()) &&
1026 "modules enabled but created an external source that "
1027 "doesn't support modules");
1028 }
1029
1030 // If we were asked to load any module files, do so now.
1031 for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) {
1032 serialization::ModuleFile *Loaded = nullptr;
1033 if (!CI.loadModuleFile(ModuleFile, Loaded))
1034 return false;
1035
1036 if (Loaded && Loaded->StandardCXXModule)
1038 diag::warn_eagerly_load_for_standard_cplusplus_modules);
1039 }
1040
1041 // If there is a layout overrides file, attach an external AST source that
1042 // provides the layouts from that file.
1043 if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
1046 Override(new LayoutOverrideSource(
1048 CI.getASTContext().setExternalSource(Override);
1049 }
1050
1051 // Setup HLSL External Sema Source
1052 if (CI.getLangOpts().HLSL && CI.hasASTContext()) {
1055 if (auto *SemaSource = dyn_cast_if_present<ExternalSemaSource>(
1058 new MultiplexExternalSemaSource(SemaSource, HLSLSema.get()));
1059 CI.getASTContext().setExternalSource(MultiSema);
1060 } else
1061 CI.getASTContext().setExternalSource(HLSLSema);
1062 }
1063
1064 FailureCleanup.release();
1065 return true;
1066}
1067
1070
1071 if (CI.hasFrontendTimer()) {
1072 llvm::TimeRegion Timer(CI.getFrontendTimer());
1073 ExecuteAction();
1074 }
1075 else ExecuteAction();
1076
1077 // If we are supposed to rebuild the global module index, do so now unless
1078 // there were any module-build failures.
1080 CI.hasPreprocessor()) {
1081 StringRef Cache =
1083 if (!Cache.empty()) {
1084 if (llvm::Error Err = GlobalModuleIndex::writeIndex(
1086 // FIXME this drops the error on the floor, but
1087 // Index/pch-from-libclang.c seems to rely on dropping at least some of
1088 // the error conditions!
1089 consumeError(std::move(Err));
1090 }
1091 }
1092 }
1093
1094 return llvm::Error::success();
1095}
1096
1099
1100 // Inform the diagnostic client we are done with this source file.
1102
1103 // Inform the preprocessor we are done.
1104 if (CI.hasPreprocessor())
1106
1107 // Finalize the action.
1109
1110 // Sema references the ast consumer, so reset sema first.
1111 //
1112 // FIXME: There is more per-file stuff we could just drop here?
1113 bool DisableFree = CI.getFrontendOpts().DisableFree;
1114 if (DisableFree) {
1115 CI.resetAndLeakSema();
1117 llvm::BuryPointer(CI.takeASTConsumer().get());
1118 } else {
1119 CI.setSema(nullptr);
1120 CI.setASTContext(nullptr);
1121 CI.setASTConsumer(nullptr);
1122 }
1123
1124 if (CI.getFrontendOpts().ShowStats) {
1125 llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFileOrBufferName() << "':\n";
1130 llvm::errs() << "\n";
1131 }
1132
1133 // Cleanup the output streams, and erase the output files if instructed by the
1134 // FrontendAction.
1135 CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
1136
1137 // The resources are owned by AST when the current file is AST.
1138 // So we reset the resources here to avoid users accessing it
1139 // accidently.
1140 if (isCurrentFileAST()) {
1141 if (DisableFree) {
1145 llvm::BuryPointer(std::move(CurrentASTUnit));
1146 } else {
1147 CI.setPreprocessor(nullptr);
1148 CI.setSourceManager(nullptr);
1149 CI.setFileManager(nullptr);
1150 }
1151 }
1152
1153 setCompilerInstance(nullptr);
1155 CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
1156}
1157
1160}
1161
1162//===----------------------------------------------------------------------===//
1163// Utility Actions
1164//===----------------------------------------------------------------------===//
1165
1168 if (!CI.hasPreprocessor())
1169 return;
1170 // This is a fallback: If the client forgets to invoke this, we mark the
1171 // current stack as the bottom. Though not optimal, this could help prevent
1172 // stack overflow during deep recursion.
1174
1175 // FIXME: Move the truncation aspect of this into Sema, we delayed this till
1176 // here so the source manager would be initialized.
1180
1181 // Use a code completion consumer?
1182 CodeCompleteConsumer *CompletionConsumer = nullptr;
1184 CompletionConsumer = &CI.getCodeCompletionConsumer();
1185
1186 if (!CI.hasSema())
1187 CI.createSema(getTranslationUnitKind(), CompletionConsumer);
1188
1191}
1192
1193void PluginASTAction::anchor() { }
1194
1195std::unique_ptr<ASTConsumer>
1197 StringRef InFile) {
1198 llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
1199}
1200
1202 return WrappedAction->PrepareToExecuteAction(CI);
1203}
1204std::unique_ptr<ASTConsumer>
1206 StringRef InFile) {
1207 return WrappedAction->CreateASTConsumer(CI, InFile);
1208}
1210 return WrappedAction->BeginInvocation(CI);
1211}
1213 WrappedAction->setCurrentInput(getCurrentInput());
1214 WrappedAction->setCompilerInstance(&CI);
1215 auto Ret = WrappedAction->BeginSourceFileAction(CI);
1216 // BeginSourceFileAction may change CurrentInput, e.g. during module builds.
1217 setCurrentInput(WrappedAction->getCurrentInput());
1218 return Ret;
1219}
1221 WrappedAction->ExecuteAction();
1222}
1225 WrappedAction->EndSourceFileAction();
1226}
1228 return WrappedAction->shouldEraseOutputFiles();
1229}
1230
1232 return WrappedAction->usesPreprocessorOnly();
1233}
1235 return WrappedAction->getTranslationUnitKind();
1236}
1238 return WrappedAction->hasPCHSupport();
1239}
1241 return WrappedAction->hasASTFileSupport();
1242}
1244 return WrappedAction->hasIRSupport();
1245}
1247 return WrappedAction->hasCodeCompletionSupport();
1248}
1249
1251 std::unique_ptr<FrontendAction> WrappedAction)
1252 : WrappedAction(std::move(WrappedAction)) {}
Defines the clang::ASTContext interface.
StringRef P
Defines enum values for all the target-independent builtin functions.
Defines interfaces for clang::FileEntry and clang::FileEntryRef.
StringRef Filename
Definition: Format.cpp:2972
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 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...
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.
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.
StateNode * Previous
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
FullSourceLoc getFullLoc(SourceLocation Loc) const
Definition: ASTContext.h:795
void setASTMutationListener(ASTMutationListener *Listener)
Attach an AST mutation listener to the AST context.
Definition: ASTContext.h:1196
void setExternalSource(IntrusiveRefCntPtr< ExternalASTSource > Source)
Attach an external AST source to the AST context.
Definition: ASTContext.cpp:947
DiagnosticsEngine & getDiagnostics() const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Definition: ASTContext.h:1187
virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinitionRecord *MD)
A macro definition was read from the AST file.
virtual void TypeRead(serialization::TypeIdx Idx, QualType T)
A type was deserialized from the AST file.
virtual void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II)
An identifier was deserialized from the AST file.
virtual void DeclRead(serialization::DeclID ID, const Decl *D)
A decl was deserialized from the AST file.
virtual void SelectorRead(serialization::SelectorID iD, Selector Sel)
A selector was read from the AST file.
virtual void ReaderInitialized(ASTReader *Reader)
The ASTReader was initialized.
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:9536
ModuleManager & getModuleManager()
Retrieve the module manager.
Definition: ASTReader.h:1766
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:5703
@ 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:799
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.
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.
DiagnosticConsumer & getDiagnosticClient() const
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.
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
FileSystemOptions & getFileSystemOpts()
llvm::Timer & getFrontendTimer() const
bool InitializeSourceManager(const FrontendInputFile &Input)
InitializeSourceManager - Initialize the source manager to set InputFile as the main file.
FileManager & getFileManager() const
Return the current file manager to the caller.
void setASTConsumer(std::unique_ptr< ASTConsumer > Value)
setASTConsumer - Replace the current AST consumer; the compiler instance takes ownership of Value.
IntrusiveRefCntPtr< ASTReader > getASTReader() const
std::shared_ptr< LangOptions > getLangOptsPtr() const
InMemoryModuleCache & getModuleCache() const
void createASTContext()
Create the AST context.
std::shared_ptr< HeaderSearchOptions > getHeaderSearchOptsPtr() const
void setASTContext(ASTContext *Value)
setASTContext - Replace the current AST context.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
ASTContext & getASTContext() const
TargetOptions & getTargetOpts()
void setASTReader(IntrusiveRefCntPtr< ASTReader > Reader)
FrontendOptions & getFrontendOpts()
void setSema(Sema *S)
Replace the current Sema; the compiler instance takes ownership of S.
HeaderSearchOptions & getHeaderSearchOpts()
bool hasCodeCompletionConsumer() const
std::unique_ptr< ASTConsumer > takeASTConsumer()
takeASTConsumer - Remove the current AST consumer and give ownership to the caller.
PreprocessorOptions & getPreprocessorOpts()
std::string getSpecificModuleCachePath(StringRef ModuleHash)
TargetInfo & getTarget() const
void createCodeCompletionConsumer()
Create a code completion consumer using the invocation; note that this will cause the source manager ...
void clearOutputFiles(bool EraseFiles)
clearOutputFiles - Clear the output file list.
DiagnosticOptions & getDiagnosticOpts()
LangOptions & getLangOpts()
CodeGenOptions & getCodeGenOpts()
SourceManager & getSourceManager() const
Return the current source manager.
CodeCompleteConsumer & getCodeCompletionConsumer() const
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:85
SourceLocation getLocation() const
Definition: DeclBase.h:446
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:1777
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:1769
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:192
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1547
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:873
bool hasErrorOccurred() const
Definition: Diagnostic.h:843
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
llvm::vfs::FileSystem & getVirtualFileSystem() const
Definition: FileManager.h:245
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:234
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:169
const FrontendInputFile & getCurrentInput() const
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.
virtual std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile)=0
Create the AST consumer object for this action, if supported.
CompilerInstance & getCompilerInstance() const
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?
Module * getCurrentModule() const
void setCurrentInput(const FrontendInputFile &CurrentInput, std::unique_ptr< ASTUnit > AST=nullptr)
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?
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:247
Module * lookupModule(StringRef ModuleName, SourceLocation ImportLoc=SourceLocation(), bool AllowSearch=true, bool AllowExtraModuleMapSearch=false)
Lookup a module Search for a module with the given name.
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.
StringRef getModuleCachePath() const
Retrieve the path to the module cache.
Definition: HeaderSearch.h:444
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:831
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:92
@ CMK_ModuleMap
Compiling a module from a module map.
Definition: LangOptions.h:95
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:454
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
Definition: LangOptions.h:502
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:509
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:342
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
Definition: Module.h:332
static StringRef getModuleInputBufferName()
Definition: Module.h:795
llvm::iterator_range< submodule_iterator > submodules()
Definition: Module.h:782
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
Definition: Module.h:338
std::optional< Header > getUmbrellaHeaderAsWritten() const
Retrieve the umbrella header as written.
Definition: Module.h:699
OptionalDirectoryEntryRef Directory
The build directory of this module.
Definition: Module.h:159
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:528
std::optional< DirectoryName > getUmbrellaDirAsWritten() const
Retrieve the umbrella directory as written.
Definition: Module.h:691
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
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...
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.
HeaderSearch & getHeaderSearchInfo() const
IdentifierTable & getIdentifierTable()
Builtin::Context & getBuiltinInfo()
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.
A (possibly-)qualified type.
Definition: Type.h:738
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:4353
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:88
uint32_t SelectorID
An ID number that refers to an ObjC selector in an AST file.
Definition: ASTBitCodes.h:153
uint32_t PreprocessedEntityID
An ID number that refers to an entity in the detailed preprocessing record.
Definition: ASTBitCodes.h:168
uint32_t IdentID
An ID number that refers to an identifier in an AST file.
Definition: ASTBitCodes.h:134
uint32_t DeclID
An ID number that refers to a declaration in an AST file.
Definition: ASTBitCodes.h:68
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:100
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:1018
const FunctionProtoType * T
Definition: Format.h:5394
Information about a header directive as found in the module map file.
Definition: Module.h:250