xref: /llvm-project/clang/lib/Lex/ModuleMap.cpp (revision 6ddfca91e04e62089d685b31533b9a2d677d9a5e)
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       LinkKeyword,
649       ModuleKeyword,
650       Period,
651       UmbrellaKeyword,
652       RequiresKeyword,
653       Star,
654       StringLiteral,
655       LBrace,
656       RBrace,
657       LSquare,
658       RSquare
659     } Kind;
660 
661     unsigned Location;
662     unsigned StringLength;
663     const char *StringData;
664 
665     void clear() {
666       Kind = EndOfFile;
667       Location = 0;
668       StringLength = 0;
669       StringData = 0;
670     }
671 
672     bool is(TokenKind K) const { return Kind == K; }
673 
674     SourceLocation getLocation() const {
675       return SourceLocation::getFromRawEncoding(Location);
676     }
677 
678     StringRef getString() const {
679       return StringRef(StringData, StringLength);
680     }
681   };
682 
683   /// \brief The set of attributes that can be attached to a module.
684   struct Attributes {
685     Attributes() : IsSystem() { }
686 
687     /// \brief Whether this is a system module.
688     unsigned IsSystem : 1;
689   };
690 
691 
692   class ModuleMapParser {
693     Lexer &L;
694     SourceManager &SourceMgr;
695 
696     /// \brief Default target information, used only for string literal
697     /// parsing.
698     const TargetInfo *Target;
699 
700     DiagnosticsEngine &Diags;
701     ModuleMap &Map;
702 
703     /// \brief The directory that this module map resides in.
704     const DirectoryEntry *Directory;
705 
706     /// \brief The directory containing Clang-supplied headers.
707     const DirectoryEntry *BuiltinIncludeDir;
708 
709     /// \brief Whether an error occurred.
710     bool HadError;
711 
712     /// \brief Stores string data for the various string literals referenced
713     /// during parsing.
714     llvm::BumpPtrAllocator StringData;
715 
716     /// \brief The current token.
717     MMToken Tok;
718 
719     /// \brief The active module.
720     Module *ActiveModule;
721 
722     /// \brief Consume the current token and return its location.
723     SourceLocation consumeToken();
724 
725     /// \brief Skip tokens until we reach the a token with the given kind
726     /// (or the end of the file).
727     void skipUntil(MMToken::TokenKind K);
728 
729     typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
730     bool parseModuleId(ModuleId &Id);
731     void parseModuleDecl();
732     void parseRequiresDecl();
733     void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
734     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
735     void parseExportDecl();
736     void parseLinkDecl();
737     void parseInferredModuleDecl(bool Framework, bool Explicit);
738     bool parseOptionalAttributes(Attributes &Attrs);
739 
740     const DirectoryEntry *getOverriddenHeaderSearchDir();
741 
742   public:
743     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
744                              const TargetInfo *Target,
745                              DiagnosticsEngine &Diags,
746                              ModuleMap &Map,
747                              const DirectoryEntry *Directory,
748                              const DirectoryEntry *BuiltinIncludeDir)
749       : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
750         Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
751         HadError(false), ActiveModule(0)
752     {
753       Tok.clear();
754       consumeToken();
755     }
756 
757     bool parseModuleMapFile();
758   };
759 }
760 
761 SourceLocation ModuleMapParser::consumeToken() {
762 retry:
763   SourceLocation Result = Tok.getLocation();
764   Tok.clear();
765 
766   Token LToken;
767   L.LexFromRawLexer(LToken);
768   Tok.Location = LToken.getLocation().getRawEncoding();
769   switch (LToken.getKind()) {
770   case tok::raw_identifier:
771     Tok.StringData = LToken.getRawIdentifierData();
772     Tok.StringLength = LToken.getLength();
773     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
774                  .Case("header", MMToken::HeaderKeyword)
775                  .Case("exclude", MMToken::ExcludeKeyword)
776                  .Case("explicit", MMToken::ExplicitKeyword)
777                  .Case("export", MMToken::ExportKeyword)
778                  .Case("framework", MMToken::FrameworkKeyword)
779                  .Case("link", MMToken::LinkKeyword)
780                  .Case("module", MMToken::ModuleKeyword)
781                  .Case("requires", MMToken::RequiresKeyword)
782                  .Case("umbrella", MMToken::UmbrellaKeyword)
783                  .Default(MMToken::Identifier);
784     break;
785 
786   case tok::comma:
787     Tok.Kind = MMToken::Comma;
788     break;
789 
790   case tok::eof:
791     Tok.Kind = MMToken::EndOfFile;
792     break;
793 
794   case tok::l_brace:
795     Tok.Kind = MMToken::LBrace;
796     break;
797 
798   case tok::l_square:
799     Tok.Kind = MMToken::LSquare;
800     break;
801 
802   case tok::period:
803     Tok.Kind = MMToken::Period;
804     break;
805 
806   case tok::r_brace:
807     Tok.Kind = MMToken::RBrace;
808     break;
809 
810   case tok::r_square:
811     Tok.Kind = MMToken::RSquare;
812     break;
813 
814   case tok::star:
815     Tok.Kind = MMToken::Star;
816     break;
817 
818   case tok::string_literal: {
819     if (LToken.hasUDSuffix()) {
820       Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
821       HadError = true;
822       goto retry;
823     }
824 
825     // Parse the string literal.
826     LangOptions LangOpts;
827     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
828     if (StringLiteral.hadError)
829       goto retry;
830 
831     // Copy the string literal into our string data allocator.
832     unsigned Length = StringLiteral.GetStringLength();
833     char *Saved = StringData.Allocate<char>(Length + 1);
834     memcpy(Saved, StringLiteral.GetString().data(), Length);
835     Saved[Length] = 0;
836 
837     // Form the token.
838     Tok.Kind = MMToken::StringLiteral;
839     Tok.StringData = Saved;
840     Tok.StringLength = Length;
841     break;
842   }
843 
844   case tok::comment:
845     goto retry;
846 
847   default:
848     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
849     HadError = true;
850     goto retry;
851   }
852 
853   return Result;
854 }
855 
856 void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
857   unsigned braceDepth = 0;
858   unsigned squareDepth = 0;
859   do {
860     switch (Tok.Kind) {
861     case MMToken::EndOfFile:
862       return;
863 
864     case MMToken::LBrace:
865       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
866         return;
867 
868       ++braceDepth;
869       break;
870 
871     case MMToken::LSquare:
872       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
873         return;
874 
875       ++squareDepth;
876       break;
877 
878     case MMToken::RBrace:
879       if (braceDepth > 0)
880         --braceDepth;
881       else if (Tok.is(K))
882         return;
883       break;
884 
885     case MMToken::RSquare:
886       if (squareDepth > 0)
887         --squareDepth;
888       else if (Tok.is(K))
889         return;
890       break;
891 
892     default:
893       if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
894         return;
895       break;
896     }
897 
898    consumeToken();
899   } while (true);
900 }
901 
902 /// \brief Parse a module-id.
903 ///
904 ///   module-id:
905 ///     identifier
906 ///     identifier '.' module-id
907 ///
908 /// \returns true if an error occurred, false otherwise.
909 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
910   Id.clear();
911   do {
912     if (Tok.is(MMToken::Identifier)) {
913       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
914       consumeToken();
915     } else {
916       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
917       return true;
918     }
919 
920     if (!Tok.is(MMToken::Period))
921       break;
922 
923     consumeToken();
924   } while (true);
925 
926   return false;
927 }
928 
929 namespace {
930   /// \brief Enumerates the known attributes.
931   enum AttributeKind {
932     /// \brief An unknown attribute.
933     AT_unknown,
934     /// \brief The 'system' attribute.
935     AT_system
936   };
937 }
938 
939 /// \brief Parse a module declaration.
940 ///
941 ///   module-declaration:
942 ///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
943 ///       { module-member* }
944 ///
945 ///   module-member:
946 ///     requires-declaration
947 ///     header-declaration
948 ///     submodule-declaration
949 ///     export-declaration
950 ///     link-declaration
951 ///
952 ///   submodule-declaration:
953 ///     module-declaration
954 ///     inferred-submodule-declaration
955 void ModuleMapParser::parseModuleDecl() {
956   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
957          Tok.is(MMToken::FrameworkKeyword));
958   // Parse 'explicit' or 'framework' keyword, if present.
959   SourceLocation ExplicitLoc;
960   bool Explicit = false;
961   bool Framework = false;
962 
963   // Parse 'explicit' keyword, if present.
964   if (Tok.is(MMToken::ExplicitKeyword)) {
965     ExplicitLoc = consumeToken();
966     Explicit = true;
967   }
968 
969   // Parse 'framework' keyword, if present.
970   if (Tok.is(MMToken::FrameworkKeyword)) {
971     consumeToken();
972     Framework = true;
973   }
974 
975   // Parse 'module' keyword.
976   if (!Tok.is(MMToken::ModuleKeyword)) {
977     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
978     consumeToken();
979     HadError = true;
980     return;
981   }
982   consumeToken(); // 'module' keyword
983 
984   // If we have a wildcard for the module name, this is an inferred submodule.
985   // Parse it.
986   if (Tok.is(MMToken::Star))
987     return parseInferredModuleDecl(Framework, Explicit);
988 
989   // Parse the module name.
990   ModuleId Id;
991   if (parseModuleId(Id)) {
992     HadError = true;
993     return;
994   }
995 
996   if (ActiveModule) {
997     if (Id.size() > 1) {
998       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
999         << SourceRange(Id.front().second, Id.back().second);
1000 
1001       HadError = true;
1002       return;
1003     }
1004   } else if (Id.size() == 1 && Explicit) {
1005     // Top-level modules can't be explicit.
1006     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1007     Explicit = false;
1008     ExplicitLoc = SourceLocation();
1009     HadError = true;
1010   }
1011 
1012   Module *PreviousActiveModule = ActiveModule;
1013   if (Id.size() > 1) {
1014     // This module map defines a submodule. Go find the module of which it
1015     // is a submodule.
1016     ActiveModule = 0;
1017     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1018       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1019         ActiveModule = Next;
1020         continue;
1021       }
1022 
1023       if (ActiveModule) {
1024         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1025           << Id[I].first << ActiveModule->getTopLevelModule();
1026       } else {
1027         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1028       }
1029       HadError = true;
1030       return;
1031     }
1032   }
1033 
1034   StringRef ModuleName = Id.back().first;
1035   SourceLocation ModuleNameLoc = Id.back().second;
1036 
1037   // Parse the optional attribute list.
1038   Attributes Attrs;
1039   parseOptionalAttributes(Attrs);
1040 
1041   // Parse the opening brace.
1042   if (!Tok.is(MMToken::LBrace)) {
1043     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1044       << ModuleName;
1045     HadError = true;
1046     return;
1047   }
1048   SourceLocation LBraceLoc = consumeToken();
1049 
1050   // Determine whether this (sub)module has already been defined.
1051   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1052     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1053       // Skip the module definition.
1054       skipUntil(MMToken::RBrace);
1055       if (Tok.is(MMToken::RBrace))
1056         consumeToken();
1057       else {
1058         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1059         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1060         HadError = true;
1061       }
1062       return;
1063     }
1064 
1065     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1066       << ModuleName;
1067     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1068 
1069     // Skip the module definition.
1070     skipUntil(MMToken::RBrace);
1071     if (Tok.is(MMToken::RBrace))
1072       consumeToken();
1073 
1074     HadError = true;
1075     return;
1076   }
1077 
1078   // Start defining this module.
1079   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1080                                         Explicit).first;
1081   ActiveModule->DefinitionLoc = ModuleNameLoc;
1082   if (Attrs.IsSystem)
1083     ActiveModule->IsSystem = true;
1084 
1085   bool Done = false;
1086   do {
1087     switch (Tok.Kind) {
1088     case MMToken::EndOfFile:
1089     case MMToken::RBrace:
1090       Done = true;
1091       break;
1092 
1093     case MMToken::ExplicitKeyword:
1094     case MMToken::FrameworkKeyword:
1095     case MMToken::ModuleKeyword:
1096       parseModuleDecl();
1097       break;
1098 
1099     case MMToken::ExportKeyword:
1100       parseExportDecl();
1101       break;
1102 
1103     case MMToken::RequiresKeyword:
1104       parseRequiresDecl();
1105       break;
1106 
1107     case MMToken::UmbrellaKeyword: {
1108       SourceLocation UmbrellaLoc = consumeToken();
1109       if (Tok.is(MMToken::HeaderKeyword))
1110         parseHeaderDecl(UmbrellaLoc, SourceLocation());
1111       else
1112         parseUmbrellaDirDecl(UmbrellaLoc);
1113       break;
1114     }
1115 
1116     case MMToken::ExcludeKeyword: {
1117       SourceLocation ExcludeLoc = consumeToken();
1118       if (Tok.is(MMToken::HeaderKeyword)) {
1119         parseHeaderDecl(SourceLocation(), ExcludeLoc);
1120       } else {
1121         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1122           << "exclude";
1123       }
1124       break;
1125     }
1126 
1127     case MMToken::HeaderKeyword:
1128       parseHeaderDecl(SourceLocation(), SourceLocation());
1129       break;
1130 
1131     case MMToken::LinkKeyword:
1132       parseLinkDecl();
1133       break;
1134 
1135     default:
1136       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1137       consumeToken();
1138       break;
1139     }
1140   } while (!Done);
1141 
1142   if (Tok.is(MMToken::RBrace))
1143     consumeToken();
1144   else {
1145     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1146     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1147     HadError = true;
1148   }
1149 
1150   // We're done parsing this module. Pop back to the previous module.
1151   ActiveModule = PreviousActiveModule;
1152 }
1153 
1154 /// \brief Parse a requires declaration.
1155 ///
1156 ///   requires-declaration:
1157 ///     'requires' feature-list
1158 ///
1159 ///   feature-list:
1160 ///     identifier ',' feature-list
1161 ///     identifier
1162 void ModuleMapParser::parseRequiresDecl() {
1163   assert(Tok.is(MMToken::RequiresKeyword));
1164 
1165   // Parse 'requires' keyword.
1166   consumeToken();
1167 
1168   // Parse the feature-list.
1169   do {
1170     if (!Tok.is(MMToken::Identifier)) {
1171       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1172       HadError = true;
1173       return;
1174     }
1175 
1176     // Consume the feature name.
1177     std::string Feature = Tok.getString();
1178     consumeToken();
1179 
1180     // Add this feature.
1181     ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
1182 
1183     if (!Tok.is(MMToken::Comma))
1184       break;
1185 
1186     // Consume the comma.
1187     consumeToken();
1188   } while (true);
1189 }
1190 
1191 /// \brief Append to \p Paths the set of paths needed to get to the
1192 /// subframework in which the given module lives.
1193 static void appendSubframeworkPaths(Module *Mod,
1194                                     SmallVectorImpl<char> &Path) {
1195   // Collect the framework names from the given module to the top-level module.
1196   SmallVector<StringRef, 2> Paths;
1197   for (; Mod; Mod = Mod->Parent) {
1198     if (Mod->IsFramework)
1199       Paths.push_back(Mod->Name);
1200   }
1201 
1202   if (Paths.empty())
1203     return;
1204 
1205   // Add Frameworks/Name.framework for each subframework.
1206   for (unsigned I = Paths.size() - 1; I != 0; --I) {
1207     llvm::sys::path::append(Path, "Frameworks");
1208     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1209   }
1210 }
1211 
1212 /// \brief Determine whether the given file name is the name of a builtin
1213 /// header, supplied by Clang to replace, override, or augment existing system
1214 /// headers.
1215 static bool isBuiltinHeader(StringRef FileName) {
1216   return llvm::StringSwitch<bool>(FileName)
1217       .Case("float.h", true)
1218       .Case("iso646.h", true)
1219       .Case("limits.h", true)
1220       .Case("stdalign.h", true)
1221       .Case("stdarg.h", true)
1222       .Case("stdbool.h", true)
1223       .Case("stddef.h", true)
1224       .Case("stdint.h", true)
1225       .Case("tgmath.h", true)
1226       .Case("unwind.h", true)
1227       .Default(false);
1228 }
1229 
1230 /// \brief Parse a header declaration.
1231 ///
1232 ///   header-declaration:
1233 ///     'umbrella'[opt] 'header' string-literal
1234 ///     'exclude'[opt] 'header' string-literal
1235 void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1236                                       SourceLocation ExcludeLoc) {
1237   assert(Tok.is(MMToken::HeaderKeyword));
1238   consumeToken();
1239 
1240   bool Umbrella = UmbrellaLoc.isValid();
1241   bool Exclude = ExcludeLoc.isValid();
1242   assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
1243   // Parse the header name.
1244   if (!Tok.is(MMToken::StringLiteral)) {
1245     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1246       << "header";
1247     HadError = true;
1248     return;
1249   }
1250   std::string FileName = Tok.getString();
1251   SourceLocation FileNameLoc = consumeToken();
1252 
1253   // Check whether we already have an umbrella.
1254   if (Umbrella && ActiveModule->Umbrella) {
1255     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1256       << ActiveModule->getFullModuleName();
1257     HadError = true;
1258     return;
1259   }
1260 
1261   // Look for this file.
1262   const FileEntry *File = 0;
1263   const FileEntry *BuiltinFile = 0;
1264   SmallString<128> PathName;
1265   if (llvm::sys::path::is_absolute(FileName)) {
1266     PathName = FileName;
1267     File = SourceMgr.getFileManager().getFile(PathName);
1268   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1269     PathName = Dir->getName();
1270     llvm::sys::path::append(PathName, FileName);
1271     File = SourceMgr.getFileManager().getFile(PathName);
1272   } else {
1273     // Search for the header file within the search directory.
1274     PathName = Directory->getName();
1275     unsigned PathLength = PathName.size();
1276 
1277     if (ActiveModule->isPartOfFramework()) {
1278       appendSubframeworkPaths(ActiveModule, PathName);
1279 
1280       // Check whether this file is in the public headers.
1281       llvm::sys::path::append(PathName, "Headers");
1282       llvm::sys::path::append(PathName, FileName);
1283       File = SourceMgr.getFileManager().getFile(PathName);
1284 
1285       if (!File) {
1286         // Check whether this file is in the private headers.
1287         PathName.resize(PathLength);
1288         llvm::sys::path::append(PathName, "PrivateHeaders");
1289         llvm::sys::path::append(PathName, FileName);
1290         File = SourceMgr.getFileManager().getFile(PathName);
1291       }
1292     } else {
1293       // Lookup for normal headers.
1294       llvm::sys::path::append(PathName, FileName);
1295       File = SourceMgr.getFileManager().getFile(PathName);
1296 
1297       // If this is a system module with a top-level header, this header
1298       // may have a counterpart (or replacement) in the set of headers
1299       // supplied by Clang. Find that builtin header.
1300       if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1301           BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
1302         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1303         llvm::sys::path::append(BuiltinPathName, FileName);
1304         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1305 
1306         // If Clang supplies this header but the underlying system does not,
1307         // just silently swap in our builtin version. Otherwise, we'll end
1308         // up adding both (later).
1309         if (!File && BuiltinFile) {
1310           File = BuiltinFile;
1311           BuiltinFile = 0;
1312         }
1313       }
1314     }
1315   }
1316 
1317   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1318   // Come up with a lazy way to do this.
1319   if (File) {
1320     if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
1321       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
1322         << FileName << OwningModule.getModule()->getFullModuleName();
1323       HadError = true;
1324     } else if (Umbrella) {
1325       const DirectoryEntry *UmbrellaDir = File->getDir();
1326       if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1327         Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1328           << UmbrellaModule->getFullModuleName();
1329         HadError = true;
1330       } else {
1331         // Record this umbrella header.
1332         Map.setUmbrellaHeader(ActiveModule, File);
1333       }
1334     } else {
1335       // Record this header.
1336       Map.addHeader(ActiveModule, File, Exclude);
1337 
1338       // If there is a builtin counterpart to this file, add it now.
1339       if (BuiltinFile)
1340         Map.addHeader(ActiveModule, BuiltinFile, Exclude);
1341     }
1342   } else if (!Exclude) {
1343     // Ignore excluded header files. They're optional anyway.
1344 
1345     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1346       << Umbrella << FileName;
1347     HadError = true;
1348   }
1349 }
1350 
1351 /// \brief Parse an umbrella directory declaration.
1352 ///
1353 ///   umbrella-dir-declaration:
1354 ///     umbrella string-literal
1355 void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1356   // Parse the directory name.
1357   if (!Tok.is(MMToken::StringLiteral)) {
1358     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1359       << "umbrella";
1360     HadError = true;
1361     return;
1362   }
1363 
1364   std::string DirName = Tok.getString();
1365   SourceLocation DirNameLoc = consumeToken();
1366 
1367   // Check whether we already have an umbrella.
1368   if (ActiveModule->Umbrella) {
1369     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1370       << ActiveModule->getFullModuleName();
1371     HadError = true;
1372     return;
1373   }
1374 
1375   // Look for this file.
1376   const DirectoryEntry *Dir = 0;
1377   if (llvm::sys::path::is_absolute(DirName))
1378     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1379   else {
1380     SmallString<128> PathName;
1381     PathName = Directory->getName();
1382     llvm::sys::path::append(PathName, DirName);
1383     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1384   }
1385 
1386   if (!Dir) {
1387     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1388       << DirName;
1389     HadError = true;
1390     return;
1391   }
1392 
1393   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1394     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1395       << OwningModule->getFullModuleName();
1396     HadError = true;
1397     return;
1398   }
1399 
1400   // Record this umbrella directory.
1401   Map.setUmbrellaDir(ActiveModule, Dir);
1402 }
1403 
1404 /// \brief Parse a module export declaration.
1405 ///
1406 ///   export-declaration:
1407 ///     'export' wildcard-module-id
1408 ///
1409 ///   wildcard-module-id:
1410 ///     identifier
1411 ///     '*'
1412 ///     identifier '.' wildcard-module-id
1413 void ModuleMapParser::parseExportDecl() {
1414   assert(Tok.is(MMToken::ExportKeyword));
1415   SourceLocation ExportLoc = consumeToken();
1416 
1417   // Parse the module-id with an optional wildcard at the end.
1418   ModuleId ParsedModuleId;
1419   bool Wildcard = false;
1420   do {
1421     if (Tok.is(MMToken::Identifier)) {
1422       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1423                                               Tok.getLocation()));
1424       consumeToken();
1425 
1426       if (Tok.is(MMToken::Period)) {
1427         consumeToken();
1428         continue;
1429       }
1430 
1431       break;
1432     }
1433 
1434     if(Tok.is(MMToken::Star)) {
1435       Wildcard = true;
1436       consumeToken();
1437       break;
1438     }
1439 
1440     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1441     HadError = true;
1442     return;
1443   } while (true);
1444 
1445   Module::UnresolvedExportDecl Unresolved = {
1446     ExportLoc, ParsedModuleId, Wildcard
1447   };
1448   ActiveModule->UnresolvedExports.push_back(Unresolved);
1449 }
1450 
1451 /// \brief Parse a link declaration.
1452 ///
1453 ///   module-declaration:
1454 ///     'link' 'framework'[opt] string-literal
1455 void ModuleMapParser::parseLinkDecl() {
1456   assert(Tok.is(MMToken::LinkKeyword));
1457   SourceLocation LinkLoc = consumeToken();
1458 
1459   // Parse the optional 'framework' keyword.
1460   bool IsFramework = false;
1461   if (Tok.is(MMToken::FrameworkKeyword)) {
1462     consumeToken();
1463     IsFramework = true;
1464   }
1465 
1466   // Parse the library name
1467   if (!Tok.is(MMToken::StringLiteral)) {
1468     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1469       << IsFramework << SourceRange(LinkLoc);
1470     HadError = true;
1471     return;
1472   }
1473 
1474   std::string LibraryName = Tok.getString();
1475   consumeToken();
1476   ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1477                                                             IsFramework));
1478 }
1479 
1480 /// \brief Parse an inferred module declaration (wildcard modules).
1481 ///
1482 ///   module-declaration:
1483 ///     'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1484 ///       { inferred-module-member* }
1485 ///
1486 ///   inferred-module-member:
1487 ///     'export' '*'
1488 ///     'exclude' identifier
1489 void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
1490   assert(Tok.is(MMToken::Star));
1491   SourceLocation StarLoc = consumeToken();
1492   bool Failed = false;
1493 
1494   // Inferred modules must be submodules.
1495   if (!ActiveModule && !Framework) {
1496     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1497     Failed = true;
1498   }
1499 
1500   if (ActiveModule) {
1501     // Inferred modules must have umbrella directories.
1502     if (!Failed && !ActiveModule->getUmbrellaDir()) {
1503       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1504       Failed = true;
1505     }
1506 
1507     // Check for redefinition of an inferred module.
1508     if (!Failed && ActiveModule->InferSubmodules) {
1509       Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1510       if (ActiveModule->InferredSubmoduleLoc.isValid())
1511         Diags.Report(ActiveModule->InferredSubmoduleLoc,
1512                      diag::note_mmap_prev_definition);
1513       Failed = true;
1514     }
1515 
1516     // Check for the 'framework' keyword, which is not permitted here.
1517     if (Framework) {
1518       Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1519       Framework = false;
1520     }
1521   } else if (Explicit) {
1522     Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1523     Explicit = false;
1524   }
1525 
1526   // If there were any problems with this inferred submodule, skip its body.
1527   if (Failed) {
1528     if (Tok.is(MMToken::LBrace)) {
1529       consumeToken();
1530       skipUntil(MMToken::RBrace);
1531       if (Tok.is(MMToken::RBrace))
1532         consumeToken();
1533     }
1534     HadError = true;
1535     return;
1536   }
1537 
1538   // Parse optional attributes.
1539   Attributes Attrs;
1540   parseOptionalAttributes(Attrs);
1541 
1542   if (ActiveModule) {
1543     // Note that we have an inferred submodule.
1544     ActiveModule->InferSubmodules = true;
1545     ActiveModule->InferredSubmoduleLoc = StarLoc;
1546     ActiveModule->InferExplicitSubmodules = Explicit;
1547   } else {
1548     // We'll be inferring framework modules for this directory.
1549     Map.InferredDirectories[Directory].InferModules = true;
1550     Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1551   }
1552 
1553   // Parse the opening brace.
1554   if (!Tok.is(MMToken::LBrace)) {
1555     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1556     HadError = true;
1557     return;
1558   }
1559   SourceLocation LBraceLoc = consumeToken();
1560 
1561   // Parse the body of the inferred submodule.
1562   bool Done = false;
1563   do {
1564     switch (Tok.Kind) {
1565     case MMToken::EndOfFile:
1566     case MMToken::RBrace:
1567       Done = true;
1568       break;
1569 
1570     case MMToken::ExcludeKeyword: {
1571       if (ActiveModule) {
1572         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1573           << (ActiveModule != 0);
1574         consumeToken();
1575         break;
1576       }
1577 
1578       consumeToken();
1579       if (!Tok.is(MMToken::Identifier)) {
1580         Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1581         break;
1582       }
1583 
1584       Map.InferredDirectories[Directory].ExcludedModules
1585         .push_back(Tok.getString());
1586       consumeToken();
1587       break;
1588     }
1589 
1590     case MMToken::ExportKeyword:
1591       if (!ActiveModule) {
1592         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1593           << (ActiveModule != 0);
1594         consumeToken();
1595         break;
1596       }
1597 
1598       consumeToken();
1599       if (Tok.is(MMToken::Star))
1600         ActiveModule->InferExportWildcard = true;
1601       else
1602         Diags.Report(Tok.getLocation(),
1603                      diag::err_mmap_expected_export_wildcard);
1604       consumeToken();
1605       break;
1606 
1607     case MMToken::ExplicitKeyword:
1608     case MMToken::ModuleKeyword:
1609     case MMToken::HeaderKeyword:
1610     case MMToken::UmbrellaKeyword:
1611     default:
1612       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1613           << (ActiveModule != 0);
1614       consumeToken();
1615       break;
1616     }
1617   } while (!Done);
1618 
1619   if (Tok.is(MMToken::RBrace))
1620     consumeToken();
1621   else {
1622     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1623     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1624     HadError = true;
1625   }
1626 }
1627 
1628 /// \brief Parse optional attributes.
1629 ///
1630 ///   attributes:
1631 ///     attribute attributes
1632 ///     attribute
1633 ///
1634 ///   attribute:
1635 ///     [ identifier ]
1636 ///
1637 /// \param Attrs Will be filled in with the parsed attributes.
1638 ///
1639 /// \returns true if an error occurred, false otherwise.
1640 bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
1641   bool HadError = false;
1642 
1643   while (Tok.is(MMToken::LSquare)) {
1644     // Consume the '['.
1645     SourceLocation LSquareLoc = consumeToken();
1646 
1647     // Check whether we have an attribute name here.
1648     if (!Tok.is(MMToken::Identifier)) {
1649       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1650       skipUntil(MMToken::RSquare);
1651       if (Tok.is(MMToken::RSquare))
1652         consumeToken();
1653       HadError = true;
1654     }
1655 
1656     // Decode the attribute name.
1657     AttributeKind Attribute
1658       = llvm::StringSwitch<AttributeKind>(Tok.getString())
1659           .Case("system", AT_system)
1660           .Default(AT_unknown);
1661     switch (Attribute) {
1662     case AT_unknown:
1663       Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1664         << Tok.getString();
1665       break;
1666 
1667     case AT_system:
1668       Attrs.IsSystem = true;
1669       break;
1670     }
1671     consumeToken();
1672 
1673     // Consume the ']'.
1674     if (!Tok.is(MMToken::RSquare)) {
1675       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1676       Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1677       skipUntil(MMToken::RSquare);
1678       HadError = true;
1679     }
1680 
1681     if (Tok.is(MMToken::RSquare))
1682       consumeToken();
1683   }
1684 
1685   return HadError;
1686 }
1687 
1688 /// \brief If there is a specific header search directory due the presence
1689 /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1690 const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1691   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1692     // If we have an umbrella directory, use that.
1693     if (Mod->hasUmbrellaDir())
1694       return Mod->getUmbrellaDir();
1695 
1696     // If we have a framework directory, stop looking.
1697     if (Mod->IsFramework)
1698       return 0;
1699   }
1700 
1701   return 0;
1702 }
1703 
1704 /// \brief Parse a module map file.
1705 ///
1706 ///   module-map-file:
1707 ///     module-declaration*
1708 bool ModuleMapParser::parseModuleMapFile() {
1709   do {
1710     switch (Tok.Kind) {
1711     case MMToken::EndOfFile:
1712       return HadError;
1713 
1714     case MMToken::ExplicitKeyword:
1715     case MMToken::ModuleKeyword:
1716     case MMToken::FrameworkKeyword:
1717       parseModuleDecl();
1718       break;
1719 
1720     case MMToken::Comma:
1721     case MMToken::ExcludeKeyword:
1722     case MMToken::ExportKeyword:
1723     case MMToken::HeaderKeyword:
1724     case MMToken::Identifier:
1725     case MMToken::LBrace:
1726     case MMToken::LinkKeyword:
1727     case MMToken::LSquare:
1728     case MMToken::Period:
1729     case MMToken::RBrace:
1730     case MMToken::RSquare:
1731     case MMToken::RequiresKeyword:
1732     case MMToken::Star:
1733     case MMToken::StringLiteral:
1734     case MMToken::UmbrellaKeyword:
1735       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1736       HadError = true;
1737       consumeToken();
1738       break;
1739     }
1740   } while (true);
1741 }
1742 
1743 bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1744   llvm::DenseMap<const FileEntry *, bool>::iterator Known
1745     = ParsedModuleMap.find(File);
1746   if (Known != ParsedModuleMap.end())
1747     return Known->second;
1748 
1749   assert(Target != 0 && "Missing target information");
1750   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1751   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1752   if (!Buffer)
1753     return ParsedModuleMap[File] = true;
1754 
1755   // Parse this module map file.
1756   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1757   Diags->getClient()->BeginSourceFile(MMapLangOpts);
1758   ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
1759                          BuiltinIncludeDir);
1760   bool Result = Parser.parseModuleMapFile();
1761   Diags->getClient()->EndSourceFile();
1762   ParsedModuleMap[File] = Result;
1763   return Result;
1764 }
1765