1 //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
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 #include "clang/Lex/ModuleMap.h"
15 #include "clang/Basic/CharInfo.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/DiagnosticOptions.h"
18 #include "clang/Basic/FileManager.h"
19 #include "clang/Basic/TargetInfo.h"
20 #include "clang/Basic/TargetOptions.h"
21 #include "clang/Lex/HeaderSearch.h"
22 #include "clang/Lex/HeaderSearchOptions.h"
23 #include "clang/Lex/LexDiagnostic.h"
24 #include "clang/Lex/Lexer.h"
25 #include "clang/Lex/LiteralSupport.h"
26 #include "llvm/ADT/StringRef.h"
27 #include "llvm/ADT/StringSwitch.h"
28 #include "llvm/Support/Allocator.h"
29 #include "llvm/Support/FileSystem.h"
30 #include "llvm/Support/Host.h"
31 #include "llvm/Support/Path.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include <stdlib.h>
34 #if defined(LLVM_ON_UNIX)
35 #include <limits.h>
36 #endif
37 using namespace clang;
38
39 Module::ExportDecl
resolveExport(Module * Mod,const Module::UnresolvedExportDecl & Unresolved,bool Complain) const40 ModuleMap::resolveExport(Module *Mod,
41 const Module::UnresolvedExportDecl &Unresolved,
42 bool Complain) const {
43 // We may have just a wildcard.
44 if (Unresolved.Id.empty()) {
45 assert(Unresolved.Wildcard && "Invalid unresolved export");
46 return Module::ExportDecl(nullptr, true);
47 }
48
49 // Resolve the module-id.
50 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
51 if (!Context)
52 return Module::ExportDecl();
53
54 return Module::ExportDecl(Context, Unresolved.Wildcard);
55 }
56
resolveModuleId(const ModuleId & Id,Module * Mod,bool Complain) const57 Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
58 bool Complain) const {
59 // Find the starting module.
60 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
61 if (!Context) {
62 if (Complain)
63 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
64 << Id[0].first << Mod->getFullModuleName();
65
66 return nullptr;
67 }
68
69 // Dig into the module path.
70 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
71 Module *Sub = lookupModuleQualified(Id[I].first, Context);
72 if (!Sub) {
73 if (Complain)
74 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
75 << Id[I].first << Context->getFullModuleName()
76 << SourceRange(Id[0].second, Id[I-1].second);
77
78 return nullptr;
79 }
80
81 Context = Sub;
82 }
83
84 return Context;
85 }
86
ModuleMap(SourceManager & SourceMgr,DiagnosticsEngine & Diags,const LangOptions & LangOpts,const TargetInfo * Target,HeaderSearch & HeaderInfo)87 ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
88 const LangOptions &LangOpts, const TargetInfo *Target,
89 HeaderSearch &HeaderInfo)
90 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
91 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
92 SourceModule(nullptr), NumCreatedModules(0) {
93 MMapLangOpts.LineComment = true;
94 }
95
~ModuleMap()96 ModuleMap::~ModuleMap() {
97 for (auto &M : Modules)
98 delete M.getValue();
99 }
100
setTarget(const TargetInfo & Target)101 void ModuleMap::setTarget(const TargetInfo &Target) {
102 assert((!this->Target || this->Target == &Target) &&
103 "Improper target override");
104 this->Target = &Target;
105 }
106
107 /// \brief "Sanitize" a filename so that it can be used as an identifier.
sanitizeFilenameAsIdentifier(StringRef Name,SmallVectorImpl<char> & Buffer)108 static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
109 SmallVectorImpl<char> &Buffer) {
110 if (Name.empty())
111 return Name;
112
113 if (!isValidIdentifier(Name)) {
114 // If we don't already have something with the form of an identifier,
115 // create a buffer with the sanitized name.
116 Buffer.clear();
117 if (isDigit(Name[0]))
118 Buffer.push_back('_');
119 Buffer.reserve(Buffer.size() + Name.size());
120 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
121 if (isIdentifierBody(Name[I]))
122 Buffer.push_back(Name[I]);
123 else
124 Buffer.push_back('_');
125 }
126
127 Name = StringRef(Buffer.data(), Buffer.size());
128 }
129
130 while (llvm::StringSwitch<bool>(Name)
131 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
132 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
133 #include "clang/Basic/TokenKinds.def"
134 .Default(false)) {
135 if (Name.data() != Buffer.data())
136 Buffer.append(Name.begin(), Name.end());
137 Buffer.push_back('_');
138 Name = StringRef(Buffer.data(), Buffer.size());
139 }
140
141 return Name;
142 }
143
144 /// \brief Determine whether the given file name is the name of a builtin
145 /// header, supplied by Clang to replace, override, or augment existing system
146 /// headers.
isBuiltinHeader(StringRef FileName)147 static bool isBuiltinHeader(StringRef FileName) {
148 return llvm::StringSwitch<bool>(FileName)
149 .Case("float.h", true)
150 .Case("iso646.h", true)
151 .Case("limits.h", true)
152 .Case("stdalign.h", true)
153 .Case("stdarg.h", true)
154 .Case("stdatomic.h", true)
155 .Case("stdbool.h", true)
156 .Case("stddef.h", true)
157 .Case("stdint.h", true)
158 .Case("tgmath.h", true)
159 .Case("unwind.h", true)
160 .Default(false);
161 }
162
163 ModuleMap::HeadersMap::iterator
findKnownHeader(const FileEntry * File)164 ModuleMap::findKnownHeader(const FileEntry *File) {
165 HeadersMap::iterator Known = Headers.find(File);
166 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
167 Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
168 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
169 HeaderInfo.loadTopLevelSystemModules();
170 return Headers.find(File);
171 }
172 return Known;
173 }
174
175 ModuleMap::KnownHeader
findHeaderInUmbrellaDirs(const FileEntry * File,SmallVectorImpl<const DirectoryEntry * > & IntermediateDirs)176 ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
177 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
178 if (UmbrellaDirs.empty())
179 return KnownHeader();
180
181 const DirectoryEntry *Dir = File->getDir();
182 assert(Dir && "file in no directory");
183
184 // Note: as an egregious but useful hack we use the real path here, because
185 // frameworks moving from top-level frameworks to embedded frameworks tend
186 // to be symlinked from the top-level location to the embedded location,
187 // and we need to resolve lookups as if we had found the embedded location.
188 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
189
190 // Keep walking up the directory hierarchy, looking for a directory with
191 // an umbrella header.
192 do {
193 auto KnownDir = UmbrellaDirs.find(Dir);
194 if (KnownDir != UmbrellaDirs.end())
195 return KnownHeader(KnownDir->second, NormalHeader);
196
197 IntermediateDirs.push_back(Dir);
198
199 // Retrieve our parent path.
200 DirName = llvm::sys::path::parent_path(DirName);
201 if (DirName.empty())
202 break;
203
204 // Resolve the parent path to a directory entry.
205 Dir = SourceMgr.getFileManager().getDirectory(DirName);
206 } while (Dir);
207 return KnownHeader();
208 }
209
violatesPrivateInclude(Module * RequestingModule,const FileEntry * IncFileEnt,ModuleMap::KnownHeader Header)210 static bool violatesPrivateInclude(Module *RequestingModule,
211 const FileEntry *IncFileEnt,
212 ModuleMap::KnownHeader Header) {
213 #ifndef NDEBUG
214 if (Header.getRole() & ModuleMap::PrivateHeader) {
215 // Check for consistency between the module header role
216 // as obtained from the lookup and as obtained from the module.
217 // This check is not cheap, so enable it only for debugging.
218 bool IsPrivate = false;
219 SmallVectorImpl<Module::Header> *HeaderList[] = {
220 &Header.getModule()->Headers[Module::HK_Private],
221 &Header.getModule()->Headers[Module::HK_PrivateTextual]};
222 for (auto *Hs : HeaderList)
223 IsPrivate |=
224 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
225 return H.Entry == IncFileEnt;
226 }) != Hs->end();
227 assert(IsPrivate && "inconsistent headers and roles");
228 }
229 #endif
230 return !Header.isAccessibleFrom(RequestingModule);
231 }
232
getTopLevelOrNull(Module * M)233 static Module *getTopLevelOrNull(Module *M) {
234 return M ? M->getTopLevelModule() : nullptr;
235 }
236
diagnoseHeaderInclusion(Module * RequestingModule,bool RequestingModuleIsModuleInterface,SourceLocation FilenameLoc,StringRef Filename,const FileEntry * File)237 void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
238 bool RequestingModuleIsModuleInterface,
239 SourceLocation FilenameLoc,
240 StringRef Filename,
241 const FileEntry *File) {
242 // No errors for indirect modules. This may be a bit of a problem for modules
243 // with no source files.
244 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
245 return;
246
247 if (RequestingModule)
248 resolveUses(RequestingModule, /*Complain=*/false);
249
250 bool Excluded = false;
251 Module *Private = nullptr;
252 Module *NotUsed = nullptr;
253
254 HeadersMap::iterator Known = findKnownHeader(File);
255 if (Known != Headers.end()) {
256 for (const KnownHeader &Header : Known->second) {
257 // Remember private headers for later printing of a diagnostic.
258 if (violatesPrivateInclude(RequestingModule, File, Header)) {
259 Private = Header.getModule();
260 continue;
261 }
262
263 // If uses need to be specified explicitly, we are only allowed to return
264 // modules that are explicitly used by the requesting module.
265 if (RequestingModule && LangOpts.ModulesDeclUse &&
266 !RequestingModule->directlyUses(Header.getModule())) {
267 NotUsed = Header.getModule();
268 continue;
269 }
270
271 // We have found a module that we can happily use.
272 return;
273 }
274
275 Excluded = true;
276 }
277
278 // We have found a header, but it is private.
279 if (Private) {
280 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
281 << Filename;
282 return;
283 }
284
285 // We have found a module, but we don't use it.
286 if (NotUsed) {
287 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
288 << RequestingModule->getFullModuleName() << Filename;
289 return;
290 }
291
292 if (Excluded || isHeaderInUmbrellaDirs(File))
293 return;
294
295 // At this point, only non-modular includes remain.
296
297 if (LangOpts.ModulesStrictDeclUse) {
298 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
299 << RequestingModule->getFullModuleName() << Filename;
300 } else if (RequestingModule && RequestingModuleIsModuleInterface) {
301 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
302 diag::warn_non_modular_include_in_framework_module :
303 diag::warn_non_modular_include_in_module;
304 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
305 }
306 }
307
isBetterKnownHeader(const ModuleMap::KnownHeader & New,const ModuleMap::KnownHeader & Old)308 static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
309 const ModuleMap::KnownHeader &Old) {
310 // Prefer available modules.
311 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
312 return true;
313
314 // Prefer a public header over a private header.
315 if ((New.getRole() & ModuleMap::PrivateHeader) !=
316 (Old.getRole() & ModuleMap::PrivateHeader))
317 return !(New.getRole() & ModuleMap::PrivateHeader);
318
319 // Prefer a non-textual header over a textual header.
320 if ((New.getRole() & ModuleMap::TextualHeader) !=
321 (Old.getRole() & ModuleMap::TextualHeader))
322 return !(New.getRole() & ModuleMap::TextualHeader);
323
324 // Don't have a reason to choose between these. Just keep the first one.
325 return false;
326 }
327
findModuleForHeader(const FileEntry * File)328 ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
329 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
330 if (R.getRole() & ModuleMap::TextualHeader)
331 return ModuleMap::KnownHeader();
332 return R;
333 };
334
335 HeadersMap::iterator Known = findKnownHeader(File);
336 if (Known != Headers.end()) {
337 ModuleMap::KnownHeader Result;
338 // Iterate over all modules that 'File' is part of to find the best fit.
339 for (KnownHeader &H : Known->second) {
340 // Prefer a header from the source module over all others.
341 if (H.getModule()->getTopLevelModule() == SourceModule)
342 return MakeResult(H);
343 if (!Result || isBetterKnownHeader(H, Result))
344 Result = H;
345 }
346 return MakeResult(Result);
347 }
348
349 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
350 }
351
352 ModuleMap::KnownHeader
findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry * File)353 ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
354 assert(!Headers.count(File) && "already have a module for this header");
355
356 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
357 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
358 if (H) {
359 Module *Result = H.getModule();
360
361 // Search up the module stack until we find a module with an umbrella
362 // directory.
363 Module *UmbrellaModule = Result;
364 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
365 UmbrellaModule = UmbrellaModule->Parent;
366
367 if (UmbrellaModule->InferSubmodules) {
368 const FileEntry *UmbrellaModuleMap =
369 getModuleMapFileForUniquing(UmbrellaModule);
370
371 // Infer submodules for each of the directories we found between
372 // the directory of the umbrella header and the directory where
373 // the actual header is located.
374 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
375
376 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
377 // Find or create the module that corresponds to this directory name.
378 SmallString<32> NameBuf;
379 StringRef Name = sanitizeFilenameAsIdentifier(
380 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
381 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
382 Explicit).first;
383 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
384 Result->IsInferred = true;
385
386 // Associate the module and the directory.
387 UmbrellaDirs[SkippedDirs[I-1]] = Result;
388
389 // If inferred submodules export everything they import, add a
390 // wildcard to the set of exports.
391 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
392 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
393 }
394
395 // Infer a submodule with the same name as this header file.
396 SmallString<32> NameBuf;
397 StringRef Name = sanitizeFilenameAsIdentifier(
398 llvm::sys::path::stem(File->getName()), NameBuf);
399 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
400 Explicit).first;
401 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
402 Result->IsInferred = true;
403 Result->addTopHeader(File);
404
405 // If inferred submodules export everything they import, add a
406 // wildcard to the set of exports.
407 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
408 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
409 } else {
410 // Record each of the directories we stepped through as being part of
411 // the module we found, since the umbrella header covers them all.
412 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
413 UmbrellaDirs[SkippedDirs[I]] = Result;
414 }
415
416 KnownHeader Header(Result, NormalHeader);
417 Headers[File].push_back(Header);
418 return Header;
419 }
420
421 return KnownHeader();
422 }
423
424 ArrayRef<ModuleMap::KnownHeader>
findAllModulesForHeader(const FileEntry * File) const425 ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
426 auto It = Headers.find(File);
427 if (It == Headers.end())
428 return None;
429 return It->second;
430 }
431
isHeaderInUnavailableModule(const FileEntry * Header) const432 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
433 return isHeaderUnavailableInModule(Header, nullptr);
434 }
435
436 bool
isHeaderUnavailableInModule(const FileEntry * Header,const Module * RequestingModule) const437 ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
438 const Module *RequestingModule) const {
439 HeadersMap::const_iterator Known = Headers.find(Header);
440 if (Known != Headers.end()) {
441 for (SmallVectorImpl<KnownHeader>::const_iterator
442 I = Known->second.begin(),
443 E = Known->second.end();
444 I != E; ++I) {
445 if (I->isAvailable() && (!RequestingModule ||
446 I->getModule()->isSubModuleOf(RequestingModule)))
447 return false;
448 }
449 return true;
450 }
451
452 const DirectoryEntry *Dir = Header->getDir();
453 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
454 StringRef DirName = Dir->getName();
455
456 auto IsUnavailable = [&](const Module *M) {
457 return !M->isAvailable() && (!RequestingModule ||
458 M->isSubModuleOf(RequestingModule));
459 };
460
461 // Keep walking up the directory hierarchy, looking for a directory with
462 // an umbrella header.
463 do {
464 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
465 = UmbrellaDirs.find(Dir);
466 if (KnownDir != UmbrellaDirs.end()) {
467 Module *Found = KnownDir->second;
468 if (IsUnavailable(Found))
469 return true;
470
471 // Search up the module stack until we find a module with an umbrella
472 // directory.
473 Module *UmbrellaModule = Found;
474 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
475 UmbrellaModule = UmbrellaModule->Parent;
476
477 if (UmbrellaModule->InferSubmodules) {
478 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
479 // Find or create the module that corresponds to this directory name.
480 SmallString<32> NameBuf;
481 StringRef Name = sanitizeFilenameAsIdentifier(
482 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
483 NameBuf);
484 Found = lookupModuleQualified(Name, Found);
485 if (!Found)
486 return false;
487 if (IsUnavailable(Found))
488 return true;
489 }
490
491 // Infer a submodule with the same name as this header file.
492 SmallString<32> NameBuf;
493 StringRef Name = sanitizeFilenameAsIdentifier(
494 llvm::sys::path::stem(Header->getName()),
495 NameBuf);
496 Found = lookupModuleQualified(Name, Found);
497 if (!Found)
498 return false;
499 }
500
501 return IsUnavailable(Found);
502 }
503
504 SkippedDirs.push_back(Dir);
505
506 // Retrieve our parent path.
507 DirName = llvm::sys::path::parent_path(DirName);
508 if (DirName.empty())
509 break;
510
511 // Resolve the parent path to a directory entry.
512 Dir = SourceMgr.getFileManager().getDirectory(DirName);
513 } while (Dir);
514
515 return false;
516 }
517
findModule(StringRef Name) const518 Module *ModuleMap::findModule(StringRef Name) const {
519 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
520 if (Known != Modules.end())
521 return Known->getValue();
522
523 return nullptr;
524 }
525
lookupModuleUnqualified(StringRef Name,Module * Context) const526 Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
527 Module *Context) const {
528 for(; Context; Context = Context->Parent) {
529 if (Module *Sub = lookupModuleQualified(Name, Context))
530 return Sub;
531 }
532
533 return findModule(Name);
534 }
535
lookupModuleQualified(StringRef Name,Module * Context) const536 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
537 if (!Context)
538 return findModule(Name);
539
540 return Context->findSubmodule(Name);
541 }
542
543 std::pair<Module *, bool>
findOrCreateModule(StringRef Name,Module * Parent,bool IsFramework,bool IsExplicit)544 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
545 bool IsExplicit) {
546 // Try to find an existing module with this name.
547 if (Module *Sub = lookupModuleQualified(Name, Parent))
548 return std::make_pair(Sub, false);
549
550 // Create a new module with this name.
551 Module *Result = new Module(Name, SourceLocation(), Parent,
552 IsFramework, IsExplicit, NumCreatedModules++);
553 if (!Parent) {
554 if (LangOpts.CurrentModule == Name)
555 SourceModule = Result;
556 Modules[Name] = Result;
557 }
558 return std::make_pair(Result, true);
559 }
560
561 /// \brief For a framework module, infer the framework against which we
562 /// should link.
inferFrameworkLink(Module * Mod,const DirectoryEntry * FrameworkDir,FileManager & FileMgr)563 static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
564 FileManager &FileMgr) {
565 assert(Mod->IsFramework && "Can only infer linking for framework modules");
566 assert(!Mod->isSubFramework() &&
567 "Can only infer linking for top-level frameworks");
568
569 SmallString<128> LibName;
570 LibName += FrameworkDir->getName();
571 llvm::sys::path::append(LibName, Mod->Name);
572
573 // The library name of a framework has more than one possible extension since
574 // the introduction of the text-based dynamic library format. We need to check
575 // for both before we give up.
576 static const char *frameworkExtensions[] = {"", ".tbd"};
577 for (const auto *extension : frameworkExtensions) {
578 llvm::sys::path::replace_extension(LibName, extension);
579 if (FileMgr.getFile(LibName)) {
580 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
581 /*IsFramework=*/true));
582 return;
583 }
584 }
585 }
586
inferFrameworkModule(const DirectoryEntry * FrameworkDir,bool IsSystem,Module * Parent)587 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
588 bool IsSystem, Module *Parent) {
589 Attributes Attrs;
590 Attrs.IsSystem = IsSystem;
591 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
592 }
593
inferFrameworkModule(const DirectoryEntry * FrameworkDir,Attributes Attrs,Module * Parent)594 Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
595 Attributes Attrs, Module *Parent) {
596 // Note: as an egregious but useful hack we use the real path here, because
597 // we might be looking at an embedded framework that symlinks out to a
598 // top-level framework, and we need to infer as if we were naming the
599 // top-level framework.
600 StringRef FrameworkDirName =
601 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
602
603 // In case this is a case-insensitive filesystem, use the canonical
604 // directory name as the ModuleName, since modules are case-sensitive.
605 // FIXME: we should be able to give a fix-it hint for the correct spelling.
606 SmallString<32> ModuleNameStorage;
607 StringRef ModuleName = sanitizeFilenameAsIdentifier(
608 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
609
610 // Check whether we've already found this module.
611 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
612 return Mod;
613
614 FileManager &FileMgr = SourceMgr.getFileManager();
615
616 // If the framework has a parent path from which we're allowed to infer
617 // a framework module, do so.
618 const FileEntry *ModuleMapFile = nullptr;
619 if (!Parent) {
620 // Determine whether we're allowed to infer a module map.
621 bool canInfer = false;
622 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
623 // Figure out the parent path.
624 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
625 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
626 // Check whether we have already looked into the parent directory
627 // for a module map.
628 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
629 inferred = InferredDirectories.find(ParentDir);
630 if (inferred == InferredDirectories.end()) {
631 // We haven't looked here before. Load a module map, if there is
632 // one.
633 bool IsFrameworkDir = Parent.endswith(".framework");
634 if (const FileEntry *ModMapFile =
635 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
636 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
637 inferred = InferredDirectories.find(ParentDir);
638 }
639
640 if (inferred == InferredDirectories.end())
641 inferred = InferredDirectories.insert(
642 std::make_pair(ParentDir, InferredDirectory())).first;
643 }
644
645 if (inferred->second.InferModules) {
646 // We're allowed to infer for this directory, but make sure it's okay
647 // to infer this particular module.
648 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
649 canInfer = std::find(inferred->second.ExcludedModules.begin(),
650 inferred->second.ExcludedModules.end(),
651 Name) == inferred->second.ExcludedModules.end();
652
653 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
654 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
655 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
656 ModuleMapFile = inferred->second.ModuleMapFile;
657 }
658 }
659 }
660
661 // If we're not allowed to infer a framework module, don't.
662 if (!canInfer)
663 return nullptr;
664 } else
665 ModuleMapFile = getModuleMapFileForUniquing(Parent);
666
667
668 // Look for an umbrella header.
669 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
670 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
671 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
672
673 // FIXME: If there's no umbrella header, we could probably scan the
674 // framework to load *everything*. But, it's not clear that this is a good
675 // idea.
676 if (!UmbrellaHeader)
677 return nullptr;
678
679 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
680 /*IsFramework=*/true, /*IsExplicit=*/false,
681 NumCreatedModules++);
682 InferredModuleAllowedBy[Result] = ModuleMapFile;
683 Result->IsInferred = true;
684 if (!Parent) {
685 if (LangOpts.CurrentModule == ModuleName)
686 SourceModule = Result;
687 Modules[ModuleName] = Result;
688 }
689
690 Result->IsSystem |= Attrs.IsSystem;
691 Result->IsExternC |= Attrs.IsExternC;
692 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
693 Result->Directory = FrameworkDir;
694
695 // umbrella header "umbrella-header-name"
696 //
697 // The "Headers/" component of the name is implied because this is
698 // a framework module.
699 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
700
701 // export *
702 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
703
704 // module * { export * }
705 Result->InferSubmodules = true;
706 Result->InferExportWildcard = true;
707
708 // Look for subframeworks.
709 std::error_code EC;
710 SmallString<128> SubframeworksDirName
711 = StringRef(FrameworkDir->getName());
712 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
713 llvm::sys::path::native(SubframeworksDirName);
714 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
715 for (vfs::directory_iterator Dir = FS.dir_begin(SubframeworksDirName, EC),
716 DirEnd;
717 Dir != DirEnd && !EC; Dir.increment(EC)) {
718 if (!StringRef(Dir->getName()).endswith(".framework"))
719 continue;
720
721 if (const DirectoryEntry *SubframeworkDir =
722 FileMgr.getDirectory(Dir->getName())) {
723 // Note: as an egregious but useful hack, we use the real path here and
724 // check whether it is actually a subdirectory of the parent directory.
725 // This will not be the case if the 'subframework' is actually a symlink
726 // out to a top-level framework.
727 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
728 bool FoundParent = false;
729 do {
730 // Get the parent directory name.
731 SubframeworkDirName
732 = llvm::sys::path::parent_path(SubframeworkDirName);
733 if (SubframeworkDirName.empty())
734 break;
735
736 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
737 FoundParent = true;
738 break;
739 }
740 } while (true);
741
742 if (!FoundParent)
743 continue;
744
745 // FIXME: Do we want to warn about subframeworks without umbrella headers?
746 inferFrameworkModule(SubframeworkDir, Attrs, Result);
747 }
748 }
749
750 // If the module is a top-level framework, automatically link against the
751 // framework.
752 if (!Result->isSubFramework()) {
753 inferFrameworkLink(Result, FrameworkDir, FileMgr);
754 }
755
756 return Result;
757 }
758
setUmbrellaHeader(Module * Mod,const FileEntry * UmbrellaHeader,Twine NameAsWritten)759 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
760 Twine NameAsWritten) {
761 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
762 Mod->Umbrella = UmbrellaHeader;
763 Mod->UmbrellaAsWritten = NameAsWritten.str();
764 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
765
766 // Notify callbacks that we just added a new header.
767 for (const auto &Cb : Callbacks)
768 Cb->moduleMapAddUmbrellaHeader(&SourceMgr.getFileManager(), UmbrellaHeader);
769 }
770
setUmbrellaDir(Module * Mod,const DirectoryEntry * UmbrellaDir,Twine NameAsWritten)771 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
772 Twine NameAsWritten) {
773 Mod->Umbrella = UmbrellaDir;
774 Mod->UmbrellaAsWritten = NameAsWritten.str();
775 UmbrellaDirs[UmbrellaDir] = Mod;
776 }
777
headerRoleToKind(ModuleMap::ModuleHeaderRole Role)778 static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
779 switch ((int)Role) {
780 default: llvm_unreachable("unknown header role");
781 case ModuleMap::NormalHeader:
782 return Module::HK_Normal;
783 case ModuleMap::PrivateHeader:
784 return Module::HK_Private;
785 case ModuleMap::TextualHeader:
786 return Module::HK_Textual;
787 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
788 return Module::HK_PrivateTextual;
789 }
790 }
791
addHeader(Module * Mod,Module::Header Header,ModuleHeaderRole Role,bool Imported)792 void ModuleMap::addHeader(Module *Mod, Module::Header Header,
793 ModuleHeaderRole Role, bool Imported) {
794 KnownHeader KH(Mod, Role);
795
796 // Only add each header to the headers list once.
797 // FIXME: Should we diagnose if a header is listed twice in the
798 // same module definition?
799 auto &HeaderList = Headers[Header.Entry];
800 for (auto H : HeaderList)
801 if (H == KH)
802 return;
803
804 HeaderList.push_back(KH);
805 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
806
807 bool isCompilingModuleHeader =
808 LangOpts.CompilingModule && Mod->getTopLevelModule() == SourceModule;
809 if (!Imported || isCompilingModuleHeader) {
810 // When we import HeaderFileInfo, the external source is expected to
811 // set the isModuleHeader flag itself.
812 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
813 isCompilingModuleHeader);
814 }
815
816 // Notify callbacks that we just added a new header.
817 for (const auto &Cb : Callbacks)
818 Cb->moduleMapAddHeader(Header.Entry->getName());
819 }
820
excludeHeader(Module * Mod,Module::Header Header)821 void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
822 // Add this as a known header so we won't implicitly add it to any
823 // umbrella directory module.
824 // FIXME: Should we only exclude it from umbrella modules within the
825 // specified module?
826 (void) Headers[Header.Entry];
827
828 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
829 }
830
831 const FileEntry *
getContainingModuleMapFile(const Module * Module) const832 ModuleMap::getContainingModuleMapFile(const Module *Module) const {
833 if (Module->DefinitionLoc.isInvalid())
834 return nullptr;
835
836 return SourceMgr.getFileEntryForID(
837 SourceMgr.getFileID(Module->DefinitionLoc));
838 }
839
getModuleMapFileForUniquing(const Module * M) const840 const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
841 if (M->IsInferred) {
842 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
843 return InferredModuleAllowedBy.find(M)->second;
844 }
845 return getContainingModuleMapFile(M);
846 }
847
setInferredModuleAllowedBy(Module * M,const FileEntry * ModMap)848 void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
849 assert(M->IsInferred && "module not inferred");
850 InferredModuleAllowedBy[M] = ModMap;
851 }
852
dump()853 LLVM_DUMP_METHOD void ModuleMap::dump() {
854 llvm::errs() << "Modules:";
855 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
856 MEnd = Modules.end();
857 M != MEnd; ++M)
858 M->getValue()->print(llvm::errs(), 2);
859
860 llvm::errs() << "Headers:";
861 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
862 H != HEnd; ++H) {
863 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
864 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
865 E = H->second.end();
866 I != E; ++I) {
867 if (I != H->second.begin())
868 llvm::errs() << ",";
869 llvm::errs() << I->getModule()->getFullModuleName();
870 }
871 llvm::errs() << "\n";
872 }
873 }
874
resolveExports(Module * Mod,bool Complain)875 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
876 auto Unresolved = std::move(Mod->UnresolvedExports);
877 Mod->UnresolvedExports.clear();
878 for (auto &UE : Unresolved) {
879 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
880 if (Export.getPointer() || Export.getInt())
881 Mod->Exports.push_back(Export);
882 else
883 Mod->UnresolvedExports.push_back(UE);
884 }
885 return !Mod->UnresolvedExports.empty();
886 }
887
resolveUses(Module * Mod,bool Complain)888 bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
889 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
890 Mod->UnresolvedDirectUses.clear();
891 for (auto &UDU : Unresolved) {
892 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
893 if (DirectUse)
894 Mod->DirectUses.push_back(DirectUse);
895 else
896 Mod->UnresolvedDirectUses.push_back(UDU);
897 }
898 return !Mod->UnresolvedDirectUses.empty();
899 }
900
resolveConflicts(Module * Mod,bool Complain)901 bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
902 auto Unresolved = std::move(Mod->UnresolvedConflicts);
903 Mod->UnresolvedConflicts.clear();
904 for (auto &UC : Unresolved) {
905 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
906 Module::Conflict Conflict;
907 Conflict.Other = OtherMod;
908 Conflict.Message = UC.Message;
909 Mod->Conflicts.push_back(Conflict);
910 } else
911 Mod->UnresolvedConflicts.push_back(UC);
912 }
913 return !Mod->UnresolvedConflicts.empty();
914 }
915
inferModuleFromLocation(FullSourceLoc Loc)916 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
917 if (Loc.isInvalid())
918 return nullptr;
919
920 if (UmbrellaDirs.empty() && Headers.empty())
921 return nullptr;
922
923 // Use the expansion location to determine which module we're in.
924 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
925 if (!ExpansionLoc.isFileID())
926 return nullptr;
927
928 const SourceManager &SrcMgr = Loc.getManager();
929 FileID ExpansionFileID = ExpansionLoc.getFileID();
930
931 while (const FileEntry *ExpansionFile
932 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
933 // Find the module that owns this header (if any).
934 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
935 return Mod;
936
937 // No module owns this header, so look up the inclusion chain to see if
938 // any included header has an associated module.
939 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
940 if (IncludeLoc.isInvalid())
941 return nullptr;
942
943 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
944 }
945
946 return nullptr;
947 }
948
949 //----------------------------------------------------------------------------//
950 // Module map file parser
951 //----------------------------------------------------------------------------//
952
953 namespace clang {
954 /// \brief A token in a module map file.
955 struct MMToken {
956 enum TokenKind {
957 Comma,
958 ConfigMacros,
959 Conflict,
960 EndOfFile,
961 HeaderKeyword,
962 Identifier,
963 Exclaim,
964 ExcludeKeyword,
965 ExplicitKeyword,
966 ExportKeyword,
967 ExternKeyword,
968 FrameworkKeyword,
969 LinkKeyword,
970 ModuleKeyword,
971 Period,
972 PrivateKeyword,
973 UmbrellaKeyword,
974 UseKeyword,
975 RequiresKeyword,
976 Star,
977 StringLiteral,
978 TextualKeyword,
979 LBrace,
980 RBrace,
981 LSquare,
982 RSquare
983 } Kind;
984
985 unsigned Location;
986 unsigned StringLength;
987 const char *StringData;
988
clearclang::MMToken989 void clear() {
990 Kind = EndOfFile;
991 Location = 0;
992 StringLength = 0;
993 StringData = nullptr;
994 }
995
isclang::MMToken996 bool is(TokenKind K) const { return Kind == K; }
997
getLocationclang::MMToken998 SourceLocation getLocation() const {
999 return SourceLocation::getFromRawEncoding(Location);
1000 }
1001
getStringclang::MMToken1002 StringRef getString() const {
1003 return StringRef(StringData, StringLength);
1004 }
1005 };
1006
1007 class ModuleMapParser {
1008 Lexer &L;
1009 SourceManager &SourceMgr;
1010
1011 /// \brief Default target information, used only for string literal
1012 /// parsing.
1013 const TargetInfo *Target;
1014
1015 DiagnosticsEngine &Diags;
1016 ModuleMap ⤅
1017
1018 /// \brief The current module map file.
1019 const FileEntry *ModuleMapFile;
1020
1021 /// \brief The directory that file names in this module map file should
1022 /// be resolved relative to.
1023 const DirectoryEntry *Directory;
1024
1025 /// \brief The directory containing Clang-supplied headers.
1026 const DirectoryEntry *BuiltinIncludeDir;
1027
1028 /// \brief Whether this module map is in a system header directory.
1029 bool IsSystem;
1030
1031 /// \brief Whether an error occurred.
1032 bool HadError;
1033
1034 /// \brief Stores string data for the various string literals referenced
1035 /// during parsing.
1036 llvm::BumpPtrAllocator StringData;
1037
1038 /// \brief The current token.
1039 MMToken Tok;
1040
1041 /// \brief The active module.
1042 Module *ActiveModule;
1043
1044 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1045 /// contents as 'textual'.
1046 ///
1047 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1048 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1049 /// non-modular headers. For backwards compatibility, we continue to
1050 /// support this idiom for just these modules, and map the headers to
1051 /// 'textual' to match the original intent.
1052 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1053
1054 /// \brief Consume the current token and return its location.
1055 SourceLocation consumeToken();
1056
1057 /// \brief Skip tokens until we reach the a token with the given kind
1058 /// (or the end of the file).
1059 void skipUntil(MMToken::TokenKind K);
1060
1061 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
1062 bool parseModuleId(ModuleId &Id);
1063 void parseModuleDecl();
1064 void parseExternModuleDecl();
1065 void parseRequiresDecl();
1066 void parseHeaderDecl(clang::MMToken::TokenKind,
1067 SourceLocation LeadingLoc);
1068 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
1069 void parseExportDecl();
1070 void parseUseDecl();
1071 void parseLinkDecl();
1072 void parseConfigMacros();
1073 void parseConflict();
1074 void parseInferredModuleDecl(bool Framework, bool Explicit);
1075
1076 typedef ModuleMap::Attributes Attributes;
1077 bool parseOptionalAttributes(Attributes &Attrs);
1078
1079 public:
ModuleMapParser(Lexer & L,SourceManager & SourceMgr,const TargetInfo * Target,DiagnosticsEngine & Diags,ModuleMap & Map,const FileEntry * ModuleMapFile,const DirectoryEntry * Directory,const DirectoryEntry * BuiltinIncludeDir,bool IsSystem)1080 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
1081 const TargetInfo *Target,
1082 DiagnosticsEngine &Diags,
1083 ModuleMap &Map,
1084 const FileEntry *ModuleMapFile,
1085 const DirectoryEntry *Directory,
1086 const DirectoryEntry *BuiltinIncludeDir,
1087 bool IsSystem)
1088 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
1089 ModuleMapFile(ModuleMapFile), Directory(Directory),
1090 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
1091 HadError(false), ActiveModule(nullptr)
1092 {
1093 Tok.clear();
1094 consumeToken();
1095 }
1096
1097 bool parseModuleMapFile();
1098 };
1099 }
1100
consumeToken()1101 SourceLocation ModuleMapParser::consumeToken() {
1102 retry:
1103 SourceLocation Result = Tok.getLocation();
1104 Tok.clear();
1105
1106 Token LToken;
1107 L.LexFromRawLexer(LToken);
1108 Tok.Location = LToken.getLocation().getRawEncoding();
1109 switch (LToken.getKind()) {
1110 case tok::raw_identifier: {
1111 StringRef RI = LToken.getRawIdentifier();
1112 Tok.StringData = RI.data();
1113 Tok.StringLength = RI.size();
1114 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
1115 .Case("config_macros", MMToken::ConfigMacros)
1116 .Case("conflict", MMToken::Conflict)
1117 .Case("exclude", MMToken::ExcludeKeyword)
1118 .Case("explicit", MMToken::ExplicitKeyword)
1119 .Case("export", MMToken::ExportKeyword)
1120 .Case("extern", MMToken::ExternKeyword)
1121 .Case("framework", MMToken::FrameworkKeyword)
1122 .Case("header", MMToken::HeaderKeyword)
1123 .Case("link", MMToken::LinkKeyword)
1124 .Case("module", MMToken::ModuleKeyword)
1125 .Case("private", MMToken::PrivateKeyword)
1126 .Case("requires", MMToken::RequiresKeyword)
1127 .Case("textual", MMToken::TextualKeyword)
1128 .Case("umbrella", MMToken::UmbrellaKeyword)
1129 .Case("use", MMToken::UseKeyword)
1130 .Default(MMToken::Identifier);
1131 break;
1132 }
1133
1134 case tok::comma:
1135 Tok.Kind = MMToken::Comma;
1136 break;
1137
1138 case tok::eof:
1139 Tok.Kind = MMToken::EndOfFile;
1140 break;
1141
1142 case tok::l_brace:
1143 Tok.Kind = MMToken::LBrace;
1144 break;
1145
1146 case tok::l_square:
1147 Tok.Kind = MMToken::LSquare;
1148 break;
1149
1150 case tok::period:
1151 Tok.Kind = MMToken::Period;
1152 break;
1153
1154 case tok::r_brace:
1155 Tok.Kind = MMToken::RBrace;
1156 break;
1157
1158 case tok::r_square:
1159 Tok.Kind = MMToken::RSquare;
1160 break;
1161
1162 case tok::star:
1163 Tok.Kind = MMToken::Star;
1164 break;
1165
1166 case tok::exclaim:
1167 Tok.Kind = MMToken::Exclaim;
1168 break;
1169
1170 case tok::string_literal: {
1171 if (LToken.hasUDSuffix()) {
1172 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1173 HadError = true;
1174 goto retry;
1175 }
1176
1177 // Parse the string literal.
1178 LangOptions LangOpts;
1179 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
1180 if (StringLiteral.hadError)
1181 goto retry;
1182
1183 // Copy the string literal into our string data allocator.
1184 unsigned Length = StringLiteral.GetStringLength();
1185 char *Saved = StringData.Allocate<char>(Length + 1);
1186 memcpy(Saved, StringLiteral.GetString().data(), Length);
1187 Saved[Length] = 0;
1188
1189 // Form the token.
1190 Tok.Kind = MMToken::StringLiteral;
1191 Tok.StringData = Saved;
1192 Tok.StringLength = Length;
1193 break;
1194 }
1195
1196 case tok::comment:
1197 goto retry;
1198
1199 default:
1200 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1201 HadError = true;
1202 goto retry;
1203 }
1204
1205 return Result;
1206 }
1207
skipUntil(MMToken::TokenKind K)1208 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1209 unsigned braceDepth = 0;
1210 unsigned squareDepth = 0;
1211 do {
1212 switch (Tok.Kind) {
1213 case MMToken::EndOfFile:
1214 return;
1215
1216 case MMToken::LBrace:
1217 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1218 return;
1219
1220 ++braceDepth;
1221 break;
1222
1223 case MMToken::LSquare:
1224 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1225 return;
1226
1227 ++squareDepth;
1228 break;
1229
1230 case MMToken::RBrace:
1231 if (braceDepth > 0)
1232 --braceDepth;
1233 else if (Tok.is(K))
1234 return;
1235 break;
1236
1237 case MMToken::RSquare:
1238 if (squareDepth > 0)
1239 --squareDepth;
1240 else if (Tok.is(K))
1241 return;
1242 break;
1243
1244 default:
1245 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1246 return;
1247 break;
1248 }
1249
1250 consumeToken();
1251 } while (true);
1252 }
1253
1254 /// \brief Parse a module-id.
1255 ///
1256 /// module-id:
1257 /// identifier
1258 /// identifier '.' module-id
1259 ///
1260 /// \returns true if an error occurred, false otherwise.
parseModuleId(ModuleId & Id)1261 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1262 Id.clear();
1263 do {
1264 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
1265 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1266 consumeToken();
1267 } else {
1268 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1269 return true;
1270 }
1271
1272 if (!Tok.is(MMToken::Period))
1273 break;
1274
1275 consumeToken();
1276 } while (true);
1277
1278 return false;
1279 }
1280
1281 namespace {
1282 /// \brief Enumerates the known attributes.
1283 enum AttributeKind {
1284 /// \brief An unknown attribute.
1285 AT_unknown,
1286 /// \brief The 'system' attribute.
1287 AT_system,
1288 /// \brief The 'extern_c' attribute.
1289 AT_extern_c,
1290 /// \brief The 'exhaustive' attribute.
1291 AT_exhaustive
1292 };
1293 }
1294
1295 /// \brief Parse a module declaration.
1296 ///
1297 /// module-declaration:
1298 /// 'extern' 'module' module-id string-literal
1299 /// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1300 /// { module-member* }
1301 ///
1302 /// module-member:
1303 /// requires-declaration
1304 /// header-declaration
1305 /// submodule-declaration
1306 /// export-declaration
1307 /// link-declaration
1308 ///
1309 /// submodule-declaration:
1310 /// module-declaration
1311 /// inferred-submodule-declaration
parseModuleDecl()1312 void ModuleMapParser::parseModuleDecl() {
1313 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1314 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1315 if (Tok.is(MMToken::ExternKeyword)) {
1316 parseExternModuleDecl();
1317 return;
1318 }
1319
1320 // Parse 'explicit' or 'framework' keyword, if present.
1321 SourceLocation ExplicitLoc;
1322 bool Explicit = false;
1323 bool Framework = false;
1324
1325 // Parse 'explicit' keyword, if present.
1326 if (Tok.is(MMToken::ExplicitKeyword)) {
1327 ExplicitLoc = consumeToken();
1328 Explicit = true;
1329 }
1330
1331 // Parse 'framework' keyword, if present.
1332 if (Tok.is(MMToken::FrameworkKeyword)) {
1333 consumeToken();
1334 Framework = true;
1335 }
1336
1337 // Parse 'module' keyword.
1338 if (!Tok.is(MMToken::ModuleKeyword)) {
1339 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1340 consumeToken();
1341 HadError = true;
1342 return;
1343 }
1344 consumeToken(); // 'module' keyword
1345
1346 // If we have a wildcard for the module name, this is an inferred submodule.
1347 // Parse it.
1348 if (Tok.is(MMToken::Star))
1349 return parseInferredModuleDecl(Framework, Explicit);
1350
1351 // Parse the module name.
1352 ModuleId Id;
1353 if (parseModuleId(Id)) {
1354 HadError = true;
1355 return;
1356 }
1357
1358 if (ActiveModule) {
1359 if (Id.size() > 1) {
1360 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1361 << SourceRange(Id.front().second, Id.back().second);
1362
1363 HadError = true;
1364 return;
1365 }
1366 } else if (Id.size() == 1 && Explicit) {
1367 // Top-level modules can't be explicit.
1368 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1369 Explicit = false;
1370 ExplicitLoc = SourceLocation();
1371 HadError = true;
1372 }
1373
1374 Module *PreviousActiveModule = ActiveModule;
1375 if (Id.size() > 1) {
1376 // This module map defines a submodule. Go find the module of which it
1377 // is a submodule.
1378 ActiveModule = nullptr;
1379 const Module *TopLevelModule = nullptr;
1380 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1381 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1382 if (I == 0)
1383 TopLevelModule = Next;
1384 ActiveModule = Next;
1385 continue;
1386 }
1387
1388 if (ActiveModule) {
1389 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1390 << Id[I].first
1391 << ActiveModule->getTopLevelModule()->getFullModuleName();
1392 } else {
1393 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1394 }
1395 HadError = true;
1396 return;
1397 }
1398
1399 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1400 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1401 "submodule defined in same file as 'module *' that allowed its "
1402 "top-level module");
1403 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1404 }
1405 }
1406
1407 StringRef ModuleName = Id.back().first;
1408 SourceLocation ModuleNameLoc = Id.back().second;
1409
1410 // Parse the optional attribute list.
1411 Attributes Attrs;
1412 if (parseOptionalAttributes(Attrs))
1413 return;
1414
1415
1416 // Parse the opening brace.
1417 if (!Tok.is(MMToken::LBrace)) {
1418 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1419 << ModuleName;
1420 HadError = true;
1421 return;
1422 }
1423 SourceLocation LBraceLoc = consumeToken();
1424
1425 // Determine whether this (sub)module has already been defined.
1426 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1427 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1428 // Skip the module definition.
1429 skipUntil(MMToken::RBrace);
1430 if (Tok.is(MMToken::RBrace))
1431 consumeToken();
1432 else {
1433 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1434 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1435 HadError = true;
1436 }
1437 return;
1438 }
1439
1440 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1441 << ModuleName;
1442 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1443
1444 // Skip the module definition.
1445 skipUntil(MMToken::RBrace);
1446 if (Tok.is(MMToken::RBrace))
1447 consumeToken();
1448
1449 HadError = true;
1450 return;
1451 }
1452
1453 // Start defining this module.
1454 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1455 Explicit).first;
1456 ActiveModule->DefinitionLoc = ModuleNameLoc;
1457 if (Attrs.IsSystem || IsSystem)
1458 ActiveModule->IsSystem = true;
1459 if (Attrs.IsExternC)
1460 ActiveModule->IsExternC = true;
1461 ActiveModule->Directory = Directory;
1462
1463 bool Done = false;
1464 do {
1465 switch (Tok.Kind) {
1466 case MMToken::EndOfFile:
1467 case MMToken::RBrace:
1468 Done = true;
1469 break;
1470
1471 case MMToken::ConfigMacros:
1472 parseConfigMacros();
1473 break;
1474
1475 case MMToken::Conflict:
1476 parseConflict();
1477 break;
1478
1479 case MMToken::ExplicitKeyword:
1480 case MMToken::ExternKeyword:
1481 case MMToken::FrameworkKeyword:
1482 case MMToken::ModuleKeyword:
1483 parseModuleDecl();
1484 break;
1485
1486 case MMToken::ExportKeyword:
1487 parseExportDecl();
1488 break;
1489
1490 case MMToken::UseKeyword:
1491 parseUseDecl();
1492 break;
1493
1494 case MMToken::RequiresKeyword:
1495 parseRequiresDecl();
1496 break;
1497
1498 case MMToken::TextualKeyword:
1499 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
1500 break;
1501
1502 case MMToken::UmbrellaKeyword: {
1503 SourceLocation UmbrellaLoc = consumeToken();
1504 if (Tok.is(MMToken::HeaderKeyword))
1505 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
1506 else
1507 parseUmbrellaDirDecl(UmbrellaLoc);
1508 break;
1509 }
1510
1511 case MMToken::ExcludeKeyword:
1512 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
1513 break;
1514
1515 case MMToken::PrivateKeyword:
1516 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
1517 break;
1518
1519 case MMToken::HeaderKeyword:
1520 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
1521 break;
1522
1523 case MMToken::LinkKeyword:
1524 parseLinkDecl();
1525 break;
1526
1527 default:
1528 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1529 consumeToken();
1530 break;
1531 }
1532 } while (!Done);
1533
1534 if (Tok.is(MMToken::RBrace))
1535 consumeToken();
1536 else {
1537 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1538 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1539 HadError = true;
1540 }
1541
1542 // If the active module is a top-level framework, and there are no link
1543 // libraries, automatically link against the framework.
1544 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1545 ActiveModule->LinkLibraries.empty()) {
1546 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1547 }
1548
1549 // If the module meets all requirements but is still unavailable, mark the
1550 // whole tree as unavailable to prevent it from building.
1551 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1552 ActiveModule->Parent) {
1553 ActiveModule->getTopLevelModule()->markUnavailable();
1554 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1555 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1556 }
1557
1558 // We're done parsing this module. Pop back to the previous module.
1559 ActiveModule = PreviousActiveModule;
1560 }
1561
1562 /// \brief Parse an extern module declaration.
1563 ///
1564 /// extern module-declaration:
1565 /// 'extern' 'module' module-id string-literal
parseExternModuleDecl()1566 void ModuleMapParser::parseExternModuleDecl() {
1567 assert(Tok.is(MMToken::ExternKeyword));
1568 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
1569
1570 // Parse 'module' keyword.
1571 if (!Tok.is(MMToken::ModuleKeyword)) {
1572 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1573 consumeToken();
1574 HadError = true;
1575 return;
1576 }
1577 consumeToken(); // 'module' keyword
1578
1579 // Parse the module name.
1580 ModuleId Id;
1581 if (parseModuleId(Id)) {
1582 HadError = true;
1583 return;
1584 }
1585
1586 // Parse the referenced module map file name.
1587 if (!Tok.is(MMToken::StringLiteral)) {
1588 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1589 HadError = true;
1590 return;
1591 }
1592 std::string FileName = Tok.getString();
1593 consumeToken(); // filename
1594
1595 StringRef FileNameRef = FileName;
1596 SmallString<128> ModuleMapFileName;
1597 if (llvm::sys::path::is_relative(FileNameRef)) {
1598 ModuleMapFileName += Directory->getName();
1599 llvm::sys::path::append(ModuleMapFileName, FileName);
1600 FileNameRef = ModuleMapFileName;
1601 }
1602 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1603 Map.parseModuleMapFile(
1604 File, /*IsSystem=*/false,
1605 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1606 ? Directory
1607 : File->getDir(), ExternLoc);
1608 }
1609
1610 /// Whether to add the requirement \p Feature to the module \p M.
1611 ///
1612 /// This preserves backwards compatibility for two hacks in the Darwin system
1613 /// module map files:
1614 ///
1615 /// 1. The use of 'requires excluded' to make headers non-modular, which
1616 /// should really be mapped to 'textual' now that we have this feature. We
1617 /// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1618 /// true. Later, this bit will be used to map all the headers inside this
1619 /// module to 'textual'.
1620 ///
1621 /// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1622 ///
1623 /// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1624 /// was never correct and causes issues now that we check it, so drop it.
shouldAddRequirement(Module * M,StringRef Feature,bool & IsRequiresExcludedHack)1625 static bool shouldAddRequirement(Module *M, StringRef Feature,
1626 bool &IsRequiresExcludedHack) {
1627 static const StringRef DarwinCExcluded[] = {"Darwin", "C", "excluded"};
1628 static const StringRef TclPrivate[] = {"Tcl", "Private"};
1629 static const StringRef IOKitAVC[] = {"IOKit", "avc"};
1630
1631 if (Feature == "excluded" && (M->fullModuleNameIs(DarwinCExcluded) ||
1632 M->fullModuleNameIs(TclPrivate))) {
1633 IsRequiresExcludedHack = true;
1634 return false;
1635 } else if (Feature == "cplusplus" && M->fullModuleNameIs(IOKitAVC)) {
1636 return false;
1637 }
1638
1639 return true;
1640 }
1641
1642 /// \brief Parse a requires declaration.
1643 ///
1644 /// requires-declaration:
1645 /// 'requires' feature-list
1646 ///
1647 /// feature-list:
1648 /// feature ',' feature-list
1649 /// feature
1650 ///
1651 /// feature:
1652 /// '!'[opt] identifier
parseRequiresDecl()1653 void ModuleMapParser::parseRequiresDecl() {
1654 assert(Tok.is(MMToken::RequiresKeyword));
1655
1656 // Parse 'requires' keyword.
1657 consumeToken();
1658
1659 // Parse the feature-list.
1660 do {
1661 bool RequiredState = true;
1662 if (Tok.is(MMToken::Exclaim)) {
1663 RequiredState = false;
1664 consumeToken();
1665 }
1666
1667 if (!Tok.is(MMToken::Identifier)) {
1668 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1669 HadError = true;
1670 return;
1671 }
1672
1673 // Consume the feature name.
1674 std::string Feature = Tok.getString();
1675 consumeToken();
1676
1677 bool IsRequiresExcludedHack = false;
1678 bool ShouldAddRequirement =
1679 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
1680
1681 if (IsRequiresExcludedHack)
1682 UsesRequiresExcludedHack.insert(ActiveModule);
1683
1684 if (ShouldAddRequirement) {
1685 // Add this feature.
1686 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
1687 *Map.Target);
1688 }
1689
1690 if (!Tok.is(MMToken::Comma))
1691 break;
1692
1693 // Consume the comma.
1694 consumeToken();
1695 } while (true);
1696 }
1697
1698 /// \brief Append to \p Paths the set of paths needed to get to the
1699 /// subframework in which the given module lives.
appendSubframeworkPaths(Module * Mod,SmallVectorImpl<char> & Path)1700 static void appendSubframeworkPaths(Module *Mod,
1701 SmallVectorImpl<char> &Path) {
1702 // Collect the framework names from the given module to the top-level module.
1703 SmallVector<StringRef, 2> Paths;
1704 for (; Mod; Mod = Mod->Parent) {
1705 if (Mod->IsFramework)
1706 Paths.push_back(Mod->Name);
1707 }
1708
1709 if (Paths.empty())
1710 return;
1711
1712 // Add Frameworks/Name.framework for each subframework.
1713 for (unsigned I = Paths.size() - 1; I != 0; --I)
1714 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
1715 }
1716
1717 /// \brief Parse a header declaration.
1718 ///
1719 /// header-declaration:
1720 /// 'textual'[opt] 'header' string-literal
1721 /// 'private' 'textual'[opt] 'header' string-literal
1722 /// 'exclude' 'header' string-literal
1723 /// 'umbrella' 'header' string-literal
1724 ///
1725 /// FIXME: Support 'private textual header'.
parseHeaderDecl(MMToken::TokenKind LeadingToken,SourceLocation LeadingLoc)1726 void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1727 SourceLocation LeadingLoc) {
1728 // We've already consumed the first token.
1729 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1730 if (LeadingToken == MMToken::PrivateKeyword) {
1731 Role = ModuleMap::PrivateHeader;
1732 // 'private' may optionally be followed by 'textual'.
1733 if (Tok.is(MMToken::TextualKeyword)) {
1734 LeadingToken = Tok.Kind;
1735 consumeToken();
1736 }
1737 }
1738
1739 if (LeadingToken == MMToken::TextualKeyword)
1740 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1741
1742 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1743 // Mark this header 'textual' (see doc comment for
1744 // Module::UsesRequiresExcludedHack).
1745 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1746 }
1747
1748 if (LeadingToken != MMToken::HeaderKeyword) {
1749 if (!Tok.is(MMToken::HeaderKeyword)) {
1750 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1751 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1752 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1753 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1754 return;
1755 }
1756 consumeToken();
1757 }
1758
1759 // Parse the header name.
1760 if (!Tok.is(MMToken::StringLiteral)) {
1761 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1762 << "header";
1763 HadError = true;
1764 return;
1765 }
1766 Module::UnresolvedHeaderDirective Header;
1767 Header.FileName = Tok.getString();
1768 Header.FileNameLoc = consumeToken();
1769
1770 // Check whether we already have an umbrella.
1771 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
1772 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
1773 << ActiveModule->getFullModuleName();
1774 HadError = true;
1775 return;
1776 }
1777
1778 // Look for this file.
1779 const FileEntry *File = nullptr;
1780 const FileEntry *BuiltinFile = nullptr;
1781 SmallString<128> RelativePathName;
1782 if (llvm::sys::path::is_absolute(Header.FileName)) {
1783 RelativePathName = Header.FileName;
1784 File = SourceMgr.getFileManager().getFile(RelativePathName);
1785 } else {
1786 // Search for the header file within the search directory.
1787 SmallString<128> FullPathName(Directory->getName());
1788 unsigned FullPathLength = FullPathName.size();
1789
1790 if (ActiveModule->isPartOfFramework()) {
1791 appendSubframeworkPaths(ActiveModule, RelativePathName);
1792
1793 // Check whether this file is in the public headers.
1794 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
1795 llvm::sys::path::append(FullPathName, RelativePathName);
1796 File = SourceMgr.getFileManager().getFile(FullPathName);
1797
1798 if (!File) {
1799 // Check whether this file is in the private headers.
1800 // FIXME: Should we retain the subframework paths here?
1801 RelativePathName.clear();
1802 FullPathName.resize(FullPathLength);
1803 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1804 Header.FileName);
1805 llvm::sys::path::append(FullPathName, RelativePathName);
1806 File = SourceMgr.getFileManager().getFile(FullPathName);
1807 }
1808 } else {
1809 // Lookup for normal headers.
1810 llvm::sys::path::append(RelativePathName, Header.FileName);
1811 llvm::sys::path::append(FullPathName, RelativePathName);
1812 File = SourceMgr.getFileManager().getFile(FullPathName);
1813
1814 // If this is a system module with a top-level header, this header
1815 // may have a counterpart (or replacement) in the set of headers
1816 // supplied by Clang. Find that builtin header.
1817 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1818 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1819 isBuiltinHeader(Header.FileName)) {
1820 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1821 llvm::sys::path::append(BuiltinPathName, Header.FileName);
1822 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1823
1824 // If Clang supplies this header but the underlying system does not,
1825 // just silently swap in our builtin version. Otherwise, we'll end
1826 // up adding both (later).
1827 //
1828 // For local visibility, entirely replace the system file with our
1829 // one and textually include the system one. We need to pass macros
1830 // from our header to the system one if we #include_next it.
1831 //
1832 // FIXME: Can we do this in all cases?
1833 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
1834 File = BuiltinFile;
1835 RelativePathName = BuiltinPathName;
1836 BuiltinFile = nullptr;
1837 }
1838 }
1839 }
1840 }
1841
1842 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1843 // Come up with a lazy way to do this.
1844 if (File) {
1845 if (LeadingToken == MMToken::UmbrellaKeyword) {
1846 const DirectoryEntry *UmbrellaDir = File->getDir();
1847 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1848 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
1849 << UmbrellaModule->getFullModuleName();
1850 HadError = true;
1851 } else {
1852 // Record this umbrella header.
1853 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
1854 }
1855 } else if (LeadingToken == MMToken::ExcludeKeyword) {
1856 Module::Header H = {RelativePathName.str(), File};
1857 Map.excludeHeader(ActiveModule, H);
1858 } else {
1859 // If there is a builtin counterpart to this file, add it now, before
1860 // the "real" header, so we build the built-in one first when building
1861 // the module.
1862 if (BuiltinFile) {
1863 // FIXME: Taking the name from the FileEntry is unstable and can give
1864 // different results depending on how we've previously named that file
1865 // in this build.
1866 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1867 Map.addHeader(ActiveModule, H, Role);
1868 }
1869
1870 // Record this header.
1871 Module::Header H = { RelativePathName.str(), File };
1872 Map.addHeader(ActiveModule, H, Role);
1873 }
1874 } else if (LeadingToken != MMToken::ExcludeKeyword) {
1875 // Ignore excluded header files. They're optional anyway.
1876
1877 // If we find a module that has a missing header, we mark this module as
1878 // unavailable and store the header directive for displaying diagnostics.
1879 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
1880 ActiveModule->markUnavailable();
1881 ActiveModule->MissingHeaders.push_back(Header);
1882 }
1883 }
1884
compareModuleHeaders(const Module::Header * A,const Module::Header * B)1885 static int compareModuleHeaders(const Module::Header *A,
1886 const Module::Header *B) {
1887 return A->NameAsWritten.compare(B->NameAsWritten);
1888 }
1889
1890 /// \brief Parse an umbrella directory declaration.
1891 ///
1892 /// umbrella-dir-declaration:
1893 /// umbrella string-literal
parseUmbrellaDirDecl(SourceLocation UmbrellaLoc)1894 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1895 // Parse the directory name.
1896 if (!Tok.is(MMToken::StringLiteral)) {
1897 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1898 << "umbrella";
1899 HadError = true;
1900 return;
1901 }
1902
1903 std::string DirName = Tok.getString();
1904 SourceLocation DirNameLoc = consumeToken();
1905
1906 // Check whether we already have an umbrella.
1907 if (ActiveModule->Umbrella) {
1908 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1909 << ActiveModule->getFullModuleName();
1910 HadError = true;
1911 return;
1912 }
1913
1914 // Look for this file.
1915 const DirectoryEntry *Dir = nullptr;
1916 if (llvm::sys::path::is_absolute(DirName))
1917 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1918 else {
1919 SmallString<128> PathName;
1920 PathName = Directory->getName();
1921 llvm::sys::path::append(PathName, DirName);
1922 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1923 }
1924
1925 if (!Dir) {
1926 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1927 << DirName;
1928 HadError = true;
1929 return;
1930 }
1931
1932 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1933 // Mark this header 'textual' (see doc comment for
1934 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
1935 // directory is relatively expensive, in practice this only applies to the
1936 // uncommonly used Tcl module on Darwin platforms.
1937 std::error_code EC;
1938 SmallVector<Module::Header, 6> Headers;
1939 vfs::FileSystem &FS = *SourceMgr.getFileManager().getVirtualFileSystem();
1940 for (vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
1941 I != E && !EC; I.increment(EC)) {
1942 if (const FileEntry *FE =
1943 SourceMgr.getFileManager().getFile(I->getName())) {
1944
1945 Module::Header Header = {I->getName(), FE};
1946 Headers.push_back(std::move(Header));
1947 }
1948 }
1949
1950 // Sort header paths so that the pcm doesn't depend on iteration order.
1951 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
1952
1953 for (auto &Header : Headers)
1954 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
1955 return;
1956 }
1957
1958 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1959 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1960 << OwningModule->getFullModuleName();
1961 HadError = true;
1962 return;
1963 }
1964
1965 // Record this umbrella directory.
1966 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
1967 }
1968
1969 /// \brief Parse a module export declaration.
1970 ///
1971 /// export-declaration:
1972 /// 'export' wildcard-module-id
1973 ///
1974 /// wildcard-module-id:
1975 /// identifier
1976 /// '*'
1977 /// identifier '.' wildcard-module-id
parseExportDecl()1978 void ModuleMapParser::parseExportDecl() {
1979 assert(Tok.is(MMToken::ExportKeyword));
1980 SourceLocation ExportLoc = consumeToken();
1981
1982 // Parse the module-id with an optional wildcard at the end.
1983 ModuleId ParsedModuleId;
1984 bool Wildcard = false;
1985 do {
1986 // FIXME: Support string-literal module names here.
1987 if (Tok.is(MMToken::Identifier)) {
1988 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1989 Tok.getLocation()));
1990 consumeToken();
1991
1992 if (Tok.is(MMToken::Period)) {
1993 consumeToken();
1994 continue;
1995 }
1996
1997 break;
1998 }
1999
2000 if(Tok.is(MMToken::Star)) {
2001 Wildcard = true;
2002 consumeToken();
2003 break;
2004 }
2005
2006 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
2007 HadError = true;
2008 return;
2009 } while (true);
2010
2011 Module::UnresolvedExportDecl Unresolved = {
2012 ExportLoc, ParsedModuleId, Wildcard
2013 };
2014 ActiveModule->UnresolvedExports.push_back(Unresolved);
2015 }
2016
2017 /// \brief Parse a module use declaration.
2018 ///
2019 /// use-declaration:
2020 /// 'use' wildcard-module-id
parseUseDecl()2021 void ModuleMapParser::parseUseDecl() {
2022 assert(Tok.is(MMToken::UseKeyword));
2023 auto KWLoc = consumeToken();
2024 // Parse the module-id.
2025 ModuleId ParsedModuleId;
2026 parseModuleId(ParsedModuleId);
2027
2028 if (ActiveModule->Parent)
2029 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2030 else
2031 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
2032 }
2033
2034 /// \brief Parse a link declaration.
2035 ///
2036 /// module-declaration:
2037 /// 'link' 'framework'[opt] string-literal
parseLinkDecl()2038 void ModuleMapParser::parseLinkDecl() {
2039 assert(Tok.is(MMToken::LinkKeyword));
2040 SourceLocation LinkLoc = consumeToken();
2041
2042 // Parse the optional 'framework' keyword.
2043 bool IsFramework = false;
2044 if (Tok.is(MMToken::FrameworkKeyword)) {
2045 consumeToken();
2046 IsFramework = true;
2047 }
2048
2049 // Parse the library name
2050 if (!Tok.is(MMToken::StringLiteral)) {
2051 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2052 << IsFramework << SourceRange(LinkLoc);
2053 HadError = true;
2054 return;
2055 }
2056
2057 std::string LibraryName = Tok.getString();
2058 consumeToken();
2059 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2060 IsFramework));
2061 }
2062
2063 /// \brief Parse a configuration macro declaration.
2064 ///
2065 /// module-declaration:
2066 /// 'config_macros' attributes[opt] config-macro-list?
2067 ///
2068 /// config-macro-list:
2069 /// identifier (',' identifier)?
parseConfigMacros()2070 void ModuleMapParser::parseConfigMacros() {
2071 assert(Tok.is(MMToken::ConfigMacros));
2072 SourceLocation ConfigMacrosLoc = consumeToken();
2073
2074 // Only top-level modules can have configuration macros.
2075 if (ActiveModule->Parent) {
2076 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2077 }
2078
2079 // Parse the optional attributes.
2080 Attributes Attrs;
2081 if (parseOptionalAttributes(Attrs))
2082 return;
2083
2084 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2085 ActiveModule->ConfigMacrosExhaustive = true;
2086 }
2087
2088 // If we don't have an identifier, we're done.
2089 // FIXME: Support macros with the same name as a keyword here.
2090 if (!Tok.is(MMToken::Identifier))
2091 return;
2092
2093 // Consume the first identifier.
2094 if (!ActiveModule->Parent) {
2095 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2096 }
2097 consumeToken();
2098
2099 do {
2100 // If there's a comma, consume it.
2101 if (!Tok.is(MMToken::Comma))
2102 break;
2103 consumeToken();
2104
2105 // We expect to see a macro name here.
2106 // FIXME: Support macros with the same name as a keyword here.
2107 if (!Tok.is(MMToken::Identifier)) {
2108 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2109 break;
2110 }
2111
2112 // Consume the macro name.
2113 if (!ActiveModule->Parent) {
2114 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2115 }
2116 consumeToken();
2117 } while (true);
2118 }
2119
2120 /// \brief Format a module-id into a string.
formatModuleId(const ModuleId & Id)2121 static std::string formatModuleId(const ModuleId &Id) {
2122 std::string result;
2123 {
2124 llvm::raw_string_ostream OS(result);
2125
2126 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2127 if (I)
2128 OS << ".";
2129 OS << Id[I].first;
2130 }
2131 }
2132
2133 return result;
2134 }
2135
2136 /// \brief Parse a conflict declaration.
2137 ///
2138 /// module-declaration:
2139 /// 'conflict' module-id ',' string-literal
parseConflict()2140 void ModuleMapParser::parseConflict() {
2141 assert(Tok.is(MMToken::Conflict));
2142 SourceLocation ConflictLoc = consumeToken();
2143 Module::UnresolvedConflict Conflict;
2144
2145 // Parse the module-id.
2146 if (parseModuleId(Conflict.Id))
2147 return;
2148
2149 // Parse the ','.
2150 if (!Tok.is(MMToken::Comma)) {
2151 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2152 << SourceRange(ConflictLoc);
2153 return;
2154 }
2155 consumeToken();
2156
2157 // Parse the message.
2158 if (!Tok.is(MMToken::StringLiteral)) {
2159 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2160 << formatModuleId(Conflict.Id);
2161 return;
2162 }
2163 Conflict.Message = Tok.getString().str();
2164 consumeToken();
2165
2166 // Add this unresolved conflict.
2167 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2168 }
2169
2170 /// \brief Parse an inferred module declaration (wildcard modules).
2171 ///
2172 /// module-declaration:
2173 /// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2174 /// { inferred-module-member* }
2175 ///
2176 /// inferred-module-member:
2177 /// 'export' '*'
2178 /// 'exclude' identifier
parseInferredModuleDecl(bool Framework,bool Explicit)2179 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
2180 assert(Tok.is(MMToken::Star));
2181 SourceLocation StarLoc = consumeToken();
2182 bool Failed = false;
2183
2184 // Inferred modules must be submodules.
2185 if (!ActiveModule && !Framework) {
2186 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2187 Failed = true;
2188 }
2189
2190 if (ActiveModule) {
2191 // Inferred modules must have umbrella directories.
2192 if (!Failed && ActiveModule->IsAvailable &&
2193 !ActiveModule->getUmbrellaDir()) {
2194 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2195 Failed = true;
2196 }
2197
2198 // Check for redefinition of an inferred module.
2199 if (!Failed && ActiveModule->InferSubmodules) {
2200 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2201 if (ActiveModule->InferredSubmoduleLoc.isValid())
2202 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2203 diag::note_mmap_prev_definition);
2204 Failed = true;
2205 }
2206
2207 // Check for the 'framework' keyword, which is not permitted here.
2208 if (Framework) {
2209 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2210 Framework = false;
2211 }
2212 } else if (Explicit) {
2213 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2214 Explicit = false;
2215 }
2216
2217 // If there were any problems with this inferred submodule, skip its body.
2218 if (Failed) {
2219 if (Tok.is(MMToken::LBrace)) {
2220 consumeToken();
2221 skipUntil(MMToken::RBrace);
2222 if (Tok.is(MMToken::RBrace))
2223 consumeToken();
2224 }
2225 HadError = true;
2226 return;
2227 }
2228
2229 // Parse optional attributes.
2230 Attributes Attrs;
2231 if (parseOptionalAttributes(Attrs))
2232 return;
2233
2234 if (ActiveModule) {
2235 // Note that we have an inferred submodule.
2236 ActiveModule->InferSubmodules = true;
2237 ActiveModule->InferredSubmoduleLoc = StarLoc;
2238 ActiveModule->InferExplicitSubmodules = Explicit;
2239 } else {
2240 // We'll be inferring framework modules for this directory.
2241 Map.InferredDirectories[Directory].InferModules = true;
2242 Map.InferredDirectories[Directory].Attrs = Attrs;
2243 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
2244 // FIXME: Handle the 'framework' keyword.
2245 }
2246
2247 // Parse the opening brace.
2248 if (!Tok.is(MMToken::LBrace)) {
2249 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2250 HadError = true;
2251 return;
2252 }
2253 SourceLocation LBraceLoc = consumeToken();
2254
2255 // Parse the body of the inferred submodule.
2256 bool Done = false;
2257 do {
2258 switch (Tok.Kind) {
2259 case MMToken::EndOfFile:
2260 case MMToken::RBrace:
2261 Done = true;
2262 break;
2263
2264 case MMToken::ExcludeKeyword: {
2265 if (ActiveModule) {
2266 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2267 << (ActiveModule != nullptr);
2268 consumeToken();
2269 break;
2270 }
2271
2272 consumeToken();
2273 // FIXME: Support string-literal module names here.
2274 if (!Tok.is(MMToken::Identifier)) {
2275 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2276 break;
2277 }
2278
2279 Map.InferredDirectories[Directory].ExcludedModules
2280 .push_back(Tok.getString());
2281 consumeToken();
2282 break;
2283 }
2284
2285 case MMToken::ExportKeyword:
2286 if (!ActiveModule) {
2287 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2288 << (ActiveModule != nullptr);
2289 consumeToken();
2290 break;
2291 }
2292
2293 consumeToken();
2294 if (Tok.is(MMToken::Star))
2295 ActiveModule->InferExportWildcard = true;
2296 else
2297 Diags.Report(Tok.getLocation(),
2298 diag::err_mmap_expected_export_wildcard);
2299 consumeToken();
2300 break;
2301
2302 case MMToken::ExplicitKeyword:
2303 case MMToken::ModuleKeyword:
2304 case MMToken::HeaderKeyword:
2305 case MMToken::PrivateKeyword:
2306 case MMToken::UmbrellaKeyword:
2307 default:
2308 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
2309 << (ActiveModule != nullptr);
2310 consumeToken();
2311 break;
2312 }
2313 } while (!Done);
2314
2315 if (Tok.is(MMToken::RBrace))
2316 consumeToken();
2317 else {
2318 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2319 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2320 HadError = true;
2321 }
2322 }
2323
2324 /// \brief Parse optional attributes.
2325 ///
2326 /// attributes:
2327 /// attribute attributes
2328 /// attribute
2329 ///
2330 /// attribute:
2331 /// [ identifier ]
2332 ///
2333 /// \param Attrs Will be filled in with the parsed attributes.
2334 ///
2335 /// \returns true if an error occurred, false otherwise.
parseOptionalAttributes(Attributes & Attrs)2336 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2337 bool HadError = false;
2338
2339 while (Tok.is(MMToken::LSquare)) {
2340 // Consume the '['.
2341 SourceLocation LSquareLoc = consumeToken();
2342
2343 // Check whether we have an attribute name here.
2344 if (!Tok.is(MMToken::Identifier)) {
2345 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2346 skipUntil(MMToken::RSquare);
2347 if (Tok.is(MMToken::RSquare))
2348 consumeToken();
2349 HadError = true;
2350 }
2351
2352 // Decode the attribute name.
2353 AttributeKind Attribute
2354 = llvm::StringSwitch<AttributeKind>(Tok.getString())
2355 .Case("exhaustive", AT_exhaustive)
2356 .Case("extern_c", AT_extern_c)
2357 .Case("system", AT_system)
2358 .Default(AT_unknown);
2359 switch (Attribute) {
2360 case AT_unknown:
2361 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2362 << Tok.getString();
2363 break;
2364
2365 case AT_system:
2366 Attrs.IsSystem = true;
2367 break;
2368
2369 case AT_extern_c:
2370 Attrs.IsExternC = true;
2371 break;
2372
2373 case AT_exhaustive:
2374 Attrs.IsExhaustive = true;
2375 break;
2376 }
2377 consumeToken();
2378
2379 // Consume the ']'.
2380 if (!Tok.is(MMToken::RSquare)) {
2381 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2382 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2383 skipUntil(MMToken::RSquare);
2384 HadError = true;
2385 }
2386
2387 if (Tok.is(MMToken::RSquare))
2388 consumeToken();
2389 }
2390
2391 return HadError;
2392 }
2393
2394 /// \brief Parse a module map file.
2395 ///
2396 /// module-map-file:
2397 /// module-declaration*
parseModuleMapFile()2398 bool ModuleMapParser::parseModuleMapFile() {
2399 do {
2400 switch (Tok.Kind) {
2401 case MMToken::EndOfFile:
2402 return HadError;
2403
2404 case MMToken::ExplicitKeyword:
2405 case MMToken::ExternKeyword:
2406 case MMToken::ModuleKeyword:
2407 case MMToken::FrameworkKeyword:
2408 parseModuleDecl();
2409 break;
2410
2411 case MMToken::Comma:
2412 case MMToken::ConfigMacros:
2413 case MMToken::Conflict:
2414 case MMToken::Exclaim:
2415 case MMToken::ExcludeKeyword:
2416 case MMToken::ExportKeyword:
2417 case MMToken::HeaderKeyword:
2418 case MMToken::Identifier:
2419 case MMToken::LBrace:
2420 case MMToken::LinkKeyword:
2421 case MMToken::LSquare:
2422 case MMToken::Period:
2423 case MMToken::PrivateKeyword:
2424 case MMToken::RBrace:
2425 case MMToken::RSquare:
2426 case MMToken::RequiresKeyword:
2427 case MMToken::Star:
2428 case MMToken::StringLiteral:
2429 case MMToken::TextualKeyword:
2430 case MMToken::UmbrellaKeyword:
2431 case MMToken::UseKeyword:
2432 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2433 HadError = true;
2434 consumeToken();
2435 break;
2436 }
2437 } while (true);
2438 }
2439
parseModuleMapFile(const FileEntry * File,bool IsSystem,const DirectoryEntry * Dir,SourceLocation ExternModuleLoc)2440 bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
2441 const DirectoryEntry *Dir,
2442 SourceLocation ExternModuleLoc) {
2443 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2444 = ParsedModuleMap.find(File);
2445 if (Known != ParsedModuleMap.end())
2446 return Known->second;
2447
2448 assert(Target && "Missing target information");
2449 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2450 FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
2451 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2452 if (!Buffer)
2453 return ParsedModuleMap[File] = true;
2454
2455 // Parse this module map file.
2456 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
2457 SourceLocation Start = L.getSourceLocation();
2458 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
2459 BuiltinIncludeDir, IsSystem);
2460 bool Result = Parser.parseModuleMapFile();
2461 ParsedModuleMap[File] = Result;
2462
2463 // Notify callbacks that we parsed it.
2464 for (const auto &Cb : Callbacks)
2465 Cb->moduleMapFileRead(Start, *File, IsSystem);
2466 return Result;
2467 }
2468