xref: /llvm-project/clang/lib/Lex/ModuleMap.cpp (revision 09a22f071bae8320c322645d1ff0bc86fadfe1b4)
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/Lex/Lexer.h"
16 #include "clang/Lex/LiteralSupport.h"
17 #include "clang/Lex/LexDiagnostic.h"
18 #include "clang/Basic/Diagnostic.h"
19 #include "clang/Basic/FileManager.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Basic/TargetOptions.h"
22 #include "llvm/Support/Allocator.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/Host.h"
25 #include "llvm/Support/PathV2.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/ADT/StringSwitch.h"
29 using namespace clang;
30 
31 Module::ExportDecl
32 ModuleMap::resolveExport(Module *Mod,
33                          const Module::UnresolvedExportDecl &Unresolved,
34                          bool Complain) {
35   // We may have just a wildcard.
36   if (Unresolved.Id.empty()) {
37     assert(Unresolved.Wildcard && "Invalid unresolved export");
38     return Module::ExportDecl(0, true);
39   }
40 
41   // Find the starting module.
42   Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
43   if (!Context) {
44     if (Complain)
45       Diags->Report(Unresolved.Id[0].second,
46                     diag::err_mmap_missing_module_unqualified)
47         << Unresolved.Id[0].first << Mod->getFullModuleName();
48 
49     return Module::ExportDecl();
50   }
51 
52   // Dig into the module path.
53   for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
54     Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
55                                         Context);
56     if (!Sub) {
57       if (Complain)
58         Diags->Report(Unresolved.Id[I].second,
59                       diag::err_mmap_missing_module_qualified)
60           << Unresolved.Id[I].first << Context->getFullModuleName()
61           << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
62 
63       return Module::ExportDecl();
64     }
65 
66     Context = Sub;
67   }
68 
69   return Module::ExportDecl(Context, Unresolved.Wildcard);
70 }
71 
72 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
73                      const LangOptions &LangOpts)
74   : LangOpts(LangOpts)
75 {
76   llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
77   Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>(
78             new DiagnosticsEngine(DiagIDs));
79   Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
80   SourceMgr = new SourceManager(*Diags, FileMgr);
81 }
82 
83 ModuleMap::~ModuleMap() {
84   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
85                                         IEnd = Modules.end();
86        I != IEnd; ++I) {
87     delete I->getValue();
88   }
89 
90   delete SourceMgr;
91 }
92 
93 Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
94   llvm::DenseMap<const FileEntry *, Module *>::iterator Known
95     = Headers.find(File);
96   if (Known != Headers.end()) {
97     // If a header corresponds to an unavailable module, don't report
98     // that it maps to anything.
99     if (!Known->second->isAvailable())
100       return 0;
101 
102     return Known->second;
103   }
104 
105   const DirectoryEntry *Dir = File->getDir();
106   llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
107   StringRef DirName = Dir->getName();
108 
109   // Keep walking up the directory hierarchy, looking for a directory with
110   // an umbrella header.
111   do {
112     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
113       = UmbrellaDirs.find(Dir);
114     if (KnownDir != UmbrellaDirs.end()) {
115       Module *Result = KnownDir->second;
116 
117       // Search up the module stack until we find a module with an umbrella
118       // directory.
119       Module *UmbrellaModule = Result;
120       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
121         UmbrellaModule = UmbrellaModule->Parent;
122 
123       if (UmbrellaModule->InferSubmodules) {
124         // Infer submodules for each of the directories we found between
125         // the directory of the umbrella header and the directory where
126         // the actual header is located.
127         bool Explicit = UmbrellaModule->InferExplicitSubmodules;
128 
129         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
130           // Find or create the module that corresponds to this directory name.
131           StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
132           Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
133                                       Explicit).first;
134 
135           // Associate the module and the directory.
136           UmbrellaDirs[SkippedDirs[I-1]] = Result;
137 
138           // If inferred submodules export everything they import, add a
139           // wildcard to the set of exports.
140           if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
141             Result->Exports.push_back(Module::ExportDecl(0, true));
142         }
143 
144         // Infer a submodule with the same name as this header file.
145         StringRef Name = llvm::sys::path::stem(File->getName());
146         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
147                                     Explicit).first;
148 
149         // If inferred submodules export everything they import, add a
150         // wildcard to the set of exports.
151         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
152           Result->Exports.push_back(Module::ExportDecl(0, true));
153       } else {
154         // Record each of the directories we stepped through as being part of
155         // the module we found, since the umbrella header covers them all.
156         for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
157           UmbrellaDirs[SkippedDirs[I]] = Result;
158       }
159 
160       Headers[File] = Result;
161 
162       // If a header corresponds to an unavailable module, don't report
163       // that it maps to anything.
164       if (!Result->isAvailable())
165         return 0;
166 
167       return Result;
168     }
169 
170     SkippedDirs.push_back(Dir);
171 
172     // Retrieve our parent path.
173     DirName = llvm::sys::path::parent_path(DirName);
174     if (DirName.empty())
175       break;
176 
177     // Resolve the parent path to a directory entry.
178     Dir = SourceMgr->getFileManager().getDirectory(DirName);
179   } while (Dir);
180 
181   return 0;
182 }
183 
184 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
185   llvm::DenseMap<const FileEntry *, Module *>::iterator Known
186     = Headers.find(Header);
187   if (Known != Headers.end())
188     return !Known->second->isAvailable();
189 
190   const DirectoryEntry *Dir = Header->getDir();
191   llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
192   StringRef DirName = Dir->getName();
193 
194   // Keep walking up the directory hierarchy, looking for a directory with
195   // an umbrella header.
196   do {
197     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
198       = UmbrellaDirs.find(Dir);
199     if (KnownDir != UmbrellaDirs.end()) {
200       Module *Found = KnownDir->second;
201       if (!Found->isAvailable())
202         return true;
203 
204       // Search up the module stack until we find a module with an umbrella
205       // directory.
206       Module *UmbrellaModule = Found;
207       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
208         UmbrellaModule = UmbrellaModule->Parent;
209 
210       if (UmbrellaModule->InferSubmodules) {
211         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
212           // Find or create the module that corresponds to this directory name.
213           StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
214           Found = lookupModuleQualified(Name, Found);
215           if (!Found)
216             return false;
217           if (!Found->isAvailable())
218             return true;
219         }
220 
221         // Infer a submodule with the same name as this header file.
222         StringRef Name = llvm::sys::path::stem(Header->getName());
223         Found = lookupModuleQualified(Name, Found);
224         if (!Found)
225           return false;
226       }
227 
228       return !Found->isAvailable();
229     }
230 
231     SkippedDirs.push_back(Dir);
232 
233     // Retrieve our parent path.
234     DirName = llvm::sys::path::parent_path(DirName);
235     if (DirName.empty())
236       break;
237 
238     // Resolve the parent path to a directory entry.
239     Dir = SourceMgr->getFileManager().getDirectory(DirName);
240   } while (Dir);
241 
242   return false;
243 }
244 
245 Module *ModuleMap::findModule(StringRef Name) {
246   llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
247   if (Known != Modules.end())
248     return Known->getValue();
249 
250   return 0;
251 }
252 
253 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
254   for(; Context; Context = Context->Parent) {
255     if (Module *Sub = lookupModuleQualified(Name, Context))
256       return Sub;
257   }
258 
259   return findModule(Name);
260 }
261 
262 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
263   if (!Context)
264     return findModule(Name);
265 
266   return Context->findSubmodule(Name);
267 }
268 
269 std::pair<Module *, bool>
270 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
271                               bool IsExplicit) {
272   // Try to find an existing module with this name.
273   if (Module *Sub = lookupModuleQualified(Name, Parent))
274     return std::make_pair(Sub, false);
275 
276   // Create a new module with this name.
277   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
278                               IsExplicit);
279   if (!Parent)
280     Modules[Name] = Result;
281   return std::make_pair(Result, true);
282 }
283 
284 Module *
285 ModuleMap::inferFrameworkModule(StringRef ModuleName,
286                                 const DirectoryEntry *FrameworkDir,
287                                 Module *Parent) {
288   // Check whether we've already found this module.
289   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
290     return Mod;
291 
292   FileManager &FileMgr = SourceMgr->getFileManager();
293 
294   // Look for an umbrella header.
295   llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
296   llvm::sys::path::append(UmbrellaName, "Headers");
297   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
298   const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
299 
300   // FIXME: If there's no umbrella header, we could probably scan the
301   // framework to load *everything*. But, it's not clear that this is a good
302   // idea.
303   if (!UmbrellaHeader)
304     return 0;
305 
306   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
307                               /*IsFramework=*/true, /*IsExplicit=*/false);
308   if (!Parent)
309     Modules[ModuleName] = Result;
310 
311   // umbrella header "umbrella-header-name"
312   Result->Umbrella = UmbrellaHeader;
313   Headers[UmbrellaHeader] = Result;
314   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
315 
316   // export *
317   Result->Exports.push_back(Module::ExportDecl(0, true));
318 
319   // module * { export * }
320   Result->InferSubmodules = true;
321   Result->InferExportWildcard = true;
322 
323   // Look for subframeworks.
324   llvm::error_code EC;
325   llvm::SmallString<128> SubframeworksDirName
326     = StringRef(FrameworkDir->getName());
327   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
328   llvm::SmallString<128> SubframeworksDirNameNative;
329   llvm::sys::path::native(SubframeworksDirName.str(),
330                           SubframeworksDirNameNative);
331   for (llvm::sys::fs::directory_iterator
332          Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
333        Dir != DirEnd && !EC; Dir.increment(EC)) {
334     if (!StringRef(Dir->path()).endswith(".framework"))
335       continue;
336 
337     if (const DirectoryEntry *SubframeworkDir
338           = FileMgr.getDirectory(Dir->path())) {
339       // FIXME: Do we want to warn about subframeworks without umbrella headers?
340       inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir,
341                            Result);
342     }
343   }
344 
345   return Result;
346 }
347 
348 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
349   Headers[UmbrellaHeader] = Mod;
350   Mod->Umbrella = UmbrellaHeader;
351   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
352 }
353 
354 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
355   Mod->Umbrella = UmbrellaDir;
356   UmbrellaDirs[UmbrellaDir] = Mod;
357 }
358 
359 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) {
360   Mod->Headers.push_back(Header);
361   Headers[Header] = Mod;
362 }
363 
364 const FileEntry *
365 ModuleMap::getContainingModuleMapFile(Module *Module) {
366   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
367     return 0;
368 
369   return SourceMgr->getFileEntryForID(
370            SourceMgr->getFileID(Module->DefinitionLoc));
371 }
372 
373 void ModuleMap::dump() {
374   llvm::errs() << "Modules:";
375   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
376                                         MEnd = Modules.end();
377        M != MEnd; ++M)
378     M->getValue()->print(llvm::errs(), 2);
379 
380   llvm::errs() << "Headers:";
381   for (llvm::DenseMap<const FileEntry *, Module *>::iterator
382             H = Headers.begin(),
383          HEnd = Headers.end();
384        H != HEnd; ++H) {
385     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
386                  << H->second->getFullModuleName() << "\n";
387   }
388 }
389 
390 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
391   bool HadError = false;
392   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
393     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
394                                               Complain);
395     if (Export.getPointer() || Export.getInt())
396       Mod->Exports.push_back(Export);
397     else
398       HadError = true;
399   }
400   Mod->UnresolvedExports.clear();
401   return HadError;
402 }
403 
404 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
405   if (Loc.isInvalid())
406     return 0;
407 
408   // Use the expansion location to determine which module we're in.
409   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
410   if (!ExpansionLoc.isFileID())
411     return 0;
412 
413 
414   const SourceManager &SrcMgr = Loc.getManager();
415   FileID ExpansionFileID = ExpansionLoc.getFileID();
416 
417   while (const FileEntry *ExpansionFile
418            = SrcMgr.getFileEntryForID(ExpansionFileID)) {
419     // Find the module that owns this header (if any).
420     if (Module *Mod = findModuleForHeader(ExpansionFile))
421       return Mod;
422 
423     // No module owns this header, so look up the inclusion chain to see if
424     // any included header has an associated module.
425     SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
426     if (IncludeLoc.isInvalid())
427       return 0;
428 
429     ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
430   }
431 
432   return 0;
433 }
434 
435 //----------------------------------------------------------------------------//
436 // Module map file parser
437 //----------------------------------------------------------------------------//
438 
439 namespace clang {
440   /// \brief A token in a module map file.
441   struct MMToken {
442     enum TokenKind {
443       Comma,
444       EndOfFile,
445       HeaderKeyword,
446       Identifier,
447       ExplicitKeyword,
448       ExportKeyword,
449       FrameworkKeyword,
450       ModuleKeyword,
451       Period,
452       UmbrellaKeyword,
453       RequiresKeyword,
454       Star,
455       StringLiteral,
456       LBrace,
457       RBrace
458     } Kind;
459 
460     unsigned Location;
461     unsigned StringLength;
462     const char *StringData;
463 
464     void clear() {
465       Kind = EndOfFile;
466       Location = 0;
467       StringLength = 0;
468       StringData = 0;
469     }
470 
471     bool is(TokenKind K) const { return Kind == K; }
472 
473     SourceLocation getLocation() const {
474       return SourceLocation::getFromRawEncoding(Location);
475     }
476 
477     StringRef getString() const {
478       return StringRef(StringData, StringLength);
479     }
480   };
481 
482   class ModuleMapParser {
483     Lexer &L;
484     SourceManager &SourceMgr;
485     DiagnosticsEngine &Diags;
486     ModuleMap &Map;
487 
488     /// \brief The directory that this module map resides in.
489     const DirectoryEntry *Directory;
490 
491     /// \brief Whether an error occurred.
492     bool HadError;
493 
494     /// \brief Default target information, used only for string literal
495     /// parsing.
496     TargetInfo *Target;
497 
498     /// \brief Stores string data for the various string literals referenced
499     /// during parsing.
500     llvm::BumpPtrAllocator StringData;
501 
502     /// \brief The current token.
503     MMToken Tok;
504 
505     /// \brief The active module.
506     Module *ActiveModule;
507 
508     /// \brief Consume the current token and return its location.
509     SourceLocation consumeToken();
510 
511     /// \brief Skip tokens until we reach the a token with the given kind
512     /// (or the end of the file).
513     void skipUntil(MMToken::TokenKind K);
514 
515     typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
516       ModuleId;
517     bool parseModuleId(ModuleId &Id);
518     void parseModuleDecl();
519     void parseRequiresDecl();
520     void parseHeaderDecl(SourceLocation UmbrellaLoc);
521     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
522     void parseExportDecl();
523     void parseInferredSubmoduleDecl(bool Explicit);
524 
525     const DirectoryEntry *getOverriddenHeaderSearchDir();
526 
527   public:
528     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
529                              DiagnosticsEngine &Diags,
530                              ModuleMap &Map,
531                              const DirectoryEntry *Directory)
532       : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
533         Directory(Directory), HadError(false), ActiveModule(0)
534     {
535       TargetOptions TargetOpts;
536       TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
537       Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
538 
539       Tok.clear();
540       consumeToken();
541     }
542 
543     bool parseModuleMapFile();
544   };
545 }
546 
547 SourceLocation ModuleMapParser::consumeToken() {
548 retry:
549   SourceLocation Result = Tok.getLocation();
550   Tok.clear();
551 
552   Token LToken;
553   L.LexFromRawLexer(LToken);
554   Tok.Location = LToken.getLocation().getRawEncoding();
555   switch (LToken.getKind()) {
556   case tok::raw_identifier:
557     Tok.StringData = LToken.getRawIdentifierData();
558     Tok.StringLength = LToken.getLength();
559     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
560                  .Case("header", MMToken::HeaderKeyword)
561                  .Case("explicit", MMToken::ExplicitKeyword)
562                  .Case("export", MMToken::ExportKeyword)
563                  .Case("framework", MMToken::FrameworkKeyword)
564                  .Case("module", MMToken::ModuleKeyword)
565                  .Case("requires", MMToken::RequiresKeyword)
566                  .Case("umbrella", MMToken::UmbrellaKeyword)
567                  .Default(MMToken::Identifier);
568     break;
569 
570   case tok::comma:
571     Tok.Kind = MMToken::Comma;
572     break;
573 
574   case tok::eof:
575     Tok.Kind = MMToken::EndOfFile;
576     break;
577 
578   case tok::l_brace:
579     Tok.Kind = MMToken::LBrace;
580     break;
581 
582   case tok::period:
583     Tok.Kind = MMToken::Period;
584     break;
585 
586   case tok::r_brace:
587     Tok.Kind = MMToken::RBrace;
588     break;
589 
590   case tok::star:
591     Tok.Kind = MMToken::Star;
592     break;
593 
594   case tok::string_literal: {
595     // Parse the string literal.
596     LangOptions LangOpts;
597     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
598     if (StringLiteral.hadError)
599       goto retry;
600 
601     // Copy the string literal into our string data allocator.
602     unsigned Length = StringLiteral.GetStringLength();
603     char *Saved = StringData.Allocate<char>(Length + 1);
604     memcpy(Saved, StringLiteral.GetString().data(), Length);
605     Saved[Length] = 0;
606 
607     // Form the token.
608     Tok.Kind = MMToken::StringLiteral;
609     Tok.StringData = Saved;
610     Tok.StringLength = Length;
611     break;
612   }
613 
614   case tok::comment:
615     goto retry;
616 
617   default:
618     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
619     HadError = true;
620     goto retry;
621   }
622 
623   return Result;
624 }
625 
626 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
627   unsigned braceDepth = 0;
628   do {
629     switch (Tok.Kind) {
630     case MMToken::EndOfFile:
631       return;
632 
633     case MMToken::LBrace:
634       if (Tok.is(K) && braceDepth == 0)
635         return;
636 
637       ++braceDepth;
638       break;
639 
640     case MMToken::RBrace:
641       if (braceDepth > 0)
642         --braceDepth;
643       else if (Tok.is(K))
644         return;
645       break;
646 
647     default:
648       if (braceDepth == 0 && Tok.is(K))
649         return;
650       break;
651     }
652 
653    consumeToken();
654   } while (true);
655 }
656 
657 /// \brief Parse a module-id.
658 ///
659 ///   module-id:
660 ///     identifier
661 ///     identifier '.' module-id
662 ///
663 /// \returns true if an error occurred, false otherwise.
664 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
665   Id.clear();
666   do {
667     if (Tok.is(MMToken::Identifier)) {
668       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
669       consumeToken();
670     } else {
671       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
672       return true;
673     }
674 
675     if (!Tok.is(MMToken::Period))
676       break;
677 
678     consumeToken();
679   } while (true);
680 
681   return false;
682 }
683 
684 /// \brief Parse a module declaration.
685 ///
686 ///   module-declaration:
687 ///     'explicit'[opt] 'framework'[opt] 'module' module-id { module-member* }
688 ///
689 ///   module-member:
690 ///     requires-declaration
691 ///     header-declaration
692 ///     submodule-declaration
693 ///     export-declaration
694 ///
695 ///   submodule-declaration:
696 ///     module-declaration
697 ///     inferred-submodule-declaration
698 void ModuleMapParser::parseModuleDecl() {
699   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
700          Tok.is(MMToken::FrameworkKeyword));
701   // Parse 'explicit' or 'framework' keyword, if present.
702   SourceLocation ExplicitLoc;
703   bool Explicit = false;
704   bool Framework = false;
705 
706   // Parse 'explicit' keyword, if present.
707   if (Tok.is(MMToken::ExplicitKeyword)) {
708     ExplicitLoc = consumeToken();
709     Explicit = true;
710   }
711 
712   // Parse 'framework' keyword, if present.
713   if (Tok.is(MMToken::FrameworkKeyword)) {
714     consumeToken();
715     Framework = true;
716   }
717 
718   // Parse 'module' keyword.
719   if (!Tok.is(MMToken::ModuleKeyword)) {
720     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
721     consumeToken();
722     HadError = true;
723     return;
724   }
725   consumeToken(); // 'module' keyword
726 
727   // If we have a wildcard for the module name, this is an inferred submodule.
728   // Parse it.
729   if (Tok.is(MMToken::Star))
730     return parseInferredSubmoduleDecl(Explicit);
731 
732   // Parse the module name.
733   ModuleId Id;
734   if (parseModuleId(Id)) {
735     HadError = true;
736     return;
737   }
738 
739   if (ActiveModule) {
740     if (Id.size() > 1) {
741       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
742         << SourceRange(Id.front().second, Id.back().second);
743 
744       HadError = true;
745       return;
746     }
747   } else if (Id.size() == 1 && Explicit) {
748     // Top-level modules can't be explicit.
749     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
750     Explicit = false;
751     ExplicitLoc = SourceLocation();
752     HadError = true;
753   }
754 
755   Module *PreviousActiveModule = ActiveModule;
756   if (Id.size() > 1) {
757     // This module map defines a submodule. Go find the module of which it
758     // is a submodule.
759     ActiveModule = 0;
760     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
761       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
762         ActiveModule = Next;
763         continue;
764       }
765 
766       if (ActiveModule) {
767         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
768           << Id[I].first << ActiveModule->getTopLevelModule();
769       } else {
770         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
771       }
772       HadError = true;
773       return;
774     }
775   }
776 
777   StringRef ModuleName = Id.back().first;
778   SourceLocation ModuleNameLoc = Id.back().second;
779 
780   // Parse the opening brace.
781   if (!Tok.is(MMToken::LBrace)) {
782     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
783       << ModuleName;
784     HadError = true;
785     return;
786   }
787   SourceLocation LBraceLoc = consumeToken();
788 
789   // Determine whether this (sub)module has already been defined.
790   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
791     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
792       // Skip the module definition.
793       skipUntil(MMToken::RBrace);
794       if (Tok.is(MMToken::RBrace))
795         consumeToken();
796       else {
797         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
798         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
799         HadError = true;
800       }
801       return;
802     }
803 
804     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
805       << ModuleName;
806     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
807 
808     // Skip the module definition.
809     skipUntil(MMToken::RBrace);
810     if (Tok.is(MMToken::RBrace))
811       consumeToken();
812 
813     HadError = true;
814     return;
815   }
816 
817   // Start defining this module.
818   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
819                                         Explicit).first;
820   ActiveModule->DefinitionLoc = ModuleNameLoc;
821 
822   bool Done = false;
823   do {
824     switch (Tok.Kind) {
825     case MMToken::EndOfFile:
826     case MMToken::RBrace:
827       Done = true;
828       break;
829 
830     case MMToken::ExplicitKeyword:
831     case MMToken::FrameworkKeyword:
832     case MMToken::ModuleKeyword:
833       parseModuleDecl();
834       break;
835 
836     case MMToken::ExportKeyword:
837       parseExportDecl();
838       break;
839 
840     case MMToken::RequiresKeyword:
841       parseRequiresDecl();
842       break;
843 
844     case MMToken::UmbrellaKeyword: {
845       SourceLocation UmbrellaLoc = consumeToken();
846       if (Tok.is(MMToken::HeaderKeyword))
847         parseHeaderDecl(UmbrellaLoc);
848       else
849         parseUmbrellaDirDecl(UmbrellaLoc);
850       break;
851     }
852 
853     case MMToken::HeaderKeyword:
854       parseHeaderDecl(SourceLocation());
855       break;
856 
857     default:
858       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
859       consumeToken();
860       break;
861     }
862   } while (!Done);
863 
864   if (Tok.is(MMToken::RBrace))
865     consumeToken();
866   else {
867     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
868     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
869     HadError = true;
870   }
871 
872   // We're done parsing this module. Pop back to the previous module.
873   ActiveModule = PreviousActiveModule;
874 }
875 
876 /// \brief Parse a requires declaration.
877 ///
878 ///   requires-declaration:
879 ///     'requires' feature-list
880 ///
881 ///   feature-list:
882 ///     identifier ',' feature-list
883 ///     identifier
884 void ModuleMapParser::parseRequiresDecl() {
885   assert(Tok.is(MMToken::RequiresKeyword));
886 
887   // Parse 'requires' keyword.
888   consumeToken();
889 
890   // Parse the feature-list.
891   do {
892     if (!Tok.is(MMToken::Identifier)) {
893       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
894       HadError = true;
895       return;
896     }
897 
898     // Consume the feature name.
899     std::string Feature = Tok.getString();
900     consumeToken();
901 
902     // Add this feature.
903     ActiveModule->addRequirement(Feature, Map.LangOpts);
904 
905     if (!Tok.is(MMToken::Comma))
906       break;
907 
908     // Consume the comma.
909     consumeToken();
910   } while (true);
911 }
912 
913 /// \brief Append to \p Paths the set of paths needed to get to the
914 /// subframework in which the given module lives.
915 void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) {
916   // Collect the framework names from the given module to the top-level module.
917   llvm::SmallVector<StringRef, 2> Paths;
918   for (; Mod; Mod = Mod->Parent) {
919     if (Mod->IsFramework)
920       Paths.push_back(Mod->Name);
921   }
922 
923   if (Paths.empty())
924     return;
925 
926   // Add Frameworks/Name.framework for each subframework.
927   for (unsigned I = Paths.size() - 1; I != 0; --I) {
928     llvm::sys::path::append(Path, "Frameworks");
929     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
930   }
931 }
932 
933 /// \brief Parse a header declaration.
934 ///
935 ///   header-declaration:
936 ///     'umbrella'[opt] 'header' string-literal
937 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) {
938   assert(Tok.is(MMToken::HeaderKeyword));
939   consumeToken();
940 
941   bool Umbrella = UmbrellaLoc.isValid();
942 
943   // Parse the header name.
944   if (!Tok.is(MMToken::StringLiteral)) {
945     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
946       << "header";
947     HadError = true;
948     return;
949   }
950   std::string FileName = Tok.getString();
951   SourceLocation FileNameLoc = consumeToken();
952 
953   // Check whether we already have an umbrella.
954   if (Umbrella && ActiveModule->Umbrella) {
955     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
956       << ActiveModule->getFullModuleName();
957     HadError = true;
958     return;
959   }
960 
961   // Look for this file.
962   const FileEntry *File = 0;
963   llvm::SmallString<128> PathName;
964   if (llvm::sys::path::is_absolute(FileName)) {
965     PathName = FileName;
966     File = SourceMgr.getFileManager().getFile(PathName);
967   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
968     PathName = Dir->getName();
969     llvm::sys::path::append(PathName, FileName);
970     File = SourceMgr.getFileManager().getFile(PathName);
971   } else {
972     // Search for the header file within the search directory.
973     PathName = Directory->getName();
974     unsigned PathLength = PathName.size();
975 
976     if (ActiveModule->isPartOfFramework()) {
977       appendSubframeworkPaths(ActiveModule, PathName);
978 
979       // Check whether this file is in the public headers.
980       llvm::sys::path::append(PathName, "Headers");
981       llvm::sys::path::append(PathName, FileName);
982       File = SourceMgr.getFileManager().getFile(PathName);
983 
984       if (!File) {
985         // Check whether this file is in the private headers.
986         PathName.resize(PathLength);
987         llvm::sys::path::append(PathName, "PrivateHeaders");
988         llvm::sys::path::append(PathName, FileName);
989         File = SourceMgr.getFileManager().getFile(PathName);
990       }
991     } else {
992       // Lookup for normal headers.
993       llvm::sys::path::append(PathName, FileName);
994       File = SourceMgr.getFileManager().getFile(PathName);
995     }
996   }
997 
998   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
999   // Come up with a lazy way to do this.
1000   if (File) {
1001     if (const Module *OwningModule = Map.Headers[File]) {
1002       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
1003         << FileName << OwningModule->getFullModuleName();
1004       HadError = true;
1005     } else if (Umbrella) {
1006       const DirectoryEntry *UmbrellaDir = File->getDir();
1007       if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) {
1008         Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1009           << OwningModule->getFullModuleName();
1010         HadError = true;
1011       } else {
1012         // Record this umbrella header.
1013         Map.setUmbrellaHeader(ActiveModule, File);
1014       }
1015     } else {
1016       // Record this header.
1017       Map.addHeader(ActiveModule, File);
1018     }
1019   } else {
1020     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1021       << Umbrella << FileName;
1022     HadError = true;
1023   }
1024 }
1025 
1026 /// \brief Parse an umbrella directory declaration.
1027 ///
1028 ///   umbrella-dir-declaration:
1029 ///     umbrella string-literal
1030 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1031   // Parse the directory name.
1032   if (!Tok.is(MMToken::StringLiteral)) {
1033     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1034       << "umbrella";
1035     HadError = true;
1036     return;
1037   }
1038 
1039   std::string DirName = Tok.getString();
1040   SourceLocation DirNameLoc = consumeToken();
1041 
1042   // Check whether we already have an umbrella.
1043   if (ActiveModule->Umbrella) {
1044     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1045       << ActiveModule->getFullModuleName();
1046     HadError = true;
1047     return;
1048   }
1049 
1050   // Look for this file.
1051   const DirectoryEntry *Dir = 0;
1052   if (llvm::sys::path::is_absolute(DirName))
1053     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1054   else {
1055     llvm::SmallString<128> PathName;
1056     PathName = Directory->getName();
1057     llvm::sys::path::append(PathName, DirName);
1058     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1059   }
1060 
1061   if (!Dir) {
1062     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1063       << DirName;
1064     HadError = true;
1065     return;
1066   }
1067 
1068   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1069     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1070       << OwningModule->getFullModuleName();
1071     HadError = true;
1072     return;
1073   }
1074 
1075   // Record this umbrella directory.
1076   Map.setUmbrellaDir(ActiveModule, Dir);
1077 }
1078 
1079 /// \brief Parse a module export declaration.
1080 ///
1081 ///   export-declaration:
1082 ///     'export' wildcard-module-id
1083 ///
1084 ///   wildcard-module-id:
1085 ///     identifier
1086 ///     '*'
1087 ///     identifier '.' wildcard-module-id
1088 void ModuleMapParser::parseExportDecl() {
1089   assert(Tok.is(MMToken::ExportKeyword));
1090   SourceLocation ExportLoc = consumeToken();
1091 
1092   // Parse the module-id with an optional wildcard at the end.
1093   ModuleId ParsedModuleId;
1094   bool Wildcard = false;
1095   do {
1096     if (Tok.is(MMToken::Identifier)) {
1097       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1098                                               Tok.getLocation()));
1099       consumeToken();
1100 
1101       if (Tok.is(MMToken::Period)) {
1102         consumeToken();
1103         continue;
1104       }
1105 
1106       break;
1107     }
1108 
1109     if(Tok.is(MMToken::Star)) {
1110       Wildcard = true;
1111       consumeToken();
1112       break;
1113     }
1114 
1115     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1116     HadError = true;
1117     return;
1118   } while (true);
1119 
1120   Module::UnresolvedExportDecl Unresolved = {
1121     ExportLoc, ParsedModuleId, Wildcard
1122   };
1123   ActiveModule->UnresolvedExports.push_back(Unresolved);
1124 }
1125 
1126 void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) {
1127   assert(Tok.is(MMToken::Star));
1128   SourceLocation StarLoc = consumeToken();
1129   bool Failed = false;
1130 
1131   // Inferred modules must be submodules.
1132   if (!ActiveModule) {
1133     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1134     Failed = true;
1135   }
1136 
1137   // Inferred modules must have umbrella directories.
1138   if (!Failed && !ActiveModule->getUmbrellaDir()) {
1139     Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1140     Failed = true;
1141   }
1142 
1143   // Check for redefinition of an inferred module.
1144   if (!Failed && ActiveModule->InferSubmodules) {
1145     Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1146     if (ActiveModule->InferredSubmoduleLoc.isValid())
1147       Diags.Report(ActiveModule->InferredSubmoduleLoc,
1148                    diag::note_mmap_prev_definition);
1149     Failed = true;
1150   }
1151 
1152   // If there were any problems with this inferred submodule, skip its body.
1153   if (Failed) {
1154     if (Tok.is(MMToken::LBrace)) {
1155       consumeToken();
1156       skipUntil(MMToken::RBrace);
1157       if (Tok.is(MMToken::RBrace))
1158         consumeToken();
1159     }
1160     HadError = true;
1161     return;
1162   }
1163 
1164   // Note that we have an inferred submodule.
1165   ActiveModule->InferSubmodules = true;
1166   ActiveModule->InferredSubmoduleLoc = StarLoc;
1167   ActiveModule->InferExplicitSubmodules = Explicit;
1168 
1169   // Parse the opening brace.
1170   if (!Tok.is(MMToken::LBrace)) {
1171     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1172     HadError = true;
1173     return;
1174   }
1175   SourceLocation LBraceLoc = consumeToken();
1176 
1177   // Parse the body of the inferred submodule.
1178   bool Done = false;
1179   do {
1180     switch (Tok.Kind) {
1181     case MMToken::EndOfFile:
1182     case MMToken::RBrace:
1183       Done = true;
1184       break;
1185 
1186     case MMToken::ExportKeyword: {
1187       consumeToken();
1188       if (Tok.is(MMToken::Star))
1189         ActiveModule->InferExportWildcard = true;
1190       else
1191         Diags.Report(Tok.getLocation(),
1192                      diag::err_mmap_expected_export_wildcard);
1193       consumeToken();
1194       break;
1195     }
1196 
1197     case MMToken::ExplicitKeyword:
1198     case MMToken::ModuleKeyword:
1199     case MMToken::HeaderKeyword:
1200     case MMToken::UmbrellaKeyword:
1201     default:
1202       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member);
1203       consumeToken();
1204       break;
1205     }
1206   } while (!Done);
1207 
1208   if (Tok.is(MMToken::RBrace))
1209     consumeToken();
1210   else {
1211     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1212     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1213     HadError = true;
1214   }
1215 }
1216 
1217 /// \brief If there is a specific header search directory due the presence
1218 /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1219 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1220   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1221     // If we have an umbrella directory, use that.
1222     if (Mod->hasUmbrellaDir())
1223       return Mod->getUmbrellaDir();
1224 
1225     // If we have a framework directory, stop looking.
1226     if (Mod->IsFramework)
1227       return 0;
1228   }
1229 
1230   return 0;
1231 }
1232 
1233 /// \brief Parse a module map file.
1234 ///
1235 ///   module-map-file:
1236 ///     module-declaration*
1237 bool ModuleMapParser::parseModuleMapFile() {
1238   do {
1239     switch (Tok.Kind) {
1240     case MMToken::EndOfFile:
1241       return HadError;
1242 
1243     case MMToken::ExplicitKeyword:
1244     case MMToken::ModuleKeyword:
1245     case MMToken::FrameworkKeyword:
1246       parseModuleDecl();
1247       break;
1248 
1249     case MMToken::Comma:
1250     case MMToken::ExportKeyword:
1251     case MMToken::HeaderKeyword:
1252     case MMToken::Identifier:
1253     case MMToken::LBrace:
1254     case MMToken::Period:
1255     case MMToken::RBrace:
1256     case MMToken::RequiresKeyword:
1257     case MMToken::Star:
1258     case MMToken::StringLiteral:
1259     case MMToken::UmbrellaKeyword:
1260       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1261       HadError = true;
1262       consumeToken();
1263       break;
1264     }
1265   } while (true);
1266 
1267   return HadError;
1268 }
1269 
1270 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1271   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1272   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1273   if (!Buffer)
1274     return true;
1275 
1276   // Parse this module map file.
1277   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1278   Diags->getClient()->BeginSourceFile(MMapLangOpts);
1279   ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir());
1280   bool Result = Parser.parseModuleMapFile();
1281   Diags->getClient()->EndSourceFile();
1282 
1283   return Result;
1284 }
1285