xref: /llvm-project/clang/lib/Lex/ModuleMap.cpp (revision f857950d391d06d490e2ecf014678b4dee24003f)
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/Diagnostic.h"
16 #include "clang/Basic/DiagnosticOptions.h"
17 #include "clang/Basic/FileManager.h"
18 #include "clang/Basic/TargetInfo.h"
19 #include "clang/Basic/TargetOptions.h"
20 #include "clang/Lex/LexDiagnostic.h"
21 #include "clang/Lex/Lexer.h"
22 #include "clang/Lex/LiteralSupport.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/ADT/StringSwitch.h"
25 #include "llvm/Support/Allocator.h"
26 #include "llvm/Support/FileSystem.h"
27 #include "llvm/Support/Host.h"
28 #include "llvm/Support/PathV2.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <stdlib.h>
31 using namespace clang;
32 
33 Module::ExportDecl
34 ModuleMap::resolveExport(Module *Mod,
35                          const Module::UnresolvedExportDecl &Unresolved,
36                          bool Complain) {
37   // We may have just a wildcard.
38   if (Unresolved.Id.empty()) {
39     assert(Unresolved.Wildcard && "Invalid unresolved export");
40     return Module::ExportDecl(0, true);
41   }
42 
43   // Find the starting module.
44   Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
45   if (!Context) {
46     if (Complain)
47       Diags->Report(Unresolved.Id[0].second,
48                     diag::err_mmap_missing_module_unqualified)
49         << Unresolved.Id[0].first << Mod->getFullModuleName();
50 
51     return Module::ExportDecl();
52   }
53 
54   // Dig into the module path.
55   for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
56     Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
57                                         Context);
58     if (!Sub) {
59       if (Complain)
60         Diags->Report(Unresolved.Id[I].second,
61                       diag::err_mmap_missing_module_qualified)
62           << Unresolved.Id[I].first << Context->getFullModuleName()
63           << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
64 
65       return Module::ExportDecl();
66     }
67 
68     Context = Sub;
69   }
70 
71   return Module::ExportDecl(Context, Unresolved.Wildcard);
72 }
73 
74 ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
75                      const LangOptions &LangOpts, const TargetInfo *Target)
76   : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0)
77 {
78   IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
79   Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
80             new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
81   Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
82   SourceMgr = new SourceManager(*Diags, FileMgr);
83 }
84 
85 ModuleMap::~ModuleMap() {
86   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
87                                         IEnd = Modules.end();
88        I != IEnd; ++I) {
89     delete I->getValue();
90   }
91 
92   delete SourceMgr;
93 }
94 
95 void ModuleMap::setTarget(const TargetInfo &Target) {
96   assert((!this->Target || this->Target == &Target) &&
97          "Improper target override");
98   this->Target = &Target;
99 }
100 
101 /// \brief "Sanitize" a filename so that it can be used as an identifier.
102 static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
103                                               SmallVectorImpl<char> &Buffer) {
104   if (Name.empty())
105     return Name;
106 
107   // Check whether the filename is already an identifier; this is the common
108   // case.
109   bool isIdentifier = true;
110   for (unsigned I = 0, N = Name.size(); I != N; ++I) {
111     if (isalpha(Name[I]) || Name[I] == '_' || (isdigit(Name[I]) && I > 0))
112       continue;
113 
114     isIdentifier = false;
115     break;
116   }
117 
118   if (!isIdentifier) {
119     // If we don't already have something with the form of an identifier,
120     // create a buffer with the sanitized name.
121     Buffer.clear();
122     if (isdigit(Name[0]))
123       Buffer.push_back('_');
124     Buffer.reserve(Buffer.size() + Name.size());
125     for (unsigned I = 0, N = Name.size(); I != N; ++I) {
126       if (isalnum(Name[I]) || isspace(Name[I]))
127         Buffer.push_back(Name[I]);
128       else
129         Buffer.push_back('_');
130     }
131 
132     Name = StringRef(Buffer.data(), Buffer.size());
133   }
134 
135   while (llvm::StringSwitch<bool>(Name)
136 #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
137 #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
138 #include "clang/Basic/TokenKinds.def"
139            .Default(false)) {
140     if (Name.data() != Buffer.data())
141       Buffer.append(Name.begin(), Name.end());
142     Buffer.push_back('_');
143     Name = StringRef(Buffer.data(), Buffer.size());
144   }
145 
146   return Name;
147 }
148 
149 Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
150   HeadersMap::iterator Known = Headers.find(File);
151   if (Known != Headers.end()) {
152     // If a header is not available, don't report that it maps to anything.
153     if (!Known->second.isAvailable())
154       return 0;
155 
156     return Known->second.getModule();
157   }
158 
159   const DirectoryEntry *Dir = File->getDir();
160   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
161 #ifdef LLVM_ON_UNIX
162   // Note: as an egregious but useful hack we use the real path here, because
163   // frameworks moving from top-level frameworks to embedded frameworks tend
164   // to be symlinked from the top-level location to the embedded location,
165   // and we need to resolve lookups as if we had found the embedded location.
166   char RealDirName[PATH_MAX];
167   StringRef DirName;
168   if (realpath(Dir->getName(), RealDirName))
169     DirName = RealDirName;
170   else
171     DirName = Dir->getName();
172 #else
173   StringRef DirName = Dir->getName();
174 #endif
175 
176   // Keep walking up the directory hierarchy, looking for a directory with
177   // an umbrella header.
178   do {
179     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
180       = UmbrellaDirs.find(Dir);
181     if (KnownDir != UmbrellaDirs.end()) {
182       Module *Result = KnownDir->second;
183 
184       // Search up the module stack until we find a module with an umbrella
185       // directory.
186       Module *UmbrellaModule = Result;
187       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
188         UmbrellaModule = UmbrellaModule->Parent;
189 
190       if (UmbrellaModule->InferSubmodules) {
191         // Infer submodules for each of the directories we found between
192         // the directory of the umbrella header and the directory where
193         // the actual header is located.
194         bool Explicit = UmbrellaModule->InferExplicitSubmodules;
195 
196         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
197           // Find or create the module that corresponds to this directory name.
198           SmallString<32> NameBuf;
199           StringRef Name = sanitizeFilenameAsIdentifier(
200                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
201                              NameBuf);
202           Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
203                                       Explicit).first;
204 
205           // Associate the module and the directory.
206           UmbrellaDirs[SkippedDirs[I-1]] = Result;
207 
208           // If inferred submodules export everything they import, add a
209           // wildcard to the set of exports.
210           if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
211             Result->Exports.push_back(Module::ExportDecl(0, true));
212         }
213 
214         // Infer a submodule with the same name as this header file.
215         SmallString<32> NameBuf;
216         StringRef Name = sanitizeFilenameAsIdentifier(
217                            llvm::sys::path::stem(File->getName()), NameBuf);
218         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
219                                     Explicit).first;
220         Result->TopHeaders.insert(File);
221 
222         // If inferred submodules export everything they import, add a
223         // wildcard to the set of exports.
224         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
225           Result->Exports.push_back(Module::ExportDecl(0, true));
226       } else {
227         // Record each of the directories we stepped through as being part of
228         // the module we found, since the umbrella header covers them all.
229         for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
230           UmbrellaDirs[SkippedDirs[I]] = Result;
231       }
232 
233       Headers[File] = KnownHeader(Result, /*Excluded=*/false);
234 
235       // If a header corresponds to an unavailable module, don't report
236       // that it maps to anything.
237       if (!Result->isAvailable())
238         return 0;
239 
240       return Result;
241     }
242 
243     SkippedDirs.push_back(Dir);
244 
245     // Retrieve our parent path.
246     DirName = llvm::sys::path::parent_path(DirName);
247     if (DirName.empty())
248       break;
249 
250     // Resolve the parent path to a directory entry.
251     Dir = SourceMgr->getFileManager().getDirectory(DirName);
252   } while (Dir);
253 
254   return 0;
255 }
256 
257 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
258   HeadersMap::iterator Known = Headers.find(Header);
259   if (Known != Headers.end())
260     return !Known->second.isAvailable();
261 
262   const DirectoryEntry *Dir = Header->getDir();
263   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
264   StringRef DirName = Dir->getName();
265 
266   // Keep walking up the directory hierarchy, looking for a directory with
267   // an umbrella header.
268   do {
269     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
270       = UmbrellaDirs.find(Dir);
271     if (KnownDir != UmbrellaDirs.end()) {
272       Module *Found = KnownDir->second;
273       if (!Found->isAvailable())
274         return true;
275 
276       // Search up the module stack until we find a module with an umbrella
277       // directory.
278       Module *UmbrellaModule = Found;
279       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
280         UmbrellaModule = UmbrellaModule->Parent;
281 
282       if (UmbrellaModule->InferSubmodules) {
283         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
284           // Find or create the module that corresponds to this directory name.
285           SmallString<32> NameBuf;
286           StringRef Name = sanitizeFilenameAsIdentifier(
287                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
288                              NameBuf);
289           Found = lookupModuleQualified(Name, Found);
290           if (!Found)
291             return false;
292           if (!Found->isAvailable())
293             return true;
294         }
295 
296         // Infer a submodule with the same name as this header file.
297         SmallString<32> NameBuf;
298         StringRef Name = sanitizeFilenameAsIdentifier(
299                            llvm::sys::path::stem(Header->getName()),
300                            NameBuf);
301         Found = lookupModuleQualified(Name, Found);
302         if (!Found)
303           return false;
304       }
305 
306       return !Found->isAvailable();
307     }
308 
309     SkippedDirs.push_back(Dir);
310 
311     // Retrieve our parent path.
312     DirName = llvm::sys::path::parent_path(DirName);
313     if (DirName.empty())
314       break;
315 
316     // Resolve the parent path to a directory entry.
317     Dir = SourceMgr->getFileManager().getDirectory(DirName);
318   } while (Dir);
319 
320   return false;
321 }
322 
323 Module *ModuleMap::findModule(StringRef Name) {
324   llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
325   if (Known != Modules.end())
326     return Known->getValue();
327 
328   return 0;
329 }
330 
331 Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
332   for(; Context; Context = Context->Parent) {
333     if (Module *Sub = lookupModuleQualified(Name, Context))
334       return Sub;
335   }
336 
337   return findModule(Name);
338 }
339 
340 Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
341   if (!Context)
342     return findModule(Name);
343 
344   return Context->findSubmodule(Name);
345 }
346 
347 std::pair<Module *, bool>
348 ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
349                               bool IsExplicit) {
350   // Try to find an existing module with this name.
351   if (Module *Sub = lookupModuleQualified(Name, Parent))
352     return std::make_pair(Sub, false);
353 
354   // Create a new module with this name.
355   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
356                               IsExplicit);
357   if (!Parent)
358     Modules[Name] = Result;
359   return std::make_pair(Result, true);
360 }
361 
362 bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
363                                         StringRef Name, bool &IsSystem) {
364   // Check whether we have already looked into the parent directory
365   // for a module map.
366   llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
367     inferred = InferredDirectories.find(ParentDir);
368   if (inferred == InferredDirectories.end())
369     return false;
370 
371   if (!inferred->second.InferModules)
372     return false;
373 
374   // We're allowed to infer for this directory, but make sure it's okay
375   // to infer this particular module.
376   bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
377                             inferred->second.ExcludedModules.end(),
378                             Name) == inferred->second.ExcludedModules.end();
379 
380   if (canInfer && inferred->second.InferSystemModules)
381     IsSystem = true;
382 
383   return canInfer;
384 }
385 
386 Module *
387 ModuleMap::inferFrameworkModule(StringRef ModuleName,
388                                 const DirectoryEntry *FrameworkDir,
389                                 bool IsSystem,
390                                 Module *Parent) {
391   // Check whether we've already found this module.
392   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
393     return Mod;
394 
395   FileManager &FileMgr = SourceMgr->getFileManager();
396 
397   // If the framework has a parent path from which we're allowed to infer
398   // a framework module, do so.
399   if (!Parent) {
400     // Determine whether we're allowed to infer a module map.
401     StringRef FrameworkDirName = FrameworkDir->getName();
402 #ifdef LLVM_ON_UNIX
403     // Note: as an egregious but useful hack we use the real path here, because
404     // we might be looking at an embedded framework that symlinks out to a
405     // top-level framework, and we need to infer as if we were naming the
406     // top-level framework.
407     char RealFrameworkDirName[PATH_MAX];
408     if (realpath(FrameworkDir->getName(), RealFrameworkDirName))
409       FrameworkDirName = RealFrameworkDirName;
410 #endif
411 
412     bool canInfer = false;
413     if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
414       // Figure out the parent path.
415       StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
416       if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
417         // Check whether we have already looked into the parent directory
418         // for a module map.
419         llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
420           inferred = InferredDirectories.find(ParentDir);
421         if (inferred == InferredDirectories.end()) {
422           // We haven't looked here before. Load a module map, if there is
423           // one.
424           SmallString<128> ModMapPath = Parent;
425           llvm::sys::path::append(ModMapPath, "module.map");
426           if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
427             parseModuleMapFile(ModMapFile);
428             inferred = InferredDirectories.find(ParentDir);
429           }
430 
431           if (inferred == InferredDirectories.end())
432             inferred = InferredDirectories.insert(
433                          std::make_pair(ParentDir, InferredDirectory())).first;
434         }
435 
436         if (inferred->second.InferModules) {
437           // We're allowed to infer for this directory, but make sure it's okay
438           // to infer this particular module.
439           StringRef Name = llvm::sys::path::stem(FrameworkDirName);
440           canInfer = std::find(inferred->second.ExcludedModules.begin(),
441                                inferred->second.ExcludedModules.end(),
442                                Name) == inferred->second.ExcludedModules.end();
443 
444           if (inferred->second.InferSystemModules)
445             IsSystem = true;
446         }
447       }
448     }
449 
450     // If we're not allowed to infer a framework module, don't.
451     if (!canInfer)
452       return 0;
453   }
454 
455 
456   // Look for an umbrella header.
457   SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
458   llvm::sys::path::append(UmbrellaName, "Headers");
459   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
460   const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
461 
462   // FIXME: If there's no umbrella header, we could probably scan the
463   // framework to load *everything*. But, it's not clear that this is a good
464   // idea.
465   if (!UmbrellaHeader)
466     return 0;
467 
468   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
469                               /*IsFramework=*/true, /*IsExplicit=*/false);
470   if (IsSystem)
471     Result->IsSystem = IsSystem;
472 
473   if (!Parent)
474     Modules[ModuleName] = Result;
475 
476   // umbrella header "umbrella-header-name"
477   Result->Umbrella = UmbrellaHeader;
478   Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
479   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
480 
481   // export *
482   Result->Exports.push_back(Module::ExportDecl(0, true));
483 
484   // module * { export * }
485   Result->InferSubmodules = true;
486   Result->InferExportWildcard = true;
487 
488   // Look for subframeworks.
489   llvm::error_code EC;
490   SmallString<128> SubframeworksDirName
491     = StringRef(FrameworkDir->getName());
492   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
493   SmallString<128> SubframeworksDirNameNative;
494   llvm::sys::path::native(SubframeworksDirName.str(),
495                           SubframeworksDirNameNative);
496   for (llvm::sys::fs::directory_iterator
497          Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
498        Dir != DirEnd && !EC; Dir.increment(EC)) {
499     if (!StringRef(Dir->path()).endswith(".framework"))
500       continue;
501 
502     if (const DirectoryEntry *SubframeworkDir
503           = FileMgr.getDirectory(Dir->path())) {
504       // Note: as an egregious but useful hack, we use the real path here and
505       // check whether it is actually a subdirectory of the parent directory.
506       // This will not be the case if the 'subframework' is actually a symlink
507       // out to a top-level framework.
508 #ifdef LLVM_ON_UNIX
509       char RealSubframeworkDirName[PATH_MAX];
510       if (realpath(Dir->path().c_str(), RealSubframeworkDirName)) {
511         StringRef SubframeworkDirName = RealSubframeworkDirName;
512 
513         bool FoundParent = false;
514         do {
515           // Get the parent directory name.
516           SubframeworkDirName
517             = llvm::sys::path::parent_path(SubframeworkDirName);
518           if (SubframeworkDirName.empty())
519             break;
520 
521           if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
522             FoundParent = true;
523             break;
524           }
525         } while (true);
526 
527         if (!FoundParent)
528           continue;
529       }
530 #endif
531 
532       // FIXME: Do we want to warn about subframeworks without umbrella headers?
533       SmallString<32> NameBuf;
534       inferFrameworkModule(sanitizeFilenameAsIdentifier(
535                              llvm::sys::path::stem(Dir->path()), NameBuf),
536                            SubframeworkDir, IsSystem, Result);
537     }
538   }
539 
540   return Result;
541 }
542 
543 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
544   Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
545   Mod->Umbrella = UmbrellaHeader;
546   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
547 }
548 
549 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
550   Mod->Umbrella = UmbrellaDir;
551   UmbrellaDirs[UmbrellaDir] = Mod;
552 }
553 
554 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
555                           bool Excluded) {
556   if (Excluded)
557     Mod->ExcludedHeaders.push_back(Header);
558   else
559     Mod->Headers.push_back(Header);
560   Headers[Header] = KnownHeader(Mod, Excluded);
561 }
562 
563 const FileEntry *
564 ModuleMap::getContainingModuleMapFile(Module *Module) {
565   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
566     return 0;
567 
568   return SourceMgr->getFileEntryForID(
569            SourceMgr->getFileID(Module->DefinitionLoc));
570 }
571 
572 void ModuleMap::dump() {
573   llvm::errs() << "Modules:";
574   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
575                                         MEnd = Modules.end();
576        M != MEnd; ++M)
577     M->getValue()->print(llvm::errs(), 2);
578 
579   llvm::errs() << "Headers:";
580   for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
581        H != HEnd; ++H) {
582     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
583                  << H->second.getModule()->getFullModuleName() << "\n";
584   }
585 }
586 
587 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
588   bool HadError = false;
589   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
590     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
591                                               Complain);
592     if (Export.getPointer() || Export.getInt())
593       Mod->Exports.push_back(Export);
594     else
595       HadError = true;
596   }
597   Mod->UnresolvedExports.clear();
598   return HadError;
599 }
600 
601 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
602   if (Loc.isInvalid())
603     return 0;
604 
605   // Use the expansion location to determine which module we're in.
606   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
607   if (!ExpansionLoc.isFileID())
608     return 0;
609 
610 
611   const SourceManager &SrcMgr = Loc.getManager();
612   FileID ExpansionFileID = ExpansionLoc.getFileID();
613 
614   while (const FileEntry *ExpansionFile
615            = SrcMgr.getFileEntryForID(ExpansionFileID)) {
616     // Find the module that owns this header (if any).
617     if (Module *Mod = findModuleForHeader(ExpansionFile))
618       return Mod;
619 
620     // No module owns this header, so look up the inclusion chain to see if
621     // any included header has an associated module.
622     SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
623     if (IncludeLoc.isInvalid())
624       return 0;
625 
626     ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
627   }
628 
629   return 0;
630 }
631 
632 //----------------------------------------------------------------------------//
633 // Module map file parser
634 //----------------------------------------------------------------------------//
635 
636 namespace clang {
637   /// \brief A token in a module map file.
638   struct MMToken {
639     enum TokenKind {
640       Comma,
641       EndOfFile,
642       HeaderKeyword,
643       Identifier,
644       ExcludeKeyword,
645       ExplicitKeyword,
646       ExportKeyword,
647       FrameworkKeyword,
648       ModuleKeyword,
649       Period,
650       UmbrellaKeyword,
651       RequiresKeyword,
652       Star,
653       StringLiteral,
654       LBrace,
655       RBrace,
656       LSquare,
657       RSquare
658     } Kind;
659 
660     unsigned Location;
661     unsigned StringLength;
662     const char *StringData;
663 
664     void clear() {
665       Kind = EndOfFile;
666       Location = 0;
667       StringLength = 0;
668       StringData = 0;
669     }
670 
671     bool is(TokenKind K) const { return Kind == K; }
672 
673     SourceLocation getLocation() const {
674       return SourceLocation::getFromRawEncoding(Location);
675     }
676 
677     StringRef getString() const {
678       return StringRef(StringData, StringLength);
679     }
680   };
681 
682   /// \brief The set of attributes that can be attached to a module.
683   struct Attributes {
684     Attributes() : IsSystem() { }
685 
686     /// \brief Whether this is a system module.
687     unsigned IsSystem : 1;
688   };
689 
690 
691   class ModuleMapParser {
692     Lexer &L;
693     SourceManager &SourceMgr;
694 
695     /// \brief Default target information, used only for string literal
696     /// parsing.
697     const TargetInfo *Target;
698 
699     DiagnosticsEngine &Diags;
700     ModuleMap &Map;
701 
702     /// \brief The directory that this module map resides in.
703     const DirectoryEntry *Directory;
704 
705     /// \brief The directory containing Clang-supplied headers.
706     const DirectoryEntry *BuiltinIncludeDir;
707 
708     /// \brief Whether an error occurred.
709     bool HadError;
710 
711     /// \brief Stores string data for the various string literals referenced
712     /// during parsing.
713     llvm::BumpPtrAllocator StringData;
714 
715     /// \brief The current token.
716     MMToken Tok;
717 
718     /// \brief The active module.
719     Module *ActiveModule;
720 
721     /// \brief Consume the current token and return its location.
722     SourceLocation consumeToken();
723 
724     /// \brief Skip tokens until we reach the a token with the given kind
725     /// (or the end of the file).
726     void skipUntil(MMToken::TokenKind K);
727 
728     typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
729     bool parseModuleId(ModuleId &Id);
730     void parseModuleDecl();
731     void parseRequiresDecl();
732     void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
733     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
734     void parseExportDecl();
735     void parseInferredModuleDecl(bool Framework, bool Explicit);
736     bool parseOptionalAttributes(Attributes &Attrs);
737 
738     const DirectoryEntry *getOverriddenHeaderSearchDir();
739 
740   public:
741     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
742                              const TargetInfo *Target,
743                              DiagnosticsEngine &Diags,
744                              ModuleMap &Map,
745                              const DirectoryEntry *Directory,
746                              const DirectoryEntry *BuiltinIncludeDir)
747       : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
748         Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
749         HadError(false), ActiveModule(0)
750     {
751       Tok.clear();
752       consumeToken();
753     }
754 
755     bool parseModuleMapFile();
756   };
757 }
758 
759 SourceLocation ModuleMapParser::consumeToken() {
760 retry:
761   SourceLocation Result = Tok.getLocation();
762   Tok.clear();
763 
764   Token LToken;
765   L.LexFromRawLexer(LToken);
766   Tok.Location = LToken.getLocation().getRawEncoding();
767   switch (LToken.getKind()) {
768   case tok::raw_identifier:
769     Tok.StringData = LToken.getRawIdentifierData();
770     Tok.StringLength = LToken.getLength();
771     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
772                  .Case("header", MMToken::HeaderKeyword)
773                  .Case("exclude", MMToken::ExcludeKeyword)
774                  .Case("explicit", MMToken::ExplicitKeyword)
775                  .Case("export", MMToken::ExportKeyword)
776                  .Case("framework", MMToken::FrameworkKeyword)
777                  .Case("module", MMToken::ModuleKeyword)
778                  .Case("requires", MMToken::RequiresKeyword)
779                  .Case("umbrella", MMToken::UmbrellaKeyword)
780                  .Default(MMToken::Identifier);
781     break;
782 
783   case tok::comma:
784     Tok.Kind = MMToken::Comma;
785     break;
786 
787   case tok::eof:
788     Tok.Kind = MMToken::EndOfFile;
789     break;
790 
791   case tok::l_brace:
792     Tok.Kind = MMToken::LBrace;
793     break;
794 
795   case tok::l_square:
796     Tok.Kind = MMToken::LSquare;
797     break;
798 
799   case tok::period:
800     Tok.Kind = MMToken::Period;
801     break;
802 
803   case tok::r_brace:
804     Tok.Kind = MMToken::RBrace;
805     break;
806 
807   case tok::r_square:
808     Tok.Kind = MMToken::RSquare;
809     break;
810 
811   case tok::star:
812     Tok.Kind = MMToken::Star;
813     break;
814 
815   case tok::string_literal: {
816     if (LToken.hasUDSuffix()) {
817       Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
818       HadError = true;
819       goto retry;
820     }
821 
822     // Parse the string literal.
823     LangOptions LangOpts;
824     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
825     if (StringLiteral.hadError)
826       goto retry;
827 
828     // Copy the string literal into our string data allocator.
829     unsigned Length = StringLiteral.GetStringLength();
830     char *Saved = StringData.Allocate<char>(Length + 1);
831     memcpy(Saved, StringLiteral.GetString().data(), Length);
832     Saved[Length] = 0;
833 
834     // Form the token.
835     Tok.Kind = MMToken::StringLiteral;
836     Tok.StringData = Saved;
837     Tok.StringLength = Length;
838     break;
839   }
840 
841   case tok::comment:
842     goto retry;
843 
844   default:
845     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
846     HadError = true;
847     goto retry;
848   }
849 
850   return Result;
851 }
852 
853 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
854   unsigned braceDepth = 0;
855   unsigned squareDepth = 0;
856   do {
857     switch (Tok.Kind) {
858     case MMToken::EndOfFile:
859       return;
860 
861     case MMToken::LBrace:
862       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
863         return;
864 
865       ++braceDepth;
866       break;
867 
868     case MMToken::LSquare:
869       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
870         return;
871 
872       ++squareDepth;
873       break;
874 
875     case MMToken::RBrace:
876       if (braceDepth > 0)
877         --braceDepth;
878       else if (Tok.is(K))
879         return;
880       break;
881 
882     case MMToken::RSquare:
883       if (squareDepth > 0)
884         --squareDepth;
885       else if (Tok.is(K))
886         return;
887       break;
888 
889     default:
890       if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
891         return;
892       break;
893     }
894 
895    consumeToken();
896   } while (true);
897 }
898 
899 /// \brief Parse a module-id.
900 ///
901 ///   module-id:
902 ///     identifier
903 ///     identifier '.' module-id
904 ///
905 /// \returns true if an error occurred, false otherwise.
906 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
907   Id.clear();
908   do {
909     if (Tok.is(MMToken::Identifier)) {
910       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
911       consumeToken();
912     } else {
913       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
914       return true;
915     }
916 
917     if (!Tok.is(MMToken::Period))
918       break;
919 
920     consumeToken();
921   } while (true);
922 
923   return false;
924 }
925 
926 namespace {
927   /// \brief Enumerates the known attributes.
928   enum AttributeKind {
929     /// \brief An unknown attribute.
930     AT_unknown,
931     /// \brief The 'system' attribute.
932     AT_system
933   };
934 }
935 
936 /// \brief Parse a module declaration.
937 ///
938 ///   module-declaration:
939 ///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
940 ///       { module-member* }
941 ///
942 ///   module-member:
943 ///     requires-declaration
944 ///     header-declaration
945 ///     submodule-declaration
946 ///     export-declaration
947 ///
948 ///   submodule-declaration:
949 ///     module-declaration
950 ///     inferred-submodule-declaration
951 void ModuleMapParser::parseModuleDecl() {
952   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
953          Tok.is(MMToken::FrameworkKeyword));
954   // Parse 'explicit' or 'framework' keyword, if present.
955   SourceLocation ExplicitLoc;
956   bool Explicit = false;
957   bool Framework = false;
958 
959   // Parse 'explicit' keyword, if present.
960   if (Tok.is(MMToken::ExplicitKeyword)) {
961     ExplicitLoc = consumeToken();
962     Explicit = true;
963   }
964 
965   // Parse 'framework' keyword, if present.
966   if (Tok.is(MMToken::FrameworkKeyword)) {
967     consumeToken();
968     Framework = true;
969   }
970 
971   // Parse 'module' keyword.
972   if (!Tok.is(MMToken::ModuleKeyword)) {
973     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
974     consumeToken();
975     HadError = true;
976     return;
977   }
978   consumeToken(); // 'module' keyword
979 
980   // If we have a wildcard for the module name, this is an inferred submodule.
981   // Parse it.
982   if (Tok.is(MMToken::Star))
983     return parseInferredModuleDecl(Framework, Explicit);
984 
985   // Parse the module name.
986   ModuleId Id;
987   if (parseModuleId(Id)) {
988     HadError = true;
989     return;
990   }
991 
992   if (ActiveModule) {
993     if (Id.size() > 1) {
994       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
995         << SourceRange(Id.front().second, Id.back().second);
996 
997       HadError = true;
998       return;
999     }
1000   } else if (Id.size() == 1 && Explicit) {
1001     // Top-level modules can't be explicit.
1002     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1003     Explicit = false;
1004     ExplicitLoc = SourceLocation();
1005     HadError = true;
1006   }
1007 
1008   Module *PreviousActiveModule = ActiveModule;
1009   if (Id.size() > 1) {
1010     // This module map defines a submodule. Go find the module of which it
1011     // is a submodule.
1012     ActiveModule = 0;
1013     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1014       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1015         ActiveModule = Next;
1016         continue;
1017       }
1018 
1019       if (ActiveModule) {
1020         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1021           << Id[I].first << ActiveModule->getTopLevelModule();
1022       } else {
1023         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1024       }
1025       HadError = true;
1026       return;
1027     }
1028   }
1029 
1030   StringRef ModuleName = Id.back().first;
1031   SourceLocation ModuleNameLoc = Id.back().second;
1032 
1033   // Parse the optional attribute list.
1034   Attributes Attrs;
1035   parseOptionalAttributes(Attrs);
1036 
1037   // Parse the opening brace.
1038   if (!Tok.is(MMToken::LBrace)) {
1039     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1040       << ModuleName;
1041     HadError = true;
1042     return;
1043   }
1044   SourceLocation LBraceLoc = consumeToken();
1045 
1046   // Determine whether this (sub)module has already been defined.
1047   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1048     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1049       // Skip the module definition.
1050       skipUntil(MMToken::RBrace);
1051       if (Tok.is(MMToken::RBrace))
1052         consumeToken();
1053       else {
1054         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1055         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1056         HadError = true;
1057       }
1058       return;
1059     }
1060 
1061     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1062       << ModuleName;
1063     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1064 
1065     // Skip the module definition.
1066     skipUntil(MMToken::RBrace);
1067     if (Tok.is(MMToken::RBrace))
1068       consumeToken();
1069 
1070     HadError = true;
1071     return;
1072   }
1073 
1074   // Start defining this module.
1075   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1076                                         Explicit).first;
1077   ActiveModule->DefinitionLoc = ModuleNameLoc;
1078   if (Attrs.IsSystem)
1079     ActiveModule->IsSystem = true;
1080 
1081   bool Done = false;
1082   do {
1083     switch (Tok.Kind) {
1084     case MMToken::EndOfFile:
1085     case MMToken::RBrace:
1086       Done = true;
1087       break;
1088 
1089     case MMToken::ExplicitKeyword:
1090     case MMToken::FrameworkKeyword:
1091     case MMToken::ModuleKeyword:
1092       parseModuleDecl();
1093       break;
1094 
1095     case MMToken::ExportKeyword:
1096       parseExportDecl();
1097       break;
1098 
1099     case MMToken::RequiresKeyword:
1100       parseRequiresDecl();
1101       break;
1102 
1103     case MMToken::UmbrellaKeyword: {
1104       SourceLocation UmbrellaLoc = consumeToken();
1105       if (Tok.is(MMToken::HeaderKeyword))
1106         parseHeaderDecl(UmbrellaLoc, SourceLocation());
1107       else
1108         parseUmbrellaDirDecl(UmbrellaLoc);
1109       break;
1110     }
1111 
1112     case MMToken::ExcludeKeyword: {
1113       SourceLocation ExcludeLoc = consumeToken();
1114       if (Tok.is(MMToken::HeaderKeyword)) {
1115         parseHeaderDecl(SourceLocation(), ExcludeLoc);
1116       } else {
1117         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1118           << "exclude";
1119       }
1120       break;
1121     }
1122 
1123     case MMToken::HeaderKeyword:
1124       parseHeaderDecl(SourceLocation(), SourceLocation());
1125       break;
1126 
1127     default:
1128       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1129       consumeToken();
1130       break;
1131     }
1132   } while (!Done);
1133 
1134   if (Tok.is(MMToken::RBrace))
1135     consumeToken();
1136   else {
1137     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1138     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1139     HadError = true;
1140   }
1141 
1142   // We're done parsing this module. Pop back to the previous module.
1143   ActiveModule = PreviousActiveModule;
1144 }
1145 
1146 /// \brief Parse a requires declaration.
1147 ///
1148 ///   requires-declaration:
1149 ///     'requires' feature-list
1150 ///
1151 ///   feature-list:
1152 ///     identifier ',' feature-list
1153 ///     identifier
1154 void ModuleMapParser::parseRequiresDecl() {
1155   assert(Tok.is(MMToken::RequiresKeyword));
1156 
1157   // Parse 'requires' keyword.
1158   consumeToken();
1159 
1160   // Parse the feature-list.
1161   do {
1162     if (!Tok.is(MMToken::Identifier)) {
1163       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1164       HadError = true;
1165       return;
1166     }
1167 
1168     // Consume the feature name.
1169     std::string Feature = Tok.getString();
1170     consumeToken();
1171 
1172     // Add this feature.
1173     ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
1174 
1175     if (!Tok.is(MMToken::Comma))
1176       break;
1177 
1178     // Consume the comma.
1179     consumeToken();
1180   } while (true);
1181 }
1182 
1183 /// \brief Append to \p Paths the set of paths needed to get to the
1184 /// subframework in which the given module lives.
1185 static void appendSubframeworkPaths(Module *Mod,
1186                                     SmallVectorImpl<char> &Path) {
1187   // Collect the framework names from the given module to the top-level module.
1188   SmallVector<StringRef, 2> Paths;
1189   for (; Mod; Mod = Mod->Parent) {
1190     if (Mod->IsFramework)
1191       Paths.push_back(Mod->Name);
1192   }
1193 
1194   if (Paths.empty())
1195     return;
1196 
1197   // Add Frameworks/Name.framework for each subframework.
1198   for (unsigned I = Paths.size() - 1; I != 0; --I) {
1199     llvm::sys::path::append(Path, "Frameworks");
1200     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1201   }
1202 }
1203 
1204 /// \brief Determine whether the given file name is the name of a builtin
1205 /// header, supplied by Clang to replace, override, or augment existing system
1206 /// headers.
1207 static bool isBuiltinHeader(StringRef FileName) {
1208   return llvm::StringSwitch<bool>(FileName)
1209       .Case("float.h", true)
1210       .Case("iso646.h", true)
1211       .Case("limits.h", true)
1212       .Case("stdalign.h", true)
1213       .Case("stdarg.h", true)
1214       .Case("stdbool.h", true)
1215       .Case("stddef.h", true)
1216       .Case("stdint.h", true)
1217       .Case("tgmath.h", true)
1218       .Case("unwind.h", true)
1219       .Default(false);
1220 }
1221 
1222 /// \brief Parse a header declaration.
1223 ///
1224 ///   header-declaration:
1225 ///     'umbrella'[opt] 'header' string-literal
1226 ///     'exclude'[opt] 'header' string-literal
1227 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1228                                       SourceLocation ExcludeLoc) {
1229   assert(Tok.is(MMToken::HeaderKeyword));
1230   consumeToken();
1231 
1232   bool Umbrella = UmbrellaLoc.isValid();
1233   bool Exclude = ExcludeLoc.isValid();
1234   assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
1235   // Parse the header name.
1236   if (!Tok.is(MMToken::StringLiteral)) {
1237     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1238       << "header";
1239     HadError = true;
1240     return;
1241   }
1242   std::string FileName = Tok.getString();
1243   SourceLocation FileNameLoc = consumeToken();
1244 
1245   // Check whether we already have an umbrella.
1246   if (Umbrella && ActiveModule->Umbrella) {
1247     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1248       << ActiveModule->getFullModuleName();
1249     HadError = true;
1250     return;
1251   }
1252 
1253   // Look for this file.
1254   const FileEntry *File = 0;
1255   const FileEntry *BuiltinFile = 0;
1256   SmallString<128> PathName;
1257   if (llvm::sys::path::is_absolute(FileName)) {
1258     PathName = FileName;
1259     File = SourceMgr.getFileManager().getFile(PathName);
1260   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1261     PathName = Dir->getName();
1262     llvm::sys::path::append(PathName, FileName);
1263     File = SourceMgr.getFileManager().getFile(PathName);
1264   } else {
1265     // Search for the header file within the search directory.
1266     PathName = Directory->getName();
1267     unsigned PathLength = PathName.size();
1268 
1269     if (ActiveModule->isPartOfFramework()) {
1270       appendSubframeworkPaths(ActiveModule, PathName);
1271 
1272       // Check whether this file is in the public headers.
1273       llvm::sys::path::append(PathName, "Headers");
1274       llvm::sys::path::append(PathName, FileName);
1275       File = SourceMgr.getFileManager().getFile(PathName);
1276 
1277       if (!File) {
1278         // Check whether this file is in the private headers.
1279         PathName.resize(PathLength);
1280         llvm::sys::path::append(PathName, "PrivateHeaders");
1281         llvm::sys::path::append(PathName, FileName);
1282         File = SourceMgr.getFileManager().getFile(PathName);
1283       }
1284     } else {
1285       // Lookup for normal headers.
1286       llvm::sys::path::append(PathName, FileName);
1287       File = SourceMgr.getFileManager().getFile(PathName);
1288 
1289       // If this is a system module with a top-level header, this header
1290       // may have a counterpart (or replacement) in the set of headers
1291       // supplied by Clang. Find that builtin header.
1292       if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1293           BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
1294         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1295         llvm::sys::path::append(BuiltinPathName, FileName);
1296         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1297 
1298         // If Clang supplies this header but the underlying system does not,
1299         // just silently swap in our builtin version. Otherwise, we'll end
1300         // up adding both (later).
1301         if (!File && BuiltinFile) {
1302           File = BuiltinFile;
1303           BuiltinFile = 0;
1304         }
1305       }
1306     }
1307   }
1308 
1309   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1310   // Come up with a lazy way to do this.
1311   if (File) {
1312     if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
1313       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
1314         << FileName << OwningModule.getModule()->getFullModuleName();
1315       HadError = true;
1316     } else if (Umbrella) {
1317       const DirectoryEntry *UmbrellaDir = File->getDir();
1318       if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1319         Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1320           << UmbrellaModule->getFullModuleName();
1321         HadError = true;
1322       } else {
1323         // Record this umbrella header.
1324         Map.setUmbrellaHeader(ActiveModule, File);
1325       }
1326     } else {
1327       // Record this header.
1328       Map.addHeader(ActiveModule, File, Exclude);
1329 
1330       // If there is a builtin counterpart to this file, add it now.
1331       if (BuiltinFile)
1332         Map.addHeader(ActiveModule, BuiltinFile, Exclude);
1333     }
1334   } else if (!Exclude) {
1335     // Ignore excluded header files. They're optional anyway.
1336 
1337     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1338       << Umbrella << FileName;
1339     HadError = true;
1340   }
1341 }
1342 
1343 /// \brief Parse an umbrella directory declaration.
1344 ///
1345 ///   umbrella-dir-declaration:
1346 ///     umbrella string-literal
1347 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1348   // Parse the directory name.
1349   if (!Tok.is(MMToken::StringLiteral)) {
1350     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1351       << "umbrella";
1352     HadError = true;
1353     return;
1354   }
1355 
1356   std::string DirName = Tok.getString();
1357   SourceLocation DirNameLoc = consumeToken();
1358 
1359   // Check whether we already have an umbrella.
1360   if (ActiveModule->Umbrella) {
1361     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1362       << ActiveModule->getFullModuleName();
1363     HadError = true;
1364     return;
1365   }
1366 
1367   // Look for this file.
1368   const DirectoryEntry *Dir = 0;
1369   if (llvm::sys::path::is_absolute(DirName))
1370     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1371   else {
1372     SmallString<128> PathName;
1373     PathName = Directory->getName();
1374     llvm::sys::path::append(PathName, DirName);
1375     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1376   }
1377 
1378   if (!Dir) {
1379     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1380       << DirName;
1381     HadError = true;
1382     return;
1383   }
1384 
1385   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1386     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1387       << OwningModule->getFullModuleName();
1388     HadError = true;
1389     return;
1390   }
1391 
1392   // Record this umbrella directory.
1393   Map.setUmbrellaDir(ActiveModule, Dir);
1394 }
1395 
1396 /// \brief Parse a module export declaration.
1397 ///
1398 ///   export-declaration:
1399 ///     'export' wildcard-module-id
1400 ///
1401 ///   wildcard-module-id:
1402 ///     identifier
1403 ///     '*'
1404 ///     identifier '.' wildcard-module-id
1405 void ModuleMapParser::parseExportDecl() {
1406   assert(Tok.is(MMToken::ExportKeyword));
1407   SourceLocation ExportLoc = consumeToken();
1408 
1409   // Parse the module-id with an optional wildcard at the end.
1410   ModuleId ParsedModuleId;
1411   bool Wildcard = false;
1412   do {
1413     if (Tok.is(MMToken::Identifier)) {
1414       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1415                                               Tok.getLocation()));
1416       consumeToken();
1417 
1418       if (Tok.is(MMToken::Period)) {
1419         consumeToken();
1420         continue;
1421       }
1422 
1423       break;
1424     }
1425 
1426     if(Tok.is(MMToken::Star)) {
1427       Wildcard = true;
1428       consumeToken();
1429       break;
1430     }
1431 
1432     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1433     HadError = true;
1434     return;
1435   } while (true);
1436 
1437   Module::UnresolvedExportDecl Unresolved = {
1438     ExportLoc, ParsedModuleId, Wildcard
1439   };
1440   ActiveModule->UnresolvedExports.push_back(Unresolved);
1441 }
1442 
1443 /// \brief Parse an inferried module declaration (wildcard modules).
1444 ///
1445 ///   module-declaration:
1446 ///     'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1447 ///       { inferred-module-member* }
1448 ///
1449 ///   inferred-module-member:
1450 ///     'export' '*'
1451 ///     'exclude' identifier
1452 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
1453   assert(Tok.is(MMToken::Star));
1454   SourceLocation StarLoc = consumeToken();
1455   bool Failed = false;
1456 
1457   // Inferred modules must be submodules.
1458   if (!ActiveModule && !Framework) {
1459     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1460     Failed = true;
1461   }
1462 
1463   if (ActiveModule) {
1464     // Inferred modules must have umbrella directories.
1465     if (!Failed && !ActiveModule->getUmbrellaDir()) {
1466       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1467       Failed = true;
1468     }
1469 
1470     // Check for redefinition of an inferred module.
1471     if (!Failed && ActiveModule->InferSubmodules) {
1472       Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1473       if (ActiveModule->InferredSubmoduleLoc.isValid())
1474         Diags.Report(ActiveModule->InferredSubmoduleLoc,
1475                      diag::note_mmap_prev_definition);
1476       Failed = true;
1477     }
1478 
1479     // Check for the 'framework' keyword, which is not permitted here.
1480     if (Framework) {
1481       Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1482       Framework = false;
1483     }
1484   } else if (Explicit) {
1485     Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1486     Explicit = false;
1487   }
1488 
1489   // If there were any problems with this inferred submodule, skip its body.
1490   if (Failed) {
1491     if (Tok.is(MMToken::LBrace)) {
1492       consumeToken();
1493       skipUntil(MMToken::RBrace);
1494       if (Tok.is(MMToken::RBrace))
1495         consumeToken();
1496     }
1497     HadError = true;
1498     return;
1499   }
1500 
1501   // Parse optional attributes.
1502   Attributes Attrs;
1503   parseOptionalAttributes(Attrs);
1504 
1505   if (ActiveModule) {
1506     // Note that we have an inferred submodule.
1507     ActiveModule->InferSubmodules = true;
1508     ActiveModule->InferredSubmoduleLoc = StarLoc;
1509     ActiveModule->InferExplicitSubmodules = Explicit;
1510   } else {
1511     // We'll be inferring framework modules for this directory.
1512     Map.InferredDirectories[Directory].InferModules = true;
1513     Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1514   }
1515 
1516   // Parse the opening brace.
1517   if (!Tok.is(MMToken::LBrace)) {
1518     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1519     HadError = true;
1520     return;
1521   }
1522   SourceLocation LBraceLoc = consumeToken();
1523 
1524   // Parse the body of the inferred submodule.
1525   bool Done = false;
1526   do {
1527     switch (Tok.Kind) {
1528     case MMToken::EndOfFile:
1529     case MMToken::RBrace:
1530       Done = true;
1531       break;
1532 
1533     case MMToken::ExcludeKeyword: {
1534       if (ActiveModule) {
1535         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1536           << (ActiveModule != 0);
1537         consumeToken();
1538         break;
1539       }
1540 
1541       consumeToken();
1542       if (!Tok.is(MMToken::Identifier)) {
1543         Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1544         break;
1545       }
1546 
1547       Map.InferredDirectories[Directory].ExcludedModules
1548         .push_back(Tok.getString());
1549       consumeToken();
1550       break;
1551     }
1552 
1553     case MMToken::ExportKeyword:
1554       if (!ActiveModule) {
1555         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1556           << (ActiveModule != 0);
1557         consumeToken();
1558         break;
1559       }
1560 
1561       consumeToken();
1562       if (Tok.is(MMToken::Star))
1563         ActiveModule->InferExportWildcard = true;
1564       else
1565         Diags.Report(Tok.getLocation(),
1566                      diag::err_mmap_expected_export_wildcard);
1567       consumeToken();
1568       break;
1569 
1570     case MMToken::ExplicitKeyword:
1571     case MMToken::ModuleKeyword:
1572     case MMToken::HeaderKeyword:
1573     case MMToken::UmbrellaKeyword:
1574     default:
1575       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1576           << (ActiveModule != 0);
1577       consumeToken();
1578       break;
1579     }
1580   } while (!Done);
1581 
1582   if (Tok.is(MMToken::RBrace))
1583     consumeToken();
1584   else {
1585     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1586     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1587     HadError = true;
1588   }
1589 }
1590 
1591 /// \brief Parse optional attributes.
1592 ///
1593 ///   attributes:
1594 ///     attribute attributes
1595 ///     attribute
1596 ///
1597 ///   attribute:
1598 ///     [ identifier ]
1599 ///
1600 /// \param Attrs Will be filled in with the parsed attributes.
1601 ///
1602 /// \returns true if an error occurred, false otherwise.
1603 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
1604   bool HadError = false;
1605 
1606   while (Tok.is(MMToken::LSquare)) {
1607     // Consume the '['.
1608     SourceLocation LSquareLoc = consumeToken();
1609 
1610     // Check whether we have an attribute name here.
1611     if (!Tok.is(MMToken::Identifier)) {
1612       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1613       skipUntil(MMToken::RSquare);
1614       if (Tok.is(MMToken::RSquare))
1615         consumeToken();
1616       HadError = true;
1617     }
1618 
1619     // Decode the attribute name.
1620     AttributeKind Attribute
1621       = llvm::StringSwitch<AttributeKind>(Tok.getString())
1622           .Case("system", AT_system)
1623           .Default(AT_unknown);
1624     switch (Attribute) {
1625     case AT_unknown:
1626       Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1627         << Tok.getString();
1628       break;
1629 
1630     case AT_system:
1631       Attrs.IsSystem = true;
1632       break;
1633     }
1634     consumeToken();
1635 
1636     // Consume the ']'.
1637     if (!Tok.is(MMToken::RSquare)) {
1638       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1639       Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1640       skipUntil(MMToken::RSquare);
1641       HadError = true;
1642     }
1643 
1644     if (Tok.is(MMToken::RSquare))
1645       consumeToken();
1646   }
1647 
1648   return HadError;
1649 }
1650 
1651 /// \brief If there is a specific header search directory due the presence
1652 /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1653 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1654   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1655     // If we have an umbrella directory, use that.
1656     if (Mod->hasUmbrellaDir())
1657       return Mod->getUmbrellaDir();
1658 
1659     // If we have a framework directory, stop looking.
1660     if (Mod->IsFramework)
1661       return 0;
1662   }
1663 
1664   return 0;
1665 }
1666 
1667 /// \brief Parse a module map file.
1668 ///
1669 ///   module-map-file:
1670 ///     module-declaration*
1671 bool ModuleMapParser::parseModuleMapFile() {
1672   do {
1673     switch (Tok.Kind) {
1674     case MMToken::EndOfFile:
1675       return HadError;
1676 
1677     case MMToken::ExplicitKeyword:
1678     case MMToken::ModuleKeyword:
1679     case MMToken::FrameworkKeyword:
1680       parseModuleDecl();
1681       break;
1682 
1683     case MMToken::Comma:
1684     case MMToken::ExcludeKeyword:
1685     case MMToken::ExportKeyword:
1686     case MMToken::HeaderKeyword:
1687     case MMToken::Identifier:
1688     case MMToken::LBrace:
1689     case MMToken::LSquare:
1690     case MMToken::Period:
1691     case MMToken::RBrace:
1692     case MMToken::RSquare:
1693     case MMToken::RequiresKeyword:
1694     case MMToken::Star:
1695     case MMToken::StringLiteral:
1696     case MMToken::UmbrellaKeyword:
1697       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1698       HadError = true;
1699       consumeToken();
1700       break;
1701     }
1702   } while (true);
1703 }
1704 
1705 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1706   llvm::DenseMap<const FileEntry *, bool>::iterator Known
1707     = ParsedModuleMap.find(File);
1708   if (Known != ParsedModuleMap.end())
1709     return Known->second;
1710 
1711   assert(Target != 0 && "Missing target information");
1712   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1713   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1714   if (!Buffer)
1715     return ParsedModuleMap[File] = true;
1716 
1717   // Parse this module map file.
1718   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1719   Diags->getClient()->BeginSourceFile(MMapLangOpts);
1720   ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
1721                          BuiltinIncludeDir);
1722   bool Result = Parser.parseModuleMapFile();
1723   Diags->getClient()->EndSourceFile();
1724   ParsedModuleMap[File] = Result;
1725   return Result;
1726 }
1727