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   llvm::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   llvm::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     bool canInfer = false;
401     if (llvm::sys::path::has_parent_path(FrameworkDir->getName())) {
402       // Figure out the parent path.
403       StringRef Parent = llvm::sys::path::parent_path(FrameworkDir->getName());
404       if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
405         // Check whether we have already looked into the parent directory
406         // for a module map.
407         llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::iterator
408           inferred = InferredDirectories.find(ParentDir);
409         if (inferred == InferredDirectories.end()) {
410           // We haven't looked here before. Load a module map, if there is
411           // one.
412           SmallString<128> ModMapPath = Parent;
413           llvm::sys::path::append(ModMapPath, "module.map");
414           if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
415             parseModuleMapFile(ModMapFile);
416             inferred = InferredDirectories.find(ParentDir);
417           }
418 
419           if (inferred == InferredDirectories.end())
420             inferred = InferredDirectories.insert(
421                          std::make_pair(ParentDir, InferredDirectory())).first;
422         }
423 
424         if (inferred->second.InferModules) {
425           // We're allowed to infer for this directory, but make sure it's okay
426           // to infer this particular module.
427           StringRef Name = llvm::sys::path::filename(FrameworkDir->getName());
428           canInfer = std::find(inferred->second.ExcludedModules.begin(),
429                                inferred->second.ExcludedModules.end(),
430                                Name) == inferred->second.ExcludedModules.end();
431 
432           if (inferred->second.InferSystemModules)
433             IsSystem = true;
434         }
435       }
436     }
437 
438     // If we're not allowed to infer a framework module, don't.
439     if (!canInfer)
440       return 0;
441   }
442 
443 
444   // Look for an umbrella header.
445   SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
446   llvm::sys::path::append(UmbrellaName, "Headers");
447   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
448   const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
449 
450   // FIXME: If there's no umbrella header, we could probably scan the
451   // framework to load *everything*. But, it's not clear that this is a good
452   // idea.
453   if (!UmbrellaHeader)
454     return 0;
455 
456   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
457                               /*IsFramework=*/true, /*IsExplicit=*/false);
458   if (IsSystem)
459     Result->IsSystem = IsSystem;
460 
461   if (!Parent)
462     Modules[ModuleName] = Result;
463 
464   // umbrella header "umbrella-header-name"
465   Result->Umbrella = UmbrellaHeader;
466   Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
467   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
468 
469   // export *
470   Result->Exports.push_back(Module::ExportDecl(0, true));
471 
472   // module * { export * }
473   Result->InferSubmodules = true;
474   Result->InferExportWildcard = true;
475 
476   // Look for subframeworks.
477   llvm::error_code EC;
478   SmallString<128> SubframeworksDirName
479     = StringRef(FrameworkDir->getName());
480   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
481   SmallString<128> SubframeworksDirNameNative;
482   llvm::sys::path::native(SubframeworksDirName.str(),
483                           SubframeworksDirNameNative);
484   for (llvm::sys::fs::directory_iterator
485          Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
486        Dir != DirEnd && !EC; Dir.increment(EC)) {
487     if (!StringRef(Dir->path()).endswith(".framework"))
488       continue;
489 
490     if (const DirectoryEntry *SubframeworkDir
491           = FileMgr.getDirectory(Dir->path())) {
492       // Note: as an egregious but useful hack, we use the real path here and
493       // check whether it is actually a subdirectory of the parent directory.
494       // This will not be the case if the 'subframework' is actually a symlink
495       // out to a top-level framework.
496 #ifdef LLVM_ON_UNIX
497       char RealSubframeworkDirName[PATH_MAX];
498       if (realpath(Dir->path().c_str(), RealSubframeworkDirName)) {
499         StringRef SubframeworkDirName = RealSubframeworkDirName;
500 
501         bool FoundParent = false;
502         do {
503           // Get the parent directory name.
504           SubframeworkDirName
505             = llvm::sys::path::parent_path(SubframeworkDirName);
506           if (SubframeworkDirName.empty())
507             break;
508 
509           if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
510             FoundParent = true;
511             break;
512           }
513         } while (true);
514 
515         if (!FoundParent)
516           continue;
517       }
518 #endif
519 
520       // FIXME: Do we want to warn about subframeworks without umbrella headers?
521       SmallString<32> NameBuf;
522       inferFrameworkModule(sanitizeFilenameAsIdentifier(
523                              llvm::sys::path::stem(Dir->path()), NameBuf),
524                            SubframeworkDir, IsSystem, Result);
525     }
526   }
527 
528   return Result;
529 }
530 
531 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
532   Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
533   Mod->Umbrella = UmbrellaHeader;
534   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
535 }
536 
537 void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
538   Mod->Umbrella = UmbrellaDir;
539   UmbrellaDirs[UmbrellaDir] = Mod;
540 }
541 
542 void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
543                           bool Excluded) {
544   if (Excluded)
545     Mod->ExcludedHeaders.push_back(Header);
546   else
547     Mod->Headers.push_back(Header);
548   Headers[Header] = KnownHeader(Mod, Excluded);
549 }
550 
551 const FileEntry *
552 ModuleMap::getContainingModuleMapFile(Module *Module) {
553   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
554     return 0;
555 
556   return SourceMgr->getFileEntryForID(
557            SourceMgr->getFileID(Module->DefinitionLoc));
558 }
559 
560 void ModuleMap::dump() {
561   llvm::errs() << "Modules:";
562   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
563                                         MEnd = Modules.end();
564        M != MEnd; ++M)
565     M->getValue()->print(llvm::errs(), 2);
566 
567   llvm::errs() << "Headers:";
568   for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
569        H != HEnd; ++H) {
570     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
571                  << H->second.getModule()->getFullModuleName() << "\n";
572   }
573 }
574 
575 bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
576   bool HadError = false;
577   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
578     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
579                                               Complain);
580     if (Export.getPointer() || Export.getInt())
581       Mod->Exports.push_back(Export);
582     else
583       HadError = true;
584   }
585   Mod->UnresolvedExports.clear();
586   return HadError;
587 }
588 
589 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
590   if (Loc.isInvalid())
591     return 0;
592 
593   // Use the expansion location to determine which module we're in.
594   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
595   if (!ExpansionLoc.isFileID())
596     return 0;
597 
598 
599   const SourceManager &SrcMgr = Loc.getManager();
600   FileID ExpansionFileID = ExpansionLoc.getFileID();
601 
602   while (const FileEntry *ExpansionFile
603            = SrcMgr.getFileEntryForID(ExpansionFileID)) {
604     // Find the module that owns this header (if any).
605     if (Module *Mod = findModuleForHeader(ExpansionFile))
606       return Mod;
607 
608     // No module owns this header, so look up the inclusion chain to see if
609     // any included header has an associated module.
610     SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
611     if (IncludeLoc.isInvalid())
612       return 0;
613 
614     ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
615   }
616 
617   return 0;
618 }
619 
620 //----------------------------------------------------------------------------//
621 // Module map file parser
622 //----------------------------------------------------------------------------//
623 
624 namespace clang {
625   /// \brief A token in a module map file.
626   struct MMToken {
627     enum TokenKind {
628       Comma,
629       EndOfFile,
630       HeaderKeyword,
631       Identifier,
632       ExcludeKeyword,
633       ExplicitKeyword,
634       ExportKeyword,
635       FrameworkKeyword,
636       ModuleKeyword,
637       Period,
638       UmbrellaKeyword,
639       RequiresKeyword,
640       Star,
641       StringLiteral,
642       LBrace,
643       RBrace,
644       LSquare,
645       RSquare
646     } Kind;
647 
648     unsigned Location;
649     unsigned StringLength;
650     const char *StringData;
651 
652     void clear() {
653       Kind = EndOfFile;
654       Location = 0;
655       StringLength = 0;
656       StringData = 0;
657     }
658 
659     bool is(TokenKind K) const { return Kind == K; }
660 
661     SourceLocation getLocation() const {
662       return SourceLocation::getFromRawEncoding(Location);
663     }
664 
665     StringRef getString() const {
666       return StringRef(StringData, StringLength);
667     }
668   };
669 
670   /// \brief The set of attributes that can be attached to a module.
671   struct Attributes {
672     Attributes() : IsSystem() { }
673 
674     /// \brief Whether this is a system module.
675     unsigned IsSystem : 1;
676   };
677 
678 
679   class ModuleMapParser {
680     Lexer &L;
681     SourceManager &SourceMgr;
682 
683     /// \brief Default target information, used only for string literal
684     /// parsing.
685     const TargetInfo *Target;
686 
687     DiagnosticsEngine &Diags;
688     ModuleMap &Map;
689 
690     /// \brief The directory that this module map resides in.
691     const DirectoryEntry *Directory;
692 
693     /// \brief The directory containing Clang-supplied headers.
694     const DirectoryEntry *BuiltinIncludeDir;
695 
696     /// \brief Whether an error occurred.
697     bool HadError;
698 
699     /// \brief Stores string data for the various string literals referenced
700     /// during parsing.
701     llvm::BumpPtrAllocator StringData;
702 
703     /// \brief The current token.
704     MMToken Tok;
705 
706     /// \brief The active module.
707     Module *ActiveModule;
708 
709     /// \brief Consume the current token and return its location.
710     SourceLocation consumeToken();
711 
712     /// \brief Skip tokens until we reach the a token with the given kind
713     /// (or the end of the file).
714     void skipUntil(MMToken::TokenKind K);
715 
716     typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
717       ModuleId;
718     bool parseModuleId(ModuleId &Id);
719     void parseModuleDecl();
720     void parseRequiresDecl();
721     void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
722     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
723     void parseExportDecl();
724     void parseInferredModuleDecl(bool Framework, bool Explicit);
725     bool parseOptionalAttributes(Attributes &Attrs);
726 
727     const DirectoryEntry *getOverriddenHeaderSearchDir();
728 
729   public:
730     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
731                              const TargetInfo *Target,
732                              DiagnosticsEngine &Diags,
733                              ModuleMap &Map,
734                              const DirectoryEntry *Directory,
735                              const DirectoryEntry *BuiltinIncludeDir)
736       : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
737         Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
738         HadError(false), ActiveModule(0)
739     {
740       Tok.clear();
741       consumeToken();
742     }
743 
744     bool parseModuleMapFile();
745   };
746 }
747 
748 SourceLocation ModuleMapParser::consumeToken() {
749 retry:
750   SourceLocation Result = Tok.getLocation();
751   Tok.clear();
752 
753   Token LToken;
754   L.LexFromRawLexer(LToken);
755   Tok.Location = LToken.getLocation().getRawEncoding();
756   switch (LToken.getKind()) {
757   case tok::raw_identifier:
758     Tok.StringData = LToken.getRawIdentifierData();
759     Tok.StringLength = LToken.getLength();
760     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
761                  .Case("header", MMToken::HeaderKeyword)
762                  .Case("exclude", MMToken::ExcludeKeyword)
763                  .Case("explicit", MMToken::ExplicitKeyword)
764                  .Case("export", MMToken::ExportKeyword)
765                  .Case("framework", MMToken::FrameworkKeyword)
766                  .Case("module", MMToken::ModuleKeyword)
767                  .Case("requires", MMToken::RequiresKeyword)
768                  .Case("umbrella", MMToken::UmbrellaKeyword)
769                  .Default(MMToken::Identifier);
770     break;
771 
772   case tok::comma:
773     Tok.Kind = MMToken::Comma;
774     break;
775 
776   case tok::eof:
777     Tok.Kind = MMToken::EndOfFile;
778     break;
779 
780   case tok::l_brace:
781     Tok.Kind = MMToken::LBrace;
782     break;
783 
784   case tok::l_square:
785     Tok.Kind = MMToken::LSquare;
786     break;
787 
788   case tok::period:
789     Tok.Kind = MMToken::Period;
790     break;
791 
792   case tok::r_brace:
793     Tok.Kind = MMToken::RBrace;
794     break;
795 
796   case tok::r_square:
797     Tok.Kind = MMToken::RSquare;
798     break;
799 
800   case tok::star:
801     Tok.Kind = MMToken::Star;
802     break;
803 
804   case tok::string_literal: {
805     if (LToken.hasUDSuffix()) {
806       Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
807       HadError = true;
808       goto retry;
809     }
810 
811     // Parse the string literal.
812     LangOptions LangOpts;
813     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
814     if (StringLiteral.hadError)
815       goto retry;
816 
817     // Copy the string literal into our string data allocator.
818     unsigned Length = StringLiteral.GetStringLength();
819     char *Saved = StringData.Allocate<char>(Length + 1);
820     memcpy(Saved, StringLiteral.GetString().data(), Length);
821     Saved[Length] = 0;
822 
823     // Form the token.
824     Tok.Kind = MMToken::StringLiteral;
825     Tok.StringData = Saved;
826     Tok.StringLength = Length;
827     break;
828   }
829 
830   case tok::comment:
831     goto retry;
832 
833   default:
834     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
835     HadError = true;
836     goto retry;
837   }
838 
839   return Result;
840 }
841 
842 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
843   unsigned braceDepth = 0;
844   unsigned squareDepth = 0;
845   do {
846     switch (Tok.Kind) {
847     case MMToken::EndOfFile:
848       return;
849 
850     case MMToken::LBrace:
851       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
852         return;
853 
854       ++braceDepth;
855       break;
856 
857     case MMToken::LSquare:
858       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
859         return;
860 
861       ++squareDepth;
862       break;
863 
864     case MMToken::RBrace:
865       if (braceDepth > 0)
866         --braceDepth;
867       else if (Tok.is(K))
868         return;
869       break;
870 
871     case MMToken::RSquare:
872       if (squareDepth > 0)
873         --squareDepth;
874       else if (Tok.is(K))
875         return;
876       break;
877 
878     default:
879       if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
880         return;
881       break;
882     }
883 
884    consumeToken();
885   } while (true);
886 }
887 
888 /// \brief Parse a module-id.
889 ///
890 ///   module-id:
891 ///     identifier
892 ///     identifier '.' module-id
893 ///
894 /// \returns true if an error occurred, false otherwise.
895 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
896   Id.clear();
897   do {
898     if (Tok.is(MMToken::Identifier)) {
899       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
900       consumeToken();
901     } else {
902       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
903       return true;
904     }
905 
906     if (!Tok.is(MMToken::Period))
907       break;
908 
909     consumeToken();
910   } while (true);
911 
912   return false;
913 }
914 
915 namespace {
916   /// \brief Enumerates the known attributes.
917   enum AttributeKind {
918     /// \brief An unknown attribute.
919     AT_unknown,
920     /// \brief The 'system' attribute.
921     AT_system
922   };
923 }
924 
925 /// \brief Parse a module declaration.
926 ///
927 ///   module-declaration:
928 ///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
929 ///       { module-member* }
930 ///
931 ///   module-member:
932 ///     requires-declaration
933 ///     header-declaration
934 ///     submodule-declaration
935 ///     export-declaration
936 ///
937 ///   submodule-declaration:
938 ///     module-declaration
939 ///     inferred-submodule-declaration
940 void ModuleMapParser::parseModuleDecl() {
941   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
942          Tok.is(MMToken::FrameworkKeyword));
943   // Parse 'explicit' or 'framework' keyword, if present.
944   SourceLocation ExplicitLoc;
945   bool Explicit = false;
946   bool Framework = false;
947 
948   // Parse 'explicit' keyword, if present.
949   if (Tok.is(MMToken::ExplicitKeyword)) {
950     ExplicitLoc = consumeToken();
951     Explicit = true;
952   }
953 
954   // Parse 'framework' keyword, if present.
955   if (Tok.is(MMToken::FrameworkKeyword)) {
956     consumeToken();
957     Framework = true;
958   }
959 
960   // Parse 'module' keyword.
961   if (!Tok.is(MMToken::ModuleKeyword)) {
962     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
963     consumeToken();
964     HadError = true;
965     return;
966   }
967   consumeToken(); // 'module' keyword
968 
969   // If we have a wildcard for the module name, this is an inferred submodule.
970   // Parse it.
971   if (Tok.is(MMToken::Star))
972     return parseInferredModuleDecl(Framework, Explicit);
973 
974   // Parse the module name.
975   ModuleId Id;
976   if (parseModuleId(Id)) {
977     HadError = true;
978     return;
979   }
980 
981   if (ActiveModule) {
982     if (Id.size() > 1) {
983       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
984         << SourceRange(Id.front().second, Id.back().second);
985 
986       HadError = true;
987       return;
988     }
989   } else if (Id.size() == 1 && Explicit) {
990     // Top-level modules can't be explicit.
991     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
992     Explicit = false;
993     ExplicitLoc = SourceLocation();
994     HadError = true;
995   }
996 
997   Module *PreviousActiveModule = ActiveModule;
998   if (Id.size() > 1) {
999     // This module map defines a submodule. Go find the module of which it
1000     // is a submodule.
1001     ActiveModule = 0;
1002     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1003       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1004         ActiveModule = Next;
1005         continue;
1006       }
1007 
1008       if (ActiveModule) {
1009         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1010           << Id[I].first << ActiveModule->getTopLevelModule();
1011       } else {
1012         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1013       }
1014       HadError = true;
1015       return;
1016     }
1017   }
1018 
1019   StringRef ModuleName = Id.back().first;
1020   SourceLocation ModuleNameLoc = Id.back().second;
1021 
1022   // Parse the optional attribute list.
1023   Attributes Attrs;
1024   parseOptionalAttributes(Attrs);
1025 
1026   // Parse the opening brace.
1027   if (!Tok.is(MMToken::LBrace)) {
1028     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1029       << ModuleName;
1030     HadError = true;
1031     return;
1032   }
1033   SourceLocation LBraceLoc = consumeToken();
1034 
1035   // Determine whether this (sub)module has already been defined.
1036   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1037     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1038       // Skip the module definition.
1039       skipUntil(MMToken::RBrace);
1040       if (Tok.is(MMToken::RBrace))
1041         consumeToken();
1042       else {
1043         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1044         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1045         HadError = true;
1046       }
1047       return;
1048     }
1049 
1050     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1051       << ModuleName;
1052     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1053 
1054     // Skip the module definition.
1055     skipUntil(MMToken::RBrace);
1056     if (Tok.is(MMToken::RBrace))
1057       consumeToken();
1058 
1059     HadError = true;
1060     return;
1061   }
1062 
1063   // Start defining this module.
1064   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1065                                         Explicit).first;
1066   ActiveModule->DefinitionLoc = ModuleNameLoc;
1067   if (Attrs.IsSystem)
1068     ActiveModule->IsSystem = true;
1069 
1070   bool Done = false;
1071   do {
1072     switch (Tok.Kind) {
1073     case MMToken::EndOfFile:
1074     case MMToken::RBrace:
1075       Done = true;
1076       break;
1077 
1078     case MMToken::ExplicitKeyword:
1079     case MMToken::FrameworkKeyword:
1080     case MMToken::ModuleKeyword:
1081       parseModuleDecl();
1082       break;
1083 
1084     case MMToken::ExportKeyword:
1085       parseExportDecl();
1086       break;
1087 
1088     case MMToken::RequiresKeyword:
1089       parseRequiresDecl();
1090       break;
1091 
1092     case MMToken::UmbrellaKeyword: {
1093       SourceLocation UmbrellaLoc = consumeToken();
1094       if (Tok.is(MMToken::HeaderKeyword))
1095         parseHeaderDecl(UmbrellaLoc, SourceLocation());
1096       else
1097         parseUmbrellaDirDecl(UmbrellaLoc);
1098       break;
1099     }
1100 
1101     case MMToken::ExcludeKeyword: {
1102       SourceLocation ExcludeLoc = consumeToken();
1103       if (Tok.is(MMToken::HeaderKeyword)) {
1104         parseHeaderDecl(SourceLocation(), ExcludeLoc);
1105       } else {
1106         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1107           << "exclude";
1108       }
1109       break;
1110     }
1111 
1112     case MMToken::HeaderKeyword:
1113       parseHeaderDecl(SourceLocation(), SourceLocation());
1114       break;
1115 
1116     default:
1117       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1118       consumeToken();
1119       break;
1120     }
1121   } while (!Done);
1122 
1123   if (Tok.is(MMToken::RBrace))
1124     consumeToken();
1125   else {
1126     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1127     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1128     HadError = true;
1129   }
1130 
1131   // We're done parsing this module. Pop back to the previous module.
1132   ActiveModule = PreviousActiveModule;
1133 }
1134 
1135 /// \brief Parse a requires declaration.
1136 ///
1137 ///   requires-declaration:
1138 ///     'requires' feature-list
1139 ///
1140 ///   feature-list:
1141 ///     identifier ',' feature-list
1142 ///     identifier
1143 void ModuleMapParser::parseRequiresDecl() {
1144   assert(Tok.is(MMToken::RequiresKeyword));
1145 
1146   // Parse 'requires' keyword.
1147   consumeToken();
1148 
1149   // Parse the feature-list.
1150   do {
1151     if (!Tok.is(MMToken::Identifier)) {
1152       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1153       HadError = true;
1154       return;
1155     }
1156 
1157     // Consume the feature name.
1158     std::string Feature = Tok.getString();
1159     consumeToken();
1160 
1161     // Add this feature.
1162     ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
1163 
1164     if (!Tok.is(MMToken::Comma))
1165       break;
1166 
1167     // Consume the comma.
1168     consumeToken();
1169   } while (true);
1170 }
1171 
1172 /// \brief Append to \p Paths the set of paths needed to get to the
1173 /// subframework in which the given module lives.
1174 static void appendSubframeworkPaths(Module *Mod,
1175                                     llvm::SmallVectorImpl<char> &Path) {
1176   // Collect the framework names from the given module to the top-level module.
1177   llvm::SmallVector<StringRef, 2> Paths;
1178   for (; Mod; Mod = Mod->Parent) {
1179     if (Mod->IsFramework)
1180       Paths.push_back(Mod->Name);
1181   }
1182 
1183   if (Paths.empty())
1184     return;
1185 
1186   // Add Frameworks/Name.framework for each subframework.
1187   for (unsigned I = Paths.size() - 1; I != 0; --I) {
1188     llvm::sys::path::append(Path, "Frameworks");
1189     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1190   }
1191 }
1192 
1193 /// \brief Determine whether the given file name is the name of a builtin
1194 /// header, supplied by Clang to replace, override, or augment existing system
1195 /// headers.
1196 static bool isBuiltinHeader(StringRef FileName) {
1197   return llvm::StringSwitch<bool>(FileName)
1198       .Case("float.h", true)
1199       .Case("iso646.h", true)
1200       .Case("limits.h", true)
1201       .Case("stdalign.h", true)
1202       .Case("stdarg.h", true)
1203       .Case("stdbool.h", true)
1204       .Case("stddef.h", true)
1205       .Case("stdint.h", true)
1206       .Case("tgmath.h", true)
1207       .Case("unwind.h", true)
1208       .Default(false);
1209 }
1210 
1211 /// \brief Parse a header declaration.
1212 ///
1213 ///   header-declaration:
1214 ///     'umbrella'[opt] 'header' string-literal
1215 ///     'exclude'[opt] 'header' string-literal
1216 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1217                                       SourceLocation ExcludeLoc) {
1218   assert(Tok.is(MMToken::HeaderKeyword));
1219   consumeToken();
1220 
1221   bool Umbrella = UmbrellaLoc.isValid();
1222   bool Exclude = ExcludeLoc.isValid();
1223   assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
1224   // Parse the header name.
1225   if (!Tok.is(MMToken::StringLiteral)) {
1226     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1227       << "header";
1228     HadError = true;
1229     return;
1230   }
1231   std::string FileName = Tok.getString();
1232   SourceLocation FileNameLoc = consumeToken();
1233 
1234   // Check whether we already have an umbrella.
1235   if (Umbrella && ActiveModule->Umbrella) {
1236     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1237       << ActiveModule->getFullModuleName();
1238     HadError = true;
1239     return;
1240   }
1241 
1242   // Look for this file.
1243   const FileEntry *File = 0;
1244   const FileEntry *BuiltinFile = 0;
1245   SmallString<128> PathName;
1246   if (llvm::sys::path::is_absolute(FileName)) {
1247     PathName = FileName;
1248     File = SourceMgr.getFileManager().getFile(PathName);
1249   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1250     PathName = Dir->getName();
1251     llvm::sys::path::append(PathName, FileName);
1252     File = SourceMgr.getFileManager().getFile(PathName);
1253   } else {
1254     // Search for the header file within the search directory.
1255     PathName = Directory->getName();
1256     unsigned PathLength = PathName.size();
1257 
1258     if (ActiveModule->isPartOfFramework()) {
1259       appendSubframeworkPaths(ActiveModule, PathName);
1260 
1261       // Check whether this file is in the public headers.
1262       llvm::sys::path::append(PathName, "Headers");
1263       llvm::sys::path::append(PathName, FileName);
1264       File = SourceMgr.getFileManager().getFile(PathName);
1265 
1266       if (!File) {
1267         // Check whether this file is in the private headers.
1268         PathName.resize(PathLength);
1269         llvm::sys::path::append(PathName, "PrivateHeaders");
1270         llvm::sys::path::append(PathName, FileName);
1271         File = SourceMgr.getFileManager().getFile(PathName);
1272       }
1273     } else {
1274       // Lookup for normal headers.
1275       llvm::sys::path::append(PathName, FileName);
1276       File = SourceMgr.getFileManager().getFile(PathName);
1277 
1278       // If this is a system module with a top-level header, this header
1279       // may have a counterpart (or replacement) in the set of headers
1280       // supplied by Clang. Find that builtin header.
1281       if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1282           BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
1283         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1284         llvm::sys::path::append(BuiltinPathName, FileName);
1285         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1286 
1287         // If Clang supplies this header but the underlying system does not,
1288         // just silently swap in our builtin version. Otherwise, we'll end
1289         // up adding both (later).
1290         if (!File && BuiltinFile) {
1291           File = BuiltinFile;
1292           BuiltinFile = 0;
1293         }
1294       }
1295     }
1296   }
1297 
1298   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1299   // Come up with a lazy way to do this.
1300   if (File) {
1301     if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
1302       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
1303         << FileName << OwningModule.getModule()->getFullModuleName();
1304       HadError = true;
1305     } else if (Umbrella) {
1306       const DirectoryEntry *UmbrellaDir = File->getDir();
1307       if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1308         Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1309           << UmbrellaModule->getFullModuleName();
1310         HadError = true;
1311       } else {
1312         // Record this umbrella header.
1313         Map.setUmbrellaHeader(ActiveModule, File);
1314       }
1315     } else {
1316       // Record this header.
1317       Map.addHeader(ActiveModule, File, Exclude);
1318 
1319       // If there is a builtin counterpart to this file, add it now.
1320       if (BuiltinFile)
1321         Map.addHeader(ActiveModule, BuiltinFile, Exclude);
1322     }
1323   } else if (!Exclude) {
1324     // Ignore excluded header files. They're optional anyway.
1325 
1326     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1327       << Umbrella << FileName;
1328     HadError = true;
1329   }
1330 }
1331 
1332 /// \brief Parse an umbrella directory declaration.
1333 ///
1334 ///   umbrella-dir-declaration:
1335 ///     umbrella string-literal
1336 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1337   // Parse the directory name.
1338   if (!Tok.is(MMToken::StringLiteral)) {
1339     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1340       << "umbrella";
1341     HadError = true;
1342     return;
1343   }
1344 
1345   std::string DirName = Tok.getString();
1346   SourceLocation DirNameLoc = consumeToken();
1347 
1348   // Check whether we already have an umbrella.
1349   if (ActiveModule->Umbrella) {
1350     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1351       << ActiveModule->getFullModuleName();
1352     HadError = true;
1353     return;
1354   }
1355 
1356   // Look for this file.
1357   const DirectoryEntry *Dir = 0;
1358   if (llvm::sys::path::is_absolute(DirName))
1359     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1360   else {
1361     SmallString<128> PathName;
1362     PathName = Directory->getName();
1363     llvm::sys::path::append(PathName, DirName);
1364     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1365   }
1366 
1367   if (!Dir) {
1368     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1369       << DirName;
1370     HadError = true;
1371     return;
1372   }
1373 
1374   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1375     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1376       << OwningModule->getFullModuleName();
1377     HadError = true;
1378     return;
1379   }
1380 
1381   // Record this umbrella directory.
1382   Map.setUmbrellaDir(ActiveModule, Dir);
1383 }
1384 
1385 /// \brief Parse a module export declaration.
1386 ///
1387 ///   export-declaration:
1388 ///     'export' wildcard-module-id
1389 ///
1390 ///   wildcard-module-id:
1391 ///     identifier
1392 ///     '*'
1393 ///     identifier '.' wildcard-module-id
1394 void ModuleMapParser::parseExportDecl() {
1395   assert(Tok.is(MMToken::ExportKeyword));
1396   SourceLocation ExportLoc = consumeToken();
1397 
1398   // Parse the module-id with an optional wildcard at the end.
1399   ModuleId ParsedModuleId;
1400   bool Wildcard = false;
1401   do {
1402     if (Tok.is(MMToken::Identifier)) {
1403       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1404                                               Tok.getLocation()));
1405       consumeToken();
1406 
1407       if (Tok.is(MMToken::Period)) {
1408         consumeToken();
1409         continue;
1410       }
1411 
1412       break;
1413     }
1414 
1415     if(Tok.is(MMToken::Star)) {
1416       Wildcard = true;
1417       consumeToken();
1418       break;
1419     }
1420 
1421     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1422     HadError = true;
1423     return;
1424   } while (true);
1425 
1426   Module::UnresolvedExportDecl Unresolved = {
1427     ExportLoc, ParsedModuleId, Wildcard
1428   };
1429   ActiveModule->UnresolvedExports.push_back(Unresolved);
1430 }
1431 
1432 /// \brief Parse an inferried module declaration (wildcard modules).
1433 ///
1434 ///   module-declaration:
1435 ///     'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1436 ///       { inferred-module-member* }
1437 ///
1438 ///   inferred-module-member:
1439 ///     'export' '*'
1440 ///     'exclude' identifier
1441 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
1442   assert(Tok.is(MMToken::Star));
1443   SourceLocation StarLoc = consumeToken();
1444   bool Failed = false;
1445 
1446   // Inferred modules must be submodules.
1447   if (!ActiveModule && !Framework) {
1448     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1449     Failed = true;
1450   }
1451 
1452   if (ActiveModule) {
1453     // Inferred modules must have umbrella directories.
1454     if (!Failed && !ActiveModule->getUmbrellaDir()) {
1455       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1456       Failed = true;
1457     }
1458 
1459     // Check for redefinition of an inferred module.
1460     if (!Failed && ActiveModule->InferSubmodules) {
1461       Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1462       if (ActiveModule->InferredSubmoduleLoc.isValid())
1463         Diags.Report(ActiveModule->InferredSubmoduleLoc,
1464                      diag::note_mmap_prev_definition);
1465       Failed = true;
1466     }
1467 
1468     // Check for the 'framework' keyword, which is not permitted here.
1469     if (Framework) {
1470       Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1471       Framework = false;
1472     }
1473   } else if (Explicit) {
1474     Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1475     Explicit = false;
1476   }
1477 
1478   // If there were any problems with this inferred submodule, skip its body.
1479   if (Failed) {
1480     if (Tok.is(MMToken::LBrace)) {
1481       consumeToken();
1482       skipUntil(MMToken::RBrace);
1483       if (Tok.is(MMToken::RBrace))
1484         consumeToken();
1485     }
1486     HadError = true;
1487     return;
1488   }
1489 
1490   // Parse optional attributes.
1491   Attributes Attrs;
1492   parseOptionalAttributes(Attrs);
1493 
1494   if (ActiveModule) {
1495     // Note that we have an inferred submodule.
1496     ActiveModule->InferSubmodules = true;
1497     ActiveModule->InferredSubmoduleLoc = StarLoc;
1498     ActiveModule->InferExplicitSubmodules = Explicit;
1499   } else {
1500     // We'll be inferring framework modules for this directory.
1501     Map.InferredDirectories[Directory].InferModules = true;
1502     Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1503   }
1504 
1505   // Parse the opening brace.
1506   if (!Tok.is(MMToken::LBrace)) {
1507     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1508     HadError = true;
1509     return;
1510   }
1511   SourceLocation LBraceLoc = consumeToken();
1512 
1513   // Parse the body of the inferred submodule.
1514   bool Done = false;
1515   do {
1516     switch (Tok.Kind) {
1517     case MMToken::EndOfFile:
1518     case MMToken::RBrace:
1519       Done = true;
1520       break;
1521 
1522     case MMToken::ExcludeKeyword: {
1523       if (ActiveModule) {
1524         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1525           << (ActiveModule != 0);
1526         consumeToken();
1527         break;
1528       }
1529 
1530       consumeToken();
1531       if (!Tok.is(MMToken::Identifier)) {
1532         Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1533         break;
1534       }
1535 
1536       Map.InferredDirectories[Directory].ExcludedModules
1537         .push_back(Tok.getString());
1538       consumeToken();
1539       break;
1540     }
1541 
1542     case MMToken::ExportKeyword:
1543       if (!ActiveModule) {
1544         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1545           << (ActiveModule != 0);
1546         consumeToken();
1547         break;
1548       }
1549 
1550       consumeToken();
1551       if (Tok.is(MMToken::Star))
1552         ActiveModule->InferExportWildcard = true;
1553       else
1554         Diags.Report(Tok.getLocation(),
1555                      diag::err_mmap_expected_export_wildcard);
1556       consumeToken();
1557       break;
1558 
1559     case MMToken::ExplicitKeyword:
1560     case MMToken::ModuleKeyword:
1561     case MMToken::HeaderKeyword:
1562     case MMToken::UmbrellaKeyword:
1563     default:
1564       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1565           << (ActiveModule != 0);
1566       consumeToken();
1567       break;
1568     }
1569   } while (!Done);
1570 
1571   if (Tok.is(MMToken::RBrace))
1572     consumeToken();
1573   else {
1574     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1575     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1576     HadError = true;
1577   }
1578 }
1579 
1580 /// \brief Parse optional attributes.
1581 ///
1582 ///   attributes:
1583 ///     attribute attributes
1584 ///     attribute
1585 ///
1586 ///   attribute:
1587 ///     [ identifier ]
1588 ///
1589 /// \param Attrs Will be filled in with the parsed attributes.
1590 ///
1591 /// \returns true if an error occurred, false otherwise.
1592 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
1593   bool HadError = false;
1594 
1595   while (Tok.is(MMToken::LSquare)) {
1596     // Consume the '['.
1597     SourceLocation LSquareLoc = consumeToken();
1598 
1599     // Check whether we have an attribute name here.
1600     if (!Tok.is(MMToken::Identifier)) {
1601       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1602       skipUntil(MMToken::RSquare);
1603       if (Tok.is(MMToken::RSquare))
1604         consumeToken();
1605       HadError = true;
1606     }
1607 
1608     // Decode the attribute name.
1609     AttributeKind Attribute
1610       = llvm::StringSwitch<AttributeKind>(Tok.getString())
1611           .Case("system", AT_system)
1612           .Default(AT_unknown);
1613     switch (Attribute) {
1614     case AT_unknown:
1615       Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1616         << Tok.getString();
1617       break;
1618 
1619     case AT_system:
1620       Attrs.IsSystem = true;
1621       break;
1622     }
1623     consumeToken();
1624 
1625     // Consume the ']'.
1626     if (!Tok.is(MMToken::RSquare)) {
1627       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1628       Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1629       skipUntil(MMToken::RSquare);
1630       HadError = true;
1631     }
1632 
1633     if (Tok.is(MMToken::RSquare))
1634       consumeToken();
1635   }
1636 
1637   return HadError;
1638 }
1639 
1640 /// \brief If there is a specific header search directory due the presence
1641 /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1642 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1643   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1644     // If we have an umbrella directory, use that.
1645     if (Mod->hasUmbrellaDir())
1646       return Mod->getUmbrellaDir();
1647 
1648     // If we have a framework directory, stop looking.
1649     if (Mod->IsFramework)
1650       return 0;
1651   }
1652 
1653   return 0;
1654 }
1655 
1656 /// \brief Parse a module map file.
1657 ///
1658 ///   module-map-file:
1659 ///     module-declaration*
1660 bool ModuleMapParser::parseModuleMapFile() {
1661   do {
1662     switch (Tok.Kind) {
1663     case MMToken::EndOfFile:
1664       return HadError;
1665 
1666     case MMToken::ExplicitKeyword:
1667     case MMToken::ModuleKeyword:
1668     case MMToken::FrameworkKeyword:
1669       parseModuleDecl();
1670       break;
1671 
1672     case MMToken::Comma:
1673     case MMToken::ExcludeKeyword:
1674     case MMToken::ExportKeyword:
1675     case MMToken::HeaderKeyword:
1676     case MMToken::Identifier:
1677     case MMToken::LBrace:
1678     case MMToken::LSquare:
1679     case MMToken::Period:
1680     case MMToken::RBrace:
1681     case MMToken::RSquare:
1682     case MMToken::RequiresKeyword:
1683     case MMToken::Star:
1684     case MMToken::StringLiteral:
1685     case MMToken::UmbrellaKeyword:
1686       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1687       HadError = true;
1688       consumeToken();
1689       break;
1690     }
1691   } while (true);
1692 }
1693 
1694 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1695   assert(Target != 0 && "Missing target information");
1696   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1697   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1698   if (!Buffer)
1699     return true;
1700 
1701   // Parse this module map file.
1702   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1703   Diags->getClient()->BeginSourceFile(MMapLangOpts);
1704   ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
1705                          BuiltinIncludeDir);
1706   bool Result = Parser.parseModuleMapFile();
1707   Diags->getClient()->EndSourceFile();
1708 
1709   return Result;
1710 }
1711