clang 17.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"
36#include "llvm/ADT/ScopeExit.h"
37#include "llvm/Support/BuryPointer.h"
38#include "llvm/Support/ErrorHandling.h"
39#include "llvm/Support/FileSystem.h"
40#include "llvm/Support/Path.h"
41#include "llvm/Support/Timer.h"
42#include "llvm/Support/raw_ostream.h"
43#include <memory>
44#include <system_error>
45using namespace clang;
46
47LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)
48
49namespace {
50
51class DelegatingDeserializationListener : public ASTDeserializationListener {
53 bool DeletePrevious;
54
55public:
56 explicit DelegatingDeserializationListener(
57 ASTDeserializationListener *Previous, bool DeletePrevious)
58 : Previous(Previous), DeletePrevious(DeletePrevious) {}
59 ~DelegatingDeserializationListener() override {
60 if (DeletePrevious)
61 delete Previous;
62 }
63
64 void ReaderInitialized(ASTReader *Reader) override {
65 if (Previous)
66 Previous->ReaderInitialized(Reader);
67 }
69 IdentifierInfo *II) override {
70 if (Previous)
71 Previous->IdentifierRead(ID, II);
72 }
73 void TypeRead(serialization::TypeIdx Idx, QualType T) override {
74 if (Previous)
75 Previous->TypeRead(Idx, T);
76 }
77 void DeclRead(serialization::DeclID ID, const Decl *D) override {
78 if (Previous)
79 Previous->DeclRead(ID, D);
80 }
81 void SelectorRead(serialization::SelectorID ID, Selector Sel) override {
82 if (Previous)
83 Previous->SelectorRead(ID, Sel);
84 }
86 MacroDefinitionRecord *MD) override {
87 if (Previous)
88 Previous->MacroDefinitionRead(PPID, MD);
89 }
90};
91
92/// Dumps deserialized declarations.
93class DeserializedDeclsDumper : public DelegatingDeserializationListener {
94public:
95 explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
96 bool DeletePrevious)
97 : DelegatingDeserializationListener(Previous, DeletePrevious) {}
98
99 void DeclRead(serialization::DeclID ID, const Decl *D) override {
100 llvm::outs() << "PCH DECL: " << D->getDeclKindName();
101 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
102 llvm::outs() << " - ";
103 ND->printQualifiedName(llvm::outs());
104 }
105 llvm::outs() << "\n";
106
107 DelegatingDeserializationListener::DeclRead(ID, D);
108 }
109};
110
111/// Checks deserialized declarations and emits error if a name
112/// matches one given in command-line using -error-on-deserialized-decl.
113class DeserializedDeclsChecker : public DelegatingDeserializationListener {
114 ASTContext &Ctx;
115 std::set<std::string> NamesToCheck;
116
117public:
118 DeserializedDeclsChecker(ASTContext &Ctx,
119 const std::set<std::string> &NamesToCheck,
121 bool DeletePrevious)
122 : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
123 NamesToCheck(NamesToCheck) {}
124
125 void DeclRead(serialization::DeclID ID, const Decl *D) override {
126 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
127 if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
128 unsigned DiagID
130 "%0 was deserialized");
131 Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID)
132 << ND;
133 }
134
135 DelegatingDeserializationListener::DeclRead(ID, D);
136 }
137};
138
139} // end anonymous namespace
140
141FrontendAction::FrontendAction() : Instance(nullptr) {}
142
144
146 std::unique_ptr<ASTUnit> AST) {
147 this->CurrentInput = CurrentInput;
148 CurrentASTUnit = std::move(AST);
149}
150
154 CI.getLangOpts().CurrentModule, SourceLocation(), /*AllowSearch*/false);
155}
156
157std::unique_ptr<ASTConsumer>
158FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
159 StringRef InFile) {
160 std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile);
161 if (!Consumer)
162 return nullptr;
163
164 // Validate -add-plugin args.
165 bool FoundAllPlugins = true;
166 for (const std::string &Arg : CI.getFrontendOpts().AddPluginActions) {
167 bool Found = false;
168 for (const FrontendPluginRegistry::entry &Plugin :
169 FrontendPluginRegistry::entries()) {
170 if (Plugin.getName() == Arg)
171 Found = true;
172 }
173 if (!Found) {
174 CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << Arg;
175 FoundAllPlugins = false;
176 }
177 }
178 if (!FoundAllPlugins)
179 return nullptr;
180
181 // If there are no registered plugins we don't need to wrap the consumer
182 if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())
183 return Consumer;
184
185 // If this is a code completion run, avoid invoking the plugin consumers
187 return Consumer;
188
189 // Collect the list of plugins that go before the main action (in Consumers)
190 // or after it (in AfterConsumers)
191 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
192 std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers;
193 for (const FrontendPluginRegistry::entry &Plugin :
194 FrontendPluginRegistry::entries()) {
195 std::unique_ptr<PluginASTAction> P = Plugin.instantiate();
196 PluginASTAction::ActionType ActionType = P->getActionType();
197 if (ActionType == PluginASTAction::CmdlineAfterMainAction ||
199 // This is O(|plugins| * |add_plugins|), but since both numbers are
200 // way below 50 in practice, that's ok.
201 if (llvm::is_contained(CI.getFrontendOpts().AddPluginActions,
202 Plugin.getName())) {
205 else
207 }
208 }
209 if ((ActionType == PluginASTAction::AddBeforeMainAction ||
211 P->ParseArgs(
212 CI,
213 CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())])) {
214 std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile);
215 if (ActionType == PluginASTAction::AddBeforeMainAction) {
216 Consumers.push_back(std::move(PluginConsumer));
217 } else {
218 AfterConsumers.push_back(std::move(PluginConsumer));
219 }
220 }
221 }
222
223 // Add to Consumers the main consumer, then all the plugins that go after it
224 Consumers.push_back(std::move(Consumer));
225 if (!AfterConsumers.empty()) {
226 // If we have plugins after the main consumer, which may be the codegen
227 // action, they likely will need the ASTContext, so don't clear it in the
228 // codegen action.
229 CI.getCodeGenOpts().ClearASTBeforeBackend = false;
230 for (auto &C : AfterConsumers)
231 Consumers.push_back(std::move(C));
232 }
233
234 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
235}
236
237/// For preprocessed files, if the first line is the linemarker and specifies
238/// the original source file name, use that name as the input file name.
239/// Returns the location of the first token after the line marker directive.
240///
241/// \param CI The compiler instance.
242/// \param InputFile Populated with the filename from the line marker.
243/// \param IsModuleMap If \c true, add a line note corresponding to this line
244/// directive. (We need to do this because the directive will not be
245/// visited by the preprocessor.)
247 std::string &InputFile,
248 bool IsModuleMap = false) {
249 auto &SourceMgr = CI.getSourceManager();
250 auto MainFileID = SourceMgr.getMainFileID();
251
252 auto MainFileBuf = SourceMgr.getBufferOrNone(MainFileID);
253 if (!MainFileBuf)
254 return SourceLocation();
255
256 std::unique_ptr<Lexer> RawLexer(
257 new Lexer(MainFileID, *MainFileBuf, SourceMgr, CI.getLangOpts()));
258
259 // If the first line has the syntax of
260 //
261 // # NUM "FILENAME"
262 //
263 // we use FILENAME as the input file name.
264 Token T;
265 if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)
266 return SourceLocation();
267 if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||
268 T.getKind() != tok::numeric_constant)
269 return SourceLocation();
270
271 unsigned LineNo;
272 SourceLocation LineNoLoc = T.getLocation();
273 if (IsModuleMap) {
275 if (Lexer::getSpelling(LineNoLoc, Buffer, SourceMgr, CI.getLangOpts())
276 .getAsInteger(10, LineNo))
277 return SourceLocation();
278 }
279
280 RawLexer->LexFromRawLexer(T);
281 if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
282 return SourceLocation();
283
284 StringLiteralParser Literal(T, CI.getPreprocessor());
285 if (Literal.hadError)
286 return SourceLocation();
287 RawLexer->LexFromRawLexer(T);
288 if (T.isNot(tok::eof) && !T.isAtStartOfLine())
289 return SourceLocation();
290 InputFile = Literal.GetString().str();
291
292 if (IsModuleMap)
294 LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile), false,
296
297 return T.getLocation();
298}
299
301operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
302 Includes.append(RHS.begin(), RHS.end());
303 return Includes;
304}
305
306static void addHeaderInclude(StringRef HeaderName,
307 SmallVectorImpl<char> &Includes,
308 const LangOptions &LangOpts,
309 bool IsExternC) {
310 if (IsExternC && LangOpts.CPlusPlus)
311 Includes += "extern \"C\" {\n";
312 if (LangOpts.ObjC)
313 Includes += "#import \"";
314 else
315 Includes += "#include \"";
316
317 Includes += HeaderName;
318
319 Includes += "\"\n";
320 if (IsExternC && LangOpts.CPlusPlus)
321 Includes += "}\n";
322}
323
324/// Collect the set of header includes needed to construct the given
325/// module and update the TopHeaders file set of the module.
326///
327/// \param Module The module we're collecting includes from.
328///
329/// \param Includes Will be augmented with the set of \#includes or \#imports
330/// needed to load all of the named headers.
331static std::error_code collectModuleHeaderIncludes(
332 const LangOptions &LangOpts, FileManager &FileMgr, DiagnosticsEngine &Diag,
334 // Don't collect any headers for unavailable modules.
335 if (!Module->isAvailable())
336 return std::error_code();
337
338 // Resolve all lazy header directives to header files.
339 ModMap.resolveHeaderDirectives(Module, /*File=*/std::nullopt);
340
341 // If any headers are missing, we can't build this module. In most cases,
342 // diagnostics for this should have already been produced; we only get here
343 // if explicit stat information was provided.
344 // FIXME: If the name resolves to a file with different stat information,
345 // produce a better diagnostic.
346 if (!Module->MissingHeaders.empty()) {
347 auto &MissingHeader = Module->MissingHeaders.front();
348 Diag.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
349 << MissingHeader.IsUmbrella << MissingHeader.FileName;
350 return std::error_code();
351 }
352
353 // Add includes for each of these headers.
354 for (auto HK : {Module::HK_Normal, Module::HK_Private}) {
355 for (Module::Header &H : Module->Headers[HK]) {
356 Module->addTopHeader(H.Entry);
357 // Use the path as specified in the module map file. We'll look for this
358 // file relative to the module build directory (the directory containing
359 // the module map file) so this will find the same file that we found
360 // while parsing the module map.
361 addHeaderInclude(H.PathRelativeToRootModuleDirectory, Includes, LangOpts,
363 }
364 }
365 // Note that Module->PrivateHeaders will not be a TopHeader.
366
367 if (Module::Header UmbrellaHeader = Module->getUmbrellaHeader()) {
368 Module->addTopHeader(UmbrellaHeader.Entry);
369 if (Module->Parent)
370 // Include the umbrella header for submodules.
371 addHeaderInclude(UmbrellaHeader.PathRelativeToRootModuleDirectory,
372 Includes, LangOpts, Module->IsExternC);
373 } else if (Module::DirectoryName UmbrellaDir = Module->getUmbrellaDir()) {
374 // Add all of the headers we find in this subdirectory.
375 std::error_code EC;
376 SmallString<128> DirNative;
377 llvm::sys::path::native(UmbrellaDir.Entry->getName(), DirNative);
378
379 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
381 std::pair<std::string, OptionalFileEntryRefDegradesToFileEntryPtr>, 8>
382 Headers;
383 for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
384 Dir != End && !EC; Dir.increment(EC)) {
385 // Check whether this entry has an extension typically associated with
386 // headers.
387 if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path()))
388 .Cases(".h", ".H", ".hh", ".hpp", true)
389 .Default(false))
390 continue;
391
392 auto Header = FileMgr.getOptionalFileRef(Dir->path());
393 // FIXME: This shouldn't happen unless there is a file system race. Is
394 // that worth diagnosing?
395 if (!Header)
396 continue;
397
398 // If this header is marked 'unavailable' in this module, don't include
399 // it.
400 if (ModMap.isHeaderUnavailableInModule(*Header, Module))
401 continue;
402
403 // Compute the relative path from the directory to this file.
405 auto PathIt = llvm::sys::path::rbegin(Dir->path());
406 for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt)
407 Components.push_back(*PathIt);
408 SmallString<128> RelativeHeader(
409 UmbrellaDir.PathRelativeToRootModuleDirectory);
410 for (auto It = Components.rbegin(), End = Components.rend(); It != End;
411 ++It)
412 llvm::sys::path::append(RelativeHeader, *It);
413
414 std::string RelName = RelativeHeader.c_str();
415 Headers.push_back(std::make_pair(RelName, *Header));
416 }
417
418 if (EC)
419 return EC;
420
421 // Sort header paths and make the header inclusion order deterministic
422 // across different OSs and filesystems.
423 llvm::sort(Headers, llvm::less_first());
424 for (auto &H : Headers) {
425 // Include this header as part of the umbrella directory.
426 Module->addTopHeader(H.second);
427 addHeaderInclude(H.first, Includes, LangOpts, Module->IsExternC);
428 }
429 }
430
431 // Recurse into submodules.
433 SubEnd = Module->submodule_end();
434 Sub != SubEnd; ++Sub)
435 if (std::error_code Err = collectModuleHeaderIncludes(
436 LangOpts, FileMgr, Diag, ModMap, *Sub, Includes))
437 return Err;
438
439 return std::error_code();
440}
441
442static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem,
443 bool IsPreprocessed,
444 std::string &PresumedModuleMapFile,
445 unsigned &Offset) {
446 auto &SrcMgr = CI.getSourceManager();
448
449 // Map the current input to a file.
450 FileID ModuleMapID = SrcMgr.getMainFileID();
451 const FileEntry *ModuleMap = SrcMgr.getFileEntryForID(ModuleMapID);
452
453 // If the module map is preprocessed, handle the initial line marker;
454 // line directives are not part of the module map syntax in general.
455 Offset = 0;
456 if (IsPreprocessed) {
457 SourceLocation EndOfLineMarker =
458 ReadOriginalFileName(CI, PresumedModuleMapFile, /*IsModuleMap*/ true);
459 if (EndOfLineMarker.isValid())
460 Offset = CI.getSourceManager().getDecomposedLoc(EndOfLineMarker).second;
461 }
462
463 // Load the module map file.
464 if (HS.loadModuleMapFile(ModuleMap, IsSystem, ModuleMapID, &Offset,
465 PresumedModuleMapFile))
466 return true;
467
468 if (SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset)
469 Offset = 0;
470
471 // Infer framework module if possible.
472 if (HS.getModuleMap().canInferFrameworkModule(ModuleMap->getDir())) {
473 SmallString<128> InferredFrameworkPath = ModuleMap->getDir()->getName();
474 llvm::sys::path::append(InferredFrameworkPath,
475 CI.getLangOpts().ModuleName + ".framework");
476 if (auto Dir = CI.getFileManager().getDirectory(InferredFrameworkPath))
477 (void)HS.getModuleMap().inferFrameworkModule(*Dir, IsSystem, nullptr);
478 }
479
480 return false;
481}
482
484 StringRef ModuleMapFilename) {
485 if (CI.getLangOpts().CurrentModule.empty()) {
486 CI.getDiagnostics().Report(diag::err_missing_module_name);
487
488 // FIXME: Eventually, we could consider asking whether there was just
489 // a single module described in the module map, and use that as a
490 // default. Then it would be fairly trivial to just "compile" a module
491 // map with a single module (the common case).
492 return nullptr;
493 }
494
495 // Dig out the module definition.
498 /*AllowSearch=*/true);
499 if (!M) {
500 CI.getDiagnostics().Report(diag::err_missing_module)
501 << CI.getLangOpts().CurrentModule << ModuleMapFilename;
502
503 return nullptr;
504 }
505
506 // Check whether we can build this module at all.
508 CI.getDiagnostics(), M))
509 return nullptr;
510
511 // Inform the preprocessor that includes from within the input buffer should
512 // be resolved relative to the build directory of the module map file.
514
515 // If the module was inferred from a different module map (via an expanded
516 // umbrella module definition), track that fact.
517 // FIXME: It would be preferable to fill this in as part of processing
518 // the module map, rather than adding it after the fact.
519 StringRef OriginalModuleMapName = CI.getFrontendOpts().OriginalModuleMap;
520 if (!OriginalModuleMapName.empty()) {
521 auto OriginalModuleMap =
522 CI.getFileManager().getFile(OriginalModuleMapName,
523 /*openFile*/ true);
524 if (!OriginalModuleMap) {
525 CI.getDiagnostics().Report(diag::err_module_map_not_found)
526 << OriginalModuleMapName;
527 return nullptr;
528 }
529 if (*OriginalModuleMap != CI.getSourceManager().getFileEntryForID(
531 M->IsInferred = true;
533 .setInferredModuleAllowedBy(M, *OriginalModuleMap);
534 }
535 }
536
537 // If we're being run from the command-line, the module build stack will not
538 // have been filled in yet, so complete it now in order to allow us to detect
539 // module cycles.
540 SourceManager &SourceMgr = CI.getSourceManager();
541 if (SourceMgr.getModuleBuildStack().empty())
543 FullSourceLoc(SourceLocation(), SourceMgr));
544 return M;
545}
546
547/// Compute the input buffer that should be used to build the specified module.
548static std::unique_ptr<llvm::MemoryBuffer>
550 FileManager &FileMgr = CI.getFileManager();
551
552 // Collect the set of #includes we need to build the module.
553 SmallString<256> HeaderContents;
554 std::error_code Err = std::error_code();
555 if (Module::Header UmbrellaHeader = M->getUmbrellaHeader())
556 addHeaderInclude(UmbrellaHeader.PathRelativeToRootModuleDirectory,
557 HeaderContents, CI.getLangOpts(), M->IsExternC);
559 CI.getLangOpts(), FileMgr, CI.getDiagnostics(),
561 HeaderContents);
562
563 if (Err) {
564 CI.getDiagnostics().Report(diag::err_module_cannot_create_includes)
565 << M->getFullModuleName() << Err.message();
566 return nullptr;
567 }
568
569 return llvm::MemoryBuffer::getMemBufferCopy(
570 HeaderContents, Module::getModuleInputBufferName());
571}
572
574 const FrontendInputFile &RealInput) {
575 FrontendInputFile Input(RealInput);
576 assert(!Instance && "Already processing a source file!");
577 assert(!Input.isEmpty() && "Unexpected empty filename!");
578 setCurrentInput(Input);
580
581 bool HasBegunSourceFile = false;
582 bool ReplayASTFile = Input.getKind().getFormat() == InputKind::Precompiled &&
584
585 // If we fail, reset state since the client will not end up calling the
586 // matching EndSourceFile(). All paths that return true should release this.
587 auto FailureCleanup = llvm::make_scope_exit([&]() {
588 if (HasBegunSourceFile)
590 CI.setASTConsumer(nullptr);
591 CI.clearOutputFiles(/*EraseFiles=*/true);
592 CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
594 setCompilerInstance(nullptr);
595 });
596
597 if (!BeginInvocation(CI))
598 return false;
599
600 // If we're replaying the build of an AST file, import it and set up
601 // the initial state from its build.
602 if (ReplayASTFile) {
604
605 // The AST unit populates its own diagnostics engine rather than ours.
607 new DiagnosticsEngine(Diags->getDiagnosticIDs(),
608 &Diags->getDiagnosticOptions()));
609 ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false);
610
611 // FIXME: What if the input is a memory buffer?
612 StringRef InputFile = Input.getFile();
613
614 std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
615 std::string(InputFile), CI.getPCHContainerReader(),
617 CI.getCodeGenOpts().DebugTypeExtRefs);
618 if (!AST)
619 return false;
620
621 // Options relating to how we treat the input (but not what we do with it)
622 // are inherited from the AST unit.
623 CI.getHeaderSearchOpts() = AST->getHeaderSearchOpts();
624 CI.getPreprocessorOpts() = AST->getPreprocessorOpts();
625 CI.getLangOpts() = AST->getLangOpts();
626
627 // Set the shared objects, these are reset when we finish processing the
628 // file, otherwise the CompilerInstance will happily destroy them.
629 CI.setFileManager(&AST->getFileManager());
631 CI.getSourceManager().initializeForReplay(AST->getSourceManager());
632
633 // Preload all the module files loaded transitively by the AST unit. Also
634 // load all module map files that were parsed as part of building the AST
635 // unit.
636 if (auto ASTReader = AST->getASTReader()) {
637 auto &MM = ASTReader->getModuleManager();
638 auto &PrimaryModule = MM.getPrimaryModule();
639
640 for (serialization::ModuleFile &MF : MM)
641 if (&MF != &PrimaryModule)
642 CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName);
643
644 ASTReader->visitTopLevelModuleMaps(PrimaryModule, [&](FileEntryRef FE) {
645 CI.getFrontendOpts().ModuleMapFiles.push_back(
646 std::string(FE.getName()));
647 });
648 }
649
650 // Set up the input file for replay purposes.
651 auto Kind = AST->getInputKind();
652 if (Kind.getFormat() == InputKind::ModuleMap) {
653 Module *ASTModule =
654 AST->getPreprocessor().getHeaderSearchInfo().lookupModule(
655 AST->getLangOpts().CurrentModule, SourceLocation(),
656 /*AllowSearch*/ false);
657 assert(ASTModule && "module file does not define its own module");
658 Input = FrontendInputFile(ASTModule->PresumedModuleMapFile, Kind);
659 } else {
660 auto &OldSM = AST->getSourceManager();
661 FileID ID = OldSM.getMainFileID();
662 if (auto *File = OldSM.getFileEntryForID(ID))
663 Input = FrontendInputFile(File->getName(), Kind);
664 else
665 Input = FrontendInputFile(OldSM.getBufferOrFake(ID), Kind);
666 }
667 setCurrentInput(Input, std::move(AST));
668 }
669
670 // AST files follow a very different path, since they share objects via the
671 // AST unit.
672 if (Input.getKind().getFormat() == InputKind::Precompiled) {
673 assert(!usesPreprocessorOnly() && "this case was handled above");
674 assert(hasASTFileSupport() &&
675 "This action does not have AST file support!");
676
678
679 // FIXME: What if the input is a memory buffer?
680 StringRef InputFile = Input.getFile();
681
682 std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
683 std::string(InputFile), CI.getPCHContainerReader(),
685 CI.getCodeGenOpts().DebugTypeExtRefs);
686
687 if (!AST)
688 return false;
689
690 // Inform the diagnostic client we are processing a source file.
692 HasBegunSourceFile = true;
693
694 // Set the shared objects, these are reset when we finish processing the
695 // file, otherwise the CompilerInstance will happily destroy them.
696 CI.setFileManager(&AST->getFileManager());
697 CI.setSourceManager(&AST->getSourceManager());
698 CI.setPreprocessor(AST->getPreprocessorPtr());
699 Preprocessor &PP = CI.getPreprocessor();
701 PP.getLangOpts());
702 CI.setASTContext(&AST->getASTContext());
703
704 setCurrentInput(Input, std::move(AST));
705
706 // Initialize the action.
707 if (!BeginSourceFileAction(CI))
708 return false;
709
710 // Create the AST consumer.
711 CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));
712 if (!CI.hasASTConsumer())
713 return false;
714
715 FailureCleanup.release();
716 return true;
717 }
718
719 // Set up the file and source managers, if needed.
720 if (!CI.hasFileManager()) {
721 if (!CI.createFileManager()) {
722 return false;
723 }
724 }
725 if (!CI.hasSourceManager()) {
727 if (CI.getDiagnosticOpts().getFormat() == DiagnosticOptions::SARIF) {
728 static_cast<SARIFDiagnosticPrinter *>(&CI.getDiagnosticClient())
729 ->setSarifWriter(
730 std::make_unique<SarifDocumentWriter>(CI.getSourceManager()));
731 }
732 }
733
734 // Set up embedding for any specified files. Do this before we load any
735 // source files, including the primary module map for the compilation.
736 for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
737 if (auto FE = CI.getFileManager().getFile(F, /*openFile*/true))
739 else
740 CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
741 }
744
745 // IR files bypass the rest of initialization.
746 if (Input.getKind().getLanguage() == Language::LLVM_IR) {
747 assert(hasIRSupport() &&
748 "This action does not have IR file support!");
749
750 // Inform the diagnostic client we are processing a source file.
752 HasBegunSourceFile = true;
753
754 // Initialize the action.
755 if (!BeginSourceFileAction(CI))
756 return false;
757
758 // Initialize the main file entry.
759 if (!CI.InitializeSourceManager(CurrentInput))
760 return false;
761
762 FailureCleanup.release();
763 return true;
764 }
765
766 // If the implicit PCH include is actually a directory, rather than
767 // a single file, search for a suitable PCH file in that directory.
768 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
769 FileManager &FileMgr = CI.getFileManager();
771 StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
772 std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
773 if (auto PCHDir = FileMgr.getOptionalDirectoryRef(PCHInclude)) {
774 std::error_code EC;
775 SmallString<128> DirNative;
776 llvm::sys::path::native(PCHDir->getName(), DirNative);
777 bool Found = false;
778 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
779 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
780 DirEnd;
781 Dir != DirEnd && !EC; Dir.increment(EC)) {
782 // Check whether this is an acceptable AST file.
784 Dir->path(), FileMgr, CI.getModuleCache(),
787 SpecificModuleCachePath, /*RequireStrictOptionMatches=*/true)) {
788 PPOpts.ImplicitPCHInclude = std::string(Dir->path());
789 Found = true;
790 break;
791 }
792 }
793
794 if (!Found) {
795 CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
796 return false;
797 }
798 }
799 }
800
801 // Set up the preprocessor if needed. When parsing model files the
802 // preprocessor of the original source is reused.
805
806 // Inform the diagnostic client we are processing a source file.
808 &CI.getPreprocessor());
809 HasBegunSourceFile = true;
810
811 // Handle C++20 header units.
812 // Here, the user has the option to specify that the header name should be
813 // looked up in the pre-processor search paths (and the main filename as
814 // passed by the driver might therefore be incomplete until that look-up).
815 if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
816 !Input.getKind().isPreprocessed()) {
817 StringRef FileName = Input.getFile();
818 InputKind Kind = Input.getKind();
819 if (Kind.getHeaderUnitKind() != InputKind::HeaderUnit_Abs) {
820 assert(CI.hasPreprocessor() &&
821 "trying to build a header unit without a Pre-processor?");
823 // Relative searches begin from CWD.
824 const DirectoryEntry *Dir = nullptr;
825 if (auto DirOrErr = CI.getFileManager().getDirectory("."))
826 Dir = *DirOrErr;
828 CWD.push_back({nullptr, Dir});
830 HS.LookupFile(FileName, SourceLocation(),
831 /*Angled*/ Input.getKind().getHeaderUnitKind() ==
833 nullptr, nullptr, CWD, nullptr, nullptr, nullptr,
834 nullptr, nullptr, nullptr);
835 if (!FE) {
836 CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
837 << FileName;
838 return false;
839 }
840 // We now have the filename...
841 FileName = FE->getFileEntry().getName();
842 // ... still a header unit, but now use the path as written.
844 Input = FrontendInputFile(FileName, Kind, Input.isSystem());
845 }
846 // Unless the user has overridden the name, the header unit module name is
847 // the pathname for the file.
848 if (CI.getLangOpts().ModuleName.empty())
849 CI.getLangOpts().ModuleName = std::string(FileName);
851 }
852
853 if (!CI.InitializeSourceManager(Input))
854 return false;
855
856 if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
858 // We have an input filename like foo.iih, but we want to find the right
859 // module name (and original file, to build the map entry).
860 // Check if the first line specifies the original source file name with a
861 // linemarker.
862 std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
863 ReadOriginalFileName(CI, PresumedInputFile);
864 // Unless the user overrides this, the module name is the name by which the
865 // original file was known.
866 if (CI.getLangOpts().ModuleName.empty())
867 CI.getLangOpts().ModuleName = std::string(PresumedInputFile);
869 }
870
871 // For module map files, we first parse the module map and synthesize a
872 // "<module-includes>" buffer before more conventional processing.
873 if (Input.getKind().getFormat() == InputKind::ModuleMap) {
874 CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);
875
876 std::string PresumedModuleMapFile;
877 unsigned OffsetToContents;
879 Input.isPreprocessed(),
880 PresumedModuleMapFile, OffsetToContents))
881 return false;
882
883 auto *CurrentModule = prepareToBuildModule(CI, Input.getFile());
884 if (!CurrentModule)
885 return false;
886
887 CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;
888
889 if (OffsetToContents)
890 // If the module contents are in the same file, skip to them.
891 CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true);
892 else {
893 // Otherwise, convert the module description to a suitable input buffer.
894 auto Buffer = getInputBufferForModule(CI, CurrentModule);
895 if (!Buffer)
896 return false;
897
898 // Reinitialize the main file entry to refer to the new input.
899 auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
900 auto &SourceMgr = CI.getSourceManager();
901 auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);
902 assert(BufferID.isValid() && "couldn't create module buffer ID");
903 SourceMgr.setMainFileID(BufferID);
904 }
905 }
906
907 // Initialize the action.
908 if (!BeginSourceFileAction(CI))
909 return false;
910
911 // If we were asked to load any module map files, do so now.
912 for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
913 if (auto File = CI.getFileManager().getFile(Filename))
915 *File, /*IsSystem*/false);
916 else
917 CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
918 }
919
920 // If compiling implementation of a module, load its module map file now.
922
923 // Add a module declaration scope so that modules from -fmodule-map-file
924 // arguments may shadow modules found implicitly in search paths.
925 CI.getPreprocessor()
927 .getModuleMap()
929
930 // Create the AST context and consumer unless this is a preprocessor only
931 // action.
932 if (!usesPreprocessorOnly()) {
933 // Parsing a model file should reuse the existing ASTContext.
935 CI.createASTContext();
936
937 // For preprocessed files, check if the first line specifies the original
938 // source file name with a linemarker.
939 std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
940 if (Input.isPreprocessed())
941 ReadOriginalFileName(CI, PresumedInputFile);
942
943 std::unique_ptr<ASTConsumer> Consumer =
944 CreateWrappedASTConsumer(CI, PresumedInputFile);
945 if (!Consumer)
946 return false;
947
948 // FIXME: should not overwrite ASTMutationListener when parsing model files?
950 CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
951
952 if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
953 // Convert headers to PCH and chain them.
954 IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
955 source = createChainedIncludesSource(CI, FinalReader);
956 if (!source)
957 return false;
958 CI.setASTReader(static_cast<ASTReader *>(FinalReader.get()));
959 CI.getASTContext().setExternalSource(source);
960 } else if (CI.getLangOpts().Modules ||
962 // Use PCM or PCH.
963 assert(hasPCHSupport() && "This action does not have PCH support!");
964 ASTDeserializationListener *DeserialListener =
965 Consumer->GetASTDeserializationListener();
966 bool DeleteDeserialListener = false;
968 DeserialListener = new DeserializedDeclsDumper(DeserialListener,
969 DeleteDeserialListener);
970 DeleteDeserialListener = true;
971 }
973 DeserialListener = new DeserializedDeclsChecker(
974 CI.getASTContext(),
976 DeserialListener, DeleteDeserialListener);
977 DeleteDeserialListener = true;
978 }
979 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
984 DeserialListener, DeleteDeserialListener);
986 return false;
987 }
988 // If modules are enabled, create the AST reader before creating
989 // any builtins, so that all declarations know that they might be
990 // extended by an external source.
991 if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
993 CI.createASTReader();
994 CI.getASTReader()->setDeserializationListener(DeserialListener,
995 DeleteDeserialListener);
996 }
997 }
998
999 CI.setASTConsumer(std::move(Consumer));
1000 if (!CI.hasASTConsumer())
1001 return false;
1002 }
1003
1004 // Initialize built-in info as long as we aren't using an external AST
1005 // source.
1006 if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1008 Preprocessor &PP = CI.getPreprocessor();
1010 PP.getLangOpts());
1011 } else {
1012 // FIXME: If this is a problem, recover from it by creating a multiplex
1013 // source.
1014 assert((!CI.getLangOpts().Modules || CI.getASTReader()) &&
1015 "modules enabled but created an external source that "
1016 "doesn't support modules");
1017 }
1018
1019 // If we were asked to load any module files, do so now.
1020 for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles)
1021 if (!CI.loadModuleFile(ModuleFile))
1022 return false;
1023
1024 // If there is a layout overrides file, attach an external AST source that
1025 // provides the layouts from that file.
1026 if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
1029 Override(new LayoutOverrideSource(
1031 CI.getASTContext().setExternalSource(Override);
1032 }
1033
1034 // Setup HLSL External Sema Source
1035 if (CI.getLangOpts().HLSL && CI.hasASTContext()) {
1038 if (auto *SemaSource = dyn_cast_if_present<ExternalSemaSource>(
1041 new MultiplexExternalSemaSource(SemaSource, HLSLSema.get()));
1042 CI.getASTContext().setExternalSource(MultiSema);
1043 } else
1044 CI.getASTContext().setExternalSource(HLSLSema);
1045 }
1046
1047 FailureCleanup.release();
1048 return true;
1049}
1050
1053
1054 if (CI.hasFrontendTimer()) {
1055 llvm::TimeRegion Timer(CI.getFrontendTimer());
1056 ExecuteAction();
1057 }
1058 else ExecuteAction();
1059
1060 // If we are supposed to rebuild the global module index, do so now unless
1061 // there were any module-build failures.
1063 CI.hasPreprocessor()) {
1064 StringRef Cache =
1066 if (!Cache.empty()) {
1067 if (llvm::Error Err = GlobalModuleIndex::writeIndex(
1069 // FIXME this drops the error on the floor, but
1070 // Index/pch-from-libclang.c seems to rely on dropping at least some of
1071 // the error conditions!
1072 consumeError(std::move(Err));
1073 }
1074 }
1075 }
1076
1077 return llvm::Error::success();
1078}
1079
1082
1083 // Inform the diagnostic client we are done with this source file.
1085
1086 // Inform the preprocessor we are done.
1087 if (CI.hasPreprocessor())
1089
1090 // Finalize the action.
1092
1093 // Sema references the ast consumer, so reset sema first.
1094 //
1095 // FIXME: There is more per-file stuff we could just drop here?
1096 bool DisableFree = CI.getFrontendOpts().DisableFree;
1097 if (DisableFree) {
1098 CI.resetAndLeakSema();
1100 llvm::BuryPointer(CI.takeASTConsumer().get());
1101 } else {
1102 CI.setSema(nullptr);
1103 CI.setASTContext(nullptr);
1104 CI.setASTConsumer(nullptr);
1105 }
1106
1107 if (CI.getFrontendOpts().ShowStats) {
1108 llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFileOrBufferName() << "':\n";
1113 llvm::errs() << "\n";
1114 }
1115
1116 // Cleanup the output streams, and erase the output files if instructed by the
1117 // FrontendAction.
1118 CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
1119
1120 // The resources are owned by AST when the current file is AST.
1121 // So we reset the resources here to avoid users accessing it
1122 // accidently.
1123 if (isCurrentFileAST()) {
1124 if (DisableFree) {
1128 llvm::BuryPointer(std::move(CurrentASTUnit));
1129 } else {
1130 CI.setPreprocessor(nullptr);
1131 CI.setSourceManager(nullptr);
1132 CI.setFileManager(nullptr);
1133 }
1134 }
1135
1136 setCompilerInstance(nullptr);
1138 CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
1139}
1140
1143}
1144
1145//===----------------------------------------------------------------------===//
1146// Utility Actions
1147//===----------------------------------------------------------------------===//
1148
1151 if (!CI.hasPreprocessor())
1152 return;
1153
1154 // FIXME: Move the truncation aspect of this into Sema, we delayed this till
1155 // here so the source manager would be initialized.
1159
1160 // Use a code completion consumer?
1161 CodeCompleteConsumer *CompletionConsumer = nullptr;
1163 CompletionConsumer = &CI.getCodeCompletionConsumer();
1164
1165 if (!CI.hasSema())
1166 CI.createSema(getTranslationUnitKind(), CompletionConsumer);
1167
1170}
1171
1172void PluginASTAction::anchor() { }
1173
1174std::unique_ptr<ASTConsumer>
1176 StringRef InFile) {
1177 llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
1178}
1179
1181 return WrappedAction->PrepareToExecuteAction(CI);
1182}
1183std::unique_ptr<ASTConsumer>
1185 StringRef InFile) {
1186 return WrappedAction->CreateASTConsumer(CI, InFile);
1187}
1189 return WrappedAction->BeginInvocation(CI);
1190}
1192 WrappedAction->setCurrentInput(getCurrentInput());
1193 WrappedAction->setCompilerInstance(&CI);
1194 auto Ret = WrappedAction->BeginSourceFileAction(CI);
1195 // BeginSourceFileAction may change CurrentInput, e.g. during module builds.
1196 setCurrentInput(WrappedAction->getCurrentInput());
1197 return Ret;
1198}
1200 WrappedAction->ExecuteAction();
1201}
1204 WrappedAction->EndSourceFileAction();
1205}
1207 return WrappedAction->shouldEraseOutputFiles();
1208}
1209
1211 return WrappedAction->usesPreprocessorOnly();
1212}
1214 return WrappedAction->getTranslationUnitKind();
1215}
1217 return WrappedAction->hasPCHSupport();
1218}
1220 return WrappedAction->hasASTFileSupport();
1221}
1223 return WrappedAction->hasIRSupport();
1224}
1226 return WrappedAction->hasCodeCompletionSupport();
1227}
1228
1230 std::unique_ptr<FrontendAction> WrappedAction)
1231 : 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.
unsigned Offset
Definition: Format.cpp:2776
StringRef Filename
Definition: Format.cpp:2774
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.
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:782
void setASTMutationListener(ASTMutationListener *Listener)
Attach an AST mutation listener to the AST context.
Definition: ASTContext.h:1176
void setExternalSource(IntrusiveRefCntPtr< ExternalASTSource > Source)
Attach an external AST source to the AST context.
DiagnosticsEngine & getDiagnostics() const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Definition: ASTContext.h:1167
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:9268
ModuleManager & getModuleManager()
Retrieve the module manager.
Definition: ASTReader.h:1735
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:5505
static std::unique_ptr< ASTUnit > LoadFromASTFile(const std::string &Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, const FileSystemOptions &FileSystemOpts, bool UseDebugInfo=false, 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:785
@ LoadPreprocessorOnly
Load options and the preprocessor state.
Definition: ASTUnit.h:673
@ LoadEverything
Load everything, including Sema.
Definition: ASTUnit.h:679
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.
bool loadModuleFile(StringRef FileName)
void setASTConsumer(std::unique_ptr< ASTConsumer > Value)
setASTConsumer - Replace the current AST consumer; the compiler instance takes ownership of Value.
IntrusiveRefCntPtr< ASTReader > getASTReader() const
InMemoryModuleCache & getModuleCache() const
void createASTContext()
Create the AST context.
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.
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:83
SourceLocation getLocation() const
Definition: DeclBase.h:432
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:1772
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:1764
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:1542
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:868
bool hasErrorOccurred() const
Definition: Diagnostic.h:838
Cached information about one directory (either on disk or in the virtual file system).
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition: FileEntry.h:57
const FileEntry & getFileEntry() const
Definition: FileEntry.h:70
StringRef getName() const
The name of this FileEntry.
Definition: FileEntry.h:61
Cached information about one file (either on disk or in the virtual file system).
Definition: FileEntry.h:353
StringRef getName() const
Definition: FileEntry.h:384
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
llvm::ErrorOr< const DirectoryEntry * > getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
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:223
OptionalFileEntryRef LookupFile(StringRef Filename, SourceLocation IncludeLoc, bool isAngled, ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDir, ArrayRef< std::pair< const FileEntry *, const DirectoryEntry * > > 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.
Module * lookupModule(StringRef ModuleName, SourceLocation ImportLoc=SourceLocation(), bool AllowSearch=true, bool AllowExtraModuleMapSearch=false)
Lookup a module Search for a module with the given name.
bool loadModuleMapFile(const FileEntry *File, bool IsSystem, FileID ID=FileID(), unsigned *Offset=nullptr, StringRef OriginalModuleMapFile=StringRef())
Read the contents of the given module map file.
StringRef getModuleCachePath() const
Retrieve the path to the module cache.
Definition: HeaderSearch.h:418
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:791
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
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:82
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
Definition: LangOptions.h:430
@ CMK_ModuleMap
Compiling a module from a module map.
Definition: LangOptions.h:112
@ CMK_None
Not compiling a module interface at all.
Definition: LangOptions.h:109
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:437
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:403
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:603
bool canInferFrameworkModule(const DirectoryEntry *Dir) const
Check whether a framework module can be inferred in the given directory.
Definition: ModuleMap.h:612
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
Definition: ModuleMap.cpp:1227
void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap)
Definition: ModuleMap.cpp:1309
bool isHeaderUnavailableInModule(const FileEntry *Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
Definition: ModuleMap.cpp:712
Describes a module or submodule.
Definition: Module.h:98
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:281
Module * Parent
The parent of this module.
Definition: Module.h:147
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
Definition: Module.h:261
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
Definition: Module.h:329
static StringRef getModuleInputBufferName()
Definition: Module.h:762
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
Definition: Module.h:326
DirectoryName getUmbrellaDir() const
Retrieve the directory for which this module serves as the umbrella.
Definition: Module.cpp:264
std::vector< Module * >::iterator submodule_iterator
Definition: Module.h:741
const DirectoryEntry * Directory
The build directory of this module.
Definition: Module.h:152
void addTopHeader(const FileEntry *File)
Add a top-level header associated with this module.
Definition: Module.cpp:272
std::string PresumedModuleMapFile
The presumed file name for the module map defining this module.
Definition: Module.h:156
submodule_iterator submodule_begin()
Definition: Module.h:744
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
Definition: Module.h:504
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:239
submodule_iterator submodule_end()
Definition: Module.h:746
Header getUmbrellaHeader() const
Retrieve the header that serves as the umbrella header for this module.
Definition: Module.h:660
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:247
@ 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
Module * getCurrentModuleImplementation()
Retrieves the module whose implementation we're current compiling, if any.
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, DiagnosticsEngine &Diags, Module *M)
Check that the given module is available, producing a diagnostic if not.
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.
void setMainFileDir(const DirectoryEntry *Dir)
Set the directory in which the main file should be considered to have been found, if it is not a real...
A (possibly-)qualified type.
Definition: Type.h:736
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 setFileIsTransient(const FileEntry *SourceFile)
Specify that a file is transient.
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 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.
FileID createFileID(const FileEntry *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 initializeForReplay(const SourceManager &Old)
Initialize this source manager suitably to replay the compilation described by Old.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
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:35
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
Definition: Token.h:126
tok::TokenKind getKind() const
Definition: Token.h:93
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
Definition: Token.h:270
bool isNot(tok::TokenKind K) const
Definition: Token.h:99
The type-property cache.
Definition: Type.cpp:3967
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:122
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
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:99
IntrusiveRefCntPtr< ExternalSemaSource > createChainedIncludesSource(CompilerInstance &CI, IntrusiveRefCntPtr< ExternalSemaSource > &Reader)
The ChainedIncludesSource class converts headers to chained PCHs in memory, mainly for testing.
@ C
Languages that the frontend can parse and compile.
@ LLVM_IR
LLVM IR: we accept this so that we can run the optimizer on it, and compile it to assembly or object ...
llvm::Registry< PluginASTAction > FrontendPluginRegistry
The frontend plugin registry.
TranslationUnitKind
Describes the kind of translation unit being processed.
Definition: LangOptions.h:917
Definition: Format.h:4664
Information about a directory name as found in the module map file.
Definition: Module.h:252
Information about a header directive as found in the module map file.
Definition: Module.h:242