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