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
9#include "clang/Frontend/FrontendAction.h"
10#include "clang/AST/ASTConsumer.h"
11#include "clang/AST/ASTContext.h"
12#include "clang/AST/DeclGroup.h"
13#include "clang/Basic/Builtins.h"
14#include "clang/Basic/DiagnosticOptions.h"
15#include "clang/Basic/FileEntry.h"
16#include "clang/Basic/LangOptions.h"
17#include "clang/Basic/LangStandard.h"
18#include "clang/Basic/Sarif.h"
19#include "clang/Basic/SourceLocation.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/Stack.h"
22#include "clang/Basic/TokenKinds.h"
23#include "clang/Frontend/ASTUnit.h"
24#include "clang/Frontend/CompilerInstance.h"
25#include "clang/Frontend/FrontendDiagnostic.h"
26#include "clang/Frontend/FrontendPluginRegistry.h"
27#include "clang/Frontend/LayoutOverrideSource.h"
28#include "clang/Frontend/MultiplexConsumer.h"
29#include "clang/Frontend/SARIFDiagnosticPrinter.h"
30#include "clang/Frontend/Utils.h"
31#include "clang/Lex/HeaderSearch.h"
32#include "clang/Lex/LiteralSupport.h"
33#include "clang/Lex/Preprocessor.h"
34#include "clang/Lex/PreprocessorOptions.h"
35#include "clang/Parse/ParseAST.h"
36#include "clang/Sema/HLSLExternalSemaSource.h"
37#include "clang/Sema/MultiplexExternalSemaSource.h"
38#include "clang/Serialization/ASTDeserializationListener.h"
39#include "clang/Serialization/ASTReader.h"
40#include "clang/Serialization/GlobalModuleIndex.h"
41#include "llvm/ADT/ScopeExit.h"
42#include "llvm/ADT/StringRef.h"
43#include "llvm/Support/BuryPointer.h"
44#include "llvm/Support/ErrorHandling.h"
45#include "llvm/Support/FileSystem.h"
46#include "llvm/Support/Path.h"
47#include "llvm/Support/Timer.h"
48#include "llvm/Support/raw_ostream.h"
49#include <memory>
50#include <system_error>
51using namespace clang;
52
53LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)
54
55namespace {
56
57/// DeserializedDeclsLineRangePrinter dumps ranges of deserialized declarations
58/// to aid debugging and bug minimization. It implements ASTConsumer and
59/// ASTDeserializationListener, so that an object of
60/// DeserializedDeclsLineRangePrinter registers as its own listener. The
61/// ASTDeserializationListener interface provides the DeclRead callback that we
62/// use to collect the deserialized Decls. Note that printing or otherwise
63/// processing them as this point is dangerous, since that could trigger
64/// additional deserialization and crash compilation. Therefore, we process the
65/// collected Decls in HandleTranslationUnit method of ASTConsumer. This is a
66/// safe point, since we know that by this point all the Decls needed by the
67/// compiler frontend have been deserialized. In case our processing causes
68/// further deserialization, DeclRead from the listener might be called again.
69/// However, at that point we don't accept any more Decls for processing.
70class DeserializedDeclsSourceRangePrinter : public ASTConsumer,
71 ASTDeserializationListener {
72public:
73 explicit DeserializedDeclsSourceRangePrinter(
74 SourceManager &SM, std::unique_ptr<llvm::raw_fd_ostream> OS)
75 : ASTDeserializationListener(), SM(SM), OS(std::move(OS)) {}
76
77 ASTDeserializationListener *GetASTDeserializationListener() override {
78 return this;
79 }
80
81 void DeclRead(GlobalDeclID ID, const Decl *D) override {
82 if (!IsCollectingDecls)
83 return;
84 if (!D || isa<TranslationUnitDecl>(Val: D) || isa<LinkageSpecDecl>(Val: D) ||
85 isa<NamespaceDecl>(Val: D)) {
86 // These decls cover a lot of nested declarations that might not be used,
87 // reducing the granularity and making the output less useful.
88 return;
89 }
90 if (auto *DC = D->getDeclContext(); !DC || !DC->isFileContext()) {
91 // We choose to work at namespace level to reduce complexity and the
92 // number of cases we care about.
93 return;
94 }
95 PendingDecls.push_back(x: D);
96 }
97
98 struct Position {
99 unsigned Line;
100 unsigned Column;
101
102 bool operator<(const Position &other) const {
103 return std::tie(args: Line, args: Column) < std::tie(args: other.Line, args: other.Column);
104 }
105
106 static Position GetBeginSpelling(const SourceManager &SM,
107 const CharSourceRange &R) {
108 SourceLocation Begin = R.getBegin();
109 return {.Line: SM.getSpellingLineNumber(Loc: Begin),
110 .Column: SM.getSpellingColumnNumber(Loc: Begin)};
111 }
112
113 static Position GetEndSpelling(const SourceManager &SM,
114 const CharSourceRange &Range,
115 const LangOptions &LangOpts) {
116 // For token ranges, compute end location for end character of the range.
117 CharSourceRange R = Lexer::getAsCharRange(Range, SM, LangOpts);
118 SourceLocation End = R.getEnd();
119 // Relex the token past the end location of the last token in the source
120 // range. If it's a semicolon, advance the location by one token.
121 Token PossiblySemi;
122 Lexer::getRawToken(Loc: End, Result&: PossiblySemi, SM, LangOpts, IgnoreWhiteSpace: true);
123 if (PossiblySemi.is(K: tok::semi))
124 End = End.getLocWithOffset(Offset: 1);
125 // Column number of the returned end position is exclusive.
126 return {.Line: SM.getSpellingLineNumber(Loc: End), .Column: SM.getSpellingColumnNumber(Loc: End)};
127 }
128 };
129
130 struct RequiredRanges {
131 StringRef Filename;
132 std::vector<std::pair<Position, Position>> FromTo;
133 };
134 void HandleTranslationUnit(ASTContext &Context) override {
135 assert(IsCollectingDecls && "HandleTranslationUnit called twice?");
136 IsCollectingDecls = false;
137
138 // Merge ranges in each of the files.
139 struct FileData {
140 std::vector<std::pair<Position, Position>> FromTo;
141 OptionalFileEntryRef Ref;
142 };
143 llvm::DenseMap<const FileEntry *, FileData> FileToRanges;
144 for (const Decl *D : PendingDecls) {
145 CharSourceRange R = SM.getExpansionRange(Range: D->getSourceRange());
146 if (!R.isValid())
147 continue;
148
149 auto *F = SM.getFileEntryForID(FID: SM.getFileID(SpellingLoc: R.getBegin()));
150 if (F != SM.getFileEntryForID(FID: SM.getFileID(SpellingLoc: R.getEnd()))) {
151 // Such cases are rare and difficult to handle.
152 continue;
153 }
154
155 auto &Data = FileToRanges[F];
156 if (!Data.Ref)
157 Data.Ref = SM.getFileEntryRefForID(FID: SM.getFileID(SpellingLoc: R.getBegin()));
158 Data.FromTo.push_back(
159 x: {Position::GetBeginSpelling(SM, R),
160 Position::GetEndSpelling(SM, Range: R, LangOpts: D->getLangOpts())});
161 }
162
163 // To simplify output, merge consecutive and intersecting ranges.
164 std::vector<RequiredRanges> Result;
165 for (auto &[F, Data] : FileToRanges) {
166 auto &FromTo = Data.FromTo;
167 assert(!FromTo.empty());
168
169 if (!Data.Ref)
170 continue;
171
172 llvm::sort(C&: FromTo);
173
174 std::vector<std::pair<Position, Position>> MergedRanges;
175 MergedRanges.push_back(x: FromTo.front());
176 for (auto It = FromTo.begin() + 1; It < FromTo.end(); ++It) {
177 if (MergedRanges.back().second < It->first) {
178 MergedRanges.push_back(x: *It);
179 continue;
180 }
181 if (MergedRanges.back().second < It->second)
182 MergedRanges.back().second = It->second;
183 }
184 Result.push_back(x: {.Filename: Data.Ref->getName(), .FromTo: std::move(MergedRanges)});
185 }
186 printJson(Result);
187 }
188
189private:
190 std::vector<const Decl *> PendingDecls;
191 bool IsCollectingDecls = true;
192 const SourceManager &SM;
193 std::unique_ptr<llvm::raw_ostream> OS;
194
195 void printJson(llvm::ArrayRef<RequiredRanges> Result) {
196 *OS << "{\n";
197 *OS << R"( "required_ranges": [)" << "\n";
198 for (size_t I = 0; I < Result.size(); ++I) {
199 auto &F = Result[I].Filename;
200 auto &MergedRanges = Result[I].FromTo;
201 *OS << R"( {)" << "\n";
202 *OS << R"( "file": ")" << F << "\"," << "\n";
203 *OS << R"( "range": [)" << "\n";
204 for (size_t J = 0; J < MergedRanges.size(); ++J) {
205 auto &From = MergedRanges[J].first;
206 auto &To = MergedRanges[J].second;
207 *OS << R"( {)" << "\n";
208 *OS << R"( "from": {)" << "\n";
209 *OS << R"( "line": )" << From.Line << ",\n";
210 *OS << R"( "column": )" << From.Column << "\n"
211 << R"( },)" << "\n";
212 *OS << R"( "to": {)" << "\n";
213 *OS << R"( "line": )" << To.Line << ",\n";
214 *OS << R"( "column": )" << To.Column << "\n"
215 << R"( })" << "\n";
216 *OS << R"( })";
217 if (J < MergedRanges.size() - 1) {
218 *OS << ",";
219 }
220 *OS << "\n";
221 }
222 *OS << " ]" << "\n" << " }";
223 if (I < Result.size() - 1)
224 *OS << ",";
225 *OS << "\n";
226 }
227 *OS << " ]\n";
228 *OS << "}\n";
229 }
230};
231
232/// Dumps deserialized declarations.
233class DeserializedDeclsDumper : public DelegatingDeserializationListener {
234public:
235 explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
236 bool DeletePrevious)
237 : DelegatingDeserializationListener(Previous, DeletePrevious) {}
238
239 void DeclRead(GlobalDeclID ID, const Decl *D) override {
240 llvm::outs() << "PCH DECL: " << D->getDeclKindName();
241 if (const NamedDecl *ND = dyn_cast<NamedDecl>(Val: D)) {
242 llvm::outs() << " - ";
243 ND->printQualifiedName(OS&: llvm::outs());
244 }
245 llvm::outs() << "\n";
246
247 DelegatingDeserializationListener::DeclRead(ID, D);
248 }
249};
250
251/// Checks deserialized declarations and emits error if a name
252/// matches one given in command-line using -error-on-deserialized-decl.
253class DeserializedDeclsChecker : public DelegatingDeserializationListener {
254 ASTContext &Ctx;
255 std::set<std::string> NamesToCheck;
256
257public:
258 DeserializedDeclsChecker(ASTContext &Ctx,
259 const std::set<std::string> &NamesToCheck,
260 ASTDeserializationListener *Previous,
261 bool DeletePrevious)
262 : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
263 NamesToCheck(NamesToCheck) {}
264
265 void DeclRead(GlobalDeclID ID, const Decl *D) override {
266 if (const NamedDecl *ND = dyn_cast<NamedDecl>(Val: D))
267 if (NamesToCheck.find(x: ND->getNameAsString()) != NamesToCheck.end()) {
268 unsigned DiagID
269 = Ctx.getDiagnostics().getCustomDiagID(L: DiagnosticsEngine::Error,
270 FormatString: "%0 was deserialized");
271 Ctx.getDiagnostics().Report(Loc: Ctx.getFullLoc(Loc: D->getLocation()), DiagID)
272 << ND;
273 }
274
275 DelegatingDeserializationListener::DeclRead(ID, D);
276 }
277};
278
279} // end anonymous namespace
280
281FrontendAction::FrontendAction() : Instance(nullptr) {}
282
283FrontendAction::~FrontendAction() {}
284
285void FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput,
286 std::unique_ptr<ASTUnit> AST) {
287 this->CurrentInput = CurrentInput;
288 CurrentASTUnit = std::move(AST);
289}
290
291Module *FrontendAction::getCurrentModule() const {
292 CompilerInstance &CI = getCompilerInstance();
293 return CI.getPreprocessor().getHeaderSearchInfo().lookupModule(
294 ModuleName: CI.getLangOpts().CurrentModule, ImportLoc: SourceLocation(), /*AllowSearch*/false);
295}
296
297std::unique_ptr<ASTConsumer>
298FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
299 StringRef InFile) {
300 std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile);
301 if (!Consumer)
302 return nullptr;
303
304 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
305 llvm::StringRef DumpDeserializedDeclarationRangesPath =
306 CI.getFrontendOpts().DumpMinimizationHintsPath;
307 if (!DumpDeserializedDeclarationRangesPath.empty()) {
308 std::error_code ErrorCode;
309 auto FileStream = std::make_unique<llvm::raw_fd_ostream>(
310 args&: DumpDeserializedDeclarationRangesPath, args&: ErrorCode,
311 args: llvm::sys::fs::OF_TextWithCRLF);
312 if (!ErrorCode) {
313 Consumers.push_back(x: std::make_unique<DeserializedDeclsSourceRangePrinter>(
314 args&: CI.getSourceManager(), args: std::move(FileStream)));
315 } else {
316 llvm::errs() << "Failed to create output file for "
317 "-dump-minimization-hints flag, file path: "
318 << DumpDeserializedDeclarationRangesPath
319 << ", error: " << ErrorCode.message() << "\n";
320 }
321 }
322
323 // Validate -add-plugin args.
324 bool FoundAllPlugins = true;
325 for (const std::string &Arg : CI.getFrontendOpts().AddPluginActions) {
326 bool Found = false;
327 for (const FrontendPluginRegistry::entry &Plugin :
328 FrontendPluginRegistry::entries()) {
329 if (Plugin.getName() == Arg)
330 Found = true;
331 }
332 if (!Found) {
333 CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << Arg;
334 FoundAllPlugins = false;
335 }
336 }
337 if (!FoundAllPlugins)
338 return nullptr;
339
340 // If this is a code completion run, avoid invoking the plugin consumers
341 if (CI.hasCodeCompletionConsumer())
342 return Consumer;
343
344 // Collect the list of plugins that go before the main action (in Consumers)
345 // or after it (in AfterConsumers)
346 std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers;
347 for (const FrontendPluginRegistry::entry &Plugin :
348 FrontendPluginRegistry::entries()) {
349 std::unique_ptr<PluginASTAction> P = Plugin.instantiate();
350 PluginASTAction::ActionType ActionType = P->getActionType();
351 if (ActionType == PluginASTAction::CmdlineAfterMainAction ||
352 ActionType == PluginASTAction::CmdlineBeforeMainAction) {
353 // This is O(|plugins| * |add_plugins|), but since both numbers are
354 // way below 50 in practice, that's ok.
355 if (llvm::is_contained(Range&: CI.getFrontendOpts().AddPluginActions,
356 Element: Plugin.getName())) {
357 if (ActionType == PluginASTAction::CmdlineBeforeMainAction)
358 ActionType = PluginASTAction::AddBeforeMainAction;
359 else
360 ActionType = PluginASTAction::AddAfterMainAction;
361 }
362 }
363 if ((ActionType == PluginASTAction::AddBeforeMainAction ||
364 ActionType == PluginASTAction::AddAfterMainAction) &&
365 P->ParseArgs(
366 CI,
367 arg: CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())])) {
368 std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile);
369 if (ActionType == PluginASTAction::AddBeforeMainAction) {
370 Consumers.push_back(x: std::move(PluginConsumer));
371 } else {
372 AfterConsumers.push_back(x: std::move(PluginConsumer));
373 }
374 }
375 }
376
377 // Add to Consumers the main consumer, then all the plugins that go after it
378 Consumers.push_back(x: std::move(Consumer));
379 if (!AfterConsumers.empty()) {
380 // If we have plugins after the main consumer, which may be the codegen
381 // action, they likely will need the ASTContext, so don't clear it in the
382 // codegen action.
383 CI.getCodeGenOpts().ClearASTBeforeBackend = false;
384 for (auto &C : AfterConsumers)
385 Consumers.push_back(x: std::move(C));
386 }
387
388 assert(Consumers.size() >= 1 && "should have added the main consumer");
389 if (Consumers.size() == 1)
390 return std::move(Consumers.front());
391 return std::make_unique<MultiplexConsumer>(args: std::move(Consumers));
392}
393
394/// For preprocessed files, if the first line is the linemarker and specifies
395/// the original source file name, use that name as the input file name.
396/// Returns the location of the first token after the line marker directive.
397///
398/// \param CI The compiler instance.
399/// \param InputFile Populated with the filename from the line marker.
400/// \param IsModuleMap If \c true, add a line note corresponding to this line
401/// directive. (We need to do this because the directive will not be
402/// visited by the preprocessor.)
403static SourceLocation ReadOriginalFileName(CompilerInstance &CI,
404 std::string &InputFile,
405 bool IsModuleMap = false) {
406 auto &SourceMgr = CI.getSourceManager();
407 auto MainFileID = SourceMgr.getMainFileID();
408
409 auto MainFileBuf = SourceMgr.getBufferOrNone(FID: MainFileID);
410 if (!MainFileBuf)
411 return SourceLocation();
412
413 std::unique_ptr<Lexer> RawLexer(
414 new Lexer(MainFileID, *MainFileBuf, SourceMgr, CI.getLangOpts()));
415
416 // If the first line has the syntax of
417 //
418 // # NUM "FILENAME"
419 //
420 // we use FILENAME as the input file name.
421 Token T;
422 if (RawLexer->LexFromRawLexer(Result&: T) || T.getKind() != tok::hash)
423 return SourceLocation();
424 if (RawLexer->LexFromRawLexer(Result&: T) || T.isAtStartOfLine() ||
425 T.getKind() != tok::numeric_constant)
426 return SourceLocation();
427
428 unsigned LineNo;
429 SourceLocation LineNoLoc = T.getLocation();
430 if (IsModuleMap) {
431 llvm::SmallString<16> Buffer;
432 if (Lexer::getSpelling(loc: LineNoLoc, buffer&: Buffer, SM: SourceMgr, options: CI.getLangOpts())
433 .getAsInteger(Radix: 10, Result&: LineNo))
434 return SourceLocation();
435 }
436
437 RawLexer->LexFromRawLexer(Result&: T);
438 if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
439 return SourceLocation();
440
441 StringLiteralParser Literal(T, CI.getPreprocessor());
442 if (Literal.hadError)
443 return SourceLocation();
444 RawLexer->LexFromRawLexer(Result&: T);
445 if (T.isNot(K: tok::eof) && !T.isAtStartOfLine())
446 return SourceLocation();
447 InputFile = Literal.GetString().str();
448
449 if (IsModuleMap)
450 CI.getSourceManager().AddLineNote(
451 Loc: LineNoLoc, LineNo, FilenameID: SourceMgr.getLineTableFilenameID(Str: InputFile), IsFileEntry: false,
452 IsFileExit: false, FileKind: SrcMgr::C_User_ModuleMap);
453
454 return T.getLocation();
455}
456
457static SmallVectorImpl<char> &
458operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
459 Includes.append(in_start: RHS.begin(), in_end: RHS.end());
460 return Includes;
461}
462
463static void addHeaderInclude(StringRef HeaderName,
464 SmallVectorImpl<char> &Includes,
465 const LangOptions &LangOpts,
466 bool IsExternC) {
467 if (IsExternC && LangOpts.CPlusPlus)
468 Includes += "extern \"C\" {\n";
469 if (LangOpts.ObjC)
470 Includes += "#import \"";
471 else
472 Includes += "#include \"";
473
474 Includes += HeaderName;
475
476 Includes += "\"\n";
477 if (IsExternC && LangOpts.CPlusPlus)
478 Includes += "}\n";
479}
480
481/// Collect the set of header includes needed to construct the given
482/// module and update the TopHeaders file set of the module.
483///
484/// \param Module The module we're collecting includes from.
485///
486/// \param Includes Will be augmented with the set of \#includes or \#imports
487/// needed to load all of the named headers.
488static std::error_code collectModuleHeaderIncludes(
489 const LangOptions &LangOpts, FileManager &FileMgr, DiagnosticsEngine &Diag,
490 ModuleMap &ModMap, clang::Module *Module, SmallVectorImpl<char> &Includes) {
491 // Don't collect any headers for unavailable modules.
492 if (!Module->isAvailable())
493 return std::error_code();
494
495 // Resolve all lazy header directives to header files.
496 ModMap.resolveHeaderDirectives(Mod: Module, /*File=*/std::nullopt);
497
498 // If any headers are missing, we can't build this module. In most cases,
499 // diagnostics for this should have already been produced; we only get here
500 // if explicit stat information was provided.
501 // FIXME: If the name resolves to a file with different stat information,
502 // produce a better diagnostic.
503 if (!Module->MissingHeaders.empty()) {
504 auto &MissingHeader = Module->MissingHeaders.front();
505 Diag.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
506 << MissingHeader.IsUmbrella << MissingHeader.FileName;
507 return std::error_code();
508 }
509
510 // Add includes for each of these headers.
511 for (auto HK : {Module::HK_Normal, Module::HK_Private}) {
512 for (const Module::Header &H : Module->getHeaders(HK)) {
513 Module->addTopHeader(File: H.Entry);
514 // Use the path as specified in the module map file. We'll look for this
515 // file relative to the module build directory (the directory containing
516 // the module map file) so this will find the same file that we found
517 // while parsing the module map.
518 addHeaderInclude(HeaderName: H.PathRelativeToRootModuleDirectory, Includes, LangOpts,
519 IsExternC: Module->IsExternC);
520 }
521 }
522 // Note that Module->PrivateHeaders will not be a TopHeader.
523
524 if (std::optional<Module::Header> UmbrellaHeader =
525 Module->getUmbrellaHeaderAsWritten()) {
526 Module->addTopHeader(File: UmbrellaHeader->Entry);
527 if (Module->Parent)
528 // Include the umbrella header for submodules.
529 addHeaderInclude(HeaderName: UmbrellaHeader->PathRelativeToRootModuleDirectory,
530 Includes, LangOpts, IsExternC: Module->IsExternC);
531 } else if (std::optional<Module::DirectoryName> UmbrellaDir =
532 Module->getUmbrellaDirAsWritten()) {
533 // Add all of the headers we find in this subdirectory.
534 std::error_code EC;
535 SmallString<128> DirNative;
536 llvm::sys::path::native(path: UmbrellaDir->Entry.getName(), result&: DirNative);
537
538 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
539 SmallVector<std::pair<std::string, FileEntryRef>, 8> Headers;
540 for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
541 Dir != End && !EC; Dir.increment(EC)) {
542 // Check whether this entry has an extension typically associated with
543 // headers.
544 if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(path: Dir->path()))
545 .Cases(S0: ".h", S1: ".H", S2: ".hh", S3: ".hpp", Value: true)
546 .Default(Value: false))
547 continue;
548
549 auto Header = FileMgr.getOptionalFileRef(Filename: Dir->path());
550 // FIXME: This shouldn't happen unless there is a file system race. Is
551 // that worth diagnosing?
552 if (!Header)
553 continue;
554
555 // If this header is marked 'unavailable' in this module, don't include
556 // it.
557 if (ModMap.isHeaderUnavailableInModule(Header: *Header, RequestingModule: Module))
558 continue;
559
560 // Compute the relative path from the directory to this file.
561 SmallVector<StringRef, 16> Components;
562 auto PathIt = llvm::sys::path::rbegin(path: Dir->path());
563 for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt)
564 Components.push_back(Elt: *PathIt);
565 SmallString<128> RelativeHeader(
566 UmbrellaDir->PathRelativeToRootModuleDirectory);
567 for (auto It = Components.rbegin(), End = Components.rend(); It != End;
568 ++It)
569 llvm::sys::path::append(path&: RelativeHeader, a: *It);
570
571 std::string RelName = RelativeHeader.c_str();
572 Headers.push_back(Elt: std::make_pair(x&: RelName, y&: *Header));
573 }
574
575 if (EC)
576 return EC;
577
578 // Sort header paths and make the header inclusion order deterministic
579 // across different OSs and filesystems.
580 llvm::sort(C&: Headers, Comp: llvm::less_first());
581 for (auto &H : Headers) {
582 // Include this header as part of the umbrella directory.
583 Module->addTopHeader(File: H.second);
584 addHeaderInclude(HeaderName: H.first, Includes, LangOpts, IsExternC: Module->IsExternC);
585 }
586 }
587
588 // Recurse into submodules.
589 for (auto *Submodule : Module->submodules())
590 if (std::error_code Err = collectModuleHeaderIncludes(
591 LangOpts, FileMgr, Diag, ModMap, Module: Submodule, Includes))
592 return Err;
593
594 return std::error_code();
595}
596
597static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem,
598 bool IsPreprocessed,
599 std::string &PresumedModuleMapFile,
600 unsigned &Offset) {
601 auto &SrcMgr = CI.getSourceManager();
602 HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
603
604 // Map the current input to a file.
605 FileID ModuleMapID = SrcMgr.getMainFileID();
606 OptionalFileEntryRef ModuleMap = SrcMgr.getFileEntryRefForID(FID: ModuleMapID);
607 assert(ModuleMap && "MainFileID without FileEntry");
608
609 // If the module map is preprocessed, handle the initial line marker;
610 // line directives are not part of the module map syntax in general.
611 Offset = 0;
612 if (IsPreprocessed) {
613 SourceLocation EndOfLineMarker =
614 ReadOriginalFileName(CI, InputFile&: PresumedModuleMapFile, /*IsModuleMap*/ true);
615 if (EndOfLineMarker.isValid())
616 Offset = CI.getSourceManager().getDecomposedLoc(Loc: EndOfLineMarker).second;
617 }
618
619 // Load the module map file.
620 if (HS.parseAndLoadModuleMapFile(File: *ModuleMap, IsSystem, ID: ModuleMapID, Offset: &Offset,
621 OriginalModuleMapFile: PresumedModuleMapFile))
622 return true;
623
624 if (SrcMgr.getBufferOrFake(FID: ModuleMapID).getBufferSize() == Offset)
625 Offset = 0;
626
627 // Infer framework module if possible.
628 if (HS.getModuleMap().canInferFrameworkModule(Dir: ModuleMap->getDir())) {
629 SmallString<128> InferredFrameworkPath = ModuleMap->getDir().getName();
630 llvm::sys::path::append(path&: InferredFrameworkPath,
631 a: CI.getLangOpts().ModuleName + ".framework");
632 if (auto Dir =
633 CI.getFileManager().getOptionalDirectoryRef(DirName: InferredFrameworkPath))
634 (void)HS.getModuleMap().inferFrameworkModule(FrameworkDir: *Dir, IsSystem, Parent: nullptr);
635 }
636
637 return false;
638}
639
640static Module *prepareToBuildModule(CompilerInstance &CI,
641 StringRef ModuleMapFilename) {
642 if (CI.getLangOpts().CurrentModule.empty()) {
643 CI.getDiagnostics().Report(diag::err_missing_module_name);
644
645 // FIXME: Eventually, we could consider asking whether there was just
646 // a single module described in the module map, and use that as a
647 // default. Then it would be fairly trivial to just "compile" a module
648 // map with a single module (the common case).
649 return nullptr;
650 }
651
652 // Dig out the module definition.
653 HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
654 Module *M = HS.lookupModule(ModuleName: CI.getLangOpts().CurrentModule, ImportLoc: SourceLocation(),
655 /*AllowSearch=*/true);
656 if (!M) {
657 CI.getDiagnostics().Report(diag::err_missing_module)
658 << CI.getLangOpts().CurrentModule << ModuleMapFilename;
659
660 return nullptr;
661 }
662
663 // Check whether we can build this module at all.
664 if (Preprocessor::checkModuleIsAvailable(LangOpts: CI.getLangOpts(), TargetInfo: CI.getTarget(), M: *M,
665 Diags&: CI.getDiagnostics()))
666 return nullptr;
667
668 // Inform the preprocessor that includes from within the input buffer should
669 // be resolved relative to the build directory of the module map file.
670 CI.getPreprocessor().setMainFileDir(*M->Directory);
671
672 // If the module was inferred from a different module map (via an expanded
673 // umbrella module definition), track that fact.
674 // FIXME: It would be preferable to fill this in as part of processing
675 // the module map, rather than adding it after the fact.
676 StringRef OriginalModuleMapName = CI.getFrontendOpts().OriginalModuleMap;
677 if (!OriginalModuleMapName.empty()) {
678 auto OriginalModuleMap =
679 CI.getFileManager().getOptionalFileRef(Filename: OriginalModuleMapName,
680 /*openFile*/ OpenFile: true);
681 if (!OriginalModuleMap) {
682 CI.getDiagnostics().Report(diag::err_module_map_not_found)
683 << OriginalModuleMapName;
684 return nullptr;
685 }
686 if (*OriginalModuleMap != CI.getSourceManager().getFileEntryRefForID(
687 FID: CI.getSourceManager().getMainFileID())) {
688 auto FileCharacter =
689 M->IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
690 FileID OriginalModuleMapFID = CI.getSourceManager().getOrCreateFileID(
691 SourceFile: *OriginalModuleMap, FileCharacter);
692 CI.getPreprocessor()
693 .getHeaderSearchInfo()
694 .getModuleMap()
695 .setInferredModuleAllowedBy(M, ModMapFID: OriginalModuleMapFID);
696 }
697 }
698
699 // If we're being run from the command-line, the module build stack will not
700 // have been filled in yet, so complete it now in order to allow us to detect
701 // module cycles.
702 SourceManager &SourceMgr = CI.getSourceManager();
703 if (SourceMgr.getModuleBuildStack().empty())
704 SourceMgr.pushModuleBuildStack(moduleName: CI.getLangOpts().CurrentModule,
705 importLoc: FullSourceLoc(SourceLocation(), SourceMgr));
706 return M;
707}
708
709/// Compute the input buffer that should be used to build the specified module.
710static std::unique_ptr<llvm::MemoryBuffer>
711getInputBufferForModule(CompilerInstance &CI, Module *M) {
712 FileManager &FileMgr = CI.getFileManager();
713
714 // Collect the set of #includes we need to build the module.
715 SmallString<256> HeaderContents;
716 std::error_code Err = std::error_code();
717 if (std::optional<Module::Header> UmbrellaHeader =
718 M->getUmbrellaHeaderAsWritten())
719 addHeaderInclude(HeaderName: UmbrellaHeader->PathRelativeToRootModuleDirectory,
720 Includes&: HeaderContents, LangOpts: CI.getLangOpts(), IsExternC: M->IsExternC);
721 Err = collectModuleHeaderIncludes(
722 LangOpts: CI.getLangOpts(), FileMgr, Diag&: CI.getDiagnostics(),
723 ModMap&: CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), Module: M,
724 Includes&: HeaderContents);
725
726 if (Err) {
727 CI.getDiagnostics().Report(diag::err_module_cannot_create_includes)
728 << M->getFullModuleName() << Err.message();
729 return nullptr;
730 }
731
732 return llvm::MemoryBuffer::getMemBufferCopy(
733 InputData: HeaderContents, BufferName: Module::getModuleInputBufferName());
734}
735
736bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
737 const FrontendInputFile &RealInput) {
738 FrontendInputFile Input(RealInput);
739 assert(!Instance && "Already processing a source file!");
740 assert(!Input.isEmpty() && "Unexpected empty filename!");
741 setCurrentInput(CurrentInput: Input);
742 setCompilerInstance(&CI);
743
744 bool HasBegunSourceFile = false;
745 bool ReplayASTFile = Input.getKind().getFormat() == InputKind::Precompiled &&
746 usesPreprocessorOnly();
747
748 // If we fail, reset state since the client will not end up calling the
749 // matching EndSourceFile(). All paths that return true should release this.
750 auto FailureCleanup = llvm::make_scope_exit(F: [&]() {
751 if (HasBegunSourceFile)
752 CI.getDiagnosticClient().EndSourceFile();
753 CI.setASTConsumer(nullptr);
754 CI.clearOutputFiles(/*EraseFiles=*/true);
755 CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
756 setCurrentInput(CurrentInput: FrontendInputFile());
757 setCompilerInstance(nullptr);
758 });
759
760 if (!BeginInvocation(CI))
761 return false;
762
763 // If we're replaying the build of an AST file, import it and set up
764 // the initial state from its build.
765 if (ReplayASTFile) {
766 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
767
768 // The AST unit populates its own diagnostics engine rather than ours.
769 IntrusiveRefCntPtr<DiagnosticsEngine> ASTDiags(new DiagnosticsEngine(
770 Diags->getDiagnosticIDs(), Diags->getDiagnosticOptions()));
771 ASTDiags->setClient(client: Diags->getClient(), /*OwnsClient*/ShouldOwnClient: false);
772
773 // FIXME: What if the input is a memory buffer?
774 StringRef InputFile = Input.getFile();
775
776 std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
777 Filename: InputFile, PCHContainerRdr: CI.getPCHContainerReader(), ToLoad: ASTUnit::LoadPreprocessorOnly,
778 DiagOpts: nullptr, Diags: ASTDiags, FileSystemOpts: CI.getFileSystemOpts(), HSOpts: CI.getHeaderSearchOpts());
779 if (!AST)
780 return false;
781
782 // Options relating to how we treat the input (but not what we do with it)
783 // are inherited from the AST unit.
784 CI.getHeaderSearchOpts() = AST->getHeaderSearchOpts();
785 CI.getPreprocessorOpts() = AST->getPreprocessorOpts();
786 CI.getLangOpts() = AST->getLangOpts();
787
788 // Set the shared objects, these are reset when we finish processing the
789 // file, otherwise the CompilerInstance will happily destroy them.
790 CI.setFileManager(&AST->getFileManager());
791 CI.createSourceManager(FileMgr&: CI.getFileManager());
792 CI.getSourceManager().initializeForReplay(Old: AST->getSourceManager());
793
794 // Preload all the module files loaded transitively by the AST unit. Also
795 // load all module map files that were parsed as part of building the AST
796 // unit.
797 if (auto ASTReader = AST->getASTReader()) {
798 auto &MM = ASTReader->getModuleManager();
799 auto &PrimaryModule = MM.getPrimaryModule();
800
801 for (serialization::ModuleFile &MF : MM)
802 if (&MF != &PrimaryModule)
803 CI.getFrontendOpts().ModuleFiles.push_back(x: MF.FileName);
804
805 ASTReader->visitTopLevelModuleMaps(MF&: PrimaryModule, Visitor: [&](FileEntryRef FE) {
806 CI.getFrontendOpts().ModuleMapFiles.push_back(
807 x: std::string(FE.getName()));
808 });
809 }
810
811 // Set up the input file for replay purposes.
812 auto Kind = AST->getInputKind();
813 if (Kind.getFormat() == InputKind::ModuleMap) {
814 Module *ASTModule =
815 AST->getPreprocessor().getHeaderSearchInfo().lookupModule(
816 ModuleName: AST->getLangOpts().CurrentModule, ImportLoc: SourceLocation(),
817 /*AllowSearch*/ false);
818 assert(ASTModule && "module file does not define its own module");
819 Input = FrontendInputFile(ASTModule->PresumedModuleMapFile, Kind);
820 } else {
821 auto &OldSM = AST->getSourceManager();
822 FileID ID = OldSM.getMainFileID();
823 if (auto File = OldSM.getFileEntryRefForID(FID: ID))
824 Input = FrontendInputFile(File->getName(), Kind);
825 else
826 Input = FrontendInputFile(OldSM.getBufferOrFake(FID: ID), Kind);
827 }
828 setCurrentInput(CurrentInput: Input, AST: std::move(AST));
829 }
830
831 // AST files follow a very different path, since they share objects via the
832 // AST unit.
833 if (Input.getKind().getFormat() == InputKind::Precompiled) {
834 assert(!usesPreprocessorOnly() && "this case was handled above");
835 assert(hasASTFileSupport() &&
836 "This action does not have AST file support!");
837
838 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
839
840 // FIXME: What if the input is a memory buffer?
841 StringRef InputFile = Input.getFile();
842
843 std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
844 Filename: InputFile, PCHContainerRdr: CI.getPCHContainerReader(), ToLoad: ASTUnit::LoadEverything, DiagOpts: nullptr,
845 Diags, FileSystemOpts: CI.getFileSystemOpts(), HSOpts: CI.getHeaderSearchOpts(),
846 LangOpts: &CI.getLangOpts());
847
848 if (!AST)
849 return false;
850
851 // Inform the diagnostic client we are processing a source file.
852 CI.getDiagnosticClient().BeginSourceFile(LangOpts: CI.getLangOpts(), PP: nullptr);
853 HasBegunSourceFile = true;
854
855 // Set the shared objects, these are reset when we finish processing the
856 // file, otherwise the CompilerInstance will happily destroy them.
857 CI.setFileManager(&AST->getFileManager());
858 CI.setSourceManager(&AST->getSourceManager());
859 CI.setPreprocessor(AST->getPreprocessorPtr());
860 Preprocessor &PP = CI.getPreprocessor();
861 PP.getBuiltinInfo().initializeBuiltins(Table&: PP.getIdentifierTable(),
862 LangOpts: PP.getLangOpts());
863 CI.setASTContext(&AST->getASTContext());
864
865 setCurrentInput(CurrentInput: Input, AST: std::move(AST));
866
867 // Initialize the action.
868 if (!BeginSourceFileAction(CI))
869 return false;
870
871 // Create the AST consumer.
872 CI.setASTConsumer(CreateWrappedASTConsumer(CI, InFile: InputFile));
873 if (!CI.hasASTConsumer())
874 return false;
875
876 FailureCleanup.release();
877 return true;
878 }
879
880 // Set up the file and source managers, if needed.
881 if (!CI.hasFileManager()) {
882 if (!CI.createFileManager()) {
883 return false;
884 }
885 }
886 if (!CI.hasSourceManager()) {
887 CI.createSourceManager(FileMgr&: CI.getFileManager());
888 if (CI.getDiagnosticOpts().getFormat() == DiagnosticOptions::SARIF) {
889 static_cast<SARIFDiagnosticPrinter *>(&CI.getDiagnosticClient())
890 ->setSarifWriter(
891 std::make_unique<SarifDocumentWriter>(args&: CI.getSourceManager()));
892 }
893 }
894
895 // Set up embedding for any specified files. Do this before we load any
896 // source files, including the primary module map for the compilation.
897 for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
898 if (auto FE = CI.getFileManager().getOptionalFileRef(Filename: F, /*openFile*/OpenFile: true))
899 CI.getSourceManager().setFileIsTransient(*FE);
900 else
901 CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
902 }
903 if (CI.getFrontendOpts().ModulesEmbedAllFiles)
904 CI.getSourceManager().setAllFilesAreTransient(true);
905
906 // IR files bypass the rest of initialization.
907 if (Input.getKind().getLanguage() == Language::LLVM_IR) {
908 if (!hasIRSupport()) {
909 CI.getDiagnostics().Report(diag::err_ast_action_on_llvm_ir)
910 << Input.getFile();
911 return false;
912 }
913
914 // Inform the diagnostic client we are processing a source file.
915 CI.getDiagnosticClient().BeginSourceFile(LangOpts: CI.getLangOpts(), PP: nullptr);
916 HasBegunSourceFile = true;
917
918 // Initialize the action.
919 if (!BeginSourceFileAction(CI))
920 return false;
921
922 // Initialize the main file entry.
923 if (!CI.InitializeSourceManager(Input: CurrentInput))
924 return false;
925
926 FailureCleanup.release();
927 return true;
928 }
929
930 // If the implicit PCH include is actually a directory, rather than
931 // a single file, search for a suitable PCH file in that directory.
932 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
933 FileManager &FileMgr = CI.getFileManager();
934 PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
935 StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
936 std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
937 if (auto PCHDir = FileMgr.getOptionalDirectoryRef(DirName: PCHInclude)) {
938 std::error_code EC;
939 SmallString<128> DirNative;
940 llvm::sys::path::native(path: PCHDir->getName(), result&: DirNative);
941 bool Found = false;
942 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
943 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(Dir: DirNative, EC),
944 DirEnd;
945 Dir != DirEnd && !EC; Dir.increment(EC)) {
946 // Check whether this is an acceptable AST file.
947 if (ASTReader::isAcceptableASTFile(
948 Filename: Dir->path(), FileMgr, ModCache: CI.getModuleCache(),
949 PCHContainerRdr: CI.getPCHContainerReader(), LangOpts: CI.getLangOpts(),
950 TargetOpts: CI.getTargetOpts(), PPOpts: CI.getPreprocessorOpts(),
951 ExistingModuleCachePath: SpecificModuleCachePath, /*RequireStrictOptionMatches=*/true)) {
952 PPOpts.ImplicitPCHInclude = std::string(Dir->path());
953 Found = true;
954 break;
955 }
956 }
957
958 if (!Found) {
959 CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
960 return false;
961 }
962 }
963 }
964
965 // Set up the preprocessor if needed. When parsing model files the
966 // preprocessor of the original source is reused.
967 if (!isModelParsingAction())
968 CI.createPreprocessor(TUKind: getTranslationUnitKind());
969
970 // Inform the diagnostic client we are processing a source file.
971 CI.getDiagnosticClient().BeginSourceFile(LangOpts: CI.getLangOpts(),
972 PP: &CI.getPreprocessor());
973 HasBegunSourceFile = true;
974
975 // Handle C++20 header units.
976 // Here, the user has the option to specify that the header name should be
977 // looked up in the pre-processor search paths (and the main filename as
978 // passed by the driver might therefore be incomplete until that look-up).
979 if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
980 !Input.getKind().isPreprocessed()) {
981 StringRef FileName = Input.getFile();
982 InputKind Kind = Input.getKind();
983 if (Kind.getHeaderUnitKind() != InputKind::HeaderUnit_Abs) {
984 assert(CI.hasPreprocessor() &&
985 "trying to build a header unit without a Pre-processor?");
986 HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
987 // Relative searches begin from CWD.
988 auto Dir = CI.getFileManager().getOptionalDirectoryRef(DirName: ".");
989 SmallVector<std::pair<OptionalFileEntryRef, DirectoryEntryRef>, 1> CWD;
990 CWD.push_back(Elt: {std::nullopt, *Dir});
991 OptionalFileEntryRef FE =
992 HS.LookupFile(Filename: FileName, IncludeLoc: SourceLocation(),
993 /*Angled*/ isAngled: Input.getKind().getHeaderUnitKind() ==
994 InputKind::HeaderUnit_System,
995 FromDir: nullptr, CurDir: nullptr, Includers: CWD, SearchPath: nullptr, RelativePath: nullptr, RequestingModule: nullptr,
996 SuggestedModule: nullptr, IsMapped: nullptr, IsFrameworkFound: nullptr);
997 if (!FE) {
998 CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
999 << FileName;
1000 return false;
1001 }
1002 // We now have the filename...
1003 FileName = FE->getName();
1004 // ... still a header unit, but now use the path as written.
1005 Kind = Input.getKind().withHeaderUnit(HU: InputKind::HeaderUnit_Abs);
1006 Input = FrontendInputFile(FileName, Kind, Input.isSystem());
1007 }
1008 // Unless the user has overridden the name, the header unit module name is
1009 // the pathname for the file.
1010 if (CI.getLangOpts().ModuleName.empty())
1011 CI.getLangOpts().ModuleName = std::string(FileName);
1012 CI.getLangOpts().CurrentModule = CI.getLangOpts().ModuleName;
1013 }
1014
1015 if (!CI.InitializeSourceManager(Input))
1016 return false;
1017
1018 if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
1019 Input.getKind().isPreprocessed() && !usesPreprocessorOnly()) {
1020 // We have an input filename like foo.iih, but we want to find the right
1021 // module name (and original file, to build the map entry).
1022 // Check if the first line specifies the original source file name with a
1023 // linemarker.
1024 std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
1025 ReadOriginalFileName(CI, InputFile&: PresumedInputFile);
1026 // Unless the user overrides this, the module name is the name by which the
1027 // original file was known.
1028 if (CI.getLangOpts().ModuleName.empty())
1029 CI.getLangOpts().ModuleName = std::string(PresumedInputFile);
1030 CI.getLangOpts().CurrentModule = CI.getLangOpts().ModuleName;
1031 }
1032
1033 // For module map files, we first parse the module map and synthesize a
1034 // "<module-includes>" buffer before more conventional processing.
1035 if (Input.getKind().getFormat() == InputKind::ModuleMap) {
1036 CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);
1037
1038 std::string PresumedModuleMapFile;
1039 unsigned OffsetToContents;
1040 if (loadModuleMapForModuleBuild(CI, IsSystem: Input.isSystem(),
1041 IsPreprocessed: Input.isPreprocessed(),
1042 PresumedModuleMapFile, Offset&: OffsetToContents))
1043 return false;
1044
1045 auto *CurrentModule = prepareToBuildModule(CI, ModuleMapFilename: Input.getFile());
1046 if (!CurrentModule)
1047 return false;
1048
1049 CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;
1050
1051 if (OffsetToContents)
1052 // If the module contents are in the same file, skip to them.
1053 CI.getPreprocessor().setSkipMainFilePreamble(Bytes: OffsetToContents, StartOfLine: true);
1054 else {
1055 // Otherwise, convert the module description to a suitable input buffer.
1056 auto Buffer = getInputBufferForModule(CI, M: CurrentModule);
1057 if (!Buffer)
1058 return false;
1059
1060 // Reinitialize the main file entry to refer to the new input.
1061 auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
1062 auto &SourceMgr = CI.getSourceManager();
1063 auto BufferID = SourceMgr.createFileID(Buffer: std::move(Buffer), FileCharacter: Kind);
1064 assert(BufferID.isValid() && "couldn't create module buffer ID");
1065 SourceMgr.setMainFileID(BufferID);
1066 }
1067 }
1068
1069 // Initialize the action.
1070 if (!BeginSourceFileAction(CI))
1071 return false;
1072
1073 // If we were asked to load any module map files, do so now.
1074 for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
1075 if (auto File = CI.getFileManager().getOptionalFileRef(Filename))
1076 CI.getPreprocessor().getHeaderSearchInfo().parseAndLoadModuleMapFile(
1077 File: *File, /*IsSystem*/ false);
1078 else
1079 CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
1080 }
1081
1082 // If compiling implementation of a module, load its module map file now.
1083 (void)CI.getPreprocessor().getCurrentModuleImplementation();
1084
1085 // Add a module declaration scope so that modules from -fmodule-map-file
1086 // arguments may shadow modules found implicitly in search paths.
1087 CI.getPreprocessor()
1088 .getHeaderSearchInfo()
1089 .getModuleMap()
1090 .finishModuleDeclarationScope();
1091
1092 // Create the AST context and consumer unless this is a preprocessor only
1093 // action.
1094 if (!usesPreprocessorOnly()) {
1095 // Parsing a model file should reuse the existing ASTContext.
1096 if (!isModelParsingAction())
1097 CI.createASTContext();
1098
1099 // For preprocessed files, check if the first line specifies the original
1100 // source file name with a linemarker.
1101 std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
1102 if (Input.isPreprocessed())
1103 ReadOriginalFileName(CI, InputFile&: PresumedInputFile);
1104
1105 std::unique_ptr<ASTConsumer> Consumer =
1106 CreateWrappedASTConsumer(CI, InFile: PresumedInputFile);
1107 if (!Consumer)
1108 return false;
1109
1110 // FIXME: should not overwrite ASTMutationListener when parsing model files?
1111 if (!isModelParsingAction())
1112 CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
1113
1114 if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
1115 // Convert headers to PCH and chain them.
1116 IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
1117 source = createChainedIncludesSource(CI, Reader&: FinalReader);
1118 if (!source)
1119 return false;
1120 CI.setASTReader(static_cast<ASTReader *>(FinalReader.get()));
1121 CI.getASTContext().setExternalSource(source);
1122 } else if (CI.getLangOpts().Modules ||
1123 !CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
1124 // Use PCM or PCH.
1125 assert(hasPCHSupport() && "This action does not have PCH support!");
1126 ASTDeserializationListener *DeserialListener =
1127 Consumer->GetASTDeserializationListener();
1128 bool DeleteDeserialListener = false;
1129 if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) {
1130 DeserialListener = new DeserializedDeclsDumper(DeserialListener,
1131 DeleteDeserialListener);
1132 DeleteDeserialListener = true;
1133 }
1134 if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) {
1135 DeserialListener = new DeserializedDeclsChecker(
1136 CI.getASTContext(),
1137 CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
1138 DeserialListener, DeleteDeserialListener);
1139 DeleteDeserialListener = true;
1140 }
1141 if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
1142 CI.createPCHExternalASTSource(
1143 Path: CI.getPreprocessorOpts().ImplicitPCHInclude,
1144 DisableValidation: CI.getPreprocessorOpts().DisablePCHOrModuleValidation,
1145 AllowPCHWithCompilerErrors: CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
1146 DeserializationListener: DeserialListener, OwnDeserializationListener: DeleteDeserialListener);
1147 if (!CI.getASTContext().getExternalSource())
1148 return false;
1149 }
1150 // If modules are enabled, create the AST reader before creating
1151 // any builtins, so that all declarations know that they might be
1152 // extended by an external source.
1153 if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1154 !CI.getASTContext().getExternalSource()) {
1155 CI.createASTReader();
1156 CI.getASTReader()->setDeserializationListener(Listener: DeserialListener,
1157 TakeOwnership: DeleteDeserialListener);
1158 }
1159 }
1160
1161 CI.setASTConsumer(std::move(Consumer));
1162 if (!CI.hasASTConsumer())
1163 return false;
1164 }
1165
1166 // Initialize built-in info as long as we aren't using an external AST
1167 // source.
1168 if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1169 !CI.getASTContext().getExternalSource()) {
1170 Preprocessor &PP = CI.getPreprocessor();
1171 PP.getBuiltinInfo().initializeBuiltins(Table&: PP.getIdentifierTable(),
1172 LangOpts: PP.getLangOpts());
1173 } else {
1174 // FIXME: If this is a problem, recover from it by creating a multiplex
1175 // source.
1176 assert((!CI.getLangOpts().Modules || CI.getASTReader()) &&
1177 "modules enabled but created an external source that "
1178 "doesn't support modules");
1179 }
1180
1181 // If we were asked to load any module files, do so now.
1182 for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) {
1183 serialization::ModuleFile *Loaded = nullptr;
1184 if (!CI.loadModuleFile(FileName: ModuleFile, LoadedModuleFile&: Loaded))
1185 return false;
1186
1187 if (Loaded && Loaded->StandardCXXModule)
1188 CI.getDiagnostics().Report(
1189 diag::warn_eagerly_load_for_standard_cplusplus_modules);
1190 }
1191
1192 // If there is a layout overrides file, attach an external AST source that
1193 // provides the layouts from that file.
1194 if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
1195 CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
1196 IntrusiveRefCntPtr<ExternalASTSource>
1197 Override(new LayoutOverrideSource(
1198 CI.getFrontendOpts().OverrideRecordLayoutsFile));
1199 CI.getASTContext().setExternalSource(Override);
1200 }
1201
1202 // Setup HLSL External Sema Source
1203 if (CI.getLangOpts().HLSL && CI.hasASTContext()) {
1204 IntrusiveRefCntPtr<ExternalSemaSource> HLSLSema(
1205 new HLSLExternalSemaSource());
1206 if (auto *SemaSource = dyn_cast_if_present<ExternalSemaSource>(
1207 Val: CI.getASTContext().getExternalSource())) {
1208 IntrusiveRefCntPtr<ExternalSemaSource> MultiSema(
1209 new MultiplexExternalSemaSource(SemaSource, HLSLSema.get()));
1210 CI.getASTContext().setExternalSource(MultiSema);
1211 } else
1212 CI.getASTContext().setExternalSource(HLSLSema);
1213 }
1214
1215 FailureCleanup.release();
1216 return true;
1217}
1218
1219llvm::Error FrontendAction::Execute() {
1220 CompilerInstance &CI = getCompilerInstance();
1221 ExecuteAction();
1222
1223 // If we are supposed to rebuild the global module index, do so now unless
1224 // there were any module-build failures.
1225 if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() &&
1226 CI.hasPreprocessor()) {
1227 StringRef Cache =
1228 CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
1229 if (!Cache.empty()) {
1230 if (llvm::Error Err = GlobalModuleIndex::writeIndex(
1231 FileMgr&: CI.getFileManager(), PCHContainerRdr: CI.getPCHContainerReader(), Path: Cache)) {
1232 // FIXME this drops the error on the floor, but
1233 // Index/pch-from-libclang.c seems to rely on dropping at least some of
1234 // the error conditions!
1235 consumeError(Err: std::move(Err));
1236 }
1237 }
1238 }
1239
1240 return llvm::Error::success();
1241}
1242
1243void FrontendAction::EndSourceFile() {
1244 CompilerInstance &CI = getCompilerInstance();
1245
1246 // Inform the diagnostic client we are done with this source file.
1247 CI.getDiagnosticClient().EndSourceFile();
1248
1249 // Inform the preprocessor we are done.
1250 if (CI.hasPreprocessor())
1251 CI.getPreprocessor().EndSourceFile();
1252
1253 // Finalize the action.
1254 EndSourceFileAction();
1255
1256 // Sema references the ast consumer, so reset sema first.
1257 //
1258 // FIXME: There is more per-file stuff we could just drop here?
1259 bool DisableFree = CI.getFrontendOpts().DisableFree;
1260 if (DisableFree) {
1261 CI.resetAndLeakSema();
1262 CI.resetAndLeakASTContext();
1263 llvm::BuryPointer(Ptr: CI.takeASTConsumer().get());
1264 } else {
1265 CI.setSema(nullptr);
1266 CI.setASTContext(nullptr);
1267 CI.setASTConsumer(nullptr);
1268 }
1269
1270 if (CI.getFrontendOpts().ShowStats) {
1271 llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFileOrBufferName() << "':\n";
1272 if (CI.hasPreprocessor()) {
1273 CI.getPreprocessor().PrintStats();
1274 CI.getPreprocessor().getIdentifierTable().PrintStats();
1275 CI.getPreprocessor().getHeaderSearchInfo().PrintStats();
1276 }
1277 if (CI.hasSourceManager()) {
1278 CI.getSourceManager().PrintStats();
1279 }
1280 llvm::errs() << "\n";
1281 }
1282
1283 // Cleanup the output streams, and erase the output files if instructed by the
1284 // FrontendAction.
1285 CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
1286
1287 // The resources are owned by AST when the current file is AST.
1288 // So we reset the resources here to avoid users accessing it
1289 // accidently.
1290 if (isCurrentFileAST()) {
1291 if (DisableFree) {
1292 CI.resetAndLeakPreprocessor();
1293 CI.resetAndLeakSourceManager();
1294 CI.resetAndLeakFileManager();
1295 llvm::BuryPointer(Ptr: std::move(CurrentASTUnit));
1296 } else {
1297 CI.setPreprocessor(nullptr);
1298 CI.setSourceManager(nullptr);
1299 CI.setFileManager(nullptr);
1300 }
1301 }
1302
1303 setCompilerInstance(nullptr);
1304 setCurrentInput(CurrentInput: FrontendInputFile());
1305 CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
1306}
1307
1308bool FrontendAction::shouldEraseOutputFiles() {
1309 return getCompilerInstance().getDiagnostics().hasErrorOccurred();
1310}
1311
1312//===----------------------------------------------------------------------===//
1313// Utility Actions
1314//===----------------------------------------------------------------------===//
1315
1316void ASTFrontendAction::ExecuteAction() {
1317 CompilerInstance &CI = getCompilerInstance();
1318 if (!CI.hasPreprocessor())
1319 return;
1320 // This is a fallback: If the client forgets to invoke this, we mark the
1321 // current stack as the bottom. Though not optimal, this could help prevent
1322 // stack overflow during deep recursion.
1323 clang::noteBottomOfStack();
1324
1325 // FIXME: Move the truncation aspect of this into Sema, we delayed this till
1326 // here so the source manager would be initialized.
1327 if (hasCodeCompletionSupport() &&
1328 !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
1329 CI.createCodeCompletionConsumer();
1330
1331 // Use a code completion consumer?
1332 CodeCompleteConsumer *CompletionConsumer = nullptr;
1333 if (CI.hasCodeCompletionConsumer())
1334 CompletionConsumer = &CI.getCodeCompletionConsumer();
1335
1336 if (!CI.hasSema())
1337 CI.createSema(TUKind: getTranslationUnitKind(), CompletionConsumer);
1338
1339 ParseAST(S&: CI.getSema(), PrintStats: CI.getFrontendOpts().ShowStats,
1340 SkipFunctionBodies: CI.getFrontendOpts().SkipFunctionBodies);
1341}
1342
1343void PluginASTAction::anchor() { }
1344
1345std::unique_ptr<ASTConsumer>
1346PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
1347 StringRef InFile) {
1348 llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
1349}
1350
1351bool WrapperFrontendAction::PrepareToExecuteAction(CompilerInstance &CI) {
1352 return WrappedAction->PrepareToExecuteAction(CI);
1353}
1354std::unique_ptr<ASTConsumer>
1355WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
1356 StringRef InFile) {
1357 return WrappedAction->CreateASTConsumer(CI, InFile);
1358}
1359bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) {
1360 return WrappedAction->BeginInvocation(CI);
1361}
1362bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI) {
1363 WrappedAction->setCurrentInput(CurrentInput: getCurrentInput());
1364 WrappedAction->setCompilerInstance(&CI);
1365 auto Ret = WrappedAction->BeginSourceFileAction(CI);
1366 // BeginSourceFileAction may change CurrentInput, e.g. during module builds.
1367 setCurrentInput(CurrentInput: WrappedAction->getCurrentInput());
1368 return Ret;
1369}
1370void WrapperFrontendAction::ExecuteAction() {
1371 WrappedAction->ExecuteAction();
1372}
1373void WrapperFrontendAction::EndSourceFile() { WrappedAction->EndSourceFile(); }
1374void WrapperFrontendAction::EndSourceFileAction() {
1375 WrappedAction->EndSourceFileAction();
1376}
1377bool WrapperFrontendAction::shouldEraseOutputFiles() {
1378 return WrappedAction->shouldEraseOutputFiles();
1379}
1380
1381bool WrapperFrontendAction::usesPreprocessorOnly() const {
1382 return WrappedAction->usesPreprocessorOnly();
1383}
1384TranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() {
1385 return WrappedAction->getTranslationUnitKind();
1386}
1387bool WrapperFrontendAction::hasPCHSupport() const {
1388 return WrappedAction->hasPCHSupport();
1389}
1390bool WrapperFrontendAction::hasASTFileSupport() const {
1391 return WrappedAction->hasASTFileSupport();
1392}
1393bool WrapperFrontendAction::hasIRSupport() const {
1394 return WrappedAction->hasIRSupport();
1395}
1396bool WrapperFrontendAction::hasCodeCompletionSupport() const {
1397 return WrappedAction->hasCodeCompletionSupport();
1398}
1399
1400WrapperFrontendAction::WrapperFrontendAction(
1401 std::unique_ptr<FrontendAction> WrappedAction)
1402 : WrappedAction(std::move(WrappedAction)) {}
1403

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang/lib/Frontend/FrontendAction.cpp