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