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