clang 23.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/Decl.h"
13#include "clang/AST/DeclGroup.h"
20#include "clang/Basic/Sarif.h"
23#include "clang/Basic/Stack.h"
42#include "llvm/ADT/ScopeExit.h"
43#include "llvm/ADT/SmallPtrSet.h"
44#include "llvm/ADT/StringRef.h"
45#include "llvm/Support/BuryPointer.h"
46#include "llvm/Support/ErrorHandling.h"
47#include "llvm/Support/FileSystem.h"
48#include "llvm/Support/Path.h"
49#include "llvm/Support/Timer.h"
50#include "llvm/Support/raw_ostream.h"
51#include <memory>
52#include <system_error>
53using namespace clang;
54
55LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)
56
57namespace {
58
59/// DeserializedDeclsLineRangePrinter dumps ranges of deserialized declarations
60/// to aid debugging and bug minimization. It implements ASTConsumer and
61/// ASTDeserializationListener, so that an object of
62/// DeserializedDeclsLineRangePrinter registers as its own listener. The
63/// ASTDeserializationListener interface provides the DeclRead callback that we
64/// use to collect the deserialized Decls. Note that printing or otherwise
65/// processing them as this point is dangerous, since that could trigger
66/// additional deserialization and crash compilation. Therefore, we process the
67/// collected Decls in HandleTranslationUnit method of ASTConsumer. This is a
68/// safe point, since we know that by this point all the Decls needed by the
69/// compiler frontend have been deserialized. In case our processing causes
70/// further deserialization, DeclRead from the listener might be called again.
71/// However, at that point we don't accept any more Decls for processing.
72class DeserializedDeclsSourceRangePrinter : public ASTConsumer,
74public:
75 explicit DeserializedDeclsSourceRangePrinter(
76 SourceManager &SM, std::unique_ptr<llvm::raw_fd_ostream> OS)
77 : ASTDeserializationListener(), SM(SM), OS(std::move(OS)) {}
78
79 ASTDeserializationListener *GetASTDeserializationListener() override {
80 return this;
81 }
82
83 void DeclRead(GlobalDeclID ID, const Decl *D) override {
84 if (!IsCollectingDecls)
85 return;
88 // These decls cover a lot of nested declarations that might not be used,
89 // reducing the granularity and making the output less useful.
90 return;
91 }
92 if (isa<ParmVarDecl>(D)) {
93 // Parameters are covered by their functions.
94 return;
95 }
96 auto *DC = D->getLexicalDeclContext();
97 if (!DC || !shouldIncludeDeclsIn(DC))
98 return;
99
100 PendingDecls.push_back(D);
101 for (; (isa<ExportDecl>(DC) || isa<NamespaceDecl>(DC)) &&
102 ProcessedDeclContexts.insert(DC).second;
103 DC = DC->getLexicalParent()) {
104 // Add any interesting decl contexts that we have not seen before.
105 // Note that we filter them out from DeclRead as that would include all
106 // redeclarations of namespaces, potentially those that do not have any
107 // imported declarations.
108 PendingDecls.push_back(cast<Decl>(DC));
109 }
110 }
111
112 struct Position {
113 unsigned Line;
114 unsigned Column;
115
116 bool operator<(const Position &other) const {
117 return std::tie(Line, Column) < std::tie(other.Line, other.Column);
118 }
119
120 static Position GetBeginSpelling(const SourceManager &SM,
121 const CharSourceRange &R) {
122 SourceLocation Begin = R.getBegin();
123 return {SM.getSpellingLineNumber(Begin),
124 SM.getSpellingColumnNumber(Begin)};
125 }
126
127 static Position GetEndSpelling(const SourceManager &SM,
128 const CharSourceRange &Range,
129 const LangOptions &LangOpts) {
130 // For token ranges, compute end location for end character of the range.
131 CharSourceRange R = Lexer::getAsCharRange(Range, SM, LangOpts);
132 SourceLocation End = R.getEnd();
133 // Relex the token past the end location of the last token in the source
134 // range. If it's a semicolon, advance the location by one token.
135 Token PossiblySemi;
136 Lexer::getRawToken(End, PossiblySemi, SM, LangOpts, true);
137 if (PossiblySemi.is(tok::semi))
138 End = End.getLocWithOffset(1);
139 // Column number of the returned end position is exclusive.
140 return {SM.getSpellingLineNumber(End), SM.getSpellingColumnNumber(End)};
141 }
142 };
143
144 struct RequiredRanges {
145 StringRef Filename;
146 std::vector<std::pair<Position, Position>> FromTo;
147 };
148 void HandleTranslationUnit(ASTContext &Context) override {
149 assert(IsCollectingDecls && "HandleTranslationUnit called twice?");
150 IsCollectingDecls = false;
151
152 // Merge ranges in each of the files.
153 struct FileData {
154 std::vector<std::pair<Position, Position>> FromTo;
156 };
157 llvm::DenseMap<const FileEntry *, FileData> FileToRanges;
158
159 for (const Decl *D : PendingDecls) {
160 for (CharSourceRange R : getRangesToMark(D)) {
161 if (!R.isValid())
162 continue;
163
164 auto *F = SM.getFileEntryForID(SM.getFileID(R.getBegin()));
165 if (F != SM.getFileEntryForID(SM.getFileID(R.getEnd()))) {
166 // Such cases are rare and difficult to handle.
167 continue;
168 }
169
170 auto &Data = FileToRanges[F];
171 if (!Data.Ref)
172 Data.Ref = SM.getFileEntryRefForID(SM.getFileID(R.getBegin()));
173 Data.FromTo.push_back(
174 {Position::GetBeginSpelling(SM, R),
175 Position::GetEndSpelling(SM, R, D->getLangOpts())});
176 }
177 }
178
179 // To simplify output, merge consecutive and intersecting ranges.
180 std::vector<RequiredRanges> Result;
181 for (auto &[F, Data] : FileToRanges) {
182 auto &FromTo = Data.FromTo;
183 assert(!FromTo.empty());
184
185 if (!Data.Ref)
186 continue;
187
188 llvm::sort(FromTo);
189
190 std::vector<std::pair<Position, Position>> MergedRanges;
191 MergedRanges.push_back(FromTo.front());
192 for (auto It = FromTo.begin() + 1; It < FromTo.end(); ++It) {
193 if (MergedRanges.back().second < It->first) {
194 MergedRanges.push_back(*It);
195 continue;
196 }
197 if (MergedRanges.back().second < It->second)
198 MergedRanges.back().second = It->second;
199 }
200 Result.push_back({Data.Ref->getName(), std::move(MergedRanges)});
201 }
202 printJson(Result);
203 }
204
205private:
206 std::vector<const Decl *> PendingDecls;
207 llvm::SmallPtrSet<const DeclContext *, 0> ProcessedDeclContexts;
208 bool IsCollectingDecls = true;
209 const SourceManager &SM;
210 std::unique_ptr<llvm::raw_ostream> OS;
211
212 static bool shouldIncludeDeclsIn(const DeclContext *DC) {
213 assert(DC && "DC is null");
214 // We choose to work at namespace level to reduce complexity and the number
215 // of cases we care about.
216 // We still need to carefully handle composite declarations like
217 // `ExportDecl`.
218 for (; DC; DC = DC->getLexicalParent()) {
219 if (DC->isFileContext())
220 return true;
221 if (isa<ExportDecl>(DC))
222 continue; // Depends on the parent.
223 return false;
224 }
225 llvm_unreachable("DeclContext chain must end with a translation unit");
226 }
227
228 llvm::SmallVector<CharSourceRange, 2> getRangesToMark(const Decl *D) {
229 if (auto *ED = dyn_cast<ExportDecl>(D)) {
230 if (!ED->hasBraces())
231 return {SM.getExpansionRange(ED->getExportLoc())};
232
233 return {SM.getExpansionRange(SourceRange(
234 ED->getExportLoc(),
235 lexForLBrace(ED->getExportLoc(), D->getLangOpts()))),
236 SM.getExpansionRange(ED->getRBraceLoc())};
237 }
238
239 auto *NS = dyn_cast<NamespaceDecl>(D);
240 if (!NS)
241 return {SM.getExpansionRange(D->getSourceRange())};
242
243 SourceLocation LBraceLoc;
244 if (NS->isAnonymousNamespace()) {
245 LBraceLoc = NS->getLocation();
246 } else {
247 // Start with the location of the identifier.
248 SourceLocation TokenBeforeLBrace = NS->getLocation();
249 if (NS->hasAttrs()) {
250 for (auto *A : NS->getAttrs()) {
251 // But attributes may go after it.
252 if (SM.isBeforeInTranslationUnit(TokenBeforeLBrace,
253 A->getRange().getEnd())) {
254 // Give up, the attributes are often coming from macros and we
255 // cannot skip them reliably.
256 return {};
257 }
258 }
259 }
260 LBraceLoc = lexForLBrace(TokenBeforeLBrace, D->getLangOpts());
261 }
262 return {SM.getExpansionRange(SourceRange(NS->getBeginLoc(), LBraceLoc)),
263 SM.getExpansionRange(NS->getRBraceLoc())};
264 }
265
266 void printJson(llvm::ArrayRef<RequiredRanges> Result) {
267 *OS << "{\n";
268 *OS << R"( "required_ranges": [)" << "\n";
269 for (size_t I = 0; I < Result.size(); ++I) {
270 auto &F = Result[I].Filename;
271 auto &MergedRanges = Result[I].FromTo;
272 *OS << R"( {)" << "\n";
273 *OS << R"( "file": ")" << F << "\"," << "\n";
274 *OS << R"( "range": [)" << "\n";
275 for (size_t J = 0; J < MergedRanges.size(); ++J) {
276 auto &From = MergedRanges[J].first;
277 auto &To = MergedRanges[J].second;
278 *OS << R"( {)" << "\n";
279 *OS << R"( "from": {)" << "\n";
280 *OS << R"( "line": )" << From.Line << ",\n";
281 *OS << R"( "column": )" << From.Column << "\n"
282 << R"( },)" << "\n";
283 *OS << R"( "to": {)" << "\n";
284 *OS << R"( "line": )" << To.Line << ",\n";
285 *OS << R"( "column": )" << To.Column << "\n"
286 << R"( })" << "\n";
287 *OS << R"( })";
288 if (J < MergedRanges.size() - 1) {
289 *OS << ",";
290 }
291 *OS << "\n";
292 }
293 *OS << " ]" << "\n" << " }";
294 if (I < Result.size() - 1)
295 *OS << ",";
296 *OS << "\n";
297 }
298 *OS << " ]\n";
299 *OS << "}\n";
300
301 OS->flush();
302 }
303
304 SourceLocation lexForLBrace(SourceLocation TokenBeforeLBrace,
305 const LangOptions &LangOpts) {
306 // Now skip one token, the next should be the lbrace.
307 Token Tok;
308 if (Lexer::getRawToken(TokenBeforeLBrace, Tok, SM, LangOpts, true) ||
309 Lexer::getRawToken(Tok.getEndLoc(), Tok, SM, LangOpts, true) ||
310 Tok.getKind() != tok::l_brace) {
311 // On error or if we did not find the token we expected, avoid marking
312 // everything inside the namespace as used.
313 return SourceLocation();
314 }
315 return Tok.getLocation();
316 }
317};
318
319/// Dumps deserialized declarations.
320class DeserializedDeclsDumper : public DelegatingDeserializationListener {
321public:
322 explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
323 bool DeletePrevious)
324 : DelegatingDeserializationListener(Previous, DeletePrevious) {}
325
326 void DeclRead(GlobalDeclID ID, const Decl *D) override {
327 llvm::outs() << "PCH DECL: " << D->getDeclKindName();
328 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
329 llvm::outs() << " - ";
330 ND->printQualifiedName(llvm::outs());
331 }
332 llvm::outs() << "\n";
333
335 }
336};
337
338/// Checks deserialized declarations and emits error if a name
339/// matches one given in command-line using -error-on-deserialized-decl.
340class DeserializedDeclsChecker : public DelegatingDeserializationListener {
341 ASTContext &Ctx;
342 std::set<std::string> NamesToCheck;
343
344public:
345 DeserializedDeclsChecker(ASTContext &Ctx,
346 const std::set<std::string> &NamesToCheck,
347 ASTDeserializationListener *Previous,
348 bool DeletePrevious)
349 : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
350 NamesToCheck(NamesToCheck) {}
351
352 void DeclRead(GlobalDeclID ID, const Decl *D) override {
353 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
354 if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
355 unsigned DiagID
356 = Ctx.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
357 "%0 was deserialized");
358 Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID)
359 << ND;
360 }
361
363 }
364};
365
366} // end anonymous namespace
367
369
371
373 std::unique_ptr<ASTUnit> AST) {
374 this->CurrentInput = CurrentInput;
375 CurrentASTUnit = std::move(AST);
376}
377
383
384std::unique_ptr<ASTConsumer>
385FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
386 StringRef InFile) {
387 std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile);
388 if (!Consumer)
389 return nullptr;
390
391 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
392 llvm::StringRef DumpDeserializedDeclarationRangesPath =
394 if (!DumpDeserializedDeclarationRangesPath.empty()) {
395 std::error_code ErrorCode;
396 auto FileStream = std::make_unique<llvm::raw_fd_ostream>(
397 DumpDeserializedDeclarationRangesPath, ErrorCode,
398 llvm::sys::fs::OF_TextWithCRLF);
399 if (!ErrorCode) {
400 Consumers.push_back(std::make_unique<DeserializedDeclsSourceRangePrinter>(
401 CI.getSourceManager(), std::move(FileStream)));
402 } else {
403 llvm::errs() << "Failed to create output file for "
404 "-dump-minimization-hints flag, file path: "
405 << DumpDeserializedDeclarationRangesPath
406 << ", error: " << ErrorCode.message() << "\n";
407 }
408 }
409
410 // Validate -add-plugin args.
411 bool FoundAllPlugins = true;
412 for (const std::string &Arg : CI.getFrontendOpts().AddPluginActions) {
413 bool Found = false;
414 for (const FrontendPluginRegistry::entry &Plugin :
415 FrontendPluginRegistry::entries()) {
416 if (Plugin.getName() == Arg)
417 Found = true;
418 }
419 if (!Found) {
420 CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << Arg;
421 FoundAllPlugins = false;
422 }
423 }
424 if (!FoundAllPlugins)
425 return nullptr;
426
427 // If this is a code completion run, avoid invoking the plugin consumers
429 return Consumer;
430
431 // Collect the list of plugins that go before the main action (in Consumers)
432 // or after it (in AfterConsumers)
433 std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers;
434 for (const FrontendPluginRegistry::entry &Plugin :
435 FrontendPluginRegistry::entries()) {
436 std::unique_ptr<PluginASTAction> P = Plugin.instantiate();
437 PluginASTAction::ActionType ActionType = P->getActionType();
438 if (ActionType == PluginASTAction::CmdlineAfterMainAction ||
440 // This is O(|plugins| * |add_plugins|), but since both numbers are
441 // way below 50 in practice, that's ok.
442 if (llvm::is_contained(CI.getFrontendOpts().AddPluginActions,
443 Plugin.getName())) {
446 else
448 }
449 }
450 if ((ActionType == PluginASTAction::AddBeforeMainAction ||
452 P->ParseArgs(
453 CI,
454 CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())])) {
455 std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile);
456 if (ActionType == PluginASTAction::AddBeforeMainAction) {
457 Consumers.push_back(std::move(PluginConsumer));
458 } else {
459 AfterConsumers.push_back(std::move(PluginConsumer));
460 }
461 }
462 }
463
464 // Add to Consumers the main consumer, then all the plugins that go after it
465 Consumers.push_back(std::move(Consumer));
466 if (!AfterConsumers.empty()) {
467 // If we have plugins after the main consumer, which may be the codegen
468 // action, they likely will need the ASTContext, so don't clear it in the
469 // codegen action.
470 CI.getCodeGenOpts().ClearASTBeforeBackend = false;
471 for (auto &C : AfterConsumers)
472 Consumers.push_back(std::move(C));
473 }
474
475 assert(Consumers.size() >= 1 && "should have added the main consumer");
476 if (Consumers.size() == 1)
477 return std::move(Consumers.front());
478 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
479}
480
481/// For preprocessed files, if the first line is the linemarker and specifies
482/// the original source file name, use that name as the input file name.
483/// Returns the location of the first token after the line marker directive.
484///
485/// \param CI The compiler instance.
486/// \param InputFile Populated with the filename from the line marker.
487/// \param IsModuleMap If \c true, add a line note corresponding to this line
488/// directive. (We need to do this because the directive will not be
489/// visited by the preprocessor.)
491 std::string &InputFile,
492 bool IsModuleMap = false) {
493 auto &SourceMgr = CI.getSourceManager();
494 auto MainFileID = SourceMgr.getMainFileID();
495
496 auto MainFileBuf = SourceMgr.getBufferOrNone(MainFileID);
497 if (!MainFileBuf)
498 return SourceLocation();
499
500 std::unique_ptr<Lexer> RawLexer(
501 new Lexer(MainFileID, *MainFileBuf, SourceMgr, CI.getLangOpts()));
502
503 // If the first line has the syntax of
504 //
505 // # NUM "FILENAME"
506 //
507 // we use FILENAME as the input file name.
508 Token T;
509 if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)
510 return SourceLocation();
511 if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||
512 T.getKind() != tok::numeric_constant)
513 return SourceLocation();
514
515 unsigned LineNo;
516 SourceLocation LineNoLoc = T.getLocation();
517 if (IsModuleMap) {
519 if (Lexer::getSpelling(LineNoLoc, Buffer, SourceMgr, CI.getLangOpts())
520 .getAsInteger(10, LineNo))
521 return SourceLocation();
522 }
523
524 RawLexer->LexFromRawLexer(T);
525 if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
526 return SourceLocation();
527
528 StringLiteralParser Literal(T, CI.getPreprocessor());
529 if (Literal.hadError)
530 return SourceLocation();
531 RawLexer->LexFromRawLexer(T);
532 if (T.isNot(tok::eof) && !T.isAtStartOfLine())
533 return SourceLocation();
534 InputFile = Literal.GetString().str();
535
536 if (IsModuleMap)
538 LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile), false,
540
541 return T.getLocation();
542}
543
545operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
546 Includes.append(RHS.begin(), RHS.end());
547 return Includes;
548}
549
550static void addHeaderInclude(StringRef HeaderName,
551 SmallVectorImpl<char> &Includes,
552 const LangOptions &LangOpts,
553 bool IsExternC) {
554 if (IsExternC && LangOpts.CPlusPlus)
555 Includes += "extern \"C\" {\n";
556 if (LangOpts.ObjC)
557 Includes += "#import \"";
558 else
559 Includes += "#include \"";
560
561 Includes += HeaderName;
562
563 Includes += "\"\n";
564 if (IsExternC && LangOpts.CPlusPlus)
565 Includes += "}\n";
566}
567
568/// Collect the set of header includes needed to construct the given
569/// module and update the TopHeaders file set of the module.
570///
571/// \param Module The module we're collecting includes from.
572///
573/// \param Includes Will be augmented with the set of \#includes or \#imports
574/// needed to load all of the named headers.
575static std::error_code collectModuleHeaderIncludes(
578 // Don't collect any headers for unavailable modules.
579 if (!Module->isAvailable())
580 return std::error_code();
581
582 // Resolve all lazy header directives to header files.
583 ModMap.resolveHeaderDirectives(Module, /*File=*/std::nullopt);
584
585 // If any headers are missing, we can't build this module. In most cases,
586 // diagnostics for this should have already been produced; we only get here
587 // if explicit stat information was provided.
588 // FIXME: If the name resolves to a file with different stat information,
589 // produce a better diagnostic.
590 if (!Module->MissingHeaders.empty()) {
591 auto &MissingHeader = Module->MissingHeaders.front();
592 Diag.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
593 << MissingHeader.IsUmbrella << MissingHeader.FileName;
594 return std::error_code();
595 }
596
597 // Add includes for each of these headers.
598 for (auto HK : {Module::HK_Normal, Module::HK_Private}) {
599 for (const Module::Header &H : Module->getHeaders(HK)) {
600 Module->addTopHeader(H.Entry);
601 // Use the path as specified in the module map file. We'll look for this
602 // file relative to the module build directory (the directory containing
603 // the module map file) so this will find the same file that we found
604 // while parsing the module map.
605 addHeaderInclude(H.PathRelativeToRootModuleDirectory, Includes, LangOpts,
607 }
608 }
609 // Note that Module->PrivateHeaders will not be a TopHeader.
610
611 if (std::optional<Module::Header> UmbrellaHeader =
613 Module->addTopHeader(UmbrellaHeader->Entry);
614 if (Module->Parent)
615 // Include the umbrella header for submodules.
616 addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
617 Includes, LangOpts, Module->IsExternC);
618 } else if (std::optional<Module::DirectoryName> UmbrellaDir =
620 // Add all of the headers we find in this subdirectory.
621 std::error_code EC;
622 SmallString<128> DirNative;
623 llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative);
624
625 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
627 for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
628 Dir != End && !EC; Dir.increment(EC)) {
629 // Check whether this entry has an extension typically associated with
630 // headers.
631 if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path()))
632 .Cases({".h", ".H", ".hh", ".hpp"}, true)
633 .Default(false))
634 continue;
635
636 // Compute the relative path from the directory to this file.
638 auto PathIt = llvm::sys::path::rbegin(Dir->path());
639 for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt)
640 Components.push_back(*PathIt);
641 SmallString<128> RelativeHeader(
642 UmbrellaDir->PathRelativeToRootModuleDirectory);
643 for (auto It = Components.rbegin(), End = Components.rend(); It != End;
644 ++It)
645 llvm::sys::path::append(RelativeHeader, *It);
646
647 HeaderPaths.push_back(
648 std::make_pair(Dir->path().str(), RelativeHeader.c_str()));
649 }
650
651 if (EC)
652 return EC;
653
654 // Sort header paths and make the header inclusion order deterministic
655 // across different OSs and filesystems. As the header search table
656 // serialization order depends on the file reference UID, we need to create
657 // file references in deterministic order too.
658 llvm::sort(HeaderPaths, llvm::less_first());
659 for (auto &[Path, RelPath] : HeaderPaths) {
660 auto Header = FileMgr.getOptionalFileRef(Path);
661 // FIXME: This shouldn't happen unless there is a file system race. Is
662 // that worth diagnosing?
663 if (!Header)
664 continue;
665
666 // If this header is marked 'unavailable' in this module, don't include
667 // it.
668 if (ModMap.isHeaderUnavailableInModule(*Header, Module))
669 continue;
670
671 // Include this header as part of the umbrella directory.
672 Module->addTopHeader(*Header);
673 addHeaderInclude(RelPath, Includes, LangOpts, Module->IsExternC);
674 }
675 }
676
677 // Recurse into submodules.
678 for (auto *Submodule : Module->submodules())
679 if (std::error_code Err = collectModuleHeaderIncludes(
680 LangOpts, FileMgr, Diag, ModMap, Submodule, Includes))
681 return Err;
682
683 return std::error_code();
684}
685
686static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem,
687 bool IsPreprocessed,
688 std::string &PresumedModuleMapFile,
689 unsigned &Offset) {
690 auto &SrcMgr = CI.getSourceManager();
692
693 // Map the current input to a file.
694 FileID ModuleMapID = SrcMgr.getMainFileID();
695 OptionalFileEntryRef ModuleMap = SrcMgr.getFileEntryRefForID(ModuleMapID);
696 assert(ModuleMap && "MainFileID without FileEntry");
697
698 // If the module map is preprocessed, handle the initial line marker;
699 // line directives are not part of the module map syntax in general.
700 Offset = 0;
701 if (IsPreprocessed) {
702 SourceLocation EndOfLineMarker =
703 ReadOriginalFileName(CI, PresumedModuleMapFile, /*IsModuleMap*/ true);
704 if (EndOfLineMarker.isValid())
705 Offset = CI.getSourceManager().getDecomposedLoc(EndOfLineMarker).second;
706 }
707
708 // Load the module map file.
709 if (HS.parseAndLoadModuleMapFile(*ModuleMap, IsSystem,
710 /*ImplicitlyDiscovered=*/false, ModuleMapID,
711 &Offset, PresumedModuleMapFile))
712 return true;
713
714 if (SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset)
715 Offset = 0;
716
717 // Infer framework module if possible.
718 if (HS.getModuleMap().canInferFrameworkModule(ModuleMap->getDir())) {
719 SmallString<128> InferredFrameworkPath = ModuleMap->getDir().getName();
720 llvm::sys::path::append(InferredFrameworkPath,
721 CI.getLangOpts().ModuleName + ".framework");
722 if (auto Dir =
723 CI.getFileManager().getOptionalDirectoryRef(InferredFrameworkPath))
724 (void)HS.getModuleMap().inferFrameworkModule(*Dir, IsSystem, nullptr);
725 }
726
727 return false;
728}
729
731 StringRef ModuleMapFilename) {
732 if (CI.getLangOpts().CurrentModule.empty()) {
733 CI.getDiagnostics().Report(diag::err_missing_module_name);
734
735 // FIXME: Eventually, we could consider asking whether there was just
736 // a single module described in the module map, and use that as a
737 // default. Then it would be fairly trivial to just "compile" a module
738 // map with a single module (the common case).
739 return nullptr;
740 }
741
742 // Dig out the module definition.
745 /*AllowSearch=*/true);
746 if (!M) {
747 CI.getDiagnostics().Report(diag::err_missing_module)
748 << CI.getLangOpts().CurrentModule << ModuleMapFilename;
749
750 return nullptr;
751 }
752
753 // Check whether we can build this module at all.
755 CI.getDiagnostics()))
756 return nullptr;
757
758 // Inform the preprocessor that includes from within the input buffer should
759 // be resolved relative to the build directory of the module map file.
761
762 // If the module was inferred from a different module map (via an expanded
763 // umbrella module definition), track that fact.
764 // FIXME: It would be preferable to fill this in as part of processing
765 // the module map, rather than adding it after the fact.
766 StringRef OriginalModuleMapName = CI.getFrontendOpts().OriginalModuleMap;
767 if (!OriginalModuleMapName.empty()) {
768 auto OriginalModuleMap =
769 CI.getFileManager().getOptionalFileRef(OriginalModuleMapName,
770 /*openFile*/ true);
771 if (!OriginalModuleMap) {
772 CI.getDiagnostics().Report(diag::err_module_map_not_found)
773 << OriginalModuleMapName;
774 return nullptr;
775 }
776 if (*OriginalModuleMap != CI.getSourceManager().getFileEntryRefForID(
778 auto FileCharacter =
780 FileID OriginalModuleMapFID = CI.getSourceManager().getOrCreateFileID(
781 *OriginalModuleMap, FileCharacter);
782 CI.getPreprocessor()
784 .getModuleMap()
785 .setInferredModuleAllowedBy(M, OriginalModuleMapFID);
786 }
787 }
788
789 // If we're being run from the command-line, the module build stack will not
790 // have been filled in yet, so complete it now in order to allow us to detect
791 // module cycles.
792 SourceManager &SourceMgr = CI.getSourceManager();
793 if (SourceMgr.getModuleBuildStack().empty())
795 FullSourceLoc(SourceLocation(), SourceMgr));
796 return M;
797}
798
799/// Compute the input buffer that should be used to build the specified module.
800static std::unique_ptr<llvm::MemoryBuffer>
803
804 // Collect the set of #includes we need to build the module.
805 SmallString<256> HeaderContents;
806 std::error_code Err = std::error_code();
807 if (std::optional<Module::Header> UmbrellaHeader =
809 addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
810 HeaderContents, CI.getLangOpts(), M->IsExternC);
814 HeaderContents);
815
816 if (Err) {
817 CI.getDiagnostics().Report(diag::err_module_cannot_create_includes)
818 << M->getFullModuleName() << Err.message();
819 return nullptr;
820 }
821
822 return llvm::MemoryBuffer::getMemBufferCopy(
823 HeaderContents, Module::getModuleInputBufferName());
824}
825
827 const FrontendInputFile &RealInput) {
828 FrontendInputFile Input(RealInput);
829 assert(!Instance && "Already processing a source file!");
830 assert(!Input.isEmpty() && "Unexpected empty filename!");
831 setCurrentInput(Input);
833
834 bool HasBegunSourceFile = false;
835 bool ReplayASTFile = Input.getKind().getFormat() == InputKind::Precompiled &&
837
838 // If we fail, reset state since the client will not end up calling the
839 // matching EndSourceFile(). All paths that return true should release this.
840 llvm::scope_exit FailureCleanup([&]() {
841 if (HasBegunSourceFile)
843 CI.setASTConsumer(nullptr);
844 CI.clearOutputFiles(/*EraseFiles=*/true);
845 CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
847 setCompilerInstance(nullptr);
848 });
849
850 if (!BeginInvocation(CI))
851 return false;
852
853 // The list of module files the input AST file depends on. This is separate
854 // from FrontendOptions::ModuleFiles, because those only represent explicit
855 // modules, while this is capable of representing implicit ones too.
856 SmallVector<ModuleFileName> ModuleFiles;
857
858 // If we're replaying the build of an AST file, import it and set up
859 // the initial state from its build.
860 if (ReplayASTFile) {
862
863 // The AST unit populates its own diagnostics engine rather than ours.
864 auto ASTDiags = llvm::makeIntrusiveRefCnt<DiagnosticsEngine>(
865 Diags->getDiagnosticIDs(), Diags->getDiagnosticOptions());
866 ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false);
867
868 // FIXME: What if the input is a memory buffer?
869 StringRef InputFile = Input.getFile();
870
871 std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
873 CI.getVirtualFileSystemPtr(), nullptr, ASTDiags, CI.getFileSystemOpts(),
875 if (!AST)
876 return false;
877
878 // Options relating to how we treat the input (but not what we do with it)
879 // are inherited from the AST unit.
880 CI.getHeaderSearchOpts() = AST->getHeaderSearchOpts();
881 CI.getPreprocessorOpts() = AST->getPreprocessorOpts();
882 CI.getLangOpts() = AST->getLangOpts();
883
884 // Set the shared objects, these are reset when we finish processing the
885 // file, otherwise the CompilerInstance will happily destroy them.
886 CI.setVirtualFileSystem(AST->getFileManager().getVirtualFileSystemPtr());
887 CI.setFileManager(AST->getFileManagerPtr());
889 CI.getSourceManager().initializeForReplay(AST->getSourceManager());
890
891 // Preload all the module files loaded transitively by the AST unit. Also
892 // load all module map files that were parsed as part of building the AST
893 // unit.
894 if (auto ASTReader = AST->getASTReader()) {
895 auto &MM = ASTReader->getModuleManager();
896 auto &PrimaryModule = MM.getPrimaryModule();
897
898 for (serialization::ModuleFile &MF : MM)
899 if (&MF != &PrimaryModule)
900 ModuleFiles.emplace_back(MF.FileName);
901
902 ASTReader->visitTopLevelModuleMaps(PrimaryModule, [&](FileEntryRef FE) {
903 CI.getFrontendOpts().ModuleMapFiles.push_back(
904 std::string(FE.getName()));
905 });
906 }
907
908 // Set up the input file for replay purposes.
909 auto Kind = AST->getInputKind();
910 if (Kind.getFormat() == InputKind::ModuleMap) {
911 Module *ASTModule =
912 AST->getPreprocessor().getHeaderSearchInfo().lookupModule(
913 AST->getLangOpts().CurrentModule, SourceLocation(),
914 /*AllowSearch*/ false);
915 assert(ASTModule && "module file does not define its own module");
916 Input = FrontendInputFile(ASTModule->PresumedModuleMapFile, Kind);
917 } else {
918 auto &OldSM = AST->getSourceManager();
919 FileID ID = OldSM.getMainFileID();
920 if (auto File = OldSM.getFileEntryRefForID(ID))
921 Input = FrontendInputFile(File->getName(), Kind);
922 else
923 Input = FrontendInputFile(OldSM.getBufferOrFake(ID), Kind);
924 }
925 setCurrentInput(Input, std::move(AST));
926 }
927
928 // AST files follow a very different path, since they share objects via the
929 // AST unit.
930 if (Input.getKind().getFormat() == InputKind::Precompiled) {
931 assert(!usesPreprocessorOnly() && "this case was handled above");
932 assert(hasASTFileSupport() &&
933 "This action does not have AST file support!");
934
936
937 // FIXME: What if the input is a memory buffer?
938 StringRef InputFile = Input.getFile();
939
940 std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
942 CI.getVirtualFileSystemPtr(), nullptr, Diags, CI.getFileSystemOpts(),
943 CI.getHeaderSearchOpts(), &CI.getLangOpts());
944
945 if (!AST)
946 return false;
947
948 // Inform the diagnostic client we are processing a source file.
950 HasBegunSourceFile = true;
951
952 // Set the shared objects, these are reset when we finish processing the
953 // file, otherwise the CompilerInstance will happily destroy them.
954 CI.setVirtualFileSystem(AST->getVirtualFileSystemPtr());
955 CI.setFileManager(AST->getFileManagerPtr());
956 CI.setSourceManager(AST->getSourceManagerPtr());
957 CI.setPreprocessor(AST->getPreprocessorPtr());
958 Preprocessor &PP = CI.getPreprocessor();
960 PP.getLangOpts());
961 CI.setASTContext(AST->getASTContextPtr());
962
963 setCurrentInput(Input, std::move(AST));
964
965 // Initialize the action.
966 if (!BeginSourceFileAction(CI))
967 return false;
968
969 // Create the AST consumer.
970 CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));
971 if (!CI.hasASTConsumer())
972 return false;
973
974 FailureCleanup.release();
975 return true;
976 }
977
978 // Set up the file system, file and source managers, if needed.
979 if (!CI.hasVirtualFileSystem())
981 if (!CI.hasFileManager())
983 if (!CI.hasSourceManager()) {
985 if (CI.getDiagnosticOpts().getFormat() == DiagnosticOptions::SARIF) {
986 static_cast<SARIFDiagnosticPrinter *>(&CI.getDiagnosticClient())
988 std::make_unique<SarifDocumentWriter>(CI.getSourceManager()));
989 }
990 }
991
992 // Set up embedding for any specified files. Do this before we load any
993 // source files, including the primary module map for the compilation.
994 for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
995 if (auto FE = CI.getFileManager().getOptionalFileRef(F, /*openFile*/true))
997 else
998 CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
999 }
1002
1003 // IR files bypass the rest of initialization.
1004 if (Input.getKind().getLanguage() == Language::LLVM_IR) {
1005 if (!hasIRSupport()) {
1006 CI.getDiagnostics().Report(diag::err_ast_action_on_llvm_ir)
1007 << Input.getFile();
1008 return false;
1009 }
1010
1011 // Inform the diagnostic client we are processing a source file.
1013 HasBegunSourceFile = true;
1014
1015 // Initialize the action.
1016 if (!BeginSourceFileAction(CI))
1017 return false;
1018
1019 // Initialize the main file entry.
1020 if (!CI.InitializeSourceManager(CurrentInput))
1021 return false;
1022
1023 FailureCleanup.release();
1024 return true;
1025 }
1026
1027 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
1030
1031 // Canonicalize ImplicitPCHInclude. This way, all the downstream code,
1032 // including the ASTWriter, will receive the absolute path to the included
1033 // PCH.
1034 SmallString<128> PCHIncludePath(PPOpts.ImplicitPCHInclude);
1035 FileMgr.makeAbsolutePath(PCHIncludePath);
1036 llvm::sys::path::remove_dots(PCHIncludePath, true);
1037 PPOpts.ImplicitPCHInclude = PCHIncludePath.str();
1038 StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
1039
1040 // If the implicit PCH include is actually a directory, rather than
1041 // a single file, search for a suitable PCH file in that directory.
1042 if (auto PCHDir = FileMgr.getOptionalDirectoryRef(PCHInclude)) {
1043 std::error_code EC;
1044 SmallString<128> DirNative;
1045 llvm::sys::path::native(PCHDir->getName(), DirNative);
1046 bool Found = false;
1047 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1048 std::string SpecificModuleCachePath = createSpecificModuleCachePath(
1052 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1053 DirEnd;
1054 Dir != DirEnd && !EC; Dir.increment(EC)) {
1055 // Check whether this is an acceptable AST file.
1057 Dir->path(), FileMgr, CI.getModuleCache(),
1059 CI.getCodeGenOpts(), CI.getTargetOpts(),
1061 SpecificModuleCachePath,
1062 /*RequireStrictOptionMatches=*/true)) {
1063 PPOpts.ImplicitPCHInclude = std::string(Dir->path());
1064 Found = true;
1065 break;
1066 }
1067 }
1068
1069 if (!Found) {
1070 CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
1071 return false;
1072 }
1073 }
1074 }
1075
1076 // Set up the preprocessor if needed. When parsing model files the
1077 // preprocessor of the original source is reused.
1078 if (!isModelParsingAction())
1080
1081 // Inform the diagnostic client we are processing a source file.
1083 &CI.getPreprocessor());
1084 HasBegunSourceFile = true;
1085
1086 // Handle C++20 header units.
1087 // Here, the user has the option to specify that the header name should be
1088 // looked up in the pre-processor search paths (and the main filename as
1089 // passed by the driver might therefore be incomplete until that look-up).
1090 if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
1091 !Input.getKind().isPreprocessed()) {
1092 StringRef FileName = Input.getFile();
1093 InputKind Kind = Input.getKind();
1094 if (Kind.getHeaderUnitKind() != InputKind::HeaderUnit_Abs) {
1095 assert(CI.hasPreprocessor() &&
1096 "trying to build a header unit without a Pre-processor?");
1098 // Relative searches begin from CWD.
1099 auto Dir = CI.getFileManager().getOptionalDirectoryRef(".");
1101 CWD.push_back({std::nullopt, *Dir});
1104 /*Angled*/ Input.getKind().getHeaderUnitKind() ==
1106 nullptr, nullptr, CWD, nullptr, nullptr, nullptr,
1107 nullptr, nullptr, nullptr);
1108 if (!FE) {
1109 CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
1110 << FileName;
1111 return false;
1112 }
1113 // We now have the filename...
1114 FileName = FE->getName();
1115 // ... still a header unit, but now use the path as written.
1117 Input = FrontendInputFile(FileName, Kind, Input.isSystem());
1118 }
1119 // Unless the user has overridden the name, the header unit module name is
1120 // the pathname for the file.
1121 if (CI.getLangOpts().ModuleName.empty())
1122 CI.getLangOpts().ModuleName = std::string(FileName);
1124 }
1125
1126 if (!CI.InitializeSourceManager(Input))
1127 return false;
1128
1129 if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
1131 // We have an input filename like foo.iih, but we want to find the right
1132 // module name (and original file, to build the map entry).
1133 // Check if the first line specifies the original source file name with a
1134 // linemarker.
1135 std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
1136 ReadOriginalFileName(CI, PresumedInputFile);
1137 // Unless the user overrides this, the module name is the name by which the
1138 // original file was known.
1139 if (CI.getLangOpts().ModuleName.empty())
1140 CI.getLangOpts().ModuleName = std::string(PresumedInputFile);
1142 }
1143
1144 // For module map files, we first parse the module map and synthesize a
1145 // "<module-includes>" buffer before more conventional processing.
1146 if (Input.getKind().getFormat() == InputKind::ModuleMap) {
1147 CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);
1148
1149 std::string PresumedModuleMapFile;
1150 unsigned OffsetToContents;
1151 if (loadModuleMapForModuleBuild(CI, Input.isSystem(),
1152 Input.isPreprocessed(),
1153 PresumedModuleMapFile, OffsetToContents))
1154 return false;
1155
1156 auto *CurrentModule = prepareToBuildModule(CI, Input.getFile());
1157 if (!CurrentModule)
1158 return false;
1159
1160 CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;
1161
1162 if (OffsetToContents)
1163 // If the module contents are in the same file, skip to them.
1164 CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true);
1165 else {
1166 // Otherwise, convert the module description to a suitable input buffer.
1167 auto Buffer = getInputBufferForModule(CI, CurrentModule);
1168 if (!Buffer)
1169 return false;
1170
1171 // Reinitialize the main file entry to refer to the new input.
1172 auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
1173 auto &SourceMgr = CI.getSourceManager();
1174 auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);
1175 assert(BufferID.isValid() && "couldn't create module buffer ID");
1176 SourceMgr.setMainFileID(BufferID);
1177 }
1178 }
1179
1180 // Initialize the action.
1181 if (!BeginSourceFileAction(CI))
1182 return false;
1183
1184 // If we were asked to load any module map files, do so now.
1185 for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
1186 if (auto File = CI.getFileManager().getOptionalFileRef(Filename))
1188 *File, /*IsSystem*/ false, /*ImplicitlyDiscovered=*/false);
1189 else
1190 CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
1191 }
1192
1193 // If compiling implementation of a module, load its module map file now.
1195
1196 // Add a module declaration scope so that modules from -fmodule-map-file
1197 // arguments may shadow modules found implicitly in search paths.
1198 CI.getPreprocessor()
1200 .getModuleMap()
1202
1203 // Create the AST context and consumer unless this is a preprocessor only
1204 // action.
1205 if (!usesPreprocessorOnly()) {
1206 // Parsing a model file should reuse the existing ASTContext.
1207 if (!isModelParsingAction())
1208 CI.createASTContext();
1209
1210 // For preprocessed files, check if the first line specifies the original
1211 // source file name with a linemarker.
1212 std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
1213 if (Input.isPreprocessed())
1214 ReadOriginalFileName(CI, PresumedInputFile);
1215
1216 std::unique_ptr<ASTConsumer> Consumer =
1217 CreateWrappedASTConsumer(CI, PresumedInputFile);
1218 if (!Consumer)
1219 return false;
1220
1221 // FIXME: should not overwrite ASTMutationListener when parsing model files?
1222 if (!isModelParsingAction())
1223 CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
1224
1225 if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
1226 // Convert headers to PCH and chain them.
1229 source = createChainedIncludesSource(CI, FinalReader);
1230 if (!source)
1231 return false;
1232 CI.setASTReader(FinalReader);
1233 CI.getASTContext().setExternalSource(source);
1234 } else if (CI.getLangOpts().Modules ||
1236 // Use PCM or PCH.
1237 assert(hasPCHSupport() && "This action does not have PCH support!");
1238 ASTDeserializationListener *DeserialListener =
1239 Consumer->GetASTDeserializationListener();
1240 bool DeleteDeserialListener = false;
1242 DeserialListener = new DeserializedDeclsDumper(DeserialListener,
1243 DeleteDeserialListener);
1244 DeleteDeserialListener = true;
1245 }
1247 DeserialListener = new DeserializedDeclsChecker(
1248 CI.getASTContext(),
1250 DeserialListener, DeleteDeserialListener);
1251 DeleteDeserialListener = true;
1252 }
1253 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
1258 DeserialListener, DeleteDeserialListener);
1259 if (!CI.getASTContext().getExternalSource())
1260 return false;
1261 }
1262 // If modules are enabled, create the AST reader before creating
1263 // any builtins, so that all declarations know that they might be
1264 // extended by an external source.
1265 if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1267 CI.createASTReader();
1268 CI.getASTReader()->setDeserializationListener(DeserialListener,
1269 DeleteDeserialListener);
1270 }
1271 }
1272
1273 CI.setASTConsumer(std::move(Consumer));
1274 if (!CI.hasASTConsumer())
1275 return false;
1276 }
1277
1278 // Initialize built-in info as long as we aren't using an external AST
1279 // source.
1280 if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1282 Preprocessor &PP = CI.getPreprocessor();
1284 PP.getLangOpts());
1285 } else {
1286 // FIXME: If this is a problem, recover from it by creating a multiplex
1287 // source.
1288 assert((!CI.getLangOpts().Modules || CI.getASTReader()) &&
1289 "modules enabled but created an external source that "
1290 "doesn't support modules");
1291 }
1292
1293 // If we were asked to load any module files, do so now.
1294 for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) {
1295 serialization::ModuleFile *Loaded = nullptr;
1296 if (!CI.loadModuleFile(ModuleFileName::makeExplicit(ModuleFile), Loaded))
1297 return false;
1298
1299 if (Loaded && Loaded->StandardCXXModule)
1301 diag::warn_eagerly_load_for_standard_cplusplus_modules);
1302 }
1303
1304 // If we were asked to load any module files by the ASTUnit, do so now.
1305 for (const auto &ModuleFile : ModuleFiles) {
1306 serialization::ModuleFile *Loaded = nullptr;
1307 if (!CI.loadModuleFile(ModuleFile, Loaded))
1308 return false;
1309
1310 if (Loaded && Loaded->StandardCXXModule)
1312 diag::warn_eagerly_load_for_standard_cplusplus_modules);
1313 }
1314
1315 // If there is a layout overrides file, attach an external AST source that
1316 // provides the layouts from that file.
1317 if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
1319 auto Override = llvm::makeIntrusiveRefCnt<LayoutOverrideSource>(
1322 }
1323
1324 // Setup HLSL External Sema Source
1325 if (CI.getLangOpts().HLSL && CI.hasASTContext()) {
1326 auto HLSLSema = llvm::makeIntrusiveRefCnt<HLSLExternalSemaSource>();
1327 if (auto SemaSource = dyn_cast_if_present<ExternalSemaSource>(
1329 auto MultiSema = llvm::makeIntrusiveRefCnt<MultiplexExternalSemaSource>(
1330 std::move(SemaSource), std::move(HLSLSema));
1331 CI.getASTContext().setExternalSource(std::move(MultiSema));
1332 } else
1333 CI.getASTContext().setExternalSource(std::move(HLSLSema));
1334 }
1335
1336 FailureCleanup.release();
1337 return true;
1338}
1339
1342 ExecuteAction();
1343
1344 // If we are supposed to rebuild the global module index, do so now unless
1345 // there were any module-build failures.
1347 CI.hasPreprocessor()) {
1348 StringRef Cache =
1350 if (!Cache.empty()) {
1351 if (llvm::Error Err = GlobalModuleIndex::writeIndex(
1353 // FIXME this drops the error on the floor, but
1354 // Index/pch-from-libclang.c seems to rely on dropping at least some of
1355 // the error conditions!
1356 consumeError(std::move(Err));
1357 }
1358 }
1359 }
1360
1361 return llvm::Error::success();
1362}
1363
1366
1367 // Inform the preprocessor we are done.
1368 if (CI.hasPreprocessor())
1370
1371 // Inform the diagnostic client we are done with this source file.
1372 // Do this after notifying the preprocessor, so that end-of-file preprocessor
1373 // callbacks can report diagnostics.
1375
1376 // Finalize the action.
1378
1379 // Sema references the ast consumer, so reset sema first.
1380 //
1381 // FIXME: There is more per-file stuff we could just drop here?
1382 bool DisableFree = CI.getFrontendOpts().DisableFree;
1383 if (DisableFree) {
1384 CI.resetAndLeakSema();
1386 llvm::BuryPointer(CI.takeASTConsumer().get());
1387 } else {
1388 CI.setSema(nullptr);
1389 CI.setASTContext(nullptr);
1390 CI.setASTConsumer(nullptr);
1391 }
1392
1393 if (CI.getFrontendOpts().ShowStats) {
1394 llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFileOrBufferName() << "':\n";
1395 if (CI.hasPreprocessor()) {
1399 }
1400 if (CI.hasSourceManager()) {
1402 }
1403 llvm::errs() << "\n";
1404 }
1405
1406 // Cleanup the output streams, and erase the output files if instructed by the
1407 // FrontendAction.
1408 CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
1409
1410 // The resources are owned by AST when the current file is AST.
1411 // So we reset the resources here to avoid users accessing it
1412 // accidently.
1413 if (isCurrentFileAST()) {
1414 if (DisableFree) {
1418 llvm::BuryPointer(std::move(CurrentASTUnit));
1419 } else {
1420 CI.setPreprocessor(nullptr);
1421 CI.setSourceManager(nullptr);
1422 CI.setFileManager(nullptr);
1423 }
1424 }
1425
1426 setCompilerInstance(nullptr);
1428 CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
1429}
1430
1434
1435//===----------------------------------------------------------------------===//
1436// Utility Actions
1437//===----------------------------------------------------------------------===//
1438
1441 if (!CI.hasPreprocessor())
1442 return;
1443 // This is a fallback: If the client forgets to invoke this, we mark the
1444 // current stack as the bottom. Though not optimal, this could help prevent
1445 // stack overflow during deep recursion.
1447
1448 // FIXME: Move the truncation aspect of this into Sema, we delayed this till
1449 // here so the source manager would be initialized.
1453
1454 // Use a code completion consumer?
1455 CodeCompleteConsumer *CompletionConsumer = nullptr;
1457 CompletionConsumer = &CI.getCodeCompletionConsumer();
1458
1459 if (!CI.hasSema())
1460 CI.createSema(getTranslationUnitKind(), CompletionConsumer);
1461
1464}
1465
1466void PluginASTAction::anchor() { }
1467
1468std::unique_ptr<ASTConsumer>
1470 StringRef InFile) {
1471 llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
1472}
1473
1475 return WrappedAction->PrepareToExecuteAction(CI);
1476}
1477std::unique_ptr<ASTConsumer>
1479 StringRef InFile) {
1480 return WrappedAction->CreateASTConsumer(CI, InFile);
1481}
1483 return WrappedAction->BeginInvocation(CI);
1484}
1486 WrappedAction->setCurrentInput(getCurrentInput());
1487 WrappedAction->setCompilerInstance(&CI);
1488 auto Ret = WrappedAction->BeginSourceFileAction(CI);
1489 // BeginSourceFileAction may change CurrentInput, e.g. during module builds.
1490 setCurrentInput(WrappedAction->getCurrentInput());
1491 return Ret;
1492}
1494 WrappedAction->ExecuteAction();
1495}
1498 WrappedAction->EndSourceFileAction();
1499}
1501 return WrappedAction->shouldEraseOutputFiles();
1502}
1503
1505 return WrappedAction->usesPreprocessorOnly();
1506}
1511 return WrappedAction->hasPCHSupport();
1512}
1514 return WrappedAction->hasASTFileSupport();
1515}
1517 return WrappedAction->hasIRSupport();
1518}
1520 return WrappedAction->hasCodeCompletionSupport();
1521}
1522
1524 std::unique_ptr<FrontendAction> WrappedAction)
1525 : WrappedAction(std::move(WrappedAction)) {}
Defines the clang::ASTContext interface.
Defines enum values for all the target-independent builtin functions.
Defines interfaces for clang::FileEntry and clang::FileEntryRef.
Token Tok
The Token.
FormatToken * Previous
The previous token in the unwrapped line.
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...
Defines the clang::LangOptions interface.
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.
#define SM(sm)
Defines the clang::Preprocessor interface.
Defines clang::SarifDocumentWriter, clang::SarifRule, clang::SarifResult.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines utilities for dealing with stack allocation and stack space.
Defines the clang::TokenKind enum and support functions.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
Definition ASTConsumer.h:35
void setASTMutationListener(ASTMutationListener *Listener)
Attach an AST mutation listener to the AST context.
void setExternalSource(IntrusiveRefCntPtr< ExternalASTSource > Source)
Attach an external AST source to the AST context.
IntrusiveRefCntPtr< ExternalASTSource > getExternalSourcePtr() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
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:427
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.
ModuleManager & getModuleManager()
Retrieve the module manager.
Definition ASTReader.h:2005
static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache, const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, const CodeGenOptions &CGOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, const HeaderSearchOptions &HSOpts, StringRef SpecificModuleCachePath, bool RequireStrictOptionMatches=false)
Determine whether the given AST file is acceptable to load into a translation unit with the given lan...
static std::unique_ptr< ASTUnit > LoadFromASTFile(StringRef Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::shared_ptr< DiagnosticOptions > DiagOpts, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, const FileSystemOptions &FileSystemOpts, const HeaderSearchOptions &HSOpts, const LangOptions *LangOpts=nullptr, bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, bool AllowASTWithCompilerErrors=false, bool UserFilesAreVolatile=false)
Create a ASTUnit from an AST file.
Definition ASTUnit.cpp:692
@ LoadPreprocessorOnly
Load options and the preprocessor state.
Definition ASTUnit.h:710
@ LoadEverything
Load everything, including Sema.
Definition ASTUnit.h:716
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:293
Abstract interface for a consumer of code-completion information.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
bool loadModuleFile(ModuleFileName FileName, serialization::ModuleFile *&LoadedModuleFile)
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...
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
FileSystemOptions & getFileSystemOpts()
bool InitializeSourceManager(const FrontendInputFile &Input)
InitializeSourceManager - Initialize the source manager to set InputFile as the main file.
void createFileManager()
Create the file manager and replace any existing one with it.
void setVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
Use the given file system.
FileManager & getFileManager() const
Return the current file manager to the caller.
IntrusiveRefCntPtr< DiagnosticsEngine > getDiagnosticsPtr() const
void setASTConsumer(std::unique_ptr< ASTConsumer > Value)
setASTConsumer - Replace the current AST consumer; the compiler instance takes ownership of Value.
ModuleCache & getModuleCache() const
IntrusiveRefCntPtr< ASTReader > getASTReader() const
void createASTContext()
Create the AST context.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
ASTContext & getASTContext() const
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
TargetOptions & getTargetOpts()
void createVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS=llvm::vfs::getRealFileSystem(), DiagnosticConsumer *DC=nullptr)
Create a virtual file system instance based on the invocation.
void setASTReader(IntrusiveRefCntPtr< ASTReader > Reader)
FrontendOptions & getFrontendOpts()
void setSema(Sema *S)
Replace the current Sema; the compiler instance takes ownership of S.
void setSourceManager(llvm::IntrusiveRefCntPtr< SourceManager > Value)
setSourceManager - Replace the current source manager.
void setASTContext(llvm::IntrusiveRefCntPtr< ASTContext > Value)
setASTContext - Replace the current AST context.
HeaderSearchOptions & getHeaderSearchOpts()
bool hasCodeCompletionConsumer() const
void createSourceManager()
Create the source manager and replace any existing one with it.
CompilerInvocation & getInvocation()
std::unique_ptr< ASTConsumer > takeASTConsumer()
takeASTConsumer - Remove the current AST consumer and give ownership to the caller.
PreprocessorOptions & getPreprocessorOpts()
void setFileManager(IntrusiveRefCntPtr< FileManager > Value)
Replace the current file manager.
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()
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.
std::string computeContextHash() const
Compute the context hash - a string that uniquely identifies compiler settings.
bool isFileContext() const
Definition DeclBase.h:2180
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
Definition DeclBase.h:2125
SourceLocation getLocation() const
Definition DeclBase.h:439
const char * getDeclKindName() const
Definition DeclBase.cpp:169
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition DeclBase.h:918
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
Definition DeclBase.cpp:552
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition DeclBase.h:427
void DeclRead(GlobalDeclID ID, const Decl *D) override
A decl was deserialized from the AST file.
virtual void EndSourceFile()
Callback to inform the diagnostic client that processing of a source file has ended.
virtual void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP=nullptr)
Callback to inform the diagnostic client that processing of a source file is beginning.
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:232
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool hasErrorOccurred() const
Definition Diagnostic.h:880
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition FileEntry.h:57
StringRef getName() const
The name of this FileEntry.
Definition FileEntry.h:61
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
Definition FileManager.h:53
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
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.
std::string DumpMinimizationHintsPath
Output path to dump ranges of deserialized declarations to use as minimization hints.
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.
std::string ModuleCachePath
The directory used for the module cache.
unsigned DisableModuleHash
Whether we should disable the use of the hash string within the module cache.
Encapsulates the information needed to find the file referenced by a #include or #include_next,...
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 getSpecificModuleCachePath() const
Retrieve the specific module cache path.
ModuleMap & getModuleMap()
Retrieve the module map.
bool parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, bool ImplicitlyDiscovered, FileID ID=FileID(), unsigned *Offset=nullptr, StringRef OriginalModuleMapFile=StringRef())
Read the contents of the given module map file.
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.
@ CMK_ModuleMap
Compiling a module from a module map.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
Definition Lexer.h:78
static CharSourceRange getAsCharRange(SourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)
Given a token range, produce a corresponding CharSourceRange that is not a token range.
Definition Lexer.h:430
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:461
static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
Definition Lexer.cpp:519
static ModuleFileName makeExplicit(std::string Name)
Creates a file name for an explicit module.
Definition Module.h:111
void finishModuleDeclarationScope()
Creates a new declaration scope for module names, allowing previously defined modules to shadow defin...
Definition ModuleMap.h:621
bool canInferFrameworkModule(const DirectoryEntry *Dir) const
Check whether a framework module can be inferred in the given directory.
Definition ModuleMap.h:630
bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)
Describes a module or submodule.
Definition Module.h:246
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:444
Module * Parent
The parent of this module.
Definition Module.h:295
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
Definition Module.h:492
static StringRef getModuleInputBufferName()
Definition Module.h:965
llvm::iterator_range< submodule_iterator > submodules()
Definition Module.h:952
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
Definition Module.h:498
std::optional< Header > getUmbrellaHeaderAsWritten() const
Retrieve the umbrella header as written.
Definition Module.h:870
OptionalDirectoryEntryRef Directory
The build directory of this module.
Definition Module.h:300
std::string PresumedModuleMapFile
The presumed file name for the module map defining this module.
Definition Module.h:304
ArrayRef< Header > getHeaders(HeaderKind HK) const
Definition Module.h:405
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
Definition Module.h:689
std::optional< DirectoryName > getUmbrellaDirAsWritten() const
Retrieve the umbrella directory as written.
Definition Module.h:862
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:258
void addTopHeader(FileEntryRef File)
Add a top-level header associated with this module.
Definition Module.cpp:290
@ 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.
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.
void setSarifWriter(std::unique_ptr< SarifDocumentWriter > SarifWriter)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
FileIDAndOffset getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
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.
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.
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
SourceLocation getEndLoc() const
Definition Token.h:169
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
Definition Token.h:142
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
Definition Token.h:104
tok::TokenKind getKind() const
Definition Token.h:99
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:145
bool StandardCXXModule
Whether this module file is a standard C++ module.
Definition ModuleFile.h:194
ModuleFile & getPrimaryModule()
Returns the primary module associated with the manager, that is, the first module loaded.
Public enums and private classes that are part of the SourceManager implementation.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
Definition FileEntry.h:208
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
@ Override
Merge availability attributes for an override, which requires an exact match or a weakening of constr...
Definition Sema.h:636
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Result
The result type of a method or function.
Definition TypeBase.h:905
std::string createSpecificModuleCachePath(FileManager &FileMgr, StringRef ModuleCachePath, bool DisableModuleHash, std::string ContextHash)
IntrusiveRefCntPtr< ExternalSemaSource > createChainedIncludesSource(CompilerInstance &CI, IntrusiveRefCntPtr< ASTReader > &OutReader)
The ChainedIncludesSource class converts headers to chained PCHs in memory, mainly for testing.
llvm::Registry< PluginASTAction > FrontendPluginRegistry
The frontend plugin registry.
void noteBottomOfStack(bool ForceSet=false)
Call this once on each thread, as soon after starting the thread as feasible, to note the approximate...
Definition Stack.cpp:20
TranslationUnitKind
Describes the kind of translation unit being processed.
U cast(CodeGen::Address addr)
Definition Address.h:327
Information about a header directive as found in the module map file.
Definition Module.h:390