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