clang 19.0.0git
ModuleMap.cpp
Go to the documentation of this file.
1//===- ModuleMap.cpp - Describe the layout of modules ---------------------===//
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// This file defines the ModuleMap implementation, which describes the layout
10// of a module as it relates to headers.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Lex/ModuleMap.h"
18#include "clang/Basic/LLVM.h"
20#include "clang/Basic/Module.h"
27#include "clang/Lex/Lexer.h"
29#include "clang/Lex/Token.h"
30#include "llvm/ADT/DenseMap.h"
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/SmallPtrSet.h"
33#include "llvm/ADT/SmallString.h"
34#include "llvm/ADT/SmallVector.h"
35#include "llvm/ADT/StringMap.h"
36#include "llvm/ADT/StringRef.h"
37#include "llvm/ADT/StringSwitch.h"
38#include "llvm/Support/Allocator.h"
39#include "llvm/Support/Compiler.h"
40#include "llvm/Support/ErrorHandling.h"
41#include "llvm/Support/MemoryBuffer.h"
42#include "llvm/Support/Path.h"
43#include "llvm/Support/VirtualFileSystem.h"
44#include "llvm/Support/raw_ostream.h"
45#include <algorithm>
46#include <cassert>
47#include <cstdint>
48#include <cstring>
49#include <optional>
50#include <string>
51#include <system_error>
52#include <utility>
53
54using namespace clang;
55
56void ModuleMapCallbacks::anchor() {}
57
59 auto PendingLinkAs = PendingLinkAsModule.find(Mod->Name);
60 if (PendingLinkAs != PendingLinkAsModule.end()) {
61 for (auto &Name : PendingLinkAs->second) {
62 auto *M = findModule(Name.getKey());
63 if (M)
64 M->UseExportAsModuleLinkName = true;
65 }
66 }
67}
68
70 if (findModule(Mod->ExportAsModule))
71 Mod->UseExportAsModuleLinkName = true;
72 else
73 PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name);
74}
75
77 switch ((int)Role) {
78 case NormalHeader:
79 return Module::HK_Normal;
80 case PrivateHeader:
81 return Module::HK_Private;
82 case TextualHeader:
83 return Module::HK_Textual;
86 case ExcludedHeader:
88 }
89 llvm_unreachable("unknown header role");
90}
91
94 switch ((int)Kind) {
96 return NormalHeader;
98 return PrivateHeader;
100 return TextualHeader;
104 return ExcludedHeader;
105 }
106 llvm_unreachable("unknown header kind");
107}
108
111}
112
114ModuleMap::resolveExport(Module *Mod,
116 bool Complain) const {
117 // We may have just a wildcard.
118 if (Unresolved.Id.empty()) {
119 assert(Unresolved.Wildcard && "Invalid unresolved export");
120 return Module::ExportDecl(nullptr, true);
121 }
122
123 // Resolve the module-id.
124 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
125 if (!Context)
126 return {};
127
128 return Module::ExportDecl(Context, Unresolved.Wildcard);
129}
130
131Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
132 bool Complain) const {
133 // Find the starting module.
134 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
135 if (!Context) {
136 if (Complain)
137 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
138 << Id[0].first << Mod->getFullModuleName();
139
140 return nullptr;
141 }
142
143 // Dig into the module path.
144 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
145 Module *Sub = lookupModuleQualified(Id[I].first, Context);
146 if (!Sub) {
147 if (Complain)
148 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
149 << Id[I].first << Context->getFullModuleName()
150 << SourceRange(Id[0].second, Id[I-1].second);
151
152 return nullptr;
153 }
154
155 Context = Sub;
156 }
157
158 return Context;
159}
160
161/// Append to \p Paths the set of paths needed to get to the
162/// subframework in which the given module lives.
164 SmallVectorImpl<char> &Path) {
165 // Collect the framework names from the given module to the top-level module.
167 for (; Mod; Mod = Mod->Parent) {
168 if (Mod->IsFramework)
169 Paths.push_back(Mod->Name);
170 }
171
172 if (Paths.empty())
173 return;
174
175 // Add Frameworks/Name.framework for each subframework.
176 for (StringRef Framework : llvm::drop_begin(llvm::reverse(Paths)))
177 llvm::sys::path::append(Path, "Frameworks", Framework + ".framework");
178}
179
180OptionalFileEntryRef ModuleMap::findHeader(
182 SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework) {
183 // Search for the header file within the module's home directory.
184 auto Directory = M->Directory;
185 SmallString<128> FullPathName(Directory->getName());
186
187 auto GetFile = [&](StringRef Filename) -> OptionalFileEntryRef {
188 auto File =
189 expectedToOptional(SourceMgr.getFileManager().getFileRef(Filename));
190 if (!File || (Header.Size && File->getSize() != *Header.Size) ||
191 (Header.ModTime && File->getModificationTime() != *Header.ModTime))
192 return std::nullopt;
193 return *File;
194 };
195
196 auto GetFrameworkFile = [&]() -> OptionalFileEntryRef {
197 unsigned FullPathLength = FullPathName.size();
198 appendSubframeworkPaths(M, RelativePathName);
199 unsigned RelativePathLength = RelativePathName.size();
200
201 // Check whether this file is in the public headers.
202 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
203 llvm::sys::path::append(FullPathName, RelativePathName);
204 if (auto File = GetFile(FullPathName))
205 return File;
206
207 // Check whether this file is in the private headers.
208 // Ideally, private modules in the form 'FrameworkName.Private' should
209 // be defined as 'module FrameworkName.Private', and not as
210 // 'framework module FrameworkName.Private', since a 'Private.Framework'
211 // does not usually exist. However, since both are currently widely used
212 // for private modules, make sure we find the right path in both cases.
213 if (M->IsFramework && M->Name == "Private")
214 RelativePathName.clear();
215 else
216 RelativePathName.resize(RelativePathLength);
217 FullPathName.resize(FullPathLength);
218 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
219 Header.FileName);
220 llvm::sys::path::append(FullPathName, RelativePathName);
221 return GetFile(FullPathName);
222 };
223
224 if (llvm::sys::path::is_absolute(Header.FileName)) {
225 RelativePathName.clear();
226 RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
227 return GetFile(Header.FileName);
228 }
229
230 if (M->isPartOfFramework())
231 return GetFrameworkFile();
232
233 // Lookup for normal headers.
234 llvm::sys::path::append(RelativePathName, Header.FileName);
235 llvm::sys::path::append(FullPathName, RelativePathName);
236 auto NormalHdrFile = GetFile(FullPathName);
237
238 if (!NormalHdrFile && Directory->getName().ends_with(".framework")) {
239 // The lack of 'framework' keyword in a module declaration it's a simple
240 // mistake we can diagnose when the header exists within the proper
241 // framework style path.
242 FullPathName.assign(Directory->getName());
243 RelativePathName.clear();
244 if (GetFrameworkFile()) {
245 Diags.Report(Header.FileNameLoc,
246 diag::warn_mmap_incomplete_framework_module_declaration)
247 << Header.FileName << M->getFullModuleName();
248 NeedsFramework = true;
249 }
250 return std::nullopt;
251 }
252
253 return NormalHdrFile;
254}
255
256/// Determine whether the given file name is the name of a builtin
257/// header, supplied by Clang to replace, override, or augment existing system
258/// headers.
259static bool isBuiltinHeaderName(StringRef FileName) {
260 return llvm::StringSwitch<bool>(FileName)
261 .Case("float.h", true)
262 .Case("iso646.h", true)
263 .Case("limits.h", true)
264 .Case("stdalign.h", true)
265 .Case("stdarg.h", true)
266 .Case("stdatomic.h", true)
267 .Case("stdbool.h", true)
268 .Case("stddef.h", true)
269 .Case("stdint.h", true)
270 .Case("tgmath.h", true)
271 .Case("unwind.h", true)
272 .Default(false);
273}
274
275/// Determine whether the given module name is the name of a builtin
276/// module that is cyclic with a system module on some platforms.
277static bool isBuiltInModuleName(StringRef ModuleName) {
278 return llvm::StringSwitch<bool>(ModuleName)
279 .Case("_Builtin_float", true)
280 .Case("_Builtin_inttypes", true)
281 .Case("_Builtin_iso646", true)
282 .Case("_Builtin_limits", true)
283 .Case("_Builtin_stdalign", true)
284 .Case("_Builtin_stdarg", true)
285 .Case("_Builtin_stdatomic", true)
286 .Case("_Builtin_stdbool", true)
287 .Case("_Builtin_stddef", true)
288 .Case("_Builtin_stdint", true)
289 .Case("_Builtin_stdnoreturn", true)
290 .Case("_Builtin_tgmath", true)
291 .Case("_Builtin_unwind", true)
292 .Default(false);
293}
294
295void ModuleMap::resolveHeader(Module *Mod,
297 bool &NeedsFramework) {
298 SmallString<128> RelativePathName;
300 findHeader(Mod, Header, RelativePathName, NeedsFramework)) {
301 if (Header.IsUmbrella) {
302 const DirectoryEntry *UmbrellaDir = &File->getDir().getDirEntry();
303 if (Module *UmbrellaMod = UmbrellaDirs[UmbrellaDir])
304 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
305 << UmbrellaMod->getFullModuleName();
306 else
307 // Record this umbrella header.
309 RelativePathName.str());
310 } else {
311 Module::Header H = {Header.FileName, std::string(RelativePathName),
312 *File};
313 addHeader(Mod, H, headerKindToRole(Header.Kind));
314 }
315 } else if (Header.HasBuiltinHeader && !Header.Size && !Header.ModTime) {
316 // There's a builtin header but no corresponding on-disk header. Assume
317 // this was supposed to modularize the builtin header alone.
318 } else if (Header.Kind == Module::HK_Excluded) {
319 // Ignore missing excluded header files. They're optional anyway.
320 } else {
321 // If we find a module that has a missing header, we mark this module as
322 // unavailable and store the header directive for displaying diagnostics.
323 Mod->MissingHeaders.push_back(Header);
324 // A missing header with stat information doesn't make the module
325 // unavailable; this keeps our behavior consistent as headers are lazily
326 // resolved. (Such a module still can't be built though, except from
327 // preprocessed source.)
328 if (!Header.Size && !Header.ModTime)
329 Mod->markUnavailable(/*Unimportable=*/false);
330 }
331}
332
333bool ModuleMap::resolveAsBuiltinHeader(
334 Module *Mod, const Module::UnresolvedHeaderDirective &Header) {
335 if (Header.Kind == Module::HK_Excluded ||
336 llvm::sys::path::is_absolute(Header.FileName) ||
337 Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
338 !BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
339 !LangOpts.BuiltinHeadersInSystemModules || !isBuiltinHeaderName(Header.FileName))
340 return false;
341
342 // This is a system module with a top-level header. This header
343 // may have a counterpart (or replacement) in the set of headers
344 // supplied by Clang. Find that builtin header.
345 SmallString<128> Path;
346 llvm::sys::path::append(Path, BuiltinIncludeDir->getName(), Header.FileName);
347 auto File = SourceMgr.getFileManager().getOptionalFileRef(Path);
348 if (!File)
349 return false;
350
351 Module::Header H = {Header.FileName, Header.FileName, *File};
352 auto Role = headerKindToRole(Header.Kind);
353 addHeader(Mod, H, Role);
354 return true;
355}
356
358 const LangOptions &LangOpts, const TargetInfo *Target,
359 HeaderSearch &HeaderInfo)
360 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
361 HeaderInfo(HeaderInfo) {
362 MMapLangOpts.LineComment = true;
363}
364
366 for (auto &M : Modules)
367 delete M.getValue();
368 for (auto *M : ShadowModules)
369 delete M;
370}
371
373 assert((!this->Target || this->Target == &Target) &&
374 "Improper target override");
375 this->Target = &Target;
376}
377
378/// "Sanitize" a filename so that it can be used as an identifier.
379static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
380 SmallVectorImpl<char> &Buffer) {
381 if (Name.empty())
382 return Name;
383
384 if (!isValidAsciiIdentifier(Name)) {
385 // If we don't already have something with the form of an identifier,
386 // create a buffer with the sanitized name.
387 Buffer.clear();
388 if (isDigit(Name[0]))
389 Buffer.push_back('_');
390 Buffer.reserve(Buffer.size() + Name.size());
391 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
392 if (isAsciiIdentifierContinue(Name[I]))
393 Buffer.push_back(Name[I]);
394 else
395 Buffer.push_back('_');
396 }
397
398 Name = StringRef(Buffer.data(), Buffer.size());
399 }
400
401 while (llvm::StringSwitch<bool>(Name)
402#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
403#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
404#include "clang/Basic/TokenKinds.def"
405 .Default(false)) {
406 if (Name.data() != Buffer.data())
407 Buffer.append(Name.begin(), Name.end());
408 Buffer.push_back('_');
409 Name = StringRef(Buffer.data(), Buffer.size());
410 }
411
412 return Name;
413}
414
416 return File.getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
417 isBuiltinHeaderName(llvm::sys::path::filename(File.getName()));
418}
419
421 Module *Module) const {
422 return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
425}
426
427ModuleMap::HeadersMap::iterator ModuleMap::findKnownHeader(FileEntryRef File) {
429 HeadersMap::iterator Known = Headers.find(File);
430 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
431 Known == Headers.end() && ModuleMap::isBuiltinHeader(File)) {
432 HeaderInfo.loadTopLevelSystemModules();
433 return Headers.find(File);
434 }
435 return Known;
436}
437
438ModuleMap::KnownHeader ModuleMap::findHeaderInUmbrellaDirs(
440 if (UmbrellaDirs.empty())
441 return {};
442
443 OptionalDirectoryEntryRef Dir = File.getDir();
444
445 // Note: as an egregious but useful hack we use the real path here, because
446 // frameworks moving from top-level frameworks to embedded frameworks tend
447 // to be symlinked from the top-level location to the embedded location,
448 // and we need to resolve lookups as if we had found the embedded location.
449 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(*Dir);
450
451 // Keep walking up the directory hierarchy, looking for a directory with
452 // an umbrella header.
453 do {
454 auto KnownDir = UmbrellaDirs.find(*Dir);
455 if (KnownDir != UmbrellaDirs.end())
456 return KnownHeader(KnownDir->second, NormalHeader);
457
458 IntermediateDirs.push_back(*Dir);
459
460 // Retrieve our parent path.
461 DirName = llvm::sys::path::parent_path(DirName);
462 if (DirName.empty())
463 break;
464
465 // Resolve the parent path to a directory entry.
466 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
467 } while (Dir);
468 return {};
469}
470
471static bool violatesPrivateInclude(Module *RequestingModule,
472 const FileEntry *IncFileEnt,
473 ModuleMap::KnownHeader Header) {
474#ifndef NDEBUG
475 if (Header.getRole() & ModuleMap::PrivateHeader) {
476 // Check for consistency between the module header role
477 // as obtained from the lookup and as obtained from the module.
478 // This check is not cheap, so enable it only for debugging.
479 bool IsPrivate = false;
480 SmallVectorImpl<Module::Header> *HeaderList[] = {
483 for (auto *Hs : HeaderList)
484 IsPrivate |= llvm::any_of(
485 *Hs, [&](const Module::Header &H) { return H.Entry == IncFileEnt; });
486 assert(IsPrivate && "inconsistent headers and roles");
487 }
488#endif
489 return !Header.isAccessibleFrom(RequestingModule);
490}
491
493 return M ? M->getTopLevelModule() : nullptr;
494}
495
497 bool RequestingModuleIsModuleInterface,
498 SourceLocation FilenameLoc,
499 StringRef Filename, FileEntryRef File) {
500 // No errors for indirect modules. This may be a bit of a problem for modules
501 // with no source files.
502 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
503 return;
504
505 if (RequestingModule) {
506 resolveUses(RequestingModule, /*Complain=*/false);
507 resolveHeaderDirectives(RequestingModule, /*File=*/std::nullopt);
508 }
509
510 bool Excluded = false;
511 Module *Private = nullptr;
512 Module *NotUsed = nullptr;
513
514 HeadersMap::iterator Known = findKnownHeader(File);
515 if (Known != Headers.end()) {
516 for (const KnownHeader &Header : Known->second) {
517 // Excluded headers don't really belong to a module.
518 if (Header.getRole() == ModuleMap::ExcludedHeader) {
519 Excluded = true;
520 continue;
521 }
522
523 // Remember private headers for later printing of a diagnostic.
524 if (violatesPrivateInclude(RequestingModule, File, Header)) {
525 Private = Header.getModule();
526 continue;
527 }
528
529 // If uses need to be specified explicitly, we are only allowed to return
530 // modules that are explicitly used by the requesting module.
531 if (RequestingModule && LangOpts.ModulesDeclUse &&
532 !RequestingModule->directlyUses(Header.getModule())) {
533 NotUsed = Header.getModule();
534 continue;
535 }
536
537 // We have found a module that we can happily use.
538 return;
539 }
540
541 Excluded = true;
542 }
543
544 // We have found a header, but it is private.
545 if (Private) {
546 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
547 << Filename;
548 return;
549 }
550
551 // We have found a module, but we don't use it.
552 if (NotUsed) {
553 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module_indirect)
554 << RequestingModule->getTopLevelModule()->Name << Filename
555 << NotUsed->Name;
556 return;
557 }
558
559 if (Excluded || isHeaderInUmbrellaDirs(File))
560 return;
561
562 // At this point, only non-modular includes remain.
563
564 if (RequestingModule && LangOpts.ModulesStrictDeclUse) {
565 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
566 << RequestingModule->getTopLevelModule()->Name << Filename;
567 } else if (RequestingModule && RequestingModuleIsModuleInterface &&
568 LangOpts.isCompilingModule()) {
569 // Do not diagnose when we are not compiling a module.
570 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
571 diag::warn_non_modular_include_in_framework_module :
572 diag::warn_non_modular_include_in_module;
573 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
574 << File.getName();
575 }
576}
577
579 const ModuleMap::KnownHeader &Old) {
580 // Prefer available modules.
581 // FIXME: Considering whether the module is available rather than merely
582 // importable is non-hermetic and can result in surprising behavior for
583 // prebuilt modules. Consider only checking for importability here.
584 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
585 return true;
586
587 // Prefer a public header over a private header.
588 if ((New.getRole() & ModuleMap::PrivateHeader) !=
590 return !(New.getRole() & ModuleMap::PrivateHeader);
591
592 // Prefer a non-textual header over a textual header.
593 if ((New.getRole() & ModuleMap::TextualHeader) !=
595 return !(New.getRole() & ModuleMap::TextualHeader);
596
597 // Prefer a non-excluded header over an excluded header.
598 if ((New.getRole() == ModuleMap::ExcludedHeader) !=
600 return New.getRole() != ModuleMap::ExcludedHeader;
601
602 // Don't have a reason to choose between these. Just keep the first one.
603 return false;
604}
605
607 bool AllowTextual,
608 bool AllowExcluded) {
609 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
610 if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
611 return {};
612 return R;
613 };
614
615 HeadersMap::iterator Known = findKnownHeader(File);
616 if (Known != Headers.end()) {
618 // Iterate over all modules that 'File' is part of to find the best fit.
619 for (KnownHeader &H : Known->second) {
620 // Cannot use a module if the header is excluded in it.
621 if (!AllowExcluded && H.getRole() == ModuleMap::ExcludedHeader)
622 continue;
623 // Prefer a header from the source module over all others.
624 if (H.getModule()->getTopLevelModule() == SourceModule)
625 return MakeResult(H);
627 Result = H;
628 }
629 return MakeResult(Result);
630 }
631
632 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
633}
634
636ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
637 assert(!Headers.count(File) && "already have a module for this header");
638
640 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
641 if (H) {
642 Module *Result = H.getModule();
643
644 // Search up the module stack until we find a module with an umbrella
645 // directory.
646 Module *UmbrellaModule = Result;
647 while (!UmbrellaModule->getEffectiveUmbrellaDir() && UmbrellaModule->Parent)
648 UmbrellaModule = UmbrellaModule->Parent;
649
650 if (UmbrellaModule->InferSubmodules) {
651 OptionalFileEntryRef UmbrellaModuleMap =
652 getModuleMapFileForUniquing(UmbrellaModule);
653
654 // Infer submodules for each of the directories we found between
655 // the directory of the umbrella header and the directory where
656 // the actual header is located.
657 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
658
659 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
660 // Find or create the module that corresponds to this directory name.
661 SmallString<32> NameBuf;
662 StringRef Name = sanitizeFilenameAsIdentifier(
663 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
664 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
665 Explicit).first;
666 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
667 Result->IsInferred = true;
668
669 // Associate the module and the directory.
670 UmbrellaDirs[SkippedDir] = Result;
671
672 // If inferred submodules export everything they import, add a
673 // wildcard to the set of exports.
674 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
675 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
676 }
677
678 // Infer a submodule with the same name as this header file.
679 SmallString<32> NameBuf;
680 StringRef Name = sanitizeFilenameAsIdentifier(
681 llvm::sys::path::stem(File.getName()), NameBuf);
682 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
683 Explicit).first;
684 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
685 Result->IsInferred = true;
686 Result->addTopHeader(File);
687
688 // If inferred submodules export everything they import, add a
689 // wildcard to the set of exports.
690 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
691 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
692 } else {
693 // Record each of the directories we stepped through as being part of
694 // the module we found, since the umbrella header covers them all.
695 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
696 UmbrellaDirs[SkippedDirs[I]] = Result;
697 }
698
699 KnownHeader Header(Result, NormalHeader);
700 Headers[File].push_back(Header);
701 return Header;
702 }
703
704 return {};
705}
706
709 HeadersMap::iterator Known = findKnownHeader(File);
710 if (Known != Headers.end())
711 return Known->second;
712
713 if (findOrCreateModuleForHeaderInUmbrellaDir(File))
714 return Headers.find(File)->second;
715
716 return std::nullopt;
717}
718
721 // FIXME: Is this necessary?
723 auto It = Headers.find(File);
724 if (It == Headers.end())
725 return std::nullopt;
726 return It->second;
727}
728
730 return isHeaderUnavailableInModule(Header, nullptr);
731}
732
734 FileEntryRef Header, const Module *RequestingModule) const {
736 HeadersMap::const_iterator Known = Headers.find(Header);
737 if (Known != Headers.end()) {
739 I = Known->second.begin(),
740 E = Known->second.end();
741 I != E; ++I) {
742
743 if (I->getRole() == ModuleMap::ExcludedHeader)
744 continue;
745
746 if (I->isAvailable() &&
747 (!RequestingModule ||
748 I->getModule()->isSubModuleOf(RequestingModule))) {
749 // When no requesting module is available, the caller is looking if a
750 // header is part a module by only looking into the module map. This is
751 // done by warn_uncovered_module_header checks; don't consider textual
752 // headers part of it in this mode, otherwise we get misleading warnings
753 // that a umbrella header is not including a textual header.
754 if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
755 continue;
756 return false;
757 }
758 }
759 return true;
760 }
761
762 OptionalDirectoryEntryRef Dir = Header.getDir();
764 StringRef DirName = Dir->getName();
765
766 auto IsUnavailable = [&](const Module *M) {
767 return !M->isAvailable() && (!RequestingModule ||
768 M->isSubModuleOf(RequestingModule));
769 };
770
771 // Keep walking up the directory hierarchy, looking for a directory with
772 // an umbrella header.
773 do {
774 auto KnownDir = UmbrellaDirs.find(*Dir);
775 if (KnownDir != UmbrellaDirs.end()) {
776 Module *Found = KnownDir->second;
777 if (IsUnavailable(Found))
778 return true;
779
780 // Search up the module stack until we find a module with an umbrella
781 // directory.
782 Module *UmbrellaModule = Found;
783 while (!UmbrellaModule->getEffectiveUmbrellaDir() &&
784 UmbrellaModule->Parent)
785 UmbrellaModule = UmbrellaModule->Parent;
786
787 if (UmbrellaModule->InferSubmodules) {
788 for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
789 // Find or create the module that corresponds to this directory name.
790 SmallString<32> NameBuf;
791 StringRef Name = sanitizeFilenameAsIdentifier(
792 llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
793 Found = lookupModuleQualified(Name, Found);
794 if (!Found)
795 return false;
796 if (IsUnavailable(Found))
797 return true;
798 }
799
800 // Infer a submodule with the same name as this header file.
801 SmallString<32> NameBuf;
802 StringRef Name = sanitizeFilenameAsIdentifier(
803 llvm::sys::path::stem(Header.getName()),
804 NameBuf);
805 Found = lookupModuleQualified(Name, Found);
806 if (!Found)
807 return false;
808 }
809
810 return IsUnavailable(Found);
811 }
812
813 SkippedDirs.push_back(*Dir);
814
815 // Retrieve our parent path.
816 DirName = llvm::sys::path::parent_path(DirName);
817 if (DirName.empty())
818 break;
819
820 // Resolve the parent path to a directory entry.
821 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
822 } while (Dir);
823
824 return false;
825}
826
827Module *ModuleMap::findModule(StringRef Name) const {
828 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
829 if (Known != Modules.end())
830 return Known->getValue();
831
832 return nullptr;
833}
834
836 Module *Context) const {
837 for(; Context; Context = Context->Parent) {
838 if (Module *Sub = lookupModuleQualified(Name, Context))
839 return Sub;
840 }
841
842 return findModule(Name);
843}
844
845Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
846 if (!Context)
847 return findModule(Name);
848
849 return Context->findSubmodule(Name);
850}
851
852std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
853 Module *Parent,
854 bool IsFramework,
855 bool IsExplicit) {
856 // Try to find an existing module with this name.
857 if (Module *Sub = lookupModuleQualified(Name, Parent))
858 return std::make_pair(Sub, false);
859
860 // Create a new module with this name.
861 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
862 IsExplicit, NumCreatedModules++);
863 if (!Parent) {
864 if (LangOpts.CurrentModule == Name)
865 SourceModule = Result;
866 Modules[Name] = Result;
867 ModuleScopeIDs[Result] = CurrentModuleScopeID;
868 }
869 return std::make_pair(Result, true);
870}
871
873 Module *Parent) {
874 auto *Result = new Module("<global>", Loc, Parent, /*IsFramework*/ false,
875 /*IsExplicit*/ true, NumCreatedModules++);
877 // If the created module isn't owned by a parent, send it to PendingSubmodules
878 // to wait for its parent.
879 if (!Result->Parent)
880 PendingSubmodules.emplace_back(Result);
881 return Result;
882}
883
884Module *
886 Module *Parent) {
887 assert(Parent && "We should only create an implicit global module fragment "
888 "in a module purview");
889 // Note: Here the `IsExplicit` parameter refers to the semantics in clang
890 // modules. All the non-explicit submodules in clang modules will be exported
891 // too. Here we simplify the implementation by using the concept.
892 auto *Result =
893 new Module("<implicit global>", Loc, Parent, /*IsFramework=*/false,
894 /*IsExplicit=*/false, NumCreatedModules++);
896 return Result;
897}
898
899Module *
901 SourceLocation Loc) {
902 auto *Result =
903 new Module("<private>", Loc, Parent, /*IsFramework*/ false,
904 /*IsExplicit*/ true, NumCreatedModules++);
906 return Result;
907}
908
910 Module::ModuleKind Kind) {
911 auto *Result =
912 new Module(Name, Loc, nullptr, /*IsFramework*/ false,
913 /*IsExplicit*/ false, NumCreatedModules++);
914 Result->Kind = Kind;
915
916 // Reparent any current global module fragment as a submodule of this module.
917 for (auto &Submodule : PendingSubmodules) {
918 Submodule->setParent(Result);
919 Submodule.release(); // now owned by parent
920 }
921 PendingSubmodules.clear();
922 return Result;
923}
924
926 StringRef Name) {
927 assert(LangOpts.CurrentModule == Name && "module name mismatch");
928 assert(!Modules[Name] && "redefining existing module");
929
930 auto *Result =
932 Modules[Name] = SourceModule = Result;
933
934 // Mark the main source file as being within the newly-created module so that
935 // declarations and macros are properly visibility-restricted to it.
936 auto MainFile = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());
937 assert(MainFile && "no input file for module interface");
938 Headers[*MainFile].push_back(KnownHeader(Result, PrivateHeader));
939
940 return Result;
941}
942
944 StringRef Name) {
945 assert(LangOpts.CurrentModule == Name && "module name mismatch");
946 // The interface for this implementation must exist and be loaded.
947 assert(Modules[Name] && Modules[Name]->Kind == Module::ModuleInterfaceUnit &&
948 "creating implementation module without an interface");
949
950 // Create an entry in the modules map to own the implementation unit module.
951 // User module names must not start with a period (so that this cannot clash
952 // with any legal user-defined module name).
953 StringRef IName = ".ImplementationUnit";
954 assert(!Modules[IName] && "multiple implementation units?");
955
956 auto *Result =
958 Modules[IName] = SourceModule = Result;
959
960 // Check that the main file is present.
961 assert(SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()) &&
962 "no input file for module implementation");
963
964 return Result;
965}
966
968 Module::Header H) {
969 assert(LangOpts.CurrentModule == Name && "module name mismatch");
970 assert(!Modules[Name] && "redefining existing module");
971
972 auto *Result = new Module(Name, Loc, nullptr, /*IsFramework*/ false,
973 /*IsExplicit*/ false, NumCreatedModules++);
975 Modules[Name] = SourceModule = Result;
977 return Result;
978}
979
980/// For a framework module, infer the framework against which we
981/// should link.
982static void inferFrameworkLink(Module *Mod) {
983 assert(Mod->IsFramework && "Can only infer linking for framework modules");
984 assert(!Mod->isSubFramework() &&
985 "Can only infer linking for top-level frameworks");
986
987 StringRef FrameworkName(Mod->Name);
988 FrameworkName.consume_back("_Private");
989 Mod->LinkLibraries.push_back(Module::LinkLibrary(FrameworkName.str(),
990 /*IsFramework=*/true));
991}
992
993Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
994 bool IsSystem, Module *Parent) {
995 Attributes Attrs;
996 Attrs.IsSystem = IsSystem;
997 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
998}
999
1000Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
1001 Attributes Attrs, Module *Parent) {
1002 // Note: as an egregious but useful hack we use the real path here, because
1003 // we might be looking at an embedded framework that symlinks out to a
1004 // top-level framework, and we need to infer as if we were naming the
1005 // top-level framework.
1006 StringRef FrameworkDirName =
1007 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
1008
1009 // In case this is a case-insensitive filesystem, use the canonical
1010 // directory name as the ModuleName, since modules are case-sensitive.
1011 // FIXME: we should be able to give a fix-it hint for the correct spelling.
1012 SmallString<32> ModuleNameStorage;
1013 StringRef ModuleName = sanitizeFilenameAsIdentifier(
1014 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
1015
1016 // Check whether we've already found this module.
1017 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
1018 return Mod;
1019
1020 FileManager &FileMgr = SourceMgr.getFileManager();
1021
1022 // If the framework has a parent path from which we're allowed to infer
1023 // a framework module, do so.
1024 OptionalFileEntryRef ModuleMapFile;
1025 if (!Parent) {
1026 // Determine whether we're allowed to infer a module map.
1027 bool canInfer = false;
1028 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
1029 // Figure out the parent path.
1030 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
1031 if (auto ParentDir = FileMgr.getOptionalDirectoryRef(Parent)) {
1032 // Check whether we have already looked into the parent directory
1033 // for a module map.
1034 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
1035 inferred = InferredDirectories.find(*ParentDir);
1036 if (inferred == InferredDirectories.end()) {
1037 // We haven't looked here before. Load a module map, if there is
1038 // one.
1039 bool IsFrameworkDir = Parent.ends_with(".framework");
1040 if (OptionalFileEntryRef ModMapFile =
1041 HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) {
1042 parseModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir);
1043 inferred = InferredDirectories.find(*ParentDir);
1044 }
1045
1046 if (inferred == InferredDirectories.end())
1047 inferred = InferredDirectories.insert(
1048 std::make_pair(*ParentDir, InferredDirectory())).first;
1049 }
1050
1051 if (inferred->second.InferModules) {
1052 // We're allowed to infer for this directory, but make sure it's okay
1053 // to infer this particular module.
1054 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
1055 canInfer =
1056 !llvm::is_contained(inferred->second.ExcludedModules, Name);
1057
1058 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
1059 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
1060 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
1061 Attrs.NoUndeclaredIncludes |=
1062 inferred->second.Attrs.NoUndeclaredIncludes;
1063 ModuleMapFile = inferred->second.ModuleMapFile;
1064 }
1065 }
1066 }
1067
1068 // If we're not allowed to infer a framework module, don't.
1069 if (!canInfer)
1070 return nullptr;
1071 } else {
1072 ModuleMapFile = getModuleMapFileForUniquing(Parent);
1073 }
1074
1075 // Look for an umbrella header.
1076 SmallString<128> UmbrellaName = FrameworkDir.getName();
1077 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
1078 auto UmbrellaHeader = FileMgr.getOptionalFileRef(UmbrellaName);
1079
1080 // FIXME: If there's no umbrella header, we could probably scan the
1081 // framework to load *everything*. But, it's not clear that this is a good
1082 // idea.
1083 if (!UmbrellaHeader)
1084 return nullptr;
1085
1086 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
1087 /*IsFramework=*/true, /*IsExplicit=*/false,
1088 NumCreatedModules++);
1089 InferredModuleAllowedBy[Result] = ModuleMapFile;
1090 Result->IsInferred = true;
1091 if (!Parent) {
1092 if (LangOpts.CurrentModule == ModuleName)
1093 SourceModule = Result;
1094 Modules[ModuleName] = Result;
1095 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1096 }
1097
1098 Result->IsSystem |= Attrs.IsSystem;
1099 Result->IsExternC |= Attrs.IsExternC;
1100 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
1101 Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
1102 Result->Directory = FrameworkDir;
1103
1104 // Chop off the first framework bit, as that is implied.
1105 StringRef RelativePath = UmbrellaName.str().substr(
1106 Result->getTopLevelModule()->Directory->getName().size());
1107 RelativePath = llvm::sys::path::relative_path(RelativePath);
1108
1109 // umbrella header "umbrella-header-name"
1110 setUmbrellaHeaderAsWritten(Result, *UmbrellaHeader, ModuleName + ".h",
1111 RelativePath);
1112
1113 // export *
1114 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
1115
1116 // module * { export * }
1117 Result->InferSubmodules = true;
1118 Result->InferExportWildcard = true;
1119
1120 // Look for subframeworks.
1121 std::error_code EC;
1122 SmallString<128> SubframeworksDirName = FrameworkDir.getName();
1123 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
1124 llvm::sys::path::native(SubframeworksDirName);
1125 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1126 for (llvm::vfs::directory_iterator
1127 Dir = FS.dir_begin(SubframeworksDirName, EC),
1128 DirEnd;
1129 Dir != DirEnd && !EC; Dir.increment(EC)) {
1130 if (!StringRef(Dir->path()).ends_with(".framework"))
1131 continue;
1132
1133 if (auto SubframeworkDir = FileMgr.getOptionalDirectoryRef(Dir->path())) {
1134 // Note: as an egregious but useful hack, we use the real path here and
1135 // check whether it is actually a subdirectory of the parent directory.
1136 // This will not be the case if the 'subframework' is actually a symlink
1137 // out to a top-level framework.
1138 StringRef SubframeworkDirName =
1139 FileMgr.getCanonicalName(*SubframeworkDir);
1140 bool FoundParent = false;
1141 do {
1142 // Get the parent directory name.
1143 SubframeworkDirName
1144 = llvm::sys::path::parent_path(SubframeworkDirName);
1145 if (SubframeworkDirName.empty())
1146 break;
1147
1148 if (auto SubDir = FileMgr.getDirectory(SubframeworkDirName)) {
1149 if (*SubDir == FrameworkDir) {
1150 FoundParent = true;
1151 break;
1152 }
1153 }
1154 } while (true);
1155
1156 if (!FoundParent)
1157 continue;
1158
1159 // FIXME: Do we want to warn about subframeworks without umbrella headers?
1160 inferFrameworkModule(*SubframeworkDir, Attrs, Result);
1161 }
1162 }
1163
1164 // If the module is a top-level framework, automatically link against the
1165 // framework.
1166 if (!Result->isSubFramework())
1168
1169 return Result;
1170}
1171
1172Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
1173 Module *ShadowingModule) {
1174
1175 // Create a new module with this name.
1176 Module *Result =
1177 new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework,
1178 /*IsExplicit=*/false, NumCreatedModules++);
1179 Result->ShadowingModule = ShadowingModule;
1180 Result->markUnavailable(/*Unimportable*/true);
1181 ModuleScopeIDs[Result] = CurrentModuleScopeID;
1182 ShadowModules.push_back(Result);
1183
1184 return Result;
1185}
1186
1188 Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten,
1189 const Twine &PathRelativeToRootModuleDirectory) {
1190 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
1191 Mod->Umbrella = UmbrellaHeader;
1192 Mod->UmbrellaAsWritten = NameAsWritten.str();
1194 PathRelativeToRootModuleDirectory.str();
1195 UmbrellaDirs[UmbrellaHeader.getDir()] = Mod;
1196
1197 // Notify callbacks that we just added a new header.
1198 for (const auto &Cb : Callbacks)
1199 Cb->moduleMapAddUmbrellaHeader(UmbrellaHeader);
1200}
1201
1203 Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten,
1204 const Twine &PathRelativeToRootModuleDirectory) {
1205 Mod->Umbrella = UmbrellaDir;
1206 Mod->UmbrellaAsWritten = NameAsWritten.str();
1208 PathRelativeToRootModuleDirectory.str();
1209 UmbrellaDirs[UmbrellaDir] = Mod;
1210}
1211
1212void ModuleMap::addUnresolvedHeader(Module *Mod,
1214 bool &NeedsFramework) {
1215 // If there is a builtin counterpart to this file, add it now so it can
1216 // wrap the system header.
1217 if (resolveAsBuiltinHeader(Mod, Header)) {
1218 // If we have both a builtin and system version of the file, the
1219 // builtin version may want to inject macros into the system header, so
1220 // force the system header to be treated as a textual header in this
1221 // case.
1224 Header.HasBuiltinHeader = true;
1225 }
1226
1227 // If possible, don't stat the header until we need to. This requires the
1228 // user to have provided us with some stat information about the file.
1229 // FIXME: Add support for lazily stat'ing umbrella headers and excluded
1230 // headers.
1231 if ((Header.Size || Header.ModTime) && !Header.IsUmbrella &&
1232 Header.Kind != Module::HK_Excluded) {
1233 // We expect more variation in mtime than size, so if we're given both,
1234 // use the mtime as the key.
1235 if (Header.ModTime)
1236 LazyHeadersByModTime[*Header.ModTime].push_back(Mod);
1237 else
1238 LazyHeadersBySize[*Header.Size].push_back(Mod);
1239 Mod->UnresolvedHeaders.push_back(Header);
1240 return;
1241 }
1242
1243 // We don't have stat information or can't defer looking this file up.
1244 // Perform the lookup now.
1245 resolveHeader(Mod, Header, NeedsFramework);
1246}
1247
1249 auto BySize = LazyHeadersBySize.find(File->getSize());
1250 if (BySize != LazyHeadersBySize.end()) {
1251 for (auto *M : BySize->second)
1253 LazyHeadersBySize.erase(BySize);
1254 }
1255
1256 auto ByModTime = LazyHeadersByModTime.find(File->getModificationTime());
1257 if (ByModTime != LazyHeadersByModTime.end()) {
1258 for (auto *M : ByModTime->second)
1260 LazyHeadersByModTime.erase(ByModTime);
1261 }
1262}
1263
1265 Module *Mod, std::optional<const FileEntry *> File) const {
1266 bool NeedsFramework = false;
1268 const auto Size = File ? (*File)->getSize() : 0;
1269 const auto ModTime = File ? (*File)->getModificationTime() : 0;
1270
1271 for (auto &Header : Mod->UnresolvedHeaders) {
1272 if (File && ((Header.ModTime && Header.ModTime != ModTime) ||
1273 (Header.Size && Header.Size != Size)))
1274 NewHeaders.push_back(Header);
1275 else
1276 // This operation is logically const; we're just changing how we represent
1277 // the header information for this file.
1278 const_cast<ModuleMap *>(this)->resolveHeader(Mod, Header, NeedsFramework);
1279 }
1280 Mod->UnresolvedHeaders.swap(NewHeaders);
1281}
1282
1284 ModuleHeaderRole Role, bool Imported) {
1285 KnownHeader KH(Mod, Role);
1286
1287 // Only add each header to the headers list once.
1288 // FIXME: Should we diagnose if a header is listed twice in the
1289 // same module definition?
1290 auto &HeaderList = Headers[Header.Entry];
1291 if (llvm::is_contained(HeaderList, KH))
1292 return;
1293
1294 HeaderList.push_back(KH);
1295 Mod->Headers[headerRoleToKind(Role)].push_back(Header);
1296
1297 bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts);
1298 if (!Imported || isCompilingModuleHeader) {
1299 // When we import HeaderFileInfo, the external source is expected to
1300 // set the isModuleHeader flag itself.
1301 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
1302 isCompilingModuleHeader);
1303 }
1304
1305 // Notify callbacks that we just added a new header.
1306 for (const auto &Cb : Callbacks)
1307 Cb->moduleMapAddHeader(Header.Entry.getName());
1308}
1309
1313 return std::nullopt;
1314
1315 return SourceMgr.getFileEntryRefForID(
1316 SourceMgr.getFileID(Module->DefinitionLoc));
1317}
1318
1321 if (M->IsInferred) {
1322 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
1323 return InferredModuleAllowedBy.find(M)->second;
1324 }
1326}
1327
1329 OptionalFileEntryRef ModMap) {
1330 assert(M->IsInferred && "module not inferred");
1331 InferredModuleAllowedBy[M] = ModMap;
1332}
1333
1334std::error_code
1336 StringRef Dir = llvm::sys::path::parent_path({Path.data(), Path.size()});
1337
1338 // Do not canonicalize within the framework; the module map parser expects
1339 // Modules/ not Versions/A/Modules.
1340 if (llvm::sys::path::filename(Dir) == "Modules") {
1341 StringRef Parent = llvm::sys::path::parent_path(Dir);
1342 if (Parent.ends_with(".framework"))
1343 Dir = Parent;
1344 }
1345
1346 FileManager &FM = SourceMgr.getFileManager();
1347 auto DirEntry = FM.getDirectoryRef(Dir.empty() ? "." : Dir);
1348 if (!DirEntry)
1349 return llvm::errorToErrorCode(DirEntry.takeError());
1350
1351 // Canonicalize the directory.
1352 StringRef CanonicalDir = FM.getCanonicalName(*DirEntry);
1353 if (CanonicalDir != Dir)
1354 llvm::sys::path::replace_path_prefix(Path, Dir, CanonicalDir);
1355
1356 // In theory, the filename component should also be canonicalized if it
1357 // on a case-insensitive filesystem. However, the extra canonicalization is
1358 // expensive and if clang looked up the filename it will always be lowercase.
1359
1360 // Remove ., remove redundant separators, and switch to native separators.
1361 // This is needed for separators between CanonicalDir and the filename.
1362 llvm::sys::path::remove_dots(Path);
1363
1364 return std::error_code();
1365}
1366
1369 AdditionalModMaps[M].insert(ModuleMap);
1370}
1371
1372LLVM_DUMP_METHOD void ModuleMap::dump() {
1373 llvm::errs() << "Modules:";
1374 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
1375 MEnd = Modules.end();
1376 M != MEnd; ++M)
1377 M->getValue()->print(llvm::errs(), 2);
1378
1379 llvm::errs() << "Headers:";
1380 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
1381 H != HEnd; ++H) {
1382 llvm::errs() << " \"" << H->first.getName() << "\" -> ";
1383 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
1384 E = H->second.end();
1385 I != E; ++I) {
1386 if (I != H->second.begin())
1387 llvm::errs() << ",";
1388 llvm::errs() << I->getModule()->getFullModuleName();
1389 }
1390 llvm::errs() << "\n";
1391 }
1392}
1393
1394bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
1395 auto Unresolved = std::move(Mod->UnresolvedExports);
1396 Mod->UnresolvedExports.clear();
1397 for (auto &UE : Unresolved) {
1398 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
1399 if (Export.getPointer() || Export.getInt())
1400 Mod->Exports.push_back(Export);
1401 else
1402 Mod->UnresolvedExports.push_back(UE);
1403 }
1404 return !Mod->UnresolvedExports.empty();
1405}
1406
1407bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
1408 auto *Top = Mod->getTopLevelModule();
1409 auto Unresolved = std::move(Top->UnresolvedDirectUses);
1410 Top->UnresolvedDirectUses.clear();
1411 for (auto &UDU : Unresolved) {
1412 Module *DirectUse = resolveModuleId(UDU, Top, Complain);
1413 if (DirectUse)
1414 Top->DirectUses.push_back(DirectUse);
1415 else
1416 Top->UnresolvedDirectUses.push_back(UDU);
1417 }
1418 return !Top->UnresolvedDirectUses.empty();
1419}
1420
1421bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
1422 auto Unresolved = std::move(Mod->UnresolvedConflicts);
1423 Mod->UnresolvedConflicts.clear();
1424 for (auto &UC : Unresolved) {
1425 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
1426 Module::Conflict Conflict;
1427 Conflict.Other = OtherMod;
1428 Conflict.Message = UC.Message;
1429 Mod->Conflicts.push_back(Conflict);
1430 } else
1431 Mod->UnresolvedConflicts.push_back(UC);
1432 }
1433 return !Mod->UnresolvedConflicts.empty();
1434}
1435
1436//----------------------------------------------------------------------------//
1437// Module map file parser
1438//----------------------------------------------------------------------------//
1439
1440namespace clang {
1441
1442 /// A token in a module map file.
1443 struct MMToken {
1472 RSquare
1474
1477 union {
1478 // If Kind != IntegerLiteral.
1479 const char *StringData;
1480
1481 // If Kind == IntegerLiteral.
1483 };
1484
1485 void clear() {
1486 Kind = EndOfFile;
1487 Location = 0;
1488 StringLength = 0;
1489 StringData = nullptr;
1490 }
1491
1492 bool is(TokenKind K) const { return Kind == K; }
1493
1496 }
1497
1498 uint64_t getInteger() const {
1499 return Kind == IntegerLiteral ? IntegerValue : 0;
1500 }
1501
1502 StringRef getString() const {
1503 return Kind == IntegerLiteral ? StringRef()
1504 : StringRef(StringData, StringLength);
1505 }
1506 };
1507
1509 Lexer &L;
1510 SourceManager &SourceMgr;
1511
1512 /// Default target information, used only for string literal
1513 /// parsing.
1514 const TargetInfo *Target;
1515
1516 DiagnosticsEngine &Diags;
1517 ModuleMap &Map;
1518
1519 /// The current module map file.
1520 FileEntryRef ModuleMapFile;
1521
1522 /// Source location of most recent parsed module declaration
1523 SourceLocation CurrModuleDeclLoc;
1524
1525 /// The directory that file names in this module map file should
1526 /// be resolved relative to.
1527 DirectoryEntryRef Directory;
1528
1529 /// Whether this module map is in a system header directory.
1530 bool IsSystem;
1531
1532 /// Whether an error occurred.
1533 bool HadError = false;
1534
1535 /// Stores string data for the various string literals referenced
1536 /// during parsing.
1537 llvm::BumpPtrAllocator StringData;
1538
1539 /// The current token.
1540 MMToken Tok;
1541
1542 /// The active module.
1543 Module *ActiveModule = nullptr;
1544
1545 /// Whether a module uses the 'requires excluded' hack to mark its
1546 /// contents as 'textual'.
1547 ///
1548 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1549 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1550 /// non-modular headers. For backwards compatibility, we continue to
1551 /// support this idiom for just these modules, and map the headers to
1552 /// 'textual' to match the original intent.
1553 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1554
1555 /// Consume the current token and return its location.
1556 SourceLocation consumeToken();
1557
1558 /// Skip tokens until we reach the a token with the given kind
1559 /// (or the end of the file).
1560 void skipUntil(MMToken::TokenKind K);
1561
1562 bool parseModuleId(ModuleId &Id);
1563 void parseModuleDecl();
1564 void parseExternModuleDecl();
1565 void parseRequiresDecl();
1566 void parseHeaderDecl(MMToken::TokenKind, SourceLocation LeadingLoc);
1567 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
1568 void parseExportDecl();
1569 void parseExportAsDecl();
1570 void parseUseDecl();
1571 void parseLinkDecl();
1572 void parseConfigMacros();
1573 void parseConflict();
1574 void parseInferredModuleDecl(bool Framework, bool Explicit);
1575
1576 /// Private modules are canonicalized as Foo_Private. Clang provides extra
1577 /// module map search logic to find the appropriate private module when PCH
1578 /// is used with implicit module maps. Warn when private modules are written
1579 /// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1580 void diagnosePrivateModules(SourceLocation ExplicitLoc,
1581 SourceLocation FrameworkLoc);
1582
1583 using Attributes = ModuleMap::Attributes;
1584
1585 bool parseOptionalAttributes(Attributes &Attrs);
1586
1587 public:
1588 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
1589 const TargetInfo *Target, DiagnosticsEngine &Diags,
1590 ModuleMap &Map, FileEntryRef ModuleMapFile,
1591 DirectoryEntryRef Directory, bool IsSystem)
1592 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1593 ModuleMapFile(ModuleMapFile), Directory(Directory),
1594 IsSystem(IsSystem) {
1595 Tok.clear();
1596 consumeToken();
1597 }
1598
1599 bool parseModuleMapFile();
1600
1601 bool terminatedByDirective() { return false; }
1603 };
1604
1605} // namespace clang
1606
1607SourceLocation ModuleMapParser::consumeToken() {
1609
1610retry:
1611 Tok.clear();
1612 Token LToken;
1613 L.LexFromRawLexer(LToken);
1614 Tok.Location = LToken.getLocation().getRawEncoding();
1615 switch (LToken.getKind()) {
1616 case tok::raw_identifier: {
1617 StringRef RI = LToken.getRawIdentifier();
1618 Tok.StringData = RI.data();
1619 Tok.StringLength = RI.size();
1620 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1621 .Case("config_macros", MMToken::ConfigMacros)
1622 .Case("conflict", MMToken::Conflict)
1623 .Case("exclude", MMToken::ExcludeKeyword)
1624 .Case("explicit", MMToken::ExplicitKeyword)
1625 .Case("export", MMToken::ExportKeyword)
1626 .Case("export_as", MMToken::ExportAsKeyword)
1627 .Case("extern", MMToken::ExternKeyword)
1628 .Case("framework", MMToken::FrameworkKeyword)
1629 .Case("header", MMToken::HeaderKeyword)
1630 .Case("link", MMToken::LinkKeyword)
1631 .Case("module", MMToken::ModuleKeyword)
1632 .Case("private", MMToken::PrivateKeyword)
1633 .Case("requires", MMToken::RequiresKeyword)
1634 .Case("textual", MMToken::TextualKeyword)
1635 .Case("umbrella", MMToken::UmbrellaKeyword)
1636 .Case("use", MMToken::UseKeyword)
1637 .Default(MMToken::Identifier);
1638 break;
1639 }
1640
1641 case tok::comma:
1642 Tok.Kind = MMToken::Comma;
1643 break;
1644
1645 case tok::eof:
1647 break;
1648
1649 case tok::l_brace:
1650 Tok.Kind = MMToken::LBrace;
1651 break;
1652
1653 case tok::l_square:
1654 Tok.Kind = MMToken::LSquare;
1655 break;
1656
1657 case tok::period:
1658 Tok.Kind = MMToken::Period;
1659 break;
1660
1661 case tok::r_brace:
1662 Tok.Kind = MMToken::RBrace;
1663 break;
1664
1665 case tok::r_square:
1666 Tok.Kind = MMToken::RSquare;
1667 break;
1668
1669 case tok::star:
1670 Tok.Kind = MMToken::Star;
1671 break;
1672
1673 case tok::exclaim:
1674 Tok.Kind = MMToken::Exclaim;
1675 break;
1676
1677 case tok::string_literal: {
1678 if (LToken.hasUDSuffix()) {
1679 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1680 HadError = true;
1681 goto retry;
1682 }
1683
1684 // Parse the string literal.
1685 LangOptions LangOpts;
1686 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
1687 if (StringLiteral.hadError)
1688 goto retry;
1689
1690 // Copy the string literal into our string data allocator.
1691 unsigned Length = StringLiteral.GetStringLength();
1692 char *Saved = StringData.Allocate<char>(Length + 1);
1693 memcpy(Saved, StringLiteral.GetString().data(), Length);
1694 Saved[Length] = 0;
1695
1696 // Form the token.
1698 Tok.StringData = Saved;
1699 Tok.StringLength = Length;
1700 break;
1701 }
1702
1703 case tok::numeric_constant: {
1704 // We don't support any suffixes or other complications.
1705 SmallString<32> SpellingBuffer;
1706 SpellingBuffer.resize(LToken.getLength() + 1);
1707 const char *Start = SpellingBuffer.data();
1708 unsigned Length =
1709 Lexer::getSpelling(LToken, Start, SourceMgr, Map.LangOpts);
1711 if (StringRef(Start, Length).getAsInteger(0, Value)) {
1712 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
1713 HadError = true;
1714 goto retry;
1715 }
1716
1718 Tok.IntegerValue = Value;
1719 break;
1720 }
1721
1722 case tok::comment:
1723 goto retry;
1724
1725 case tok::hash:
1726 // A module map can be terminated prematurely by
1727 // #pragma clang module contents
1728 // When building the module, we'll treat the rest of the file as the
1729 // contents of the module.
1730 {
1731 auto NextIsIdent = [&](StringRef Str) -> bool {
1732 L.LexFromRawLexer(LToken);
1733 return !LToken.isAtStartOfLine() && LToken.is(tok::raw_identifier) &&
1734 LToken.getRawIdentifier() == Str;
1735 };
1736 if (NextIsIdent("pragma") && NextIsIdent("clang") &&
1737 NextIsIdent("module") && NextIsIdent("contents")) {
1739 break;
1740 }
1741 }
1742 [[fallthrough]];
1743
1744 default:
1745 Diags.Report(Tok.getLocation(), diag::err_mmap_unknown_token);
1746 HadError = true;
1747 goto retry;
1748 }
1749
1750 return Result;
1751}
1752
1753void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1754 unsigned braceDepth = 0;
1755 unsigned squareDepth = 0;
1756 do {
1757 switch (Tok.Kind) {
1758 case MMToken::EndOfFile:
1759 return;
1760
1761 case MMToken::LBrace:
1762 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1763 return;
1764
1765 ++braceDepth;
1766 break;
1767
1768 case MMToken::LSquare:
1769 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1770 return;
1771
1772 ++squareDepth;
1773 break;
1774
1775 case MMToken::RBrace:
1776 if (braceDepth > 0)
1777 --braceDepth;
1778 else if (Tok.is(K))
1779 return;
1780 break;
1781
1782 case MMToken::RSquare:
1783 if (squareDepth > 0)
1784 --squareDepth;
1785 else if (Tok.is(K))
1786 return;
1787 break;
1788
1789 default:
1790 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1791 return;
1792 break;
1793 }
1794
1795 consumeToken();
1796 } while (true);
1797}
1798
1799/// Parse a module-id.
1800///
1801/// module-id:
1802/// identifier
1803/// identifier '.' module-id
1804///
1805/// \returns true if an error occurred, false otherwise.
1806bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1807 Id.clear();
1808 do {
1810 Id.push_back(
1811 std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
1812 consumeToken();
1813 } else {
1814 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1815 return true;
1816 }
1817
1818 if (!Tok.is(MMToken::Period))
1819 break;
1820
1821 consumeToken();
1822 } while (true);
1823
1824 return false;
1825}
1826
1827namespace {
1828
1829 /// Enumerates the known attributes.
1830 enum AttributeKind {
1831 /// An unknown attribute.
1832 AT_unknown,
1833
1834 /// The 'system' attribute.
1835 AT_system,
1836
1837 /// The 'extern_c' attribute.
1838 AT_extern_c,
1839
1840 /// The 'exhaustive' attribute.
1841 AT_exhaustive,
1842
1843 /// The 'no_undeclared_includes' attribute.
1844 AT_no_undeclared_includes
1845 };
1846
1847} // namespace
1848
1849/// Private modules are canonicalized as Foo_Private. Clang provides extra
1850/// module map search logic to find the appropriate private module when PCH
1851/// is used with implicit module maps. Warn when private modules are written
1852/// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
1853void ModuleMapParser::diagnosePrivateModules(SourceLocation ExplicitLoc,
1854 SourceLocation FrameworkLoc) {
1855 auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
1856 const Module *M, SourceRange ReplLoc) {
1857 auto D = Diags.Report(ActiveModule->DefinitionLoc,
1858 diag::note_mmap_rename_top_level_private_module);
1859 D << BadName << M->Name;
1860 D << FixItHint::CreateReplacement(ReplLoc, Canonical);
1861 };
1862
1863 for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
1864 auto const *M = E->getValue();
1865 if (M->Directory != ActiveModule->Directory)
1866 continue;
1867
1868 SmallString<128> FullName(ActiveModule->getFullModuleName());
1869 if (!FullName.starts_with(M->Name) && !FullName.ends_with("Private"))
1870 continue;
1871 SmallString<128> FixedPrivModDecl;
1872 SmallString<128> Canonical(M->Name);
1873 Canonical.append("_Private");
1874
1875 // Foo.Private -> Foo_Private
1876 if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
1877 M->Name == ActiveModule->Parent->Name) {
1878 Diags.Report(ActiveModule->DefinitionLoc,
1879 diag::warn_mmap_mismatched_private_submodule)
1880 << FullName;
1881
1882 SourceLocation FixItInitBegin = CurrModuleDeclLoc;
1883 if (FrameworkLoc.isValid())
1884 FixItInitBegin = FrameworkLoc;
1885 if (ExplicitLoc.isValid())
1886 FixItInitBegin = ExplicitLoc;
1887
1888 if (FrameworkLoc.isValid() || ActiveModule->Parent->IsFramework)
1889 FixedPrivModDecl.append("framework ");
1890 FixedPrivModDecl.append("module ");
1891 FixedPrivModDecl.append(Canonical);
1892
1893 GenNoteAndFixIt(FullName, FixedPrivModDecl, M,
1894 SourceRange(FixItInitBegin, ActiveModule->DefinitionLoc));
1895 continue;
1896 }
1897
1898 // FooPrivate and whatnots -> Foo_Private
1899 if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
1900 ActiveModule->Name != Canonical) {
1901 Diags.Report(ActiveModule->DefinitionLoc,
1902 diag::warn_mmap_mismatched_private_module_name)
1903 << ActiveModule->Name;
1904 GenNoteAndFixIt(ActiveModule->Name, Canonical, M,
1905 SourceRange(ActiveModule->DefinitionLoc));
1906 }
1907 }
1908}
1909
1910/// Parse a module declaration.
1911///
1912/// module-declaration:
1913/// 'extern' 'module' module-id string-literal
1914/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1915/// { module-member* }
1916///
1917/// module-member:
1918/// requires-declaration
1919/// header-declaration
1920/// submodule-declaration
1921/// export-declaration
1922/// export-as-declaration
1923/// link-declaration
1924///
1925/// submodule-declaration:
1926/// module-declaration
1927/// inferred-submodule-declaration
1928void ModuleMapParser::parseModuleDecl() {
1931 if (Tok.is(MMToken::ExternKeyword)) {
1932 parseExternModuleDecl();
1933 return;
1934 }
1935
1936 // Parse 'explicit' or 'framework' keyword, if present.
1937 SourceLocation ExplicitLoc;
1938 SourceLocation FrameworkLoc;
1939 bool Explicit = false;
1940 bool Framework = false;
1941
1942 // Parse 'explicit' keyword, if present.
1943 if (Tok.is(MMToken::ExplicitKeyword)) {
1944 ExplicitLoc = consumeToken();
1945 Explicit = true;
1946 }
1947
1948 // Parse 'framework' keyword, if present.
1949 if (Tok.is(MMToken::FrameworkKeyword)) {
1950 FrameworkLoc = consumeToken();
1951 Framework = true;
1952 }
1953
1954 // Parse 'module' keyword.
1955 if (!Tok.is(MMToken::ModuleKeyword)) {
1956 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1957 consumeToken();
1958 HadError = true;
1959 return;
1960 }
1961 CurrModuleDeclLoc = consumeToken(); // 'module' keyword
1962
1963 // If we have a wildcard for the module name, this is an inferred submodule.
1964 // Parse it.
1965 if (Tok.is(MMToken::Star))
1966 return parseInferredModuleDecl(Framework, Explicit);
1967
1968 // Parse the module name.
1969 ModuleId Id;
1970 if (parseModuleId(Id)) {
1971 HadError = true;
1972 return;
1973 }
1974
1975 if (ActiveModule) {
1976 if (Id.size() > 1) {
1977 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1978 << SourceRange(Id.front().second, Id.back().second);
1979
1980 HadError = true;
1981 return;
1982 }
1983 } else if (Id.size() == 1 && Explicit) {
1984 // Top-level modules can't be explicit.
1985 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1986 Explicit = false;
1987 ExplicitLoc = SourceLocation();
1988 HadError = true;
1989 }
1990
1991 Module *PreviousActiveModule = ActiveModule;
1992 if (Id.size() > 1) {
1993 // This module map defines a submodule. Go find the module of which it
1994 // is a submodule.
1995 ActiveModule = nullptr;
1996 const Module *TopLevelModule = nullptr;
1997 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1998 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1999 if (I == 0)
2000 TopLevelModule = Next;
2001 ActiveModule = Next;
2002 continue;
2003 }
2004
2005 Diags.Report(Id[I].second, diag::err_mmap_missing_parent_module)
2006 << Id[I].first << (ActiveModule != nullptr)
2007 << (ActiveModule
2008 ? ActiveModule->getTopLevelModule()->getFullModuleName()
2009 : "");
2010 HadError = true;
2011 }
2012
2013 if (TopLevelModule &&
2014 ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
2015 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
2016 "submodule defined in same file as 'module *' that allowed its "
2017 "top-level module");
2018 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
2019 }
2020 }
2021
2022 StringRef ModuleName = Id.back().first;
2023 SourceLocation ModuleNameLoc = Id.back().second;
2024
2025 // Parse the optional attribute list.
2026 Attributes Attrs;
2027 if (parseOptionalAttributes(Attrs))
2028 return;
2029
2030 // Parse the opening brace.
2031 if (!Tok.is(MMToken::LBrace)) {
2032 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
2033 << ModuleName;
2034 HadError = true;
2035 return;
2036 }
2037 SourceLocation LBraceLoc = consumeToken();
2038
2039 // Determine whether this (sub)module has already been defined.
2040 Module *ShadowingModule = nullptr;
2041 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
2042 // We might see a (re)definition of a module that we already have a
2043 // definition for in four cases:
2044 // - If we loaded one definition from an AST file and we've just found a
2045 // corresponding definition in a module map file, or
2046 bool LoadedFromASTFile = Existing->IsFromModuleFile;
2047 // - If we previously inferred this module from different module map file.
2048 bool Inferred = Existing->IsInferred;
2049 // - If we're building a framework that vends a module map, we might've
2050 // previously seen the one in intermediate products and now the system
2051 // one.
2052 // FIXME: If we're parsing module map file that looks like this:
2053 // framework module FW { ... }
2054 // module FW.Sub { ... }
2055 // We can't check the framework qualifier, since it's not attached to
2056 // the definition of Sub. Checking that qualifier on \c Existing is
2057 // not correct either, since we might've previously seen:
2058 // module FW { ... }
2059 // module FW.Sub { ... }
2060 // We should enforce consistency of redefinitions so that we can rely
2061 // that \c Existing is part of a framework iff the redefinition of FW
2062 // we have just skipped had it too. Once we do that, stop checking
2063 // the local framework qualifier and only rely on \c Existing.
2064 bool PartOfFramework = Framework || Existing->isPartOfFramework();
2065 // - If we're building a (preprocessed) module and we've just loaded the
2066 // module map file from which it was created.
2067 bool ParsedAsMainInput =
2068 Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
2069 Map.LangOpts.CurrentModule == ModuleName &&
2070 SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
2071 SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
2072 if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) {
2073 ActiveModule = PreviousActiveModule;
2074 // Skip the module definition.
2075 skipUntil(MMToken::RBrace);
2076 if (Tok.is(MMToken::RBrace))
2077 consumeToken();
2078 else {
2079 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2080 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2081 HadError = true;
2082 }
2083 return;
2084 }
2085
2086 if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
2087 ShadowingModule = Existing;
2088 } else {
2089 // This is not a shawdowed module decl, it is an illegal redefinition.
2090 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
2091 << ModuleName;
2092 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
2093
2094 // Skip the module definition.
2095 skipUntil(MMToken::RBrace);
2096 if (Tok.is(MMToken::RBrace))
2097 consumeToken();
2098
2099 HadError = true;
2100 return;
2101 }
2102 }
2103
2104 // Start defining this module.
2105 if (ShadowingModule) {
2106 ActiveModule =
2107 Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
2108 } else {
2109 ActiveModule =
2110 Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
2111 .first;
2112 }
2113
2114 ActiveModule->DefinitionLoc = ModuleNameLoc;
2115 if (Attrs.IsSystem || IsSystem)
2116 ActiveModule->IsSystem = true;
2117 if (Attrs.IsExternC)
2118 ActiveModule->IsExternC = true;
2119 if (Attrs.NoUndeclaredIncludes)
2120 ActiveModule->NoUndeclaredIncludes = true;
2121 ActiveModule->Directory = Directory;
2122
2123 StringRef MapFileName(ModuleMapFile.getName());
2124 if (MapFileName.ends_with("module.private.modulemap") ||
2125 MapFileName.ends_with("module_private.map")) {
2126 ActiveModule->ModuleMapIsPrivate = true;
2127 }
2128
2129 // Private modules named as FooPrivate, Foo.Private or similar are likely a
2130 // user error; provide warnings, notes and fixits to direct users to use
2131 // Foo_Private instead.
2132 SourceLocation StartLoc =
2133 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
2134 if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
2135 !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
2136 StartLoc) &&
2137 !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
2138 StartLoc) &&
2139 ActiveModule->ModuleMapIsPrivate)
2140 diagnosePrivateModules(ExplicitLoc, FrameworkLoc);
2141
2142 bool Done = false;
2143 do {
2144 switch (Tok.Kind) {
2145 case MMToken::EndOfFile:
2146 case MMToken::RBrace:
2147 Done = true;
2148 break;
2149
2151 parseConfigMacros();
2152 break;
2153
2154 case MMToken::Conflict:
2155 parseConflict();
2156 break;
2157
2162 parseModuleDecl();
2163 break;
2164
2166 parseExportDecl();
2167 break;
2168
2170 parseExportAsDecl();
2171 break;
2172
2174 parseUseDecl();
2175 break;
2176
2178 parseRequiresDecl();
2179 break;
2180
2182 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
2183 break;
2184
2186 SourceLocation UmbrellaLoc = consumeToken();
2187 if (Tok.is(MMToken::HeaderKeyword))
2188 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
2189 else
2190 parseUmbrellaDirDecl(UmbrellaLoc);
2191 break;
2192 }
2193
2195 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
2196 break;
2197
2199 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
2200 break;
2201
2203 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
2204 break;
2205
2207 parseLinkDecl();
2208 break;
2209
2210 default:
2211 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
2212 consumeToken();
2213 break;
2214 }
2215 } while (!Done);
2216
2217 if (Tok.is(MMToken::RBrace))
2218 consumeToken();
2219 else {
2220 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2221 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2222 HadError = true;
2223 }
2224
2225 // If the active module is a top-level framework, and there are no link
2226 // libraries, automatically link against the framework.
2227 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
2228 ActiveModule->LinkLibraries.empty())
2229 inferFrameworkLink(ActiveModule);
2230
2231 // If the module meets all requirements but is still unavailable, mark the
2232 // whole tree as unavailable to prevent it from building.
2233 if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
2234 ActiveModule->Parent) {
2235 ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
2236 ActiveModule->getTopLevelModule()->MissingHeaders.append(
2237 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
2238 }
2239
2240 // We're done parsing this module. Pop back to the previous module.
2241 ActiveModule = PreviousActiveModule;
2242}
2243
2244/// Parse an extern module declaration.
2245///
2246/// extern module-declaration:
2247/// 'extern' 'module' module-id string-literal
2248void ModuleMapParser::parseExternModuleDecl() {
2249 assert(Tok.is(MMToken::ExternKeyword));
2250 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
2251
2252 // Parse 'module' keyword.
2253 if (!Tok.is(MMToken::ModuleKeyword)) {
2254 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2255 consumeToken();
2256 HadError = true;
2257 return;
2258 }
2259 consumeToken(); // 'module' keyword
2260
2261 // Parse the module name.
2262 ModuleId Id;
2263 if (parseModuleId(Id)) {
2264 HadError = true;
2265 return;
2266 }
2267
2268 // Parse the referenced module map file name.
2269 if (!Tok.is(MMToken::StringLiteral)) {
2270 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
2271 HadError = true;
2272 return;
2273 }
2274 std::string FileName = std::string(Tok.getString());
2275 consumeToken(); // filename
2276
2277 StringRef FileNameRef = FileName;
2278 SmallString<128> ModuleMapFileName;
2279 if (llvm::sys::path::is_relative(FileNameRef)) {
2280 ModuleMapFileName += Directory.getName();
2281 llvm::sys::path::append(ModuleMapFileName, FileName);
2282 FileNameRef = ModuleMapFileName;
2283 }
2284 if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef))
2286 *File, IsSystem,
2288 ? Directory
2289 : File->getDir(),
2290 FileID(), nullptr, ExternLoc);
2291}
2292
2293/// Whether to add the requirement \p Feature to the module \p M.
2294///
2295/// This preserves backwards compatibility for two hacks in the Darwin system
2296/// module map files:
2297///
2298/// 1. The use of 'requires excluded' to make headers non-modular, which
2299/// should really be mapped to 'textual' now that we have this feature. We
2300/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
2301/// true. Later, this bit will be used to map all the headers inside this
2302/// module to 'textual'.
2303///
2304/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
2305///
2306/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
2307/// was never correct and causes issues now that we check it, so drop it.
2308static bool shouldAddRequirement(Module *M, StringRef Feature,
2309 bool &IsRequiresExcludedHack) {
2310 if (Feature == "excluded" &&
2311 (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
2312 M->fullModuleNameIs({"Tcl", "Private"}))) {
2313 IsRequiresExcludedHack = true;
2314 return false;
2315 } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
2316 return false;
2317 }
2318
2319 return true;
2320}
2321
2322/// Parse a requires declaration.
2323///
2324/// requires-declaration:
2325/// 'requires' feature-list
2326///
2327/// feature-list:
2328/// feature ',' feature-list
2329/// feature
2330///
2331/// feature:
2332/// '!'[opt] identifier
2333void ModuleMapParser::parseRequiresDecl() {
2334 assert(Tok.is(MMToken::RequiresKeyword));
2335
2336 // Parse 'requires' keyword.
2337 consumeToken();
2338
2339 // Parse the feature-list.
2340 do {
2341 bool RequiredState = true;
2342 if (Tok.is(MMToken::Exclaim)) {
2343 RequiredState = false;
2344 consumeToken();
2345 }
2346
2347 if (!Tok.is(MMToken::Identifier)) {
2348 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
2349 HadError = true;
2350 return;
2351 }
2352
2353 // Consume the feature name.
2354 std::string Feature = std::string(Tok.getString());
2355 consumeToken();
2356
2357 bool IsRequiresExcludedHack = false;
2358 bool ShouldAddRequirement =
2359 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
2360
2361 if (IsRequiresExcludedHack)
2362 UsesRequiresExcludedHack.insert(ActiveModule);
2363
2364 if (ShouldAddRequirement) {
2365 // Add this feature.
2366 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
2367 *Map.Target);
2368 }
2369
2370 if (!Tok.is(MMToken::Comma))
2371 break;
2372
2373 // Consume the comma.
2374 consumeToken();
2375 } while (true);
2376}
2377
2378/// Parse a header declaration.
2379///
2380/// header-declaration:
2381/// 'textual'[opt] 'header' string-literal
2382/// 'private' 'textual'[opt] 'header' string-literal
2383/// 'exclude' 'header' string-literal
2384/// 'umbrella' 'header' string-literal
2385///
2386/// FIXME: Support 'private textual header'.
2387void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
2388 SourceLocation LeadingLoc) {
2389 // We've already consumed the first token.
2391
2392 if (LeadingToken == MMToken::PrivateKeyword) {
2394 // 'private' may optionally be followed by 'textual'.
2395 if (Tok.is(MMToken::TextualKeyword)) {
2396 LeadingToken = Tok.Kind;
2397 consumeToken();
2398 }
2399 } else if (LeadingToken == MMToken::ExcludeKeyword) {
2401 }
2402
2403 if (LeadingToken == MMToken::TextualKeyword)
2405
2406 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2407 // Mark this header 'textual' (see doc comment for
2408 // Module::UsesRequiresExcludedHack).
2410 }
2411
2412 if (LeadingToken != MMToken::HeaderKeyword) {
2413 if (!Tok.is(MMToken::HeaderKeyword)) {
2414 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2415 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
2416 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
2417 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
2418 return;
2419 }
2420 consumeToken();
2421 }
2422
2423 // Parse the header name.
2424 if (!Tok.is(MMToken::StringLiteral)) {
2425 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2426 << "header";
2427 HadError = true;
2428 return;
2429 }
2431 Header.FileName = std::string(Tok.getString());
2432 Header.FileNameLoc = consumeToken();
2433 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
2434 Header.Kind = Map.headerRoleToKind(Role);
2435
2436 // Check whether we already have an umbrella.
2437 if (Header.IsUmbrella &&
2438 !std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
2439 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
2440 << ActiveModule->getFullModuleName();
2441 HadError = true;
2442 return;
2443 }
2444
2445 // If we were given stat information, parse it so we can skip looking for
2446 // the file.
2447 if (Tok.is(MMToken::LBrace)) {
2448 SourceLocation LBraceLoc = consumeToken();
2449
2450 while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) {
2451 enum Attribute { Size, ModTime, Unknown };
2452 StringRef Str = Tok.getString();
2453 SourceLocation Loc = consumeToken();
2454 switch (llvm::StringSwitch<Attribute>(Str)
2455 .Case("size", Size)
2456 .Case("mtime", ModTime)
2457 .Default(Unknown)) {
2458 case Size:
2459 if (Header.Size)
2460 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2461 if (!Tok.is(MMToken::IntegerLiteral)) {
2462 Diags.Report(Tok.getLocation(),
2463 diag::err_mmap_invalid_header_attribute_value) << Str;
2464 skipUntil(MMToken::RBrace);
2465 break;
2466 }
2467 Header.Size = Tok.getInteger();
2468 consumeToken();
2469 break;
2470
2471 case ModTime:
2472 if (Header.ModTime)
2473 Diags.Report(Loc, diag::err_mmap_duplicate_header_attribute) << Str;
2474 if (!Tok.is(MMToken::IntegerLiteral)) {
2475 Diags.Report(Tok.getLocation(),
2476 diag::err_mmap_invalid_header_attribute_value) << Str;
2477 skipUntil(MMToken::RBrace);
2478 break;
2479 }
2480 Header.ModTime = Tok.getInteger();
2481 consumeToken();
2482 break;
2483
2484 case Unknown:
2485 Diags.Report(Loc, diag::err_mmap_expected_header_attribute);
2486 skipUntil(MMToken::RBrace);
2487 break;
2488 }
2489 }
2490
2491 if (Tok.is(MMToken::RBrace))
2492 consumeToken();
2493 else {
2494 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2495 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2496 HadError = true;
2497 }
2498 }
2499
2500 bool NeedsFramework = false;
2501 // Don't add the top level headers to the builtin modules if the builtin headers
2502 // belong to the system modules.
2503 if (!Map.LangOpts.BuiltinHeadersInSystemModules || ActiveModule->isSubModule() || !isBuiltInModuleName(ActiveModule->Name))
2504 Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
2505
2506 if (NeedsFramework)
2507 Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)
2508 << ActiveModule->getFullModuleName()
2509 << FixItHint::CreateReplacement(CurrModuleDeclLoc, "framework module");
2510}
2511
2513 const Module::Header &B) {
2514 return A.NameAsWritten < B.NameAsWritten;
2515}
2516
2517/// Parse an umbrella directory declaration.
2518///
2519/// umbrella-dir-declaration:
2520/// umbrella string-literal
2521void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
2522 // Parse the directory name.
2523 if (!Tok.is(MMToken::StringLiteral)) {
2524 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
2525 << "umbrella";
2526 HadError = true;
2527 return;
2528 }
2529
2530 std::string DirName = std::string(Tok.getString());
2531 std::string DirNameAsWritten = DirName;
2532 SourceLocation DirNameLoc = consumeToken();
2533
2534 // Check whether we already have an umbrella.
2535 if (!std::holds_alternative<std::monostate>(ActiveModule->Umbrella)) {
2536 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
2537 << ActiveModule->getFullModuleName();
2538 HadError = true;
2539 return;
2540 }
2541
2542 // Look for this file.
2544 if (llvm::sys::path::is_absolute(DirName)) {
2545 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(DirName);
2546 } else {
2547 SmallString<128> PathName;
2548 PathName = Directory.getName();
2549 llvm::sys::path::append(PathName, DirName);
2550 Dir = SourceMgr.getFileManager().getOptionalDirectoryRef(PathName);
2551 }
2552
2553 if (!Dir) {
2554 Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
2555 << DirName;
2556 return;
2557 }
2558
2559 if (UsesRequiresExcludedHack.count(ActiveModule)) {
2560 // Mark this header 'textual' (see doc comment for
2561 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
2562 // directory is relatively expensive, in practice this only applies to the
2563 // uncommonly used Tcl module on Darwin platforms.
2564 std::error_code EC;
2566 llvm::vfs::FileSystem &FS =
2568 for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
2569 I != E && !EC; I.increment(EC)) {
2570 if (auto FE = SourceMgr.getFileManager().getOptionalFileRef(I->path())) {
2571 Module::Header Header = {"", std::string(I->path()), *FE};
2572 Headers.push_back(std::move(Header));
2573 }
2574 }
2575
2576 // Sort header paths so that the pcm doesn't depend on iteration order.
2577 std::stable_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
2578
2579 for (auto &Header : Headers)
2580 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
2581 return;
2582 }
2583
2584 if (Module *OwningModule = Map.UmbrellaDirs[*Dir]) {
2585 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
2586 << OwningModule->getFullModuleName();
2587 HadError = true;
2588 return;
2589 }
2590
2591 // Record this umbrella directory.
2592 Map.setUmbrellaDirAsWritten(ActiveModule, *Dir, DirNameAsWritten, DirName);
2593}
2594
2595/// Parse a module export declaration.
2596///
2597/// export-declaration:
2598/// 'export' wildcard-module-id
2599///
2600/// wildcard-module-id:
2601/// identifier
2602/// '*'
2603/// identifier '.' wildcard-module-id
2604void ModuleMapParser::parseExportDecl() {
2605 assert(Tok.is(MMToken::ExportKeyword));
2606 SourceLocation ExportLoc = consumeToken();
2607
2608 // Parse the module-id with an optional wildcard at the end.
2609 ModuleId ParsedModuleId;
2610 bool Wildcard = false;
2611 do {
2612 // FIXME: Support string-literal module names here.
2613 if (Tok.is(MMToken::Identifier)) {
2614 ParsedModuleId.push_back(
2615 std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
2616 consumeToken();
2617
2618 if (Tok.is(MMToken::Period)) {
2619 consumeToken();
2620 continue;
2621 }
2622
2623 break;
2624 }
2625
2626 if(Tok.is(MMToken::Star)) {
2627 Wildcard = true;
2628 consumeToken();
2629 break;
2630 }
2631
2632 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
2633 HadError = true;
2634 return;
2635 } while (true);
2636
2638 ExportLoc, ParsedModuleId, Wildcard
2639 };
2640 ActiveModule->UnresolvedExports.push_back(Unresolved);
2641}
2642
2643/// Parse a module export_as declaration.
2644///
2645/// export-as-declaration:
2646/// 'export_as' identifier
2647void ModuleMapParser::parseExportAsDecl() {
2648 assert(Tok.is(MMToken::ExportAsKeyword));
2649 consumeToken();
2650
2651 if (!Tok.is(MMToken::Identifier)) {
2652 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
2653 HadError = true;
2654 return;
2655 }
2656
2657 if (ActiveModule->Parent) {
2658 Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);
2659 consumeToken();
2660 return;
2661 }
2662
2663 if (!ActiveModule->ExportAsModule.empty()) {
2664 if (ActiveModule->ExportAsModule == Tok.getString()) {
2665 Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as)
2666 << ActiveModule->Name << Tok.getString();
2667 } else {
2668 Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as)
2669 << ActiveModule->Name << ActiveModule->ExportAsModule
2670 << Tok.getString();
2671 }
2672 }
2673
2674 ActiveModule->ExportAsModule = std::string(Tok.getString());
2675 Map.addLinkAsDependency(ActiveModule);
2676
2677 consumeToken();
2678}
2679
2680/// Parse a module use declaration.
2681///
2682/// use-declaration:
2683/// 'use' wildcard-module-id
2684void ModuleMapParser::parseUseDecl() {
2685 assert(Tok.is(MMToken::UseKeyword));
2686 auto KWLoc = consumeToken();
2687 // Parse the module-id.
2688 ModuleId ParsedModuleId;
2689 parseModuleId(ParsedModuleId);
2690
2691 if (ActiveModule->Parent)
2692 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2693 else
2694 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
2695}
2696
2697/// Parse a link declaration.
2698///
2699/// module-declaration:
2700/// 'link' 'framework'[opt] string-literal
2701void ModuleMapParser::parseLinkDecl() {
2702 assert(Tok.is(MMToken::LinkKeyword));
2703 SourceLocation LinkLoc = consumeToken();
2704
2705 // Parse the optional 'framework' keyword.
2706 bool IsFramework = false;
2707 if (Tok.is(MMToken::FrameworkKeyword)) {
2708 consumeToken();
2709 IsFramework = true;
2710 }
2711
2712 // Parse the library name
2713 if (!Tok.is(MMToken::StringLiteral)) {
2714 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2715 << IsFramework << SourceRange(LinkLoc);
2716 HadError = true;
2717 return;
2718 }
2719
2720 std::string LibraryName = std::string(Tok.getString());
2721 consumeToken();
2722 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2723 IsFramework));
2724}
2725
2726/// Parse a configuration macro declaration.
2727///
2728/// module-declaration:
2729/// 'config_macros' attributes[opt] config-macro-list?
2730///
2731/// config-macro-list:
2732/// identifier (',' identifier)?
2733void ModuleMapParser::parseConfigMacros() {
2734 assert(Tok.is(MMToken::ConfigMacros));
2735 SourceLocation ConfigMacrosLoc = consumeToken();
2736
2737 // Only top-level modules can have configuration macros.
2738 if (ActiveModule->Parent) {
2739 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2740 }
2741
2742 // Parse the optional attributes.
2743 Attributes Attrs;
2744 if (parseOptionalAttributes(Attrs))
2745 return;
2746
2747 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2748 ActiveModule->ConfigMacrosExhaustive = true;
2749 }
2750
2751 // If we don't have an identifier, we're done.
2752 // FIXME: Support macros with the same name as a keyword here.
2753 if (!Tok.is(MMToken::Identifier))
2754 return;
2755
2756 // Consume the first identifier.
2757 if (!ActiveModule->Parent) {
2758 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2759 }
2760 consumeToken();
2761
2762 do {
2763 // If there's a comma, consume it.
2764 if (!Tok.is(MMToken::Comma))
2765 break;
2766 consumeToken();
2767
2768 // We expect to see a macro name here.
2769 // FIXME: Support macros with the same name as a keyword here.
2770 if (!Tok.is(MMToken::Identifier)) {
2771 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2772 break;
2773 }
2774
2775 // Consume the macro name.
2776 if (!ActiveModule->Parent) {
2777 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2778 }
2779 consumeToken();
2780 } while (true);
2781}
2782
2783/// Format a module-id into a string.
2784static std::string formatModuleId(const ModuleId &Id) {
2785 std::string result;
2786 {
2787 llvm::raw_string_ostream OS(result);
2788
2789 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2790 if (I)
2791 OS << ".";
2792 OS << Id[I].first;
2793 }
2794 }
2795
2796 return result;
2797}
2798
2799/// Parse a conflict declaration.
2800///
2801/// module-declaration:
2802/// 'conflict' module-id ',' string-literal
2803void ModuleMapParser::parseConflict() {
2804 assert(Tok.is(MMToken::Conflict));
2805 SourceLocation ConflictLoc = consumeToken();
2807
2808 // Parse the module-id.
2809 if (parseModuleId(Conflict.Id))
2810 return;
2811
2812 // Parse the ','.
2813 if (!Tok.is(MMToken::Comma)) {
2814 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2815 << SourceRange(ConflictLoc);
2816 return;
2817 }
2818 consumeToken();
2819
2820 // Parse the message.
2821 if (!Tok.is(MMToken::StringLiteral)) {
2822 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2823 << formatModuleId(Conflict.Id);
2824 return;
2825 }
2826 Conflict.Message = Tok.getString().str();
2827 consumeToken();
2828
2829 // Add this unresolved conflict.
2830 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2831}
2832
2833/// Parse an inferred module declaration (wildcard modules).
2834///
2835/// module-declaration:
2836/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2837/// { inferred-module-member* }
2838///
2839/// inferred-module-member:
2840/// 'export' '*'
2841/// 'exclude' identifier
2842void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
2843 assert(Tok.is(MMToken::Star));
2844 SourceLocation StarLoc = consumeToken();
2845 bool Failed = false;
2846
2847 // Inferred modules must be submodules.
2848 if (!ActiveModule && !Framework) {
2849 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2850 Failed = true;
2851 }
2852
2853 if (ActiveModule) {
2854 // Inferred modules must have umbrella directories.
2855 if (!Failed && ActiveModule->IsAvailable &&
2856 !ActiveModule->getEffectiveUmbrellaDir()) {
2857 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2858 Failed = true;
2859 }
2860
2861 // Check for redefinition of an inferred module.
2862 if (!Failed && ActiveModule->InferSubmodules) {
2863 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2864 if (ActiveModule->InferredSubmoduleLoc.isValid())
2865 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2866 diag::note_mmap_prev_definition);
2867 Failed = true;
2868 }
2869
2870 // Check for the 'framework' keyword, which is not permitted here.
2871 if (Framework) {
2872 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2873 Framework = false;
2874 }
2875 } else if (Explicit) {
2876 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2877 Explicit = false;
2878 }
2879
2880 // If there were any problems with this inferred submodule, skip its body.
2881 if (Failed) {
2882 if (Tok.is(MMToken::LBrace)) {
2883 consumeToken();
2884 skipUntil(MMToken::RBrace);
2885 if (Tok.is(MMToken::RBrace))
2886 consumeToken();
2887 }
2888 HadError = true;
2889 return;
2890 }
2891
2892 // Parse optional attributes.
2893 Attributes Attrs;
2894 if (parseOptionalAttributes(Attrs))
2895 return;
2896
2897 if (ActiveModule) {
2898 // Note that we have an inferred submodule.
2899 ActiveModule->InferSubmodules = true;
2900 ActiveModule->InferredSubmoduleLoc = StarLoc;
2901 ActiveModule->InferExplicitSubmodules = Explicit;
2902 } else {
2903 // We'll be inferring framework modules for this directory.
2904 Map.InferredDirectories[Directory].InferModules = true;
2905 Map.InferredDirectories[Directory].Attrs = Attrs;
2906 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2907 // FIXME: Handle the 'framework' keyword.
2908 }
2909
2910 // Parse the opening brace.
2911 if (!Tok.is(MMToken::LBrace)) {
2912 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2913 HadError = true;
2914 return;
2915 }
2916 SourceLocation LBraceLoc = consumeToken();
2917
2918 // Parse the body of the inferred submodule.
2919 bool Done = false;
2920 do {
2921 switch (Tok.Kind) {
2922 case MMToken::EndOfFile:
2923 case MMToken::RBrace:
2924 Done = true;
2925 break;
2926
2928 if (ActiveModule) {
2929 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2930 << (ActiveModule != nullptr);
2931 consumeToken();
2932 break;
2933 }
2934
2935 consumeToken();
2936 // FIXME: Support string-literal module names here.
2937 if (!Tok.is(MMToken::Identifier)) {
2938 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2939 break;
2940 }
2941
2942 Map.InferredDirectories[Directory].ExcludedModules.push_back(
2943 std::string(Tok.getString()));
2944 consumeToken();
2945 break;
2946
2948 if (!ActiveModule) {
2949 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2950 << (ActiveModule != nullptr);
2951 consumeToken();
2952 break;
2953 }
2954
2955 consumeToken();
2956 if (Tok.is(MMToken::Star))
2957 ActiveModule->InferExportWildcard = true;
2958 else
2959 Diags.Report(Tok.getLocation(),
2960 diag::err_mmap_expected_export_wildcard);
2961 consumeToken();
2962 break;
2963
2969 default:
2970 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2971 << (ActiveModule != nullptr);
2972 consumeToken();
2973 break;
2974 }
2975 } while (!Done);
2976
2977 if (Tok.is(MMToken::RBrace))
2978 consumeToken();
2979 else {
2980 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2981 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2982 HadError = true;
2983 }
2984}
2985
2986/// Parse optional attributes.
2987///
2988/// attributes:
2989/// attribute attributes
2990/// attribute
2991///
2992/// attribute:
2993/// [ identifier ]
2994///
2995/// \param Attrs Will be filled in with the parsed attributes.
2996///
2997/// \returns true if an error occurred, false otherwise.
2998bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2999 bool HadError = false;
3000
3001 while (Tok.is(MMToken::LSquare)) {
3002 // Consume the '['.
3003 SourceLocation LSquareLoc = consumeToken();
3004
3005 // Check whether we have an attribute name here.
3006 if (!Tok.is(MMToken::Identifier)) {
3007 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
3008 skipUntil(MMToken::RSquare);
3009 if (Tok.is(MMToken::RSquare))
3010 consumeToken();
3011 HadError = true;
3012 }
3013
3014 // Decode the attribute name.
3015 AttributeKind Attribute
3016 = llvm::StringSwitch<AttributeKind>(Tok.getString())
3017 .Case("exhaustive", AT_exhaustive)
3018 .Case("extern_c", AT_extern_c)
3019 .Case("no_undeclared_includes", AT_no_undeclared_includes)
3020 .Case("system", AT_system)
3021 .Default(AT_unknown);
3022 switch (Attribute) {
3023 case AT_unknown:
3024 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
3025 << Tok.getString();
3026 break;
3027
3028 case AT_system:
3029 Attrs.IsSystem = true;
3030 break;
3031
3032 case AT_extern_c:
3033 Attrs.IsExternC = true;
3034 break;
3035
3036 case AT_exhaustive:
3037 Attrs.IsExhaustive = true;
3038 break;
3039
3040 case AT_no_undeclared_includes:
3041 Attrs.NoUndeclaredIncludes = true;
3042 break;
3043 }
3044 consumeToken();
3045
3046 // Consume the ']'.
3047 if (!Tok.is(MMToken::RSquare)) {
3048 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
3049 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
3050 skipUntil(MMToken::RSquare);
3051 HadError = true;
3052 }
3053
3054 if (Tok.is(MMToken::RSquare))
3055 consumeToken();
3056 }
3057
3058 return HadError;
3059}
3060
3061/// Parse a module map file.
3062///
3063/// module-map-file:
3064/// module-declaration*
3066 do {
3067 switch (Tok.Kind) {
3068 case MMToken::EndOfFile:
3069 return HadError;
3070
3075 parseModuleDecl();
3076 break;
3077
3078 case MMToken::Comma:
3080 case MMToken::Conflict:
3081 case MMToken::Exclaim:
3087 case MMToken::LBrace:
3089 case MMToken::LSquare:
3090 case MMToken::Period:
3092 case MMToken::RBrace:
3093 case MMToken::RSquare:
3095 case MMToken::Star:
3101 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
3102 HadError = true;
3103 consumeToken();
3104 break;
3105 }
3106 } while (true);
3107}
3108
3110 DirectoryEntryRef Dir, FileID ID,
3111 unsigned *Offset,
3112 SourceLocation ExternModuleLoc) {
3113 assert(Target && "Missing target information");
3114 llvm::DenseMap<const FileEntry *, bool>::iterator Known
3115 = ParsedModuleMap.find(File);
3116 if (Known != ParsedModuleMap.end())
3117 return Known->second;
3118
3119 // If the module map file wasn't already entered, do so now.
3120 if (ID.isInvalid()) {
3121 auto FileCharacter =
3123 ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
3124 }
3125
3126 assert(Target && "Missing target information");
3127 std::optional<llvm::MemoryBufferRef> Buffer = SourceMgr.getBufferOrNone(ID);
3128 if (!Buffer)
3129 return ParsedModuleMap[File] = true;
3130 assert((!Offset || *Offset <= Buffer->getBufferSize()) &&
3131 "invalid buffer offset");
3132
3133 // Parse this module map file.
3134 Lexer L(SourceMgr.getLocForStartOfFile(ID), MMapLangOpts,
3135 Buffer->getBufferStart(),
3136 Buffer->getBufferStart() + (Offset ? *Offset : 0),
3137 Buffer->getBufferEnd());
3139 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
3140 IsSystem);
3141 bool Result = Parser.parseModuleMapFile();
3142 ParsedModuleMap[File] = Result;
3143
3144 if (Offset) {
3145 auto Loc = SourceMgr.getDecomposedLoc(Parser.getLocation());
3146 assert(Loc.first == ID && "stopped in a different file?");
3147 *Offset = Loc.second;
3148 }
3149
3150 // Notify callbacks that we parsed it.
3151 for (const auto &Cb : Callbacks)
3152 Cb->moduleMapFileRead(Start, File, IsSystem);
3153
3154 return Result;
3155}
NodeId Parent
Definition: ASTDiff.cpp:191
int Id
Definition: ASTDiff.cpp:190
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
StringRef Filename
Definition: Format.cpp:2962
#define ALIAS(NAME, TOK, FLAGS)
#define KEYWORD(NAME, FLAGS)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static bool isBuiltinHeaderName(StringRef FileName)
Determine whether the given file name is the name of a builtin header, supplied by Clang to replace,...
Definition: ModuleMap.cpp:259
static bool isBuiltInModuleName(StringRef ModuleName)
Determine whether the given module name is the name of a builtin module that is cyclic with a system ...
Definition: ModuleMap.cpp:277
static Module * getTopLevelOrNull(Module *M)
Definition: ModuleMap.cpp:492
static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::KnownHeader Header)
Definition: ModuleMap.cpp:471
static void inferFrameworkLink(Module *Mod)
For a framework module, infer the framework against which we should link.
Definition: ModuleMap.cpp:982
static StringRef sanitizeFilenameAsIdentifier(StringRef Name, SmallVectorImpl< char > &Buffer)
"Sanitize" a filename so that it can be used as an identifier.
Definition: ModuleMap.cpp:379
static void appendSubframeworkPaths(Module *Mod, SmallVectorImpl< char > &Path)
Append to Paths the set of paths needed to get to the subframework in which the given module lives.
Definition: ModuleMap.cpp:163
static bool shouldAddRequirement(Module *M, StringRef Feature, bool &IsRequiresExcludedHack)
Whether to add the requirement Feature to the module M.
Definition: ModuleMap.cpp:2308
static std::string formatModuleId(const ModuleId &Id)
Format a module-id into a string.
Definition: ModuleMap.cpp:2784
static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New, const ModuleMap::KnownHeader &Old)
Definition: ModuleMap.cpp:578
static bool compareModuleHeaders(const Module::Header &A, const Module::Header &B)
Definition: ModuleMap.cpp:2512
Defines the clang::Module class, which describes a module in the source code.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:192
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1547
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition: Diagnostic.h:916
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
Cached information about one directory (either on disk or in the virtual file system).
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition: FileEntry.h:57
StringRef getName() const
The name of this FileEntry.
Definition: FileEntry.h:61
DirectoryEntryRef getDir() const
Definition: FileEntry.h:73
Cached information about one file (either on disk or in the virtual file system).
Definition: FileEntry.h:300
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
Definition: FileManager.h:53
llvm::vfs::FileSystem & getVirtualFileSystem() const
Definition: FileManager.h:245
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:234
llvm::ErrorOr< const DirectoryEntry * > getDirectory(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:169
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Definition: Diagnostic.h:134
unsigned ImplicitModuleMaps
Implicit module maps.
unsigned ModuleMapFileHomeIsCwd
Set the 'home directory' of a module map file to the current working directory (or the home directory...
Encapsulates the information needed to find the file referenced by a #include or #include_next,...
Definition: HeaderSearch.h:232
void loadTopLevelSystemModules()
Load all known, top-level system modules.
void MarkFileModuleHeader(FileEntryRef FE, ModuleMap::ModuleHeaderRole Role, bool isCompilingModuleHeader)
Mark the specified file as part of a module.
OptionalFileEntryRef lookupModuleMapFile(DirectoryEntryRef Dir, bool IsFramework)
Try to find a module map file in the given directory, returning nullopt if none is found.
HeaderSearchOptions & getHeaderSearchOpts() const
Retrieve the header-search options with which this header search was initialized.
Definition: HeaderSearch.h:365
@ CMK_ModuleMap
Compiling a module from a module map.
Definition: LangOptions.h:95
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:418
bool isCompilingModule() const
Are we compiling a module?
Definition: LangOptions.h:559
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:473
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
Definition: Lexer.h:78
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
Definition: Lexer.h:236
SourceLocation getSourceLocation(const char *Loc, unsigned TokLen=1) const
getSourceLocation - Return a source location identifier for the specified offset in the current file.
Definition: Lexer.cpp:1213
static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)
getSpelling - This method is used to get the spelling of a token into a preallocated buffer,...
Definition: Lexer.cpp:452
ModuleMapParser(Lexer &L, SourceManager &SourceMgr, const TargetInfo *Target, DiagnosticsEngine &Diags, ModuleMap &Map, FileEntryRef ModuleMapFile, DirectoryEntryRef Directory, bool IsSystem)
Definition: ModuleMap.cpp:1588
SourceLocation getLocation()
Definition: ModuleMap.cpp:1602
bool parseModuleMapFile()
Parse a module map file.
Definition: ModuleMap.cpp:3065
A header that is known to reside within a given module, whether it was included or excluded.
Definition: ModuleMap.h:159
bool isAccessibleFrom(Module *M) const
Whether this header is accessible from the specified module.
Definition: ModuleMap.h:185
ModuleHeaderRole getRole() const
The role of this header within the module.
Definition: ModuleMap.h:177
Module * getModule() const
Retrieve the module the header is stored in.
Definition: ModuleMap.h:174
Module * createShadowedModule(StringRef Name, bool IsFramework, Module *ShadowingModule)
Create a new top-level module that is shadowed by ShadowingModule.
Definition: ModuleMap.cpp:1172
bool resolveExports(Module *Mod, bool Complain)
Resolve all of the unresolved exports in the given module.
Definition: ModuleMap.cpp:1394
void addLinkAsDependency(Module *Mod)
Make module to use export_as as the link dependency name if enough information is available or add it...
Definition: ModuleMap.cpp:69
void dump()
Dump the contents of the module map, for debugging purposes.
Definition: ModuleMap.cpp:1372
std::pair< Module *, bool > findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, bool IsExplicit)
Find a new module or submodule, or create it if it does not already exist.
Definition: ModuleMap.cpp:852
void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella directory of the given module to the given directory.
Definition: ModuleMap.cpp:1202
void diagnoseHeaderInclusion(Module *RequestingModule, bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, FileEntryRef File)
Reports errors if a module must not include a specific file.
Definition: ModuleMap.cpp:496
void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap)
Definition: ModuleMap.cpp:1367
OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
Definition: ModuleMap.cpp:1311
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role)
Convert a header role to a kind.
Definition: ModuleMap.cpp:76
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
Definition: ModuleMap.cpp:827
bool mayShadowNewModule(Module *ExistingModule)
Definition: ModuleMap.h:604
KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual=false, bool AllowExcluded=false)
Retrieve the module that owns the given header file, if any.
Definition: ModuleMap.cpp:606
Module * createHeaderUnit(SourceLocation Loc, StringRef Name, Module::Header H)
Create a C++20 header unit.
Definition: ModuleMap.cpp:967
static bool isModular(ModuleHeaderRole Role)
Check if the header with the given role is a modular one.
Definition: ModuleMap.cpp:109
void setInferredModuleAllowedBy(Module *M, OptionalFileEntryRef ModMap)
Definition: ModuleMap.cpp:1328
bool resolveConflicts(Module *Mod, bool Complain)
Resolve all of the unresolved conflicts in the given module.
Definition: ModuleMap.cpp:1421
bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
Definition: ModuleMap.cpp:733
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
Definition: ModuleMap.cpp:1248
module_iterator module_begin() const
Definition: ModuleMap.h:736
ArrayRef< KnownHeader > findResolvedModulesForHeader(FileEntryRef File) const
Like findAllModulesForHeader, but do not attempt to infer module ownership from umbrella headers if w...
Definition: ModuleMap.cpp:720
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module.
Definition: ModuleMap.cpp:1320
bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName, Module *Module) const
Definition: ModuleMap.cpp:420
Module * createModuleForImplementationUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module implementation unit.
Definition: ModuleMap.cpp:943
ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo)
Construct a new module map.
Definition: ModuleMap.cpp:357
std::error_code canonicalizeModuleMapPath(SmallVectorImpl< char > &Path)
Canonicalize Path in a manner suitable for a module map file.
Definition: ModuleMap.cpp:1335
void setUmbrellaHeaderAsWritten(Module *Mod, FileEntryRef UmbrellaHeader, const Twine &NameAsWritten, const Twine &PathRelativeToRootModuleDirectory)
Sets the umbrella header of the given module to the given header.
Definition: ModuleMap.cpp:1187
Module * lookupModuleUnqualified(StringRef Name, Module *Context) const
Retrieve a module with the given name using lexical name lookup, starting at the given context.
Definition: ModuleMap.cpp:835
bool isBuiltinHeader(FileEntryRef File)
Is this a compiler builtin header?
Definition: ModuleMap.cpp:415
module_iterator module_end() const
Definition: ModuleMap.h:737
bool isHeaderInUnavailableModule(FileEntryRef Header) const
Determine whether the given header is part of a module marked 'unavailable'.
Definition: ModuleMap.cpp:729
bool parseModuleMapFile(FileEntryRef File, bool IsSystem, DirectoryEntryRef HomeDir, FileID ID=FileID(), unsigned *Offset=nullptr, SourceLocation ExternModuleLoc=SourceLocation())
Parse the given module map file, and record any modules we encounter.
Definition: ModuleMap.cpp:3109
~ModuleMap()
Destroy the module map.
Definition: ModuleMap.cpp:365
Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent=nullptr)
Create a global module fragment for a C++ module unit.
Definition: ModuleMap.cpp:872
void setTarget(const TargetInfo &Target)
Set the target information.
Definition: ModuleMap.cpp:372
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup.
Definition: ModuleMap.cpp:845
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
Definition: ModuleMap.cpp:58
ModuleHeaderRole
Flags describing the role of a module header.
Definition: ModuleMap.h:127
@ PrivateHeader
This header is included but private.
Definition: ModuleMap.h:132
@ ExcludedHeader
This header is explicitly excluded from the module.
Definition: ModuleMap.h:139
@ NormalHeader
This header is normally included in the module.
Definition: ModuleMap.h:129
@ TextualHeader
This header is part of the module (for layering purposes) but should be textually included.
Definition: ModuleMap.h:136
Module * createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name)
Create a new module for a C++ module interface unit.
Definition: ModuleMap.cpp:925
void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported=false)
Adds this header to the given module.
Definition: ModuleMap.cpp:1283
Module * createPrivateModuleFragmentForInterfaceUnit(Module *Parent, SourceLocation Loc)
Create a global module fragment for a C++ module interface unit.
Definition: ModuleMap.cpp:900
ArrayRef< KnownHeader > findAllModulesForHeader(FileEntryRef File)
Retrieve all the modules that contain the given header file.
Definition: ModuleMap.cpp:708
Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent)
Definition: ModuleMap.cpp:885
Module * createModuleUnitWithKind(SourceLocation Loc, StringRef Name, Module::ModuleKind Kind)
Create a new C++ module with the specified kind, and reparent any pending global module fragment(s) t...
Definition: ModuleMap.cpp:909
static ModuleHeaderRole headerKindToRole(Module::HeaderKind Kind)
Convert a header kind to a role. Requires Kind to not be HK_Excluded.
Definition: ModuleMap.cpp:93
bool resolveUses(Module *Mod, bool Complain)
Resolve all of the unresolved uses in the given module.
Definition: ModuleMap.cpp:1407
Describes a module or submodule.
Definition: Module.h:105
void addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target)
Add the given feature requirement to the list of features required by this module.
Definition: Module.cpp:316
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
Definition: Module.h:414
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
Definition: Module.cpp:160
std::variant< std::monostate, FileEntryRef, DirectoryEntryRef > Umbrella
The umbrella header or directory.
Definition: Module.h:166
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
Definition: Module.h:349
bool directlyUses(const Module *Requested)
Determine whether this module has declared its intention to directly use another module.
Definition: Module.cpp:293
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
Definition: Module.h:471
SourceLocation InferredSubmoduleLoc
The location of the inferred submodule.
Definition: Module.h:397
unsigned IsUnimportable
Whether this module has declared itself unimportable, either because it's missing a requirement from ...
Definition: Module.h:304
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
Definition: Module.cpp:479
SourceLocation DefinitionLoc
The location of the module definition.
Definition: Module.h:111
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system.
Definition: Module.h:285
Module * Parent
The parent of this module.
Definition: Module.h:154
void markUnavailable(bool Unimportable)
Mark this module and all of its submodules as unavailable.
Definition: Module.cpp:328
SmallVector< UnresolvedHeaderDirective, 1 > UnresolvedHeaders
Headers that are mentioned in the module map file but that we have not yet attempted to resolve to a ...
Definition: Module.h:281
@ HK_PrivateTextual
Definition: Module.h:243
bool fullModuleNameIs(ArrayRef< StringRef > nameParts) const
Whether the full name of this module is equal to joining nameParts with "."s.
Definition: Module.cpp:260
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
Definition: Module.h:265
unsigned IsInferred
Whether this is an inferred submodule (module * { ... }).
Definition: Module.h:342
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
Definition: Module.h:332
std::string Name
The name of this module.
Definition: Module.h:108
bool isSubFramework() const
Determine whether this module is a subframework of another framework.
Definition: Module.h:577
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
Definition: Module.h:338
unsigned ModuleMapIsPrivate
Whether this module came from a "private" module map, found next to a regular (public) module map.
Definition: Module.h:377
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used.
Definition: Module.h:463
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
Definition: Module.h:432
std::string UmbrellaRelativeToRootModuleDirectory
Definition: Module.h:175
OptionalDirectoryEntryRef Directory
The build directory of this module.
Definition: Module.h:159
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
Definition: Module.h:438
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
Definition: Module.h:372
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
Definition: Module.h:367
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e....
Definition: Module.h:359
bool isSubModule() const
Determine whether this module is a submodule.
Definition: Module.h:554
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
Definition: Module.h:484
unsigned IsFromModuleFile
Whether this module was loaded from a module file.
Definition: Module.h:319
bool isSubModuleOf(const Module *Other) const
Check if this module is a (possibly transitive) submodule of Other.
Definition: Module.cpp:198
bool isPartOfFramework() const
Determine whether this module is a part of a framework, either because it is a framework module or be...
Definition: Module.h:567
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
Definition: Module.h:528
llvm::PointerIntPair< Module *, 1, bool > ExportDecl
Describes an exported module.
Definition: Module.h:411
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
Definition: Module.h:128
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
Definition: Module.h:146
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
Definition: Module.h:125
@ ModuleHeaderUnit
This is a C++20 header unit.
Definition: Module.h:122
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
Definition: Module.h:141
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
Definition: Module.h:138
unsigned IsFramework
Whether this is a framework module.
Definition: Module.h:323
std::string ExportAsModule
The module through which entities defined in this module will eventually be exposed,...
Definition: Module.h:179
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Definition: Module.cpp:244
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
Definition: Module.h:172
unsigned IsAvailable
Whether this module is available in the current translation unit.
Definition: Module.h:315
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
Definition: Module.h:354
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Definition: Module.h:660
OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const
Get the effective umbrella directory for this module: either the one explicitly written in the module...
Definition: Module.cpp:269
bool UseExportAsModuleLinkName
Autolinking uses the framework name for linking purposes when this is false and the export_as name ot...
Definition: Module.h:467
std::vector< Conflict > Conflicts
The list of conflicts.
Definition: Module.h:496
Parser - This implements a parser for the C family of languages.
Definition: Parser.h:54
Encodes a location in the source.
static SourceLocation getFromRawEncoding(UIntTy Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
FileManager & getFileManager() const
FileID getMainFileID() const
Returns the FileID of the main source file.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
A trivial tuple used to represent a source range.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1760
Exposes information about the current target.
Definition: TargetInfo.h:212
Token - This structure provides full information about a lexed token.
Definition: Token.h:36
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
Definition: Token.h:132
unsigned getLength() const
Definition: Token.h:135
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
Definition: Token.h:99
tok::TokenKind getKind() const
Definition: Token.h:94
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
Definition: Token.h:276
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
Definition: Token.h:303
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
Definition: Token.h:213
Defines the clang::TargetInfo interface.
bool Sub(InterpState &S, CodePtr OpPC)
Definition: Interp.h:318
@ Private
'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel loop', and 'serial loop' constru...
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
Definition: CharInfo.h:62
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
Definition: CharInfo.h:244
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
Definition: CharInfo.h:115
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
unsigned long uint64_t
A token in a module map file.
Definition: ModuleMap.cpp:1443
SourceLocation getLocation() const
Definition: ModuleMap.cpp:1494
uint64_t IntegerValue
Definition: ModuleMap.cpp:1482
const char * StringData
Definition: ModuleMap.cpp:1479
unsigned StringLength
Definition: ModuleMap.cpp:1476
bool is(TokenKind K) const
Definition: ModuleMap.cpp:1492
SourceLocation::UIntTy Location
Definition: ModuleMap.cpp:1475
StringRef getString() const
Definition: ModuleMap.cpp:1502
enum clang::MMToken::TokenKind Kind
uint64_t getInteger() const
Definition: ModuleMap.cpp:1498
A conflict between two modules.
Definition: Module.h:487
Module * Other
The module that this module conflicts with.
Definition: Module.h:489
std::string Message
The message provided to the user when there is a conflict.
Definition: Module.h:492
Information about a header directive as found in the module map file.
Definition: Module.h:250
std::string NameAsWritten
Definition: Module.h:251
FileEntryRef Entry
Definition: Module.h:253
A library or framework to link against when an entity from this module is used.
Definition: Module.h:446
An unresolved conflict with another module.
Definition: Module.h:474
std::string Message
The message provided to the user when there is a conflict.
Definition: Module.h:479
ModuleId Id
The (unresolved) module id.
Definition: Module.h:476
Describes an exported module that has not yet been resolved (perhaps because the module it refers to ...
Definition: Module.h:418
Stored information about a header directive that was found in the module map file but has not been re...
Definition: Module.h:269
std::optional< off_t > Size
Definition: Module.h:275
std::optional< time_t > ModTime
Definition: Module.h:276