1718292f2SDouglas Gregor //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
2718292f2SDouglas Gregor //
3718292f2SDouglas Gregor //                     The LLVM Compiler Infrastructure
4718292f2SDouglas Gregor //
5718292f2SDouglas Gregor // This file is distributed under the University of Illinois Open Source
6718292f2SDouglas Gregor // License. See LICENSE.TXT for details.
7718292f2SDouglas Gregor //
8718292f2SDouglas Gregor //===----------------------------------------------------------------------===//
9718292f2SDouglas Gregor //
10718292f2SDouglas Gregor // This file defines the ModuleMap implementation, which describes the layout
11718292f2SDouglas Gregor // of a module as it relates to headers.
12718292f2SDouglas Gregor //
13718292f2SDouglas Gregor //===----------------------------------------------------------------------===//
14718292f2SDouglas Gregor #include "clang/Lex/ModuleMap.h"
15718292f2SDouglas Gregor #include "clang/Lex/Lexer.h"
16718292f2SDouglas Gregor #include "clang/Lex/LiteralSupport.h"
17718292f2SDouglas Gregor #include "clang/Lex/LexDiagnostic.h"
18718292f2SDouglas Gregor #include "clang/Basic/Diagnostic.h"
19718292f2SDouglas Gregor #include "clang/Basic/FileManager.h"
20718292f2SDouglas Gregor #include "clang/Basic/TargetInfo.h"
21718292f2SDouglas Gregor #include "clang/Basic/TargetOptions.h"
22718292f2SDouglas Gregor #include "llvm/Support/Allocator.h"
23e89dbc1dSDouglas Gregor #include "llvm/Support/FileSystem.h"
24718292f2SDouglas Gregor #include "llvm/Support/Host.h"
255257fc63SDouglas Gregor #include "llvm/Support/PathV2.h"
26718292f2SDouglas Gregor #include "llvm/Support/raw_ostream.h"
27718292f2SDouglas Gregor #include "llvm/ADT/StringRef.h"
28718292f2SDouglas Gregor #include "llvm/ADT/StringSwitch.h"
29718292f2SDouglas Gregor using namespace clang;
30718292f2SDouglas Gregor 
312b82c2a5SDouglas Gregor Module::ExportDecl
322b82c2a5SDouglas Gregor ModuleMap::resolveExport(Module *Mod,
332b82c2a5SDouglas Gregor                          const Module::UnresolvedExportDecl &Unresolved,
342b82c2a5SDouglas Gregor                          bool Complain) {
35f5eedd05SDouglas Gregor   // We may have just a wildcard.
36f5eedd05SDouglas Gregor   if (Unresolved.Id.empty()) {
37f5eedd05SDouglas Gregor     assert(Unresolved.Wildcard && "Invalid unresolved export");
38f5eedd05SDouglas Gregor     return Module::ExportDecl(0, true);
39f5eedd05SDouglas Gregor   }
40f5eedd05SDouglas Gregor 
412b82c2a5SDouglas Gregor   // Find the starting module.
422b82c2a5SDouglas Gregor   Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
432b82c2a5SDouglas Gregor   if (!Context) {
442b82c2a5SDouglas Gregor     if (Complain)
452b82c2a5SDouglas Gregor       Diags->Report(Unresolved.Id[0].second,
462b82c2a5SDouglas Gregor                     diag::err_mmap_missing_module_unqualified)
472b82c2a5SDouglas Gregor         << Unresolved.Id[0].first << Mod->getFullModuleName();
482b82c2a5SDouglas Gregor 
492b82c2a5SDouglas Gregor     return Module::ExportDecl();
502b82c2a5SDouglas Gregor   }
512b82c2a5SDouglas Gregor 
522b82c2a5SDouglas Gregor   // Dig into the module path.
532b82c2a5SDouglas Gregor   for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
542b82c2a5SDouglas Gregor     Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
552b82c2a5SDouglas Gregor                                         Context);
562b82c2a5SDouglas Gregor     if (!Sub) {
572b82c2a5SDouglas Gregor       if (Complain)
582b82c2a5SDouglas Gregor         Diags->Report(Unresolved.Id[I].second,
592b82c2a5SDouglas Gregor                       diag::err_mmap_missing_module_qualified)
602b82c2a5SDouglas Gregor           << Unresolved.Id[I].first << Context->getFullModuleName()
612b82c2a5SDouglas Gregor           << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
622b82c2a5SDouglas Gregor 
632b82c2a5SDouglas Gregor       return Module::ExportDecl();
642b82c2a5SDouglas Gregor     }
652b82c2a5SDouglas Gregor 
662b82c2a5SDouglas Gregor     Context = Sub;
672b82c2a5SDouglas Gregor   }
682b82c2a5SDouglas Gregor 
692b82c2a5SDouglas Gregor   return Module::ExportDecl(Context, Unresolved.Wildcard);
702b82c2a5SDouglas Gregor }
712b82c2a5SDouglas Gregor 
721fb5c3a6SDouglas Gregor ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
731fb5c3a6SDouglas Gregor                      const LangOptions &LangOpts)
741fb5c3a6SDouglas Gregor   : LangOpts(LangOpts)
751fb5c3a6SDouglas Gregor {
76718292f2SDouglas Gregor   llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
77718292f2SDouglas Gregor   Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>(
78718292f2SDouglas Gregor             new DiagnosticsEngine(DiagIDs));
79718292f2SDouglas Gregor   Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
80718292f2SDouglas Gregor   SourceMgr = new SourceManager(*Diags, FileMgr);
81718292f2SDouglas Gregor }
82718292f2SDouglas Gregor 
83718292f2SDouglas Gregor ModuleMap::~ModuleMap() {
845acdf59eSDouglas Gregor   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
855acdf59eSDouglas Gregor                                         IEnd = Modules.end();
865acdf59eSDouglas Gregor        I != IEnd; ++I) {
875acdf59eSDouglas Gregor     delete I->getValue();
885acdf59eSDouglas Gregor   }
895acdf59eSDouglas Gregor 
90718292f2SDouglas Gregor   delete SourceMgr;
91718292f2SDouglas Gregor }
92718292f2SDouglas Gregor 
93de3ef502SDouglas Gregor Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
94ab0c8a84SDouglas Gregor   llvm::DenseMap<const FileEntry *, Module *>::iterator Known
95ab0c8a84SDouglas Gregor     = Headers.find(File);
961fb5c3a6SDouglas Gregor   if (Known != Headers.end()) {
971fb5c3a6SDouglas Gregor     // If a header corresponds to an unavailable module, don't report
981fb5c3a6SDouglas Gregor     // that it maps to anything.
991fb5c3a6SDouglas Gregor     if (!Known->second->isAvailable())
1001fb5c3a6SDouglas Gregor       return 0;
1011fb5c3a6SDouglas Gregor 
102ab0c8a84SDouglas Gregor     return Known->second;
1031fb5c3a6SDouglas Gregor   }
104ab0c8a84SDouglas Gregor 
105b65dbfffSDouglas Gregor   const DirectoryEntry *Dir = File->getDir();
106b65dbfffSDouglas Gregor   llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
107b65dbfffSDouglas Gregor   StringRef DirName = Dir->getName();
108a89c5ac4SDouglas Gregor 
109a89c5ac4SDouglas Gregor   // Keep walking up the directory hierarchy, looking for a directory with
110a89c5ac4SDouglas Gregor   // an umbrella header.
111b65dbfffSDouglas Gregor   do {
112a89c5ac4SDouglas Gregor     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
113a89c5ac4SDouglas Gregor       = UmbrellaDirs.find(Dir);
114a89c5ac4SDouglas Gregor     if (KnownDir != UmbrellaDirs.end()) {
115a89c5ac4SDouglas Gregor       Module *Result = KnownDir->second;
116930a85ccSDouglas Gregor 
117930a85ccSDouglas Gregor       // Search up the module stack until we find a module with an umbrella
11873141fa9SDouglas Gregor       // directory.
119930a85ccSDouglas Gregor       Module *UmbrellaModule = Result;
12073141fa9SDouglas Gregor       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
121930a85ccSDouglas Gregor         UmbrellaModule = UmbrellaModule->Parent;
122930a85ccSDouglas Gregor 
123930a85ccSDouglas Gregor       if (UmbrellaModule->InferSubmodules) {
124a89c5ac4SDouglas Gregor         // Infer submodules for each of the directories we found between
125a89c5ac4SDouglas Gregor         // the directory of the umbrella header and the directory where
126a89c5ac4SDouglas Gregor         // the actual header is located.
1279458f82dSDouglas Gregor         bool Explicit = UmbrellaModule->InferExplicitSubmodules;
1289458f82dSDouglas Gregor 
1297033127bSDouglas Gregor         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
130a89c5ac4SDouglas Gregor           // Find or create the module that corresponds to this directory name.
131a89c5ac4SDouglas Gregor           StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
132a89c5ac4SDouglas Gregor           Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
1339458f82dSDouglas Gregor                                       Explicit).first;
134a89c5ac4SDouglas Gregor 
135a89c5ac4SDouglas Gregor           // Associate the module and the directory.
136a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I-1]] = Result;
137a89c5ac4SDouglas Gregor 
138a89c5ac4SDouglas Gregor           // If inferred submodules export everything they import, add a
139a89c5ac4SDouglas Gregor           // wildcard to the set of exports.
140930a85ccSDouglas Gregor           if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
141a89c5ac4SDouglas Gregor             Result->Exports.push_back(Module::ExportDecl(0, true));
142a89c5ac4SDouglas Gregor         }
143a89c5ac4SDouglas Gregor 
144a89c5ac4SDouglas Gregor         // Infer a submodule with the same name as this header file.
145a89c5ac4SDouglas Gregor         StringRef Name = llvm::sys::path::stem(File->getName());
146a89c5ac4SDouglas Gregor         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
1479458f82dSDouglas Gregor                                     Explicit).first;
148a89c5ac4SDouglas Gregor 
149a89c5ac4SDouglas Gregor         // If inferred submodules export everything they import, add a
150a89c5ac4SDouglas Gregor         // wildcard to the set of exports.
151930a85ccSDouglas Gregor         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
152a89c5ac4SDouglas Gregor           Result->Exports.push_back(Module::ExportDecl(0, true));
153a89c5ac4SDouglas Gregor       } else {
154a89c5ac4SDouglas Gregor         // Record each of the directories we stepped through as being part of
155a89c5ac4SDouglas Gregor         // the module we found, since the umbrella header covers them all.
156a89c5ac4SDouglas Gregor         for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
157a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I]] = Result;
158a89c5ac4SDouglas Gregor       }
159a89c5ac4SDouglas Gregor 
160a89c5ac4SDouglas Gregor       Headers[File] = Result;
1611fb5c3a6SDouglas Gregor 
1621fb5c3a6SDouglas Gregor       // If a header corresponds to an unavailable module, don't report
1631fb5c3a6SDouglas Gregor       // that it maps to anything.
1641fb5c3a6SDouglas Gregor       if (!Result->isAvailable())
1651fb5c3a6SDouglas Gregor         return 0;
1661fb5c3a6SDouglas Gregor 
167a89c5ac4SDouglas Gregor       return Result;
168a89c5ac4SDouglas Gregor     }
169a89c5ac4SDouglas Gregor 
170a89c5ac4SDouglas Gregor     SkippedDirs.push_back(Dir);
171a89c5ac4SDouglas Gregor 
172b65dbfffSDouglas Gregor     // Retrieve our parent path.
173b65dbfffSDouglas Gregor     DirName = llvm::sys::path::parent_path(DirName);
174b65dbfffSDouglas Gregor     if (DirName.empty())
175b65dbfffSDouglas Gregor       break;
176b65dbfffSDouglas Gregor 
177b65dbfffSDouglas Gregor     // Resolve the parent path to a directory entry.
178b65dbfffSDouglas Gregor     Dir = SourceMgr->getFileManager().getDirectory(DirName);
179a89c5ac4SDouglas Gregor   } while (Dir);
180b65dbfffSDouglas Gregor 
181ab0c8a84SDouglas Gregor   return 0;
182ab0c8a84SDouglas Gregor }
183ab0c8a84SDouglas Gregor 
1841fb5c3a6SDouglas Gregor bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) {
1851fb5c3a6SDouglas Gregor   llvm::DenseMap<const FileEntry *, Module *>::iterator Known
1861fb5c3a6SDouglas Gregor     = Headers.find(Header);
1871fb5c3a6SDouglas Gregor   if (Known != Headers.end())
1881fb5c3a6SDouglas Gregor     return !Known->second->isAvailable();
1891fb5c3a6SDouglas Gregor 
1901fb5c3a6SDouglas Gregor   const DirectoryEntry *Dir = Header->getDir();
1911fb5c3a6SDouglas Gregor   llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
1921fb5c3a6SDouglas Gregor   StringRef DirName = Dir->getName();
1931fb5c3a6SDouglas Gregor 
1941fb5c3a6SDouglas Gregor   // Keep walking up the directory hierarchy, looking for a directory with
1951fb5c3a6SDouglas Gregor   // an umbrella header.
1961fb5c3a6SDouglas Gregor   do {
1971fb5c3a6SDouglas Gregor     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
1981fb5c3a6SDouglas Gregor       = UmbrellaDirs.find(Dir);
1991fb5c3a6SDouglas Gregor     if (KnownDir != UmbrellaDirs.end()) {
2001fb5c3a6SDouglas Gregor       Module *Found = KnownDir->second;
2011fb5c3a6SDouglas Gregor       if (!Found->isAvailable())
2021fb5c3a6SDouglas Gregor         return true;
2031fb5c3a6SDouglas Gregor 
2041fb5c3a6SDouglas Gregor       // Search up the module stack until we find a module with an umbrella
2051fb5c3a6SDouglas Gregor       // directory.
2061fb5c3a6SDouglas Gregor       Module *UmbrellaModule = Found;
2071fb5c3a6SDouglas Gregor       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
2081fb5c3a6SDouglas Gregor         UmbrellaModule = UmbrellaModule->Parent;
2091fb5c3a6SDouglas Gregor 
2101fb5c3a6SDouglas Gregor       if (UmbrellaModule->InferSubmodules) {
2111fb5c3a6SDouglas Gregor         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
2121fb5c3a6SDouglas Gregor           // Find or create the module that corresponds to this directory name.
2131fb5c3a6SDouglas Gregor           StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
2141fb5c3a6SDouglas Gregor           Found = lookupModuleQualified(Name, Found);
2151fb5c3a6SDouglas Gregor           if (!Found)
2161fb5c3a6SDouglas Gregor             return false;
2171fb5c3a6SDouglas Gregor           if (!Found->isAvailable())
2181fb5c3a6SDouglas Gregor             return true;
2191fb5c3a6SDouglas Gregor         }
2201fb5c3a6SDouglas Gregor 
2211fb5c3a6SDouglas Gregor         // Infer a submodule with the same name as this header file.
2221fb5c3a6SDouglas Gregor         StringRef Name = llvm::sys::path::stem(Header->getName());
2231fb5c3a6SDouglas Gregor         Found = lookupModuleQualified(Name, Found);
2241fb5c3a6SDouglas Gregor         if (!Found)
2251fb5c3a6SDouglas Gregor           return false;
2261fb5c3a6SDouglas Gregor       }
2271fb5c3a6SDouglas Gregor 
2281fb5c3a6SDouglas Gregor       return !Found->isAvailable();
2291fb5c3a6SDouglas Gregor     }
2301fb5c3a6SDouglas Gregor 
2311fb5c3a6SDouglas Gregor     SkippedDirs.push_back(Dir);
2321fb5c3a6SDouglas Gregor 
2331fb5c3a6SDouglas Gregor     // Retrieve our parent path.
2341fb5c3a6SDouglas Gregor     DirName = llvm::sys::path::parent_path(DirName);
2351fb5c3a6SDouglas Gregor     if (DirName.empty())
2361fb5c3a6SDouglas Gregor       break;
2371fb5c3a6SDouglas Gregor 
2381fb5c3a6SDouglas Gregor     // Resolve the parent path to a directory entry.
2391fb5c3a6SDouglas Gregor     Dir = SourceMgr->getFileManager().getDirectory(DirName);
2401fb5c3a6SDouglas Gregor   } while (Dir);
2411fb5c3a6SDouglas Gregor 
2421fb5c3a6SDouglas Gregor   return false;
2431fb5c3a6SDouglas Gregor }
2441fb5c3a6SDouglas Gregor 
245de3ef502SDouglas Gregor Module *ModuleMap::findModule(StringRef Name) {
24688bdfb0eSDouglas Gregor   llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
24788bdfb0eSDouglas Gregor   if (Known != Modules.end())
24888bdfb0eSDouglas Gregor     return Known->getValue();
24988bdfb0eSDouglas Gregor 
25088bdfb0eSDouglas Gregor   return 0;
25188bdfb0eSDouglas Gregor }
25288bdfb0eSDouglas Gregor 
2532b82c2a5SDouglas Gregor Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
2542b82c2a5SDouglas Gregor   for(; Context; Context = Context->Parent) {
2552b82c2a5SDouglas Gregor     if (Module *Sub = lookupModuleQualified(Name, Context))
2562b82c2a5SDouglas Gregor       return Sub;
2572b82c2a5SDouglas Gregor   }
2582b82c2a5SDouglas Gregor 
2592b82c2a5SDouglas Gregor   return findModule(Name);
2602b82c2a5SDouglas Gregor }
2612b82c2a5SDouglas Gregor 
2622b82c2a5SDouglas Gregor Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
2632b82c2a5SDouglas Gregor   if (!Context)
2642b82c2a5SDouglas Gregor     return findModule(Name);
2652b82c2a5SDouglas Gregor 
266eb90e830SDouglas Gregor   return Context->findSubmodule(Name);
2672b82c2a5SDouglas Gregor }
2682b82c2a5SDouglas Gregor 
269de3ef502SDouglas Gregor std::pair<Module *, bool>
27069021974SDouglas Gregor ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
27169021974SDouglas Gregor                               bool IsExplicit) {
27269021974SDouglas Gregor   // Try to find an existing module with this name.
273eb90e830SDouglas Gregor   if (Module *Sub = lookupModuleQualified(Name, Parent))
274eb90e830SDouglas Gregor     return std::make_pair(Sub, false);
27569021974SDouglas Gregor 
27669021974SDouglas Gregor   // Create a new module with this name.
27769021974SDouglas Gregor   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
27869021974SDouglas Gregor                               IsExplicit);
279eb90e830SDouglas Gregor   if (!Parent)
28069021974SDouglas Gregor     Modules[Name] = Result;
28169021974SDouglas Gregor   return std::make_pair(Result, true);
28269021974SDouglas Gregor }
28369021974SDouglas Gregor 
284de3ef502SDouglas Gregor Module *
28556c64013SDouglas Gregor ModuleMap::inferFrameworkModule(StringRef ModuleName,
286e89dbc1dSDouglas Gregor                                 const DirectoryEntry *FrameworkDir,
287e89dbc1dSDouglas Gregor                                 Module *Parent) {
28856c64013SDouglas Gregor   // Check whether we've already found this module.
289e89dbc1dSDouglas Gregor   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
290e89dbc1dSDouglas Gregor     return Mod;
291e89dbc1dSDouglas Gregor 
292e89dbc1dSDouglas Gregor   FileManager &FileMgr = SourceMgr->getFileManager();
29356c64013SDouglas Gregor 
29456c64013SDouglas Gregor   // Look for an umbrella header.
29556c64013SDouglas Gregor   llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
29656c64013SDouglas Gregor   llvm::sys::path::append(UmbrellaName, "Headers");
29756c64013SDouglas Gregor   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
298e89dbc1dSDouglas Gregor   const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
29956c64013SDouglas Gregor 
30056c64013SDouglas Gregor   // FIXME: If there's no umbrella header, we could probably scan the
30156c64013SDouglas Gregor   // framework to load *everything*. But, it's not clear that this is a good
30256c64013SDouglas Gregor   // idea.
30356c64013SDouglas Gregor   if (!UmbrellaHeader)
30456c64013SDouglas Gregor     return 0;
30556c64013SDouglas Gregor 
306e89dbc1dSDouglas Gregor   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
307e89dbc1dSDouglas Gregor                               /*IsFramework=*/true, /*IsExplicit=*/false);
308eb90e830SDouglas Gregor   if (!Parent)
309e89dbc1dSDouglas Gregor     Modules[ModuleName] = Result;
310e89dbc1dSDouglas Gregor 
311322f633cSDouglas Gregor   // umbrella header "umbrella-header-name"
31273141fa9SDouglas Gregor   Result->Umbrella = UmbrellaHeader;
31356c64013SDouglas Gregor   Headers[UmbrellaHeader] = Result;
3144dc71835SDouglas Gregor   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
315d8bd7537SDouglas Gregor 
316d8bd7537SDouglas Gregor   // export *
317d8bd7537SDouglas Gregor   Result->Exports.push_back(Module::ExportDecl(0, true));
318d8bd7537SDouglas Gregor 
319a89c5ac4SDouglas Gregor   // module * { export * }
320a89c5ac4SDouglas Gregor   Result->InferSubmodules = true;
321a89c5ac4SDouglas Gregor   Result->InferExportWildcard = true;
322a89c5ac4SDouglas Gregor 
323e89dbc1dSDouglas Gregor   // Look for subframeworks.
324e89dbc1dSDouglas Gregor   llvm::error_code EC;
325ddaa69cbSDouglas Gregor   llvm::SmallString<128> SubframeworksDirName
326ddaa69cbSDouglas Gregor     = StringRef(FrameworkDir->getName());
327e89dbc1dSDouglas Gregor   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
328ddaa69cbSDouglas Gregor   llvm::SmallString<128> SubframeworksDirNameNative;
329ddaa69cbSDouglas Gregor   llvm::sys::path::native(SubframeworksDirName.str(),
330ddaa69cbSDouglas Gregor                           SubframeworksDirNameNative);
331ddaa69cbSDouglas Gregor   for (llvm::sys::fs::directory_iterator
332ddaa69cbSDouglas Gregor          Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
333e89dbc1dSDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
334e89dbc1dSDouglas Gregor     if (!StringRef(Dir->path()).endswith(".framework"))
335e89dbc1dSDouglas Gregor       continue;
336f2161a70SDouglas Gregor 
337e89dbc1dSDouglas Gregor     if (const DirectoryEntry *SubframeworkDir
338e89dbc1dSDouglas Gregor           = FileMgr.getDirectory(Dir->path())) {
339e89dbc1dSDouglas Gregor       // FIXME: Do we want to warn about subframeworks without umbrella headers?
340e89dbc1dSDouglas Gregor       inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir,
341e89dbc1dSDouglas Gregor                            Result);
342e89dbc1dSDouglas Gregor     }
343e89dbc1dSDouglas Gregor   }
344e89dbc1dSDouglas Gregor 
3459458f82dSDouglas Gregor   // Look for private headers.
3469458f82dSDouglas Gregor   llvm::SmallString<128> PrivateHeadersDirName(FrameworkDir->getName());
3479458f82dSDouglas Gregor   llvm::sys::path::append(PrivateHeadersDirName, "PrivateHeaders");
3487033127bSDouglas Gregor   if (const DirectoryEntry *Dir = FileMgr.getDirectory(PrivateHeadersDirName)) {
3497033127bSDouglas Gregor     Module *Private = findOrCreateModule("Private", Result,
3509458f82dSDouglas Gregor                                          /*IsFramework=*/false,
3519458f82dSDouglas Gregor                                          /*IsExplicit=*/true).first;
3527033127bSDouglas Gregor     setUmbrellaDir(Private, Dir);
3537033127bSDouglas Gregor     Private->InferSubmodules = true;
3547033127bSDouglas Gregor     Private->InferExplicitSubmodules = true;
3557033127bSDouglas Gregor     Private->InferExportWildcard = true;
3569458f82dSDouglas Gregor   }
3579458f82dSDouglas Gregor 
35856c64013SDouglas Gregor   return Result;
35956c64013SDouglas Gregor }
36056c64013SDouglas Gregor 
361a89c5ac4SDouglas Gregor void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
362a89c5ac4SDouglas Gregor   Headers[UmbrellaHeader] = Mod;
36373141fa9SDouglas Gregor   Mod->Umbrella = UmbrellaHeader;
3647033127bSDouglas Gregor   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
365a89c5ac4SDouglas Gregor }
366a89c5ac4SDouglas Gregor 
367524e33e1SDouglas Gregor void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
368524e33e1SDouglas Gregor   Mod->Umbrella = UmbrellaDir;
369524e33e1SDouglas Gregor   UmbrellaDirs[UmbrellaDir] = Mod;
370524e33e1SDouglas Gregor }
371524e33e1SDouglas Gregor 
372a89c5ac4SDouglas Gregor void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) {
373a89c5ac4SDouglas Gregor   Mod->Headers.push_back(Header);
374a89c5ac4SDouglas Gregor   Headers[Header] = Mod;
375a89c5ac4SDouglas Gregor }
376a89c5ac4SDouglas Gregor 
377514b636aSDouglas Gregor const FileEntry *
378de3ef502SDouglas Gregor ModuleMap::getContainingModuleMapFile(Module *Module) {
379514b636aSDouglas Gregor   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
380514b636aSDouglas Gregor     return 0;
381514b636aSDouglas Gregor 
382514b636aSDouglas Gregor   return SourceMgr->getFileEntryForID(
383514b636aSDouglas Gregor            SourceMgr->getFileID(Module->DefinitionLoc));
384514b636aSDouglas Gregor }
385514b636aSDouglas Gregor 
386718292f2SDouglas Gregor void ModuleMap::dump() {
387718292f2SDouglas Gregor   llvm::errs() << "Modules:";
388718292f2SDouglas Gregor   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
389718292f2SDouglas Gregor                                         MEnd = Modules.end();
390718292f2SDouglas Gregor        M != MEnd; ++M)
391d28d1b8dSDouglas Gregor     M->getValue()->print(llvm::errs(), 2);
392718292f2SDouglas Gregor 
393718292f2SDouglas Gregor   llvm::errs() << "Headers:";
394718292f2SDouglas Gregor   for (llvm::DenseMap<const FileEntry *, Module *>::iterator
395718292f2SDouglas Gregor             H = Headers.begin(),
396718292f2SDouglas Gregor          HEnd = Headers.end();
397718292f2SDouglas Gregor        H != HEnd; ++H) {
398718292f2SDouglas Gregor     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
399718292f2SDouglas Gregor                  << H->second->getFullModuleName() << "\n";
400718292f2SDouglas Gregor   }
401718292f2SDouglas Gregor }
402718292f2SDouglas Gregor 
4032b82c2a5SDouglas Gregor bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
4042b82c2a5SDouglas Gregor   bool HadError = false;
4052b82c2a5SDouglas Gregor   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
4062b82c2a5SDouglas Gregor     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
4072b82c2a5SDouglas Gregor                                               Complain);
408f5eedd05SDouglas Gregor     if (Export.getPointer() || Export.getInt())
4092b82c2a5SDouglas Gregor       Mod->Exports.push_back(Export);
4102b82c2a5SDouglas Gregor     else
4112b82c2a5SDouglas Gregor       HadError = true;
4122b82c2a5SDouglas Gregor   }
4132b82c2a5SDouglas Gregor   Mod->UnresolvedExports.clear();
4142b82c2a5SDouglas Gregor   return HadError;
4152b82c2a5SDouglas Gregor }
4162b82c2a5SDouglas Gregor 
4170093b3c7SDouglas Gregor Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
4180093b3c7SDouglas Gregor   if (Loc.isInvalid())
4190093b3c7SDouglas Gregor     return 0;
4200093b3c7SDouglas Gregor 
4210093b3c7SDouglas Gregor   // Use the expansion location to determine which module we're in.
4220093b3c7SDouglas Gregor   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
4230093b3c7SDouglas Gregor   if (!ExpansionLoc.isFileID())
4240093b3c7SDouglas Gregor     return 0;
4250093b3c7SDouglas Gregor 
4260093b3c7SDouglas Gregor 
4270093b3c7SDouglas Gregor   const SourceManager &SrcMgr = Loc.getManager();
4280093b3c7SDouglas Gregor   FileID ExpansionFileID = ExpansionLoc.getFileID();
429*224d8a74SDouglas Gregor 
430*224d8a74SDouglas Gregor   while (const FileEntry *ExpansionFile
431*224d8a74SDouglas Gregor            = SrcMgr.getFileEntryForID(ExpansionFileID)) {
432*224d8a74SDouglas Gregor     // Find the module that owns this header (if any).
433*224d8a74SDouglas Gregor     if (Module *Mod = findModuleForHeader(ExpansionFile))
434*224d8a74SDouglas Gregor       return Mod;
435*224d8a74SDouglas Gregor 
436*224d8a74SDouglas Gregor     // No module owns this header, so look up the inclusion chain to see if
437*224d8a74SDouglas Gregor     // any included header has an associated module.
438*224d8a74SDouglas Gregor     SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
439*224d8a74SDouglas Gregor     if (IncludeLoc.isInvalid())
4400093b3c7SDouglas Gregor       return 0;
4410093b3c7SDouglas Gregor 
442*224d8a74SDouglas Gregor     ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
443*224d8a74SDouglas Gregor   }
444*224d8a74SDouglas Gregor 
445*224d8a74SDouglas Gregor   return 0;
4460093b3c7SDouglas Gregor }
4470093b3c7SDouglas Gregor 
448718292f2SDouglas Gregor //----------------------------------------------------------------------------//
449718292f2SDouglas Gregor // Module map file parser
450718292f2SDouglas Gregor //----------------------------------------------------------------------------//
451718292f2SDouglas Gregor 
452718292f2SDouglas Gregor namespace clang {
453718292f2SDouglas Gregor   /// \brief A token in a module map file.
454718292f2SDouglas Gregor   struct MMToken {
455718292f2SDouglas Gregor     enum TokenKind {
4561fb5c3a6SDouglas Gregor       Comma,
457718292f2SDouglas Gregor       EndOfFile,
458718292f2SDouglas Gregor       HeaderKeyword,
459718292f2SDouglas Gregor       Identifier,
460718292f2SDouglas Gregor       ExplicitKeyword,
4612b82c2a5SDouglas Gregor       ExportKeyword,
462755b2055SDouglas Gregor       FrameworkKeyword,
463718292f2SDouglas Gregor       ModuleKeyword,
4642b82c2a5SDouglas Gregor       Period,
465718292f2SDouglas Gregor       UmbrellaKeyword,
4661fb5c3a6SDouglas Gregor       RequiresKeyword,
4672b82c2a5SDouglas Gregor       Star,
468718292f2SDouglas Gregor       StringLiteral,
469718292f2SDouglas Gregor       LBrace,
470718292f2SDouglas Gregor       RBrace
471718292f2SDouglas Gregor     } Kind;
472718292f2SDouglas Gregor 
473718292f2SDouglas Gregor     unsigned Location;
474718292f2SDouglas Gregor     unsigned StringLength;
475718292f2SDouglas Gregor     const char *StringData;
476718292f2SDouglas Gregor 
477718292f2SDouglas Gregor     void clear() {
478718292f2SDouglas Gregor       Kind = EndOfFile;
479718292f2SDouglas Gregor       Location = 0;
480718292f2SDouglas Gregor       StringLength = 0;
481718292f2SDouglas Gregor       StringData = 0;
482718292f2SDouglas Gregor     }
483718292f2SDouglas Gregor 
484718292f2SDouglas Gregor     bool is(TokenKind K) const { return Kind == K; }
485718292f2SDouglas Gregor 
486718292f2SDouglas Gregor     SourceLocation getLocation() const {
487718292f2SDouglas Gregor       return SourceLocation::getFromRawEncoding(Location);
488718292f2SDouglas Gregor     }
489718292f2SDouglas Gregor 
490718292f2SDouglas Gregor     StringRef getString() const {
491718292f2SDouglas Gregor       return StringRef(StringData, StringLength);
492718292f2SDouglas Gregor     }
493718292f2SDouglas Gregor   };
494718292f2SDouglas Gregor 
495718292f2SDouglas Gregor   class ModuleMapParser {
496718292f2SDouglas Gregor     Lexer &L;
497718292f2SDouglas Gregor     SourceManager &SourceMgr;
498718292f2SDouglas Gregor     DiagnosticsEngine &Diags;
499718292f2SDouglas Gregor     ModuleMap &Map;
500718292f2SDouglas Gregor 
5015257fc63SDouglas Gregor     /// \brief The directory that this module map resides in.
5025257fc63SDouglas Gregor     const DirectoryEntry *Directory;
5035257fc63SDouglas Gregor 
504718292f2SDouglas Gregor     /// \brief Whether an error occurred.
505718292f2SDouglas Gregor     bool HadError;
506718292f2SDouglas Gregor 
507718292f2SDouglas Gregor     /// \brief Default target information, used only for string literal
508718292f2SDouglas Gregor     /// parsing.
509718292f2SDouglas Gregor     TargetInfo *Target;
510718292f2SDouglas Gregor 
511718292f2SDouglas Gregor     /// \brief Stores string data for the various string literals referenced
512718292f2SDouglas Gregor     /// during parsing.
513718292f2SDouglas Gregor     llvm::BumpPtrAllocator StringData;
514718292f2SDouglas Gregor 
515718292f2SDouglas Gregor     /// \brief The current token.
516718292f2SDouglas Gregor     MMToken Tok;
517718292f2SDouglas Gregor 
518718292f2SDouglas Gregor     /// \brief The active module.
519de3ef502SDouglas Gregor     Module *ActiveModule;
520718292f2SDouglas Gregor 
521718292f2SDouglas Gregor     /// \brief Consume the current token and return its location.
522718292f2SDouglas Gregor     SourceLocation consumeToken();
523718292f2SDouglas Gregor 
524718292f2SDouglas Gregor     /// \brief Skip tokens until we reach the a token with the given kind
525718292f2SDouglas Gregor     /// (or the end of the file).
526718292f2SDouglas Gregor     void skipUntil(MMToken::TokenKind K);
527718292f2SDouglas Gregor 
528e7ab3669SDouglas Gregor     typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
529e7ab3669SDouglas Gregor       ModuleId;
530e7ab3669SDouglas Gregor     bool parseModuleId(ModuleId &Id);
531718292f2SDouglas Gregor     void parseModuleDecl();
5321fb5c3a6SDouglas Gregor     void parseRequiresDecl();
533322f633cSDouglas Gregor     void parseHeaderDecl(SourceLocation UmbrellaLoc);
534524e33e1SDouglas Gregor     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
5352b82c2a5SDouglas Gregor     void parseExportDecl();
53673441091SDouglas Gregor     void parseInferredSubmoduleDecl(bool Explicit);
537718292f2SDouglas Gregor 
5387033127bSDouglas Gregor     const DirectoryEntry *getOverriddenHeaderSearchDir();
5397033127bSDouglas Gregor 
540718292f2SDouglas Gregor   public:
541718292f2SDouglas Gregor     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
542718292f2SDouglas Gregor                              DiagnosticsEngine &Diags,
5435257fc63SDouglas Gregor                              ModuleMap &Map,
5445257fc63SDouglas Gregor                              const DirectoryEntry *Directory)
5455257fc63SDouglas Gregor       : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
5465257fc63SDouglas Gregor         Directory(Directory), HadError(false), ActiveModule(0)
547718292f2SDouglas Gregor     {
548718292f2SDouglas Gregor       TargetOptions TargetOpts;
549718292f2SDouglas Gregor       TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
550718292f2SDouglas Gregor       Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
551718292f2SDouglas Gregor 
552718292f2SDouglas Gregor       Tok.clear();
553718292f2SDouglas Gregor       consumeToken();
554718292f2SDouglas Gregor     }
555718292f2SDouglas Gregor 
556718292f2SDouglas Gregor     bool parseModuleMapFile();
557718292f2SDouglas Gregor   };
558718292f2SDouglas Gregor }
559718292f2SDouglas Gregor 
560718292f2SDouglas Gregor SourceLocation ModuleMapParser::consumeToken() {
561718292f2SDouglas Gregor retry:
562718292f2SDouglas Gregor   SourceLocation Result = Tok.getLocation();
563718292f2SDouglas Gregor   Tok.clear();
564718292f2SDouglas Gregor 
565718292f2SDouglas Gregor   Token LToken;
566718292f2SDouglas Gregor   L.LexFromRawLexer(LToken);
567718292f2SDouglas Gregor   Tok.Location = LToken.getLocation().getRawEncoding();
568718292f2SDouglas Gregor   switch (LToken.getKind()) {
569718292f2SDouglas Gregor   case tok::raw_identifier:
570718292f2SDouglas Gregor     Tok.StringData = LToken.getRawIdentifierData();
571718292f2SDouglas Gregor     Tok.StringLength = LToken.getLength();
572718292f2SDouglas Gregor     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
573718292f2SDouglas Gregor                  .Case("header", MMToken::HeaderKeyword)
574718292f2SDouglas Gregor                  .Case("explicit", MMToken::ExplicitKeyword)
5752b82c2a5SDouglas Gregor                  .Case("export", MMToken::ExportKeyword)
576755b2055SDouglas Gregor                  .Case("framework", MMToken::FrameworkKeyword)
577718292f2SDouglas Gregor                  .Case("module", MMToken::ModuleKeyword)
5781fb5c3a6SDouglas Gregor                  .Case("requires", MMToken::RequiresKeyword)
579718292f2SDouglas Gregor                  .Case("umbrella", MMToken::UmbrellaKeyword)
580718292f2SDouglas Gregor                  .Default(MMToken::Identifier);
581718292f2SDouglas Gregor     break;
582718292f2SDouglas Gregor 
5831fb5c3a6SDouglas Gregor   case tok::comma:
5841fb5c3a6SDouglas Gregor     Tok.Kind = MMToken::Comma;
5851fb5c3a6SDouglas Gregor     break;
5861fb5c3a6SDouglas Gregor 
587718292f2SDouglas Gregor   case tok::eof:
588718292f2SDouglas Gregor     Tok.Kind = MMToken::EndOfFile;
589718292f2SDouglas Gregor     break;
590718292f2SDouglas Gregor 
591718292f2SDouglas Gregor   case tok::l_brace:
592718292f2SDouglas Gregor     Tok.Kind = MMToken::LBrace;
593718292f2SDouglas Gregor     break;
594718292f2SDouglas Gregor 
5952b82c2a5SDouglas Gregor   case tok::period:
5962b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Period;
5972b82c2a5SDouglas Gregor     break;
5982b82c2a5SDouglas Gregor 
599718292f2SDouglas Gregor   case tok::r_brace:
600718292f2SDouglas Gregor     Tok.Kind = MMToken::RBrace;
601718292f2SDouglas Gregor     break;
602718292f2SDouglas Gregor 
6032b82c2a5SDouglas Gregor   case tok::star:
6042b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Star;
6052b82c2a5SDouglas Gregor     break;
6062b82c2a5SDouglas Gregor 
607718292f2SDouglas Gregor   case tok::string_literal: {
608718292f2SDouglas Gregor     // Parse the string literal.
609718292f2SDouglas Gregor     LangOptions LangOpts;
610718292f2SDouglas Gregor     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
611718292f2SDouglas Gregor     if (StringLiteral.hadError)
612718292f2SDouglas Gregor       goto retry;
613718292f2SDouglas Gregor 
614718292f2SDouglas Gregor     // Copy the string literal into our string data allocator.
615718292f2SDouglas Gregor     unsigned Length = StringLiteral.GetStringLength();
616718292f2SDouglas Gregor     char *Saved = StringData.Allocate<char>(Length + 1);
617718292f2SDouglas Gregor     memcpy(Saved, StringLiteral.GetString().data(), Length);
618718292f2SDouglas Gregor     Saved[Length] = 0;
619718292f2SDouglas Gregor 
620718292f2SDouglas Gregor     // Form the token.
621718292f2SDouglas Gregor     Tok.Kind = MMToken::StringLiteral;
622718292f2SDouglas Gregor     Tok.StringData = Saved;
623718292f2SDouglas Gregor     Tok.StringLength = Length;
624718292f2SDouglas Gregor     break;
625718292f2SDouglas Gregor   }
626718292f2SDouglas Gregor 
627718292f2SDouglas Gregor   case tok::comment:
628718292f2SDouglas Gregor     goto retry;
629718292f2SDouglas Gregor 
630718292f2SDouglas Gregor   default:
631718292f2SDouglas Gregor     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
632718292f2SDouglas Gregor     HadError = true;
633718292f2SDouglas Gregor     goto retry;
634718292f2SDouglas Gregor   }
635718292f2SDouglas Gregor 
636718292f2SDouglas Gregor   return Result;
637718292f2SDouglas Gregor }
638718292f2SDouglas Gregor 
639718292f2SDouglas Gregor void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
640718292f2SDouglas Gregor   unsigned braceDepth = 0;
641718292f2SDouglas Gregor   do {
642718292f2SDouglas Gregor     switch (Tok.Kind) {
643718292f2SDouglas Gregor     case MMToken::EndOfFile:
644718292f2SDouglas Gregor       return;
645718292f2SDouglas Gregor 
646718292f2SDouglas Gregor     case MMToken::LBrace:
647718292f2SDouglas Gregor       if (Tok.is(K) && braceDepth == 0)
648718292f2SDouglas Gregor         return;
649718292f2SDouglas Gregor 
650718292f2SDouglas Gregor       ++braceDepth;
651718292f2SDouglas Gregor       break;
652718292f2SDouglas Gregor 
653718292f2SDouglas Gregor     case MMToken::RBrace:
654718292f2SDouglas Gregor       if (braceDepth > 0)
655718292f2SDouglas Gregor         --braceDepth;
656718292f2SDouglas Gregor       else if (Tok.is(K))
657718292f2SDouglas Gregor         return;
658718292f2SDouglas Gregor       break;
659718292f2SDouglas Gregor 
660718292f2SDouglas Gregor     default:
661718292f2SDouglas Gregor       if (braceDepth == 0 && Tok.is(K))
662718292f2SDouglas Gregor         return;
663718292f2SDouglas Gregor       break;
664718292f2SDouglas Gregor     }
665718292f2SDouglas Gregor 
666718292f2SDouglas Gregor    consumeToken();
667718292f2SDouglas Gregor   } while (true);
668718292f2SDouglas Gregor }
669718292f2SDouglas Gregor 
670e7ab3669SDouglas Gregor /// \brief Parse a module-id.
671e7ab3669SDouglas Gregor ///
672e7ab3669SDouglas Gregor ///   module-id:
673e7ab3669SDouglas Gregor ///     identifier
674e7ab3669SDouglas Gregor ///     identifier '.' module-id
675e7ab3669SDouglas Gregor ///
676e7ab3669SDouglas Gregor /// \returns true if an error occurred, false otherwise.
677e7ab3669SDouglas Gregor bool ModuleMapParser::parseModuleId(ModuleId &Id) {
678e7ab3669SDouglas Gregor   Id.clear();
679e7ab3669SDouglas Gregor   do {
680e7ab3669SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
681e7ab3669SDouglas Gregor       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
682e7ab3669SDouglas Gregor       consumeToken();
683e7ab3669SDouglas Gregor     } else {
684e7ab3669SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
685e7ab3669SDouglas Gregor       return true;
686e7ab3669SDouglas Gregor     }
687e7ab3669SDouglas Gregor 
688e7ab3669SDouglas Gregor     if (!Tok.is(MMToken::Period))
689e7ab3669SDouglas Gregor       break;
690e7ab3669SDouglas Gregor 
691e7ab3669SDouglas Gregor     consumeToken();
692e7ab3669SDouglas Gregor   } while (true);
693e7ab3669SDouglas Gregor 
694e7ab3669SDouglas Gregor   return false;
695e7ab3669SDouglas Gregor }
696e7ab3669SDouglas Gregor 
697718292f2SDouglas Gregor /// \brief Parse a module declaration.
698718292f2SDouglas Gregor ///
699718292f2SDouglas Gregor ///   module-declaration:
700e7ab3669SDouglas Gregor ///     'explicit'[opt] 'framework'[opt] 'module' module-id { module-member* }
701718292f2SDouglas Gregor ///
702718292f2SDouglas Gregor ///   module-member:
7031fb5c3a6SDouglas Gregor ///     requires-declaration
704718292f2SDouglas Gregor ///     header-declaration
705e7ab3669SDouglas Gregor ///     submodule-declaration
7062b82c2a5SDouglas Gregor ///     export-declaration
70773441091SDouglas Gregor ///
70873441091SDouglas Gregor ///   submodule-declaration:
70973441091SDouglas Gregor ///     module-declaration
71073441091SDouglas Gregor ///     inferred-submodule-declaration
711718292f2SDouglas Gregor void ModuleMapParser::parseModuleDecl() {
712755b2055SDouglas Gregor   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
713755b2055SDouglas Gregor          Tok.is(MMToken::FrameworkKeyword));
714f2161a70SDouglas Gregor   // Parse 'explicit' or 'framework' keyword, if present.
715e7ab3669SDouglas Gregor   SourceLocation ExplicitLoc;
716718292f2SDouglas Gregor   bool Explicit = false;
717f2161a70SDouglas Gregor   bool Framework = false;
718755b2055SDouglas Gregor 
719f2161a70SDouglas Gregor   // Parse 'explicit' keyword, if present.
720f2161a70SDouglas Gregor   if (Tok.is(MMToken::ExplicitKeyword)) {
721e7ab3669SDouglas Gregor     ExplicitLoc = consumeToken();
722f2161a70SDouglas Gregor     Explicit = true;
723f2161a70SDouglas Gregor   }
724f2161a70SDouglas Gregor 
725f2161a70SDouglas Gregor   // Parse 'framework' keyword, if present.
726755b2055SDouglas Gregor   if (Tok.is(MMToken::FrameworkKeyword)) {
727755b2055SDouglas Gregor     consumeToken();
728755b2055SDouglas Gregor     Framework = true;
729755b2055SDouglas Gregor   }
730718292f2SDouglas Gregor 
731718292f2SDouglas Gregor   // Parse 'module' keyword.
732718292f2SDouglas Gregor   if (!Tok.is(MMToken::ModuleKeyword)) {
733d6343c99SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
734718292f2SDouglas Gregor     consumeToken();
735718292f2SDouglas Gregor     HadError = true;
736718292f2SDouglas Gregor     return;
737718292f2SDouglas Gregor   }
738718292f2SDouglas Gregor   consumeToken(); // 'module' keyword
739718292f2SDouglas Gregor 
74073441091SDouglas Gregor   // If we have a wildcard for the module name, this is an inferred submodule.
74173441091SDouglas Gregor   // Parse it.
74273441091SDouglas Gregor   if (Tok.is(MMToken::Star))
74373441091SDouglas Gregor     return parseInferredSubmoduleDecl(Explicit);
74473441091SDouglas Gregor 
745718292f2SDouglas Gregor   // Parse the module name.
746e7ab3669SDouglas Gregor   ModuleId Id;
747e7ab3669SDouglas Gregor   if (parseModuleId(Id)) {
748718292f2SDouglas Gregor     HadError = true;
749718292f2SDouglas Gregor     return;
750718292f2SDouglas Gregor   }
751e7ab3669SDouglas Gregor 
752e7ab3669SDouglas Gregor   if (ActiveModule) {
753e7ab3669SDouglas Gregor     if (Id.size() > 1) {
754e7ab3669SDouglas Gregor       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
755e7ab3669SDouglas Gregor         << SourceRange(Id.front().second, Id.back().second);
756e7ab3669SDouglas Gregor 
757e7ab3669SDouglas Gregor       HadError = true;
758e7ab3669SDouglas Gregor       return;
759e7ab3669SDouglas Gregor     }
760e7ab3669SDouglas Gregor   } else if (Id.size() == 1 && Explicit) {
761e7ab3669SDouglas Gregor     // Top-level modules can't be explicit.
762e7ab3669SDouglas Gregor     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
763e7ab3669SDouglas Gregor     Explicit = false;
764e7ab3669SDouglas Gregor     ExplicitLoc = SourceLocation();
765e7ab3669SDouglas Gregor     HadError = true;
766e7ab3669SDouglas Gregor   }
767e7ab3669SDouglas Gregor 
768e7ab3669SDouglas Gregor   Module *PreviousActiveModule = ActiveModule;
769e7ab3669SDouglas Gregor   if (Id.size() > 1) {
770e7ab3669SDouglas Gregor     // This module map defines a submodule. Go find the module of which it
771e7ab3669SDouglas Gregor     // is a submodule.
772e7ab3669SDouglas Gregor     ActiveModule = 0;
773e7ab3669SDouglas Gregor     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
774e7ab3669SDouglas Gregor       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
775e7ab3669SDouglas Gregor         ActiveModule = Next;
776e7ab3669SDouglas Gregor         continue;
777e7ab3669SDouglas Gregor       }
778e7ab3669SDouglas Gregor 
779e7ab3669SDouglas Gregor       if (ActiveModule) {
780e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
781e7ab3669SDouglas Gregor           << Id[I].first << ActiveModule->getTopLevelModule();
782e7ab3669SDouglas Gregor       } else {
783e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
784e7ab3669SDouglas Gregor       }
785e7ab3669SDouglas Gregor       HadError = true;
786e7ab3669SDouglas Gregor       return;
787e7ab3669SDouglas Gregor     }
788e7ab3669SDouglas Gregor   }
789e7ab3669SDouglas Gregor 
790e7ab3669SDouglas Gregor   StringRef ModuleName = Id.back().first;
791e7ab3669SDouglas Gregor   SourceLocation ModuleNameLoc = Id.back().second;
792718292f2SDouglas Gregor 
793718292f2SDouglas Gregor   // Parse the opening brace.
794718292f2SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
795718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
796718292f2SDouglas Gregor       << ModuleName;
797718292f2SDouglas Gregor     HadError = true;
798718292f2SDouglas Gregor     return;
799718292f2SDouglas Gregor   }
800718292f2SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
801718292f2SDouglas Gregor 
802718292f2SDouglas Gregor   // Determine whether this (sub)module has already been defined.
803eb90e830SDouglas Gregor   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
804fcc54a3bSDouglas Gregor     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
805fcc54a3bSDouglas Gregor       // Skip the module definition.
806fcc54a3bSDouglas Gregor       skipUntil(MMToken::RBrace);
807fcc54a3bSDouglas Gregor       if (Tok.is(MMToken::RBrace))
808fcc54a3bSDouglas Gregor         consumeToken();
809fcc54a3bSDouglas Gregor       else {
810fcc54a3bSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
811fcc54a3bSDouglas Gregor         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
812fcc54a3bSDouglas Gregor         HadError = true;
813fcc54a3bSDouglas Gregor       }
814fcc54a3bSDouglas Gregor       return;
815fcc54a3bSDouglas Gregor     }
816fcc54a3bSDouglas Gregor 
817718292f2SDouglas Gregor     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
818718292f2SDouglas Gregor       << ModuleName;
819eb90e830SDouglas Gregor     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
820718292f2SDouglas Gregor 
821718292f2SDouglas Gregor     // Skip the module definition.
822718292f2SDouglas Gregor     skipUntil(MMToken::RBrace);
823718292f2SDouglas Gregor     if (Tok.is(MMToken::RBrace))
824718292f2SDouglas Gregor       consumeToken();
825718292f2SDouglas Gregor 
826718292f2SDouglas Gregor     HadError = true;
827718292f2SDouglas Gregor     return;
828718292f2SDouglas Gregor   }
829718292f2SDouglas Gregor 
830718292f2SDouglas Gregor   // Start defining this module.
831eb90e830SDouglas Gregor   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
832eb90e830SDouglas Gregor                                         Explicit).first;
833eb90e830SDouglas Gregor   ActiveModule->DefinitionLoc = ModuleNameLoc;
834718292f2SDouglas Gregor 
835718292f2SDouglas Gregor   bool Done = false;
836718292f2SDouglas Gregor   do {
837718292f2SDouglas Gregor     switch (Tok.Kind) {
838718292f2SDouglas Gregor     case MMToken::EndOfFile:
839718292f2SDouglas Gregor     case MMToken::RBrace:
840718292f2SDouglas Gregor       Done = true;
841718292f2SDouglas Gregor       break;
842718292f2SDouglas Gregor 
843718292f2SDouglas Gregor     case MMToken::ExplicitKeyword:
844f2161a70SDouglas Gregor     case MMToken::FrameworkKeyword:
845718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
846718292f2SDouglas Gregor       parseModuleDecl();
847718292f2SDouglas Gregor       break;
848718292f2SDouglas Gregor 
8492b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
8502b82c2a5SDouglas Gregor       parseExportDecl();
8512b82c2a5SDouglas Gregor       break;
8522b82c2a5SDouglas Gregor 
8531fb5c3a6SDouglas Gregor     case MMToken::RequiresKeyword:
8541fb5c3a6SDouglas Gregor       parseRequiresDecl();
8551fb5c3a6SDouglas Gregor       break;
8561fb5c3a6SDouglas Gregor 
857524e33e1SDouglas Gregor     case MMToken::UmbrellaKeyword: {
858524e33e1SDouglas Gregor       SourceLocation UmbrellaLoc = consumeToken();
859524e33e1SDouglas Gregor       if (Tok.is(MMToken::HeaderKeyword))
860524e33e1SDouglas Gregor         parseHeaderDecl(UmbrellaLoc);
861524e33e1SDouglas Gregor       else
862524e33e1SDouglas Gregor         parseUmbrellaDirDecl(UmbrellaLoc);
863718292f2SDouglas Gregor       break;
864524e33e1SDouglas Gregor     }
865718292f2SDouglas Gregor 
866322f633cSDouglas Gregor     case MMToken::HeaderKeyword:
867322f633cSDouglas Gregor       parseHeaderDecl(SourceLocation());
868718292f2SDouglas Gregor       break;
869718292f2SDouglas Gregor 
870718292f2SDouglas Gregor     default:
871718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
872718292f2SDouglas Gregor       consumeToken();
873718292f2SDouglas Gregor       break;
874718292f2SDouglas Gregor     }
875718292f2SDouglas Gregor   } while (!Done);
876718292f2SDouglas Gregor 
877718292f2SDouglas Gregor   if (Tok.is(MMToken::RBrace))
878718292f2SDouglas Gregor     consumeToken();
879718292f2SDouglas Gregor   else {
880718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
881718292f2SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
882718292f2SDouglas Gregor     HadError = true;
883718292f2SDouglas Gregor   }
884718292f2SDouglas Gregor 
885e7ab3669SDouglas Gregor   // We're done parsing this module. Pop back to the previous module.
886e7ab3669SDouglas Gregor   ActiveModule = PreviousActiveModule;
887718292f2SDouglas Gregor }
888718292f2SDouglas Gregor 
8891fb5c3a6SDouglas Gregor /// \brief Parse a requires declaration.
8901fb5c3a6SDouglas Gregor ///
8911fb5c3a6SDouglas Gregor ///   requires-declaration:
8921fb5c3a6SDouglas Gregor ///     'requires' feature-list
8931fb5c3a6SDouglas Gregor ///
8941fb5c3a6SDouglas Gregor ///   feature-list:
8951fb5c3a6SDouglas Gregor ///     identifier ',' feature-list
8961fb5c3a6SDouglas Gregor ///     identifier
8971fb5c3a6SDouglas Gregor void ModuleMapParser::parseRequiresDecl() {
8981fb5c3a6SDouglas Gregor   assert(Tok.is(MMToken::RequiresKeyword));
8991fb5c3a6SDouglas Gregor 
9001fb5c3a6SDouglas Gregor   // Parse 'requires' keyword.
9011fb5c3a6SDouglas Gregor   consumeToken();
9021fb5c3a6SDouglas Gregor 
9031fb5c3a6SDouglas Gregor   // Parse the feature-list.
9041fb5c3a6SDouglas Gregor   do {
9051fb5c3a6SDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
9061fb5c3a6SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
9071fb5c3a6SDouglas Gregor       HadError = true;
9081fb5c3a6SDouglas Gregor       return;
9091fb5c3a6SDouglas Gregor     }
9101fb5c3a6SDouglas Gregor 
9111fb5c3a6SDouglas Gregor     // Consume the feature name.
9121fb5c3a6SDouglas Gregor     std::string Feature = Tok.getString();
9131fb5c3a6SDouglas Gregor     consumeToken();
9141fb5c3a6SDouglas Gregor 
9151fb5c3a6SDouglas Gregor     // Add this feature.
9161fb5c3a6SDouglas Gregor     ActiveModule->addRequirement(Feature, Map.LangOpts);
9171fb5c3a6SDouglas Gregor 
9181fb5c3a6SDouglas Gregor     if (!Tok.is(MMToken::Comma))
9191fb5c3a6SDouglas Gregor       break;
9201fb5c3a6SDouglas Gregor 
9211fb5c3a6SDouglas Gregor     // Consume the comma.
9221fb5c3a6SDouglas Gregor     consumeToken();
9231fb5c3a6SDouglas Gregor   } while (true);
9241fb5c3a6SDouglas Gregor }
9251fb5c3a6SDouglas Gregor 
926f2161a70SDouglas Gregor /// \brief Append to \p Paths the set of paths needed to get to the
927f2161a70SDouglas Gregor /// subframework in which the given module lives.
928f2161a70SDouglas Gregor void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) {
929f2161a70SDouglas Gregor   // Collect the framework names from the given module to the top-level module.
930f2161a70SDouglas Gregor   llvm::SmallVector<StringRef, 2> Paths;
931f2161a70SDouglas Gregor   for (; Mod; Mod = Mod->Parent) {
932f2161a70SDouglas Gregor     if (Mod->IsFramework)
933f2161a70SDouglas Gregor       Paths.push_back(Mod->Name);
934f2161a70SDouglas Gregor   }
935f2161a70SDouglas Gregor 
936f2161a70SDouglas Gregor   if (Paths.empty())
937f2161a70SDouglas Gregor     return;
938f2161a70SDouglas Gregor 
939f2161a70SDouglas Gregor   // Add Frameworks/Name.framework for each subframework.
940f2161a70SDouglas Gregor   for (unsigned I = Paths.size() - 1; I != 0; --I) {
941f2161a70SDouglas Gregor     llvm::sys::path::append(Path, "Frameworks");
942f2161a70SDouglas Gregor     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
943f2161a70SDouglas Gregor   }
944f2161a70SDouglas Gregor }
945f2161a70SDouglas Gregor 
946718292f2SDouglas Gregor /// \brief Parse a header declaration.
947718292f2SDouglas Gregor ///
948718292f2SDouglas Gregor ///   header-declaration:
949322f633cSDouglas Gregor ///     'umbrella'[opt] 'header' string-literal
950322f633cSDouglas Gregor void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc) {
951718292f2SDouglas Gregor   assert(Tok.is(MMToken::HeaderKeyword));
9521871ed3dSBenjamin Kramer   consumeToken();
953718292f2SDouglas Gregor 
954322f633cSDouglas Gregor   bool Umbrella = UmbrellaLoc.isValid();
955322f633cSDouglas Gregor 
956718292f2SDouglas Gregor   // Parse the header name.
957718292f2SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
958718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
959718292f2SDouglas Gregor       << "header";
960718292f2SDouglas Gregor     HadError = true;
961718292f2SDouglas Gregor     return;
962718292f2SDouglas Gregor   }
963e7ab3669SDouglas Gregor   std::string FileName = Tok.getString();
964718292f2SDouglas Gregor   SourceLocation FileNameLoc = consumeToken();
965718292f2SDouglas Gregor 
966524e33e1SDouglas Gregor   // Check whether we already have an umbrella.
967524e33e1SDouglas Gregor   if (Umbrella && ActiveModule->Umbrella) {
968524e33e1SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
969524e33e1SDouglas Gregor       << ActiveModule->getFullModuleName();
970322f633cSDouglas Gregor     HadError = true;
971322f633cSDouglas Gregor     return;
972322f633cSDouglas Gregor   }
973322f633cSDouglas Gregor 
9745257fc63SDouglas Gregor   // Look for this file.
975e7ab3669SDouglas Gregor   const FileEntry *File = 0;
9765257fc63SDouglas Gregor   llvm::SmallString<128> PathName;
977e7ab3669SDouglas Gregor   if (llvm::sys::path::is_absolute(FileName)) {
978e7ab3669SDouglas Gregor     PathName = FileName;
979e7ab3669SDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
9807033127bSDouglas Gregor   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
9817033127bSDouglas Gregor     PathName = Dir->getName();
9827033127bSDouglas Gregor     llvm::sys::path::append(PathName, FileName);
9837033127bSDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
984e7ab3669SDouglas Gregor   } else {
985e7ab3669SDouglas Gregor     // Search for the header file within the search directory.
9867033127bSDouglas Gregor     PathName = Directory->getName();
987e7ab3669SDouglas Gregor     unsigned PathLength = PathName.size();
988755b2055SDouglas Gregor 
989f2161a70SDouglas Gregor     if (ActiveModule->isPartOfFramework()) {
990f2161a70SDouglas Gregor       appendSubframeworkPaths(ActiveModule, PathName);
991755b2055SDouglas Gregor 
992e7ab3669SDouglas Gregor       // Check whether this file is in the public headers.
993e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, "Headers");
9945257fc63SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
995e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
996e7ab3669SDouglas Gregor 
997e7ab3669SDouglas Gregor       if (!File) {
998e7ab3669SDouglas Gregor         // Check whether this file is in the private headers.
999e7ab3669SDouglas Gregor         PathName.resize(PathLength);
1000e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, "PrivateHeaders");
1001e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, FileName);
1002e7ab3669SDouglas Gregor         File = SourceMgr.getFileManager().getFile(PathName);
1003e7ab3669SDouglas Gregor       }
1004e7ab3669SDouglas Gregor     } else {
1005e7ab3669SDouglas Gregor       // Lookup for normal headers.
1006e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
1007e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
1008e7ab3669SDouglas Gregor     }
1009e7ab3669SDouglas Gregor   }
10105257fc63SDouglas Gregor 
10115257fc63SDouglas Gregor   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
10125257fc63SDouglas Gregor   // Come up with a lazy way to do this.
1013e7ab3669SDouglas Gregor   if (File) {
10145257fc63SDouglas Gregor     if (const Module *OwningModule = Map.Headers[File]) {
10155257fc63SDouglas Gregor       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
10165257fc63SDouglas Gregor         << FileName << OwningModule->getFullModuleName();
10175257fc63SDouglas Gregor       HadError = true;
1018322f633cSDouglas Gregor     } else if (Umbrella) {
1019322f633cSDouglas Gregor       const DirectoryEntry *UmbrellaDir = File->getDir();
1020322f633cSDouglas Gregor       if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) {
1021322f633cSDouglas Gregor         Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1022322f633cSDouglas Gregor           << OwningModule->getFullModuleName();
1023322f633cSDouglas Gregor         HadError = true;
10245257fc63SDouglas Gregor       } else {
1025322f633cSDouglas Gregor         // Record this umbrella header.
1026322f633cSDouglas Gregor         Map.setUmbrellaHeader(ActiveModule, File);
1027322f633cSDouglas Gregor       }
1028322f633cSDouglas Gregor     } else {
1029322f633cSDouglas Gregor       // Record this header.
1030a89c5ac4SDouglas Gregor       Map.addHeader(ActiveModule, File);
10315257fc63SDouglas Gregor     }
10325257fc63SDouglas Gregor   } else {
10335257fc63SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1034524e33e1SDouglas Gregor       << Umbrella << FileName;
10355257fc63SDouglas Gregor     HadError = true;
10365257fc63SDouglas Gregor   }
1037718292f2SDouglas Gregor }
1038718292f2SDouglas Gregor 
1039524e33e1SDouglas Gregor /// \brief Parse an umbrella directory declaration.
1040524e33e1SDouglas Gregor ///
1041524e33e1SDouglas Gregor ///   umbrella-dir-declaration:
1042524e33e1SDouglas Gregor ///     umbrella string-literal
1043524e33e1SDouglas Gregor void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1044524e33e1SDouglas Gregor   // Parse the directory name.
1045524e33e1SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
1046524e33e1SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1047524e33e1SDouglas Gregor       << "umbrella";
1048524e33e1SDouglas Gregor     HadError = true;
1049524e33e1SDouglas Gregor     return;
1050524e33e1SDouglas Gregor   }
1051524e33e1SDouglas Gregor 
1052524e33e1SDouglas Gregor   std::string DirName = Tok.getString();
1053524e33e1SDouglas Gregor   SourceLocation DirNameLoc = consumeToken();
1054524e33e1SDouglas Gregor 
1055524e33e1SDouglas Gregor   // Check whether we already have an umbrella.
1056524e33e1SDouglas Gregor   if (ActiveModule->Umbrella) {
1057524e33e1SDouglas Gregor     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1058524e33e1SDouglas Gregor       << ActiveModule->getFullModuleName();
1059524e33e1SDouglas Gregor     HadError = true;
1060524e33e1SDouglas Gregor     return;
1061524e33e1SDouglas Gregor   }
1062524e33e1SDouglas Gregor 
1063524e33e1SDouglas Gregor   // Look for this file.
1064524e33e1SDouglas Gregor   const DirectoryEntry *Dir = 0;
1065524e33e1SDouglas Gregor   if (llvm::sys::path::is_absolute(DirName))
1066524e33e1SDouglas Gregor     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1067524e33e1SDouglas Gregor   else {
1068524e33e1SDouglas Gregor     llvm::SmallString<128> PathName;
1069524e33e1SDouglas Gregor     PathName = Directory->getName();
1070524e33e1SDouglas Gregor     llvm::sys::path::append(PathName, DirName);
1071524e33e1SDouglas Gregor     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1072524e33e1SDouglas Gregor   }
1073524e33e1SDouglas Gregor 
1074524e33e1SDouglas Gregor   if (!Dir) {
1075524e33e1SDouglas Gregor     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1076524e33e1SDouglas Gregor       << DirName;
1077524e33e1SDouglas Gregor     HadError = true;
1078524e33e1SDouglas Gregor     return;
1079524e33e1SDouglas Gregor   }
1080524e33e1SDouglas Gregor 
1081524e33e1SDouglas Gregor   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1082524e33e1SDouglas Gregor     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1083524e33e1SDouglas Gregor       << OwningModule->getFullModuleName();
1084524e33e1SDouglas Gregor     HadError = true;
1085524e33e1SDouglas Gregor     return;
1086524e33e1SDouglas Gregor   }
1087524e33e1SDouglas Gregor 
1088524e33e1SDouglas Gregor   // Record this umbrella directory.
1089524e33e1SDouglas Gregor   Map.setUmbrellaDir(ActiveModule, Dir);
1090524e33e1SDouglas Gregor }
1091524e33e1SDouglas Gregor 
10922b82c2a5SDouglas Gregor /// \brief Parse a module export declaration.
10932b82c2a5SDouglas Gregor ///
10942b82c2a5SDouglas Gregor ///   export-declaration:
10952b82c2a5SDouglas Gregor ///     'export' wildcard-module-id
10962b82c2a5SDouglas Gregor ///
10972b82c2a5SDouglas Gregor ///   wildcard-module-id:
10982b82c2a5SDouglas Gregor ///     identifier
10992b82c2a5SDouglas Gregor ///     '*'
11002b82c2a5SDouglas Gregor ///     identifier '.' wildcard-module-id
11012b82c2a5SDouglas Gregor void ModuleMapParser::parseExportDecl() {
11022b82c2a5SDouglas Gregor   assert(Tok.is(MMToken::ExportKeyword));
11032b82c2a5SDouglas Gregor   SourceLocation ExportLoc = consumeToken();
11042b82c2a5SDouglas Gregor 
11052b82c2a5SDouglas Gregor   // Parse the module-id with an optional wildcard at the end.
11062b82c2a5SDouglas Gregor   ModuleId ParsedModuleId;
11072b82c2a5SDouglas Gregor   bool Wildcard = false;
11082b82c2a5SDouglas Gregor   do {
11092b82c2a5SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
11102b82c2a5SDouglas Gregor       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
11112b82c2a5SDouglas Gregor                                               Tok.getLocation()));
11122b82c2a5SDouglas Gregor       consumeToken();
11132b82c2a5SDouglas Gregor 
11142b82c2a5SDouglas Gregor       if (Tok.is(MMToken::Period)) {
11152b82c2a5SDouglas Gregor         consumeToken();
11162b82c2a5SDouglas Gregor         continue;
11172b82c2a5SDouglas Gregor       }
11182b82c2a5SDouglas Gregor 
11192b82c2a5SDouglas Gregor       break;
11202b82c2a5SDouglas Gregor     }
11212b82c2a5SDouglas Gregor 
11222b82c2a5SDouglas Gregor     if(Tok.is(MMToken::Star)) {
11232b82c2a5SDouglas Gregor       Wildcard = true;
1124f5eedd05SDouglas Gregor       consumeToken();
11252b82c2a5SDouglas Gregor       break;
11262b82c2a5SDouglas Gregor     }
11272b82c2a5SDouglas Gregor 
11282b82c2a5SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
11292b82c2a5SDouglas Gregor     HadError = true;
11302b82c2a5SDouglas Gregor     return;
11312b82c2a5SDouglas Gregor   } while (true);
11322b82c2a5SDouglas Gregor 
11332b82c2a5SDouglas Gregor   Module::UnresolvedExportDecl Unresolved = {
11342b82c2a5SDouglas Gregor     ExportLoc, ParsedModuleId, Wildcard
11352b82c2a5SDouglas Gregor   };
11362b82c2a5SDouglas Gregor   ActiveModule->UnresolvedExports.push_back(Unresolved);
11372b82c2a5SDouglas Gregor }
11382b82c2a5SDouglas Gregor 
113973441091SDouglas Gregor void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) {
114073441091SDouglas Gregor   assert(Tok.is(MMToken::Star));
114173441091SDouglas Gregor   SourceLocation StarLoc = consumeToken();
114273441091SDouglas Gregor   bool Failed = false;
114373441091SDouglas Gregor 
114473441091SDouglas Gregor   // Inferred modules must be submodules.
114573441091SDouglas Gregor   if (!ActiveModule) {
114673441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
114773441091SDouglas Gregor     Failed = true;
114873441091SDouglas Gregor   }
114973441091SDouglas Gregor 
1150524e33e1SDouglas Gregor   // Inferred modules must have umbrella directories.
1151524e33e1SDouglas Gregor   if (!Failed && !ActiveModule->getUmbrellaDir()) {
115273441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
115373441091SDouglas Gregor     Failed = true;
115473441091SDouglas Gregor   }
115573441091SDouglas Gregor 
115673441091SDouglas Gregor   // Check for redefinition of an inferred module.
1157dd005f69SDouglas Gregor   if (!Failed && ActiveModule->InferSubmodules) {
115873441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1159dd005f69SDouglas Gregor     if (ActiveModule->InferredSubmoduleLoc.isValid())
1160dd005f69SDouglas Gregor       Diags.Report(ActiveModule->InferredSubmoduleLoc,
116173441091SDouglas Gregor                    diag::note_mmap_prev_definition);
116273441091SDouglas Gregor     Failed = true;
116373441091SDouglas Gregor   }
116473441091SDouglas Gregor 
116573441091SDouglas Gregor   // If there were any problems with this inferred submodule, skip its body.
116673441091SDouglas Gregor   if (Failed) {
116773441091SDouglas Gregor     if (Tok.is(MMToken::LBrace)) {
116873441091SDouglas Gregor       consumeToken();
116973441091SDouglas Gregor       skipUntil(MMToken::RBrace);
117073441091SDouglas Gregor       if (Tok.is(MMToken::RBrace))
117173441091SDouglas Gregor         consumeToken();
117273441091SDouglas Gregor     }
117373441091SDouglas Gregor     HadError = true;
117473441091SDouglas Gregor     return;
117573441091SDouglas Gregor   }
117673441091SDouglas Gregor 
117773441091SDouglas Gregor   // Note that we have an inferred submodule.
1178dd005f69SDouglas Gregor   ActiveModule->InferSubmodules = true;
1179dd005f69SDouglas Gregor   ActiveModule->InferredSubmoduleLoc = StarLoc;
1180dd005f69SDouglas Gregor   ActiveModule->InferExplicitSubmodules = Explicit;
118173441091SDouglas Gregor 
118273441091SDouglas Gregor   // Parse the opening brace.
118373441091SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
118473441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
118573441091SDouglas Gregor     HadError = true;
118673441091SDouglas Gregor     return;
118773441091SDouglas Gregor   }
118873441091SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
118973441091SDouglas Gregor 
119073441091SDouglas Gregor   // Parse the body of the inferred submodule.
119173441091SDouglas Gregor   bool Done = false;
119273441091SDouglas Gregor   do {
119373441091SDouglas Gregor     switch (Tok.Kind) {
119473441091SDouglas Gregor     case MMToken::EndOfFile:
119573441091SDouglas Gregor     case MMToken::RBrace:
119673441091SDouglas Gregor       Done = true;
119773441091SDouglas Gregor       break;
119873441091SDouglas Gregor 
119973441091SDouglas Gregor     case MMToken::ExportKeyword: {
120073441091SDouglas Gregor       consumeToken();
120173441091SDouglas Gregor       if (Tok.is(MMToken::Star))
1202dd005f69SDouglas Gregor         ActiveModule->InferExportWildcard = true;
120373441091SDouglas Gregor       else
120473441091SDouglas Gregor         Diags.Report(Tok.getLocation(),
120573441091SDouglas Gregor                      diag::err_mmap_expected_export_wildcard);
120673441091SDouglas Gregor       consumeToken();
120773441091SDouglas Gregor       break;
120873441091SDouglas Gregor     }
120973441091SDouglas Gregor 
121073441091SDouglas Gregor     case MMToken::ExplicitKeyword:
121173441091SDouglas Gregor     case MMToken::ModuleKeyword:
121273441091SDouglas Gregor     case MMToken::HeaderKeyword:
121373441091SDouglas Gregor     case MMToken::UmbrellaKeyword:
121473441091SDouglas Gregor     default:
121573441091SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member);
121673441091SDouglas Gregor       consumeToken();
121773441091SDouglas Gregor       break;
121873441091SDouglas Gregor     }
121973441091SDouglas Gregor   } while (!Done);
122073441091SDouglas Gregor 
122173441091SDouglas Gregor   if (Tok.is(MMToken::RBrace))
122273441091SDouglas Gregor     consumeToken();
122373441091SDouglas Gregor   else {
122473441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
122573441091SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
122673441091SDouglas Gregor     HadError = true;
122773441091SDouglas Gregor   }
122873441091SDouglas Gregor }
122973441091SDouglas Gregor 
12307033127bSDouglas Gregor /// \brief If there is a specific header search directory due the presence
12317033127bSDouglas Gregor /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
12327033127bSDouglas Gregor const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
12337033127bSDouglas Gregor   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
12347033127bSDouglas Gregor     // If we have an umbrella directory, use that.
12357033127bSDouglas Gregor     if (Mod->hasUmbrellaDir())
12367033127bSDouglas Gregor       return Mod->getUmbrellaDir();
12377033127bSDouglas Gregor 
12387033127bSDouglas Gregor     // If we have a framework directory, stop looking.
12397033127bSDouglas Gregor     if (Mod->IsFramework)
12407033127bSDouglas Gregor       return 0;
12417033127bSDouglas Gregor   }
12427033127bSDouglas Gregor 
12437033127bSDouglas Gregor   return 0;
12447033127bSDouglas Gregor }
12457033127bSDouglas Gregor 
1246718292f2SDouglas Gregor /// \brief Parse a module map file.
1247718292f2SDouglas Gregor ///
1248718292f2SDouglas Gregor ///   module-map-file:
1249718292f2SDouglas Gregor ///     module-declaration*
1250718292f2SDouglas Gregor bool ModuleMapParser::parseModuleMapFile() {
1251718292f2SDouglas Gregor   do {
1252718292f2SDouglas Gregor     switch (Tok.Kind) {
1253718292f2SDouglas Gregor     case MMToken::EndOfFile:
1254718292f2SDouglas Gregor       return HadError;
1255718292f2SDouglas Gregor 
1256e7ab3669SDouglas Gregor     case MMToken::ExplicitKeyword:
1257718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
1258755b2055SDouglas Gregor     case MMToken::FrameworkKeyword:
1259718292f2SDouglas Gregor       parseModuleDecl();
1260718292f2SDouglas Gregor       break;
1261718292f2SDouglas Gregor 
12621fb5c3a6SDouglas Gregor     case MMToken::Comma:
12632b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
1264718292f2SDouglas Gregor     case MMToken::HeaderKeyword:
1265718292f2SDouglas Gregor     case MMToken::Identifier:
1266718292f2SDouglas Gregor     case MMToken::LBrace:
12672b82c2a5SDouglas Gregor     case MMToken::Period:
1268718292f2SDouglas Gregor     case MMToken::RBrace:
12691fb5c3a6SDouglas Gregor     case MMToken::RequiresKeyword:
12702b82c2a5SDouglas Gregor     case MMToken::Star:
1271718292f2SDouglas Gregor     case MMToken::StringLiteral:
1272718292f2SDouglas Gregor     case MMToken::UmbrellaKeyword:
1273718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1274718292f2SDouglas Gregor       HadError = true;
1275718292f2SDouglas Gregor       consumeToken();
1276718292f2SDouglas Gregor       break;
1277718292f2SDouglas Gregor     }
1278718292f2SDouglas Gregor   } while (true);
1279718292f2SDouglas Gregor 
1280718292f2SDouglas Gregor   return HadError;
1281718292f2SDouglas Gregor }
1282718292f2SDouglas Gregor 
1283718292f2SDouglas Gregor bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1284718292f2SDouglas Gregor   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1285718292f2SDouglas Gregor   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1286718292f2SDouglas Gregor   if (!Buffer)
1287718292f2SDouglas Gregor     return true;
1288718292f2SDouglas Gregor 
1289718292f2SDouglas Gregor   // Parse this module map file.
12901fb5c3a6SDouglas Gregor   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
12911fb5c3a6SDouglas Gregor   Diags->getClient()->BeginSourceFile(MMapLangOpts);
12925257fc63SDouglas Gregor   ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir());
1293718292f2SDouglas Gregor   bool Result = Parser.parseModuleMapFile();
1294718292f2SDouglas Gregor   Diags->getClient()->EndSourceFile();
1295718292f2SDouglas Gregor 
1296718292f2SDouglas Gregor   return Result;
1297718292f2SDouglas Gregor }
1298