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