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