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 
72718292f2SDouglas Gregor ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC) {
73718292f2SDouglas Gregor   llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
74718292f2SDouglas Gregor   Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>(
75718292f2SDouglas Gregor             new DiagnosticsEngine(DiagIDs));
76718292f2SDouglas Gregor   Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
77718292f2SDouglas Gregor   SourceMgr = new SourceManager(*Diags, FileMgr);
78718292f2SDouglas Gregor }
79718292f2SDouglas Gregor 
80718292f2SDouglas Gregor ModuleMap::~ModuleMap() {
815acdf59eSDouglas Gregor   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
825acdf59eSDouglas Gregor                                         IEnd = Modules.end();
835acdf59eSDouglas Gregor        I != IEnd; ++I) {
845acdf59eSDouglas Gregor     delete I->getValue();
855acdf59eSDouglas Gregor   }
865acdf59eSDouglas Gregor 
87718292f2SDouglas Gregor   delete SourceMgr;
88718292f2SDouglas Gregor }
89718292f2SDouglas Gregor 
90de3ef502SDouglas Gregor Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
91ab0c8a84SDouglas Gregor   llvm::DenseMap<const FileEntry *, Module *>::iterator Known
92ab0c8a84SDouglas Gregor     = Headers.find(File);
93ab0c8a84SDouglas Gregor   if (Known != Headers.end())
94ab0c8a84SDouglas Gregor     return Known->second;
95ab0c8a84SDouglas Gregor 
96b65dbfffSDouglas Gregor   const DirectoryEntry *Dir = File->getDir();
97b65dbfffSDouglas Gregor   llvm::SmallVector<const DirectoryEntry *, 2> SkippedDirs;
98b65dbfffSDouglas Gregor   StringRef DirName = Dir->getName();
99a89c5ac4SDouglas Gregor 
100a89c5ac4SDouglas Gregor   // Keep walking up the directory hierarchy, looking for a directory with
101a89c5ac4SDouglas Gregor   // an umbrella header.
102b65dbfffSDouglas Gregor   do {
103a89c5ac4SDouglas Gregor     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
104a89c5ac4SDouglas Gregor       = UmbrellaDirs.find(Dir);
105a89c5ac4SDouglas Gregor     if (KnownDir != UmbrellaDirs.end()) {
106a89c5ac4SDouglas Gregor       Module *Result = KnownDir->second;
107930a85ccSDouglas Gregor 
108930a85ccSDouglas Gregor       // Search up the module stack until we find a module with an umbrella
109930a85ccSDouglas Gregor       // header.
110930a85ccSDouglas Gregor       Module *UmbrellaModule = Result;
111930a85ccSDouglas Gregor       while (!UmbrellaModule->UmbrellaHeader && UmbrellaModule->Parent)
112930a85ccSDouglas Gregor         UmbrellaModule = UmbrellaModule->Parent;
113930a85ccSDouglas Gregor 
114930a85ccSDouglas Gregor       if (UmbrellaModule->InferSubmodules) {
115a89c5ac4SDouglas Gregor         // Infer submodules for each of the directories we found between
116a89c5ac4SDouglas Gregor         // the directory of the umbrella header and the directory where
117a89c5ac4SDouglas Gregor         // the actual header is located.
118a89c5ac4SDouglas Gregor 
119a89c5ac4SDouglas Gregor         // For a framework module, the umbrella directory is the framework
120a89c5ac4SDouglas Gregor         // directory, so strip off the "Headers" or "PrivateHeaders".
1219458f82dSDouglas Gregor         bool Explicit = UmbrellaModule->InferExplicitSubmodules;
122a89c5ac4SDouglas Gregor         unsigned LastSkippedDir = SkippedDirs.size();
1239458f82dSDouglas Gregor         if (LastSkippedDir && UmbrellaModule->IsFramework) {
1249458f82dSDouglas Gregor           if (llvm::sys::path::filename(SkippedDirs.back()->getName())
1259458f82dSDouglas Gregor                 == "PrivateHeaders") {
1269458f82dSDouglas Gregor             // For private headers, add an explicit "Private" module.
1279458f82dSDouglas Gregor             // FIXME: This feels somewhat hackish. Do we want to introduce
1289458f82dSDouglas Gregor             // some kind of "umbrella directory" here?
1299458f82dSDouglas Gregor             Result = findOrCreateModule("Private", Result,
1309458f82dSDouglas Gregor                                         /*IsFramework=*/false,
1319458f82dSDouglas Gregor                                         /*IsExplicit=*/true).first;
1329458f82dSDouglas Gregor             Explicit = true;
1339458f82dSDouglas Gregor           }
1349458f82dSDouglas Gregor 
135a89c5ac4SDouglas Gregor           --LastSkippedDir;
1369458f82dSDouglas Gregor         }
137a89c5ac4SDouglas Gregor 
138a89c5ac4SDouglas Gregor         for (unsigned I = LastSkippedDir; I != 0; --I) {
139a89c5ac4SDouglas Gregor           // Find or create the module that corresponds to this directory name.
140a89c5ac4SDouglas Gregor           StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
141a89c5ac4SDouglas Gregor           Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
1429458f82dSDouglas Gregor                                       Explicit).first;
143a89c5ac4SDouglas Gregor 
144a89c5ac4SDouglas Gregor           // Associate the module and the directory.
145a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I-1]] = Result;
146a89c5ac4SDouglas Gregor 
147a89c5ac4SDouglas Gregor           // If inferred submodules export everything they import, add a
148a89c5ac4SDouglas Gregor           // wildcard to the set of exports.
149930a85ccSDouglas Gregor           if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
150a89c5ac4SDouglas Gregor             Result->Exports.push_back(Module::ExportDecl(0, true));
151a89c5ac4SDouglas Gregor         }
152a89c5ac4SDouglas Gregor 
153a89c5ac4SDouglas Gregor         // Infer a submodule with the same name as this header file.
154a89c5ac4SDouglas Gregor         StringRef Name = llvm::sys::path::stem(File->getName());
155a89c5ac4SDouglas Gregor         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
1569458f82dSDouglas Gregor                                     Explicit).first;
157a89c5ac4SDouglas Gregor 
158a89c5ac4SDouglas Gregor         // If inferred submodules export everything they import, add a
159a89c5ac4SDouglas Gregor         // wildcard to the set of exports.
160930a85ccSDouglas Gregor         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
161a89c5ac4SDouglas Gregor           Result->Exports.push_back(Module::ExportDecl(0, true));
162a89c5ac4SDouglas Gregor       } else {
163a89c5ac4SDouglas Gregor         // Record each of the directories we stepped through as being part of
164a89c5ac4SDouglas Gregor         // the module we found, since the umbrella header covers them all.
165a89c5ac4SDouglas Gregor         for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
166a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I]] = Result;
167a89c5ac4SDouglas Gregor       }
168a89c5ac4SDouglas Gregor 
169a89c5ac4SDouglas Gregor       Headers[File] = Result;
170a89c5ac4SDouglas Gregor       return Result;
171a89c5ac4SDouglas Gregor     }
172a89c5ac4SDouglas Gregor 
173a89c5ac4SDouglas Gregor     SkippedDirs.push_back(Dir);
174a89c5ac4SDouglas Gregor 
175b65dbfffSDouglas Gregor     // Retrieve our parent path.
176b65dbfffSDouglas Gregor     DirName = llvm::sys::path::parent_path(DirName);
177b65dbfffSDouglas Gregor     if (DirName.empty())
178b65dbfffSDouglas Gregor       break;
179b65dbfffSDouglas Gregor 
180b65dbfffSDouglas Gregor     // Resolve the parent path to a directory entry.
181b65dbfffSDouglas Gregor     Dir = SourceMgr->getFileManager().getDirectory(DirName);
182a89c5ac4SDouglas Gregor   } while (Dir);
183b65dbfffSDouglas Gregor 
184ab0c8a84SDouglas Gregor   return 0;
185ab0c8a84SDouglas Gregor }
186ab0c8a84SDouglas Gregor 
187de3ef502SDouglas Gregor Module *ModuleMap::findModule(StringRef Name) {
18888bdfb0eSDouglas Gregor   llvm::StringMap<Module *>::iterator Known = Modules.find(Name);
18988bdfb0eSDouglas Gregor   if (Known != Modules.end())
19088bdfb0eSDouglas Gregor     return Known->getValue();
19188bdfb0eSDouglas Gregor 
19288bdfb0eSDouglas Gregor   return 0;
19388bdfb0eSDouglas Gregor }
19488bdfb0eSDouglas Gregor 
1952b82c2a5SDouglas Gregor Module *ModuleMap::lookupModuleUnqualified(StringRef Name, Module *Context) {
1962b82c2a5SDouglas Gregor   for(; Context; Context = Context->Parent) {
1972b82c2a5SDouglas Gregor     if (Module *Sub = lookupModuleQualified(Name, Context))
1982b82c2a5SDouglas Gregor       return Sub;
1992b82c2a5SDouglas Gregor   }
2002b82c2a5SDouglas Gregor 
2012b82c2a5SDouglas Gregor   return findModule(Name);
2022b82c2a5SDouglas Gregor }
2032b82c2a5SDouglas Gregor 
2042b82c2a5SDouglas Gregor Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) {
2052b82c2a5SDouglas Gregor   if (!Context)
2062b82c2a5SDouglas Gregor     return findModule(Name);
2072b82c2a5SDouglas Gregor 
2082b82c2a5SDouglas Gregor   llvm::StringMap<Module *>::iterator Sub = Context->SubModules.find(Name);
2092b82c2a5SDouglas Gregor   if (Sub != Context->SubModules.end())
2102b82c2a5SDouglas Gregor     return Sub->getValue();
2112b82c2a5SDouglas Gregor 
2122b82c2a5SDouglas Gregor   return 0;
2132b82c2a5SDouglas Gregor }
2142b82c2a5SDouglas Gregor 
215de3ef502SDouglas Gregor std::pair<Module *, bool>
21669021974SDouglas Gregor ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
21769021974SDouglas Gregor                               bool IsExplicit) {
21869021974SDouglas Gregor   // Try to find an existing module with this name.
21969021974SDouglas Gregor   if (Module *Found = Parent? Parent->SubModules[Name] : Modules[Name])
22069021974SDouglas Gregor     return std::make_pair(Found, false);
22169021974SDouglas Gregor 
22269021974SDouglas Gregor   // Create a new module with this name.
22369021974SDouglas Gregor   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
22469021974SDouglas Gregor                               IsExplicit);
22569021974SDouglas Gregor   if (Parent)
22669021974SDouglas Gregor     Parent->SubModules[Name] = Result;
22769021974SDouglas Gregor   else
22869021974SDouglas Gregor     Modules[Name] = Result;
22969021974SDouglas Gregor   return std::make_pair(Result, true);
23069021974SDouglas Gregor }
23169021974SDouglas Gregor 
232de3ef502SDouglas Gregor Module *
23356c64013SDouglas Gregor ModuleMap::inferFrameworkModule(StringRef ModuleName,
234e89dbc1dSDouglas Gregor                                 const DirectoryEntry *FrameworkDir,
235e89dbc1dSDouglas Gregor                                 Module *Parent) {
23656c64013SDouglas Gregor   // Check whether we've already found this module.
237e89dbc1dSDouglas Gregor   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
238e89dbc1dSDouglas Gregor     return Mod;
239e89dbc1dSDouglas Gregor 
240e89dbc1dSDouglas Gregor   FileManager &FileMgr = SourceMgr->getFileManager();
24156c64013SDouglas Gregor 
24256c64013SDouglas Gregor   // Look for an umbrella header.
24356c64013SDouglas Gregor   llvm::SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
24456c64013SDouglas Gregor   llvm::sys::path::append(UmbrellaName, "Headers");
24556c64013SDouglas Gregor   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
246e89dbc1dSDouglas Gregor   const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
24756c64013SDouglas Gregor 
24856c64013SDouglas Gregor   // FIXME: If there's no umbrella header, we could probably scan the
24956c64013SDouglas Gregor   // framework to load *everything*. But, it's not clear that this is a good
25056c64013SDouglas Gregor   // idea.
25156c64013SDouglas Gregor   if (!UmbrellaHeader)
25256c64013SDouglas Gregor     return 0;
25356c64013SDouglas Gregor 
254e89dbc1dSDouglas Gregor   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
255e89dbc1dSDouglas Gregor                               /*IsFramework=*/true, /*IsExplicit=*/false);
256e89dbc1dSDouglas Gregor 
257e89dbc1dSDouglas Gregor   if (Parent)
258e89dbc1dSDouglas Gregor     Parent->SubModules[ModuleName] = Result;
259e89dbc1dSDouglas Gregor   else
260e89dbc1dSDouglas Gregor     Modules[ModuleName] = Result;
261e89dbc1dSDouglas Gregor 
262d8bd7537SDouglas Gregor   // umbrella "umbrella-header-name"
26356c64013SDouglas Gregor   Result->UmbrellaHeader = UmbrellaHeader;
26456c64013SDouglas Gregor   Headers[UmbrellaHeader] = Result;
26556c64013SDouglas Gregor   UmbrellaDirs[FrameworkDir] = Result;
266d8bd7537SDouglas Gregor 
267d8bd7537SDouglas Gregor   // export *
268d8bd7537SDouglas Gregor   Result->Exports.push_back(Module::ExportDecl(0, true));
269d8bd7537SDouglas Gregor 
270a89c5ac4SDouglas Gregor   // module * { export * }
271a89c5ac4SDouglas Gregor   Result->InferSubmodules = true;
272a89c5ac4SDouglas Gregor   Result->InferExportWildcard = true;
273a89c5ac4SDouglas Gregor 
274e89dbc1dSDouglas Gregor   // Look for subframeworks.
275e89dbc1dSDouglas Gregor   llvm::error_code EC;
276*ddaa69cbSDouglas Gregor   llvm::SmallString<128> SubframeworksDirName
277*ddaa69cbSDouglas Gregor     = StringRef(FrameworkDir->getName());
278e89dbc1dSDouglas Gregor   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
279*ddaa69cbSDouglas Gregor   llvm::SmallString<128> SubframeworksDirNameNative;
280*ddaa69cbSDouglas Gregor   llvm::sys::path::native(SubframeworksDirName.str(),
281*ddaa69cbSDouglas Gregor                           SubframeworksDirNameNative);
282*ddaa69cbSDouglas Gregor   for (llvm::sys::fs::directory_iterator
283*ddaa69cbSDouglas Gregor          Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
284e89dbc1dSDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
285e89dbc1dSDouglas Gregor     if (!StringRef(Dir->path()).endswith(".framework"))
286e89dbc1dSDouglas Gregor       continue;
287f2161a70SDouglas Gregor 
288e89dbc1dSDouglas Gregor     if (const DirectoryEntry *SubframeworkDir
289e89dbc1dSDouglas Gregor           = FileMgr.getDirectory(Dir->path())) {
290e89dbc1dSDouglas Gregor       // FIXME: Do we want to warn about subframeworks without umbrella headers?
291e89dbc1dSDouglas Gregor       inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir,
292e89dbc1dSDouglas Gregor                            Result);
293e89dbc1dSDouglas Gregor     }
294e89dbc1dSDouglas Gregor   }
295e89dbc1dSDouglas Gregor 
2969458f82dSDouglas Gregor   // Look for private headers.
2979458f82dSDouglas Gregor   Module *ModulePrivate = 0;
2989458f82dSDouglas Gregor   llvm::SmallString<128> PrivateHeadersDirName(FrameworkDir->getName());
2999458f82dSDouglas Gregor   llvm::sys::path::append(PrivateHeadersDirName, "PrivateHeaders");
300*ddaa69cbSDouglas Gregor   llvm::SmallString<128> PrivateHeadersDirNameNative;
301*ddaa69cbSDouglas Gregor   llvm::sys::path::native(PrivateHeadersDirName.str(),
302*ddaa69cbSDouglas Gregor                           PrivateHeadersDirNameNative);
303*ddaa69cbSDouglas Gregor   for (llvm::sys::fs::directory_iterator
304*ddaa69cbSDouglas Gregor          Dir(PrivateHeadersDirNameNative.str(), EC), DirEnd;
3059458f82dSDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
3069458f82dSDouglas Gregor     // Check whether this entry has an extension typically associated with
3079458f82dSDouglas Gregor     // headers.
3089458f82dSDouglas Gregor     if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path()))
3099458f82dSDouglas Gregor            .Cases(".h", ".H", ".hh", ".hpp", true)
3109458f82dSDouglas Gregor            .Default(false))
3119458f82dSDouglas Gregor       continue;
3129458f82dSDouglas Gregor 
3139458f82dSDouglas Gregor     if (const FileEntry *PrivateHeader = FileMgr.getFile(Dir->path())) {
3149458f82dSDouglas Gregor       // Create the "private" submodule, if we haven't done so already.
3159458f82dSDouglas Gregor       if (!ModulePrivate) {
3169458f82dSDouglas Gregor         ModulePrivate = findOrCreateModule("Private", Result,
3179458f82dSDouglas Gregor                                            /*IsFramework=*/false,
3189458f82dSDouglas Gregor                                            /*IsExplicit=*/true).first;
3199458f82dSDouglas Gregor       }
3209458f82dSDouglas Gregor 
3219458f82dSDouglas Gregor       Module *Sub = findOrCreateModule(llvm::sys::path::stem(Dir->path()),
3229458f82dSDouglas Gregor                                        ModulePrivate, /*IsFramework=*/false,
3239458f82dSDouglas Gregor                                        /*IsExplicit=*/true).first;
3249458f82dSDouglas Gregor       // header "the private header"
3259458f82dSDouglas Gregor       Sub->Headers.push_back(PrivateHeader);
3269458f82dSDouglas Gregor 
3279458f82dSDouglas Gregor       // export *
3289458f82dSDouglas Gregor       Sub->Exports.push_back(Module::ExportDecl(0, true));
3299458f82dSDouglas Gregor 
3309458f82dSDouglas Gregor       Headers[PrivateHeader] = Sub;
3319458f82dSDouglas Gregor     }
3329458f82dSDouglas Gregor   }
3339458f82dSDouglas Gregor 
33456c64013SDouglas Gregor   return Result;
33556c64013SDouglas Gregor }
33656c64013SDouglas Gregor 
337a89c5ac4SDouglas Gregor void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
338a89c5ac4SDouglas Gregor   Headers[UmbrellaHeader] = Mod;
339a89c5ac4SDouglas Gregor   Mod->UmbrellaHeader = UmbrellaHeader;
340a89c5ac4SDouglas Gregor 
341a89c5ac4SDouglas Gregor   const DirectoryEntry *UmbrellaDir = UmbrellaHeader->getDir();
342a89c5ac4SDouglas Gregor   if (Mod->IsFramework)
343a89c5ac4SDouglas Gregor     UmbrellaDir = SourceMgr->getFileManager().getDirectory(
344a89c5ac4SDouglas Gregor                     llvm::sys::path::parent_path(UmbrellaDir->getName()));
345a89c5ac4SDouglas Gregor 
346a89c5ac4SDouglas Gregor   UmbrellaDirs[UmbrellaDir] = Mod;
347a89c5ac4SDouglas Gregor }
348a89c5ac4SDouglas Gregor 
349a89c5ac4SDouglas Gregor void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) {
350a89c5ac4SDouglas Gregor   Mod->Headers.push_back(Header);
351a89c5ac4SDouglas Gregor   Headers[Header] = Mod;
352a89c5ac4SDouglas Gregor }
353a89c5ac4SDouglas Gregor 
354514b636aSDouglas Gregor const FileEntry *
355de3ef502SDouglas Gregor ModuleMap::getContainingModuleMapFile(Module *Module) {
356514b636aSDouglas Gregor   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
357514b636aSDouglas Gregor     return 0;
358514b636aSDouglas Gregor 
359514b636aSDouglas Gregor   return SourceMgr->getFileEntryForID(
360514b636aSDouglas Gregor            SourceMgr->getFileID(Module->DefinitionLoc));
361514b636aSDouglas Gregor }
362514b636aSDouglas Gregor 
363718292f2SDouglas Gregor void ModuleMap::dump() {
364718292f2SDouglas Gregor   llvm::errs() << "Modules:";
365718292f2SDouglas Gregor   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
366718292f2SDouglas Gregor                                         MEnd = Modules.end();
367718292f2SDouglas Gregor        M != MEnd; ++M)
368d28d1b8dSDouglas Gregor     M->getValue()->print(llvm::errs(), 2);
369718292f2SDouglas Gregor 
370718292f2SDouglas Gregor   llvm::errs() << "Headers:";
371718292f2SDouglas Gregor   for (llvm::DenseMap<const FileEntry *, Module *>::iterator
372718292f2SDouglas Gregor             H = Headers.begin(),
373718292f2SDouglas Gregor          HEnd = Headers.end();
374718292f2SDouglas Gregor        H != HEnd; ++H) {
375718292f2SDouglas Gregor     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
376718292f2SDouglas Gregor                  << H->second->getFullModuleName() << "\n";
377718292f2SDouglas Gregor   }
378718292f2SDouglas Gregor }
379718292f2SDouglas Gregor 
3802b82c2a5SDouglas Gregor bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
3812b82c2a5SDouglas Gregor   bool HadError = false;
3822b82c2a5SDouglas Gregor   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
3832b82c2a5SDouglas Gregor     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
3842b82c2a5SDouglas Gregor                                               Complain);
385f5eedd05SDouglas Gregor     if (Export.getPointer() || Export.getInt())
3862b82c2a5SDouglas Gregor       Mod->Exports.push_back(Export);
3872b82c2a5SDouglas Gregor     else
3882b82c2a5SDouglas Gregor       HadError = true;
3892b82c2a5SDouglas Gregor   }
3902b82c2a5SDouglas Gregor   Mod->UnresolvedExports.clear();
3912b82c2a5SDouglas Gregor   return HadError;
3922b82c2a5SDouglas Gregor }
3932b82c2a5SDouglas Gregor 
3940093b3c7SDouglas Gregor Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
3950093b3c7SDouglas Gregor   if (Loc.isInvalid())
3960093b3c7SDouglas Gregor     return 0;
3970093b3c7SDouglas Gregor 
3980093b3c7SDouglas Gregor   // Use the expansion location to determine which module we're in.
3990093b3c7SDouglas Gregor   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
4000093b3c7SDouglas Gregor   if (!ExpansionLoc.isFileID())
4010093b3c7SDouglas Gregor     return 0;
4020093b3c7SDouglas Gregor 
4030093b3c7SDouglas Gregor 
4040093b3c7SDouglas Gregor   const SourceManager &SrcMgr = Loc.getManager();
4050093b3c7SDouglas Gregor   FileID ExpansionFileID = ExpansionLoc.getFileID();
4060093b3c7SDouglas Gregor   const FileEntry *ExpansionFile = SrcMgr.getFileEntryForID(ExpansionFileID);
4070093b3c7SDouglas Gregor   if (!ExpansionFile)
4080093b3c7SDouglas Gregor     return 0;
4090093b3c7SDouglas Gregor 
4100093b3c7SDouglas Gregor   // Find the module that owns this header.
4110093b3c7SDouglas Gregor   return findModuleForHeader(ExpansionFile);
4120093b3c7SDouglas Gregor }
4130093b3c7SDouglas Gregor 
414718292f2SDouglas Gregor //----------------------------------------------------------------------------//
415718292f2SDouglas Gregor // Module map file parser
416718292f2SDouglas Gregor //----------------------------------------------------------------------------//
417718292f2SDouglas Gregor 
418718292f2SDouglas Gregor namespace clang {
419718292f2SDouglas Gregor   /// \brief A token in a module map file.
420718292f2SDouglas Gregor   struct MMToken {
421718292f2SDouglas Gregor     enum TokenKind {
422718292f2SDouglas Gregor       EndOfFile,
423718292f2SDouglas Gregor       HeaderKeyword,
424718292f2SDouglas Gregor       Identifier,
425718292f2SDouglas Gregor       ExplicitKeyword,
4262b82c2a5SDouglas Gregor       ExportKeyword,
427755b2055SDouglas Gregor       FrameworkKeyword,
428718292f2SDouglas Gregor       ModuleKeyword,
4292b82c2a5SDouglas Gregor       Period,
430718292f2SDouglas Gregor       UmbrellaKeyword,
4312b82c2a5SDouglas Gregor       Star,
432718292f2SDouglas Gregor       StringLiteral,
433718292f2SDouglas Gregor       LBrace,
434718292f2SDouglas Gregor       RBrace
435718292f2SDouglas Gregor     } Kind;
436718292f2SDouglas Gregor 
437718292f2SDouglas Gregor     unsigned Location;
438718292f2SDouglas Gregor     unsigned StringLength;
439718292f2SDouglas Gregor     const char *StringData;
440718292f2SDouglas Gregor 
441718292f2SDouglas Gregor     void clear() {
442718292f2SDouglas Gregor       Kind = EndOfFile;
443718292f2SDouglas Gregor       Location = 0;
444718292f2SDouglas Gregor       StringLength = 0;
445718292f2SDouglas Gregor       StringData = 0;
446718292f2SDouglas Gregor     }
447718292f2SDouglas Gregor 
448718292f2SDouglas Gregor     bool is(TokenKind K) const { return Kind == K; }
449718292f2SDouglas Gregor 
450718292f2SDouglas Gregor     SourceLocation getLocation() const {
451718292f2SDouglas Gregor       return SourceLocation::getFromRawEncoding(Location);
452718292f2SDouglas Gregor     }
453718292f2SDouglas Gregor 
454718292f2SDouglas Gregor     StringRef getString() const {
455718292f2SDouglas Gregor       return StringRef(StringData, StringLength);
456718292f2SDouglas Gregor     }
457718292f2SDouglas Gregor   };
458718292f2SDouglas Gregor 
459718292f2SDouglas Gregor   class ModuleMapParser {
460718292f2SDouglas Gregor     Lexer &L;
461718292f2SDouglas Gregor     SourceManager &SourceMgr;
462718292f2SDouglas Gregor     DiagnosticsEngine &Diags;
463718292f2SDouglas Gregor     ModuleMap &Map;
464718292f2SDouglas Gregor 
4655257fc63SDouglas Gregor     /// \brief The directory that this module map resides in.
4665257fc63SDouglas Gregor     const DirectoryEntry *Directory;
4675257fc63SDouglas Gregor 
468718292f2SDouglas Gregor     /// \brief Whether an error occurred.
469718292f2SDouglas Gregor     bool HadError;
470718292f2SDouglas Gregor 
471718292f2SDouglas Gregor     /// \brief Default target information, used only for string literal
472718292f2SDouglas Gregor     /// parsing.
473718292f2SDouglas Gregor     TargetInfo *Target;
474718292f2SDouglas Gregor 
475718292f2SDouglas Gregor     /// \brief Stores string data for the various string literals referenced
476718292f2SDouglas Gregor     /// during parsing.
477718292f2SDouglas Gregor     llvm::BumpPtrAllocator StringData;
478718292f2SDouglas Gregor 
479718292f2SDouglas Gregor     /// \brief The current token.
480718292f2SDouglas Gregor     MMToken Tok;
481718292f2SDouglas Gregor 
482718292f2SDouglas Gregor     /// \brief The active module.
483de3ef502SDouglas Gregor     Module *ActiveModule;
484718292f2SDouglas Gregor 
485718292f2SDouglas Gregor     /// \brief Consume the current token and return its location.
486718292f2SDouglas Gregor     SourceLocation consumeToken();
487718292f2SDouglas Gregor 
488718292f2SDouglas Gregor     /// \brief Skip tokens until we reach the a token with the given kind
489718292f2SDouglas Gregor     /// (or the end of the file).
490718292f2SDouglas Gregor     void skipUntil(MMToken::TokenKind K);
491718292f2SDouglas Gregor 
492e7ab3669SDouglas Gregor     typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
493e7ab3669SDouglas Gregor       ModuleId;
494e7ab3669SDouglas Gregor     bool parseModuleId(ModuleId &Id);
495718292f2SDouglas Gregor     void parseModuleDecl();
496718292f2SDouglas Gregor     void parseUmbrellaDecl();
497718292f2SDouglas Gregor     void parseHeaderDecl();
4982b82c2a5SDouglas Gregor     void parseExportDecl();
49973441091SDouglas Gregor     void parseInferredSubmoduleDecl(bool Explicit);
500718292f2SDouglas Gregor 
501718292f2SDouglas Gregor   public:
502718292f2SDouglas Gregor     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
503718292f2SDouglas Gregor                              DiagnosticsEngine &Diags,
5045257fc63SDouglas Gregor                              ModuleMap &Map,
5055257fc63SDouglas Gregor                              const DirectoryEntry *Directory)
5065257fc63SDouglas Gregor       : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
5075257fc63SDouglas Gregor         Directory(Directory), HadError(false), ActiveModule(0)
508718292f2SDouglas Gregor     {
509718292f2SDouglas Gregor       TargetOptions TargetOpts;
510718292f2SDouglas Gregor       TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
511718292f2SDouglas Gregor       Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
512718292f2SDouglas Gregor 
513718292f2SDouglas Gregor       Tok.clear();
514718292f2SDouglas Gregor       consumeToken();
515718292f2SDouglas Gregor     }
516718292f2SDouglas Gregor 
517718292f2SDouglas Gregor     bool parseModuleMapFile();
518718292f2SDouglas Gregor   };
519718292f2SDouglas Gregor }
520718292f2SDouglas Gregor 
521718292f2SDouglas Gregor SourceLocation ModuleMapParser::consumeToken() {
522718292f2SDouglas Gregor retry:
523718292f2SDouglas Gregor   SourceLocation Result = Tok.getLocation();
524718292f2SDouglas Gregor   Tok.clear();
525718292f2SDouglas Gregor 
526718292f2SDouglas Gregor   Token LToken;
527718292f2SDouglas Gregor   L.LexFromRawLexer(LToken);
528718292f2SDouglas Gregor   Tok.Location = LToken.getLocation().getRawEncoding();
529718292f2SDouglas Gregor   switch (LToken.getKind()) {
530718292f2SDouglas Gregor   case tok::raw_identifier:
531718292f2SDouglas Gregor     Tok.StringData = LToken.getRawIdentifierData();
532718292f2SDouglas Gregor     Tok.StringLength = LToken.getLength();
533718292f2SDouglas Gregor     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
534718292f2SDouglas Gregor                  .Case("header", MMToken::HeaderKeyword)
535718292f2SDouglas Gregor                  .Case("explicit", MMToken::ExplicitKeyword)
5362b82c2a5SDouglas Gregor                  .Case("export", MMToken::ExportKeyword)
537755b2055SDouglas Gregor                  .Case("framework", MMToken::FrameworkKeyword)
538718292f2SDouglas Gregor                  .Case("module", MMToken::ModuleKeyword)
539718292f2SDouglas Gregor                  .Case("umbrella", MMToken::UmbrellaKeyword)
540718292f2SDouglas Gregor                  .Default(MMToken::Identifier);
541718292f2SDouglas Gregor     break;
542718292f2SDouglas Gregor 
543718292f2SDouglas Gregor   case tok::eof:
544718292f2SDouglas Gregor     Tok.Kind = MMToken::EndOfFile;
545718292f2SDouglas Gregor     break;
546718292f2SDouglas Gregor 
547718292f2SDouglas Gregor   case tok::l_brace:
548718292f2SDouglas Gregor     Tok.Kind = MMToken::LBrace;
549718292f2SDouglas Gregor     break;
550718292f2SDouglas Gregor 
5512b82c2a5SDouglas Gregor   case tok::period:
5522b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Period;
5532b82c2a5SDouglas Gregor     break;
5542b82c2a5SDouglas Gregor 
555718292f2SDouglas Gregor   case tok::r_brace:
556718292f2SDouglas Gregor     Tok.Kind = MMToken::RBrace;
557718292f2SDouglas Gregor     break;
558718292f2SDouglas Gregor 
5592b82c2a5SDouglas Gregor   case tok::star:
5602b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Star;
5612b82c2a5SDouglas Gregor     break;
5622b82c2a5SDouglas Gregor 
563718292f2SDouglas Gregor   case tok::string_literal: {
564718292f2SDouglas Gregor     // Parse the string literal.
565718292f2SDouglas Gregor     LangOptions LangOpts;
566718292f2SDouglas Gregor     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
567718292f2SDouglas Gregor     if (StringLiteral.hadError)
568718292f2SDouglas Gregor       goto retry;
569718292f2SDouglas Gregor 
570718292f2SDouglas Gregor     // Copy the string literal into our string data allocator.
571718292f2SDouglas Gregor     unsigned Length = StringLiteral.GetStringLength();
572718292f2SDouglas Gregor     char *Saved = StringData.Allocate<char>(Length + 1);
573718292f2SDouglas Gregor     memcpy(Saved, StringLiteral.GetString().data(), Length);
574718292f2SDouglas Gregor     Saved[Length] = 0;
575718292f2SDouglas Gregor 
576718292f2SDouglas Gregor     // Form the token.
577718292f2SDouglas Gregor     Tok.Kind = MMToken::StringLiteral;
578718292f2SDouglas Gregor     Tok.StringData = Saved;
579718292f2SDouglas Gregor     Tok.StringLength = Length;
580718292f2SDouglas Gregor     break;
581718292f2SDouglas Gregor   }
582718292f2SDouglas Gregor 
583718292f2SDouglas Gregor   case tok::comment:
584718292f2SDouglas Gregor     goto retry;
585718292f2SDouglas Gregor 
586718292f2SDouglas Gregor   default:
587718292f2SDouglas Gregor     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
588718292f2SDouglas Gregor     HadError = true;
589718292f2SDouglas Gregor     goto retry;
590718292f2SDouglas Gregor   }
591718292f2SDouglas Gregor 
592718292f2SDouglas Gregor   return Result;
593718292f2SDouglas Gregor }
594718292f2SDouglas Gregor 
595718292f2SDouglas Gregor void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
596718292f2SDouglas Gregor   unsigned braceDepth = 0;
597718292f2SDouglas Gregor   do {
598718292f2SDouglas Gregor     switch (Tok.Kind) {
599718292f2SDouglas Gregor     case MMToken::EndOfFile:
600718292f2SDouglas Gregor       return;
601718292f2SDouglas Gregor 
602718292f2SDouglas Gregor     case MMToken::LBrace:
603718292f2SDouglas Gregor       if (Tok.is(K) && braceDepth == 0)
604718292f2SDouglas Gregor         return;
605718292f2SDouglas Gregor 
606718292f2SDouglas Gregor       ++braceDepth;
607718292f2SDouglas Gregor       break;
608718292f2SDouglas Gregor 
609718292f2SDouglas Gregor     case MMToken::RBrace:
610718292f2SDouglas Gregor       if (braceDepth > 0)
611718292f2SDouglas Gregor         --braceDepth;
612718292f2SDouglas Gregor       else if (Tok.is(K))
613718292f2SDouglas Gregor         return;
614718292f2SDouglas Gregor       break;
615718292f2SDouglas Gregor 
616718292f2SDouglas Gregor     default:
617718292f2SDouglas Gregor       if (braceDepth == 0 && Tok.is(K))
618718292f2SDouglas Gregor         return;
619718292f2SDouglas Gregor       break;
620718292f2SDouglas Gregor     }
621718292f2SDouglas Gregor 
622718292f2SDouglas Gregor    consumeToken();
623718292f2SDouglas Gregor   } while (true);
624718292f2SDouglas Gregor }
625718292f2SDouglas Gregor 
626e7ab3669SDouglas Gregor /// \brief Parse a module-id.
627e7ab3669SDouglas Gregor ///
628e7ab3669SDouglas Gregor ///   module-id:
629e7ab3669SDouglas Gregor ///     identifier
630e7ab3669SDouglas Gregor ///     identifier '.' module-id
631e7ab3669SDouglas Gregor ///
632e7ab3669SDouglas Gregor /// \returns true if an error occurred, false otherwise.
633e7ab3669SDouglas Gregor bool ModuleMapParser::parseModuleId(ModuleId &Id) {
634e7ab3669SDouglas Gregor   Id.clear();
635e7ab3669SDouglas Gregor   do {
636e7ab3669SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
637e7ab3669SDouglas Gregor       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
638e7ab3669SDouglas Gregor       consumeToken();
639e7ab3669SDouglas Gregor     } else {
640e7ab3669SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
641e7ab3669SDouglas Gregor       return true;
642e7ab3669SDouglas Gregor     }
643e7ab3669SDouglas Gregor 
644e7ab3669SDouglas Gregor     if (!Tok.is(MMToken::Period))
645e7ab3669SDouglas Gregor       break;
646e7ab3669SDouglas Gregor 
647e7ab3669SDouglas Gregor     consumeToken();
648e7ab3669SDouglas Gregor   } while (true);
649e7ab3669SDouglas Gregor 
650e7ab3669SDouglas Gregor   return false;
651e7ab3669SDouglas Gregor }
652e7ab3669SDouglas Gregor 
653718292f2SDouglas Gregor /// \brief Parse a module declaration.
654718292f2SDouglas Gregor ///
655718292f2SDouglas Gregor ///   module-declaration:
656e7ab3669SDouglas Gregor ///     'explicit'[opt] 'framework'[opt] 'module' module-id { module-member* }
657718292f2SDouglas Gregor ///
658718292f2SDouglas Gregor ///   module-member:
659718292f2SDouglas Gregor ///     umbrella-declaration
660718292f2SDouglas Gregor ///     header-declaration
661e7ab3669SDouglas Gregor ///     submodule-declaration
6622b82c2a5SDouglas Gregor ///     export-declaration
66373441091SDouglas Gregor ///
66473441091SDouglas Gregor ///   submodule-declaration:
66573441091SDouglas Gregor ///     module-declaration
66673441091SDouglas Gregor ///     inferred-submodule-declaration
667718292f2SDouglas Gregor void ModuleMapParser::parseModuleDecl() {
668755b2055SDouglas Gregor   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
669755b2055SDouglas Gregor          Tok.is(MMToken::FrameworkKeyword));
670f2161a70SDouglas Gregor   // Parse 'explicit' or 'framework' keyword, if present.
671e7ab3669SDouglas Gregor   SourceLocation ExplicitLoc;
672718292f2SDouglas Gregor   bool Explicit = false;
673f2161a70SDouglas Gregor   bool Framework = false;
674755b2055SDouglas Gregor 
675f2161a70SDouglas Gregor   // Parse 'explicit' keyword, if present.
676f2161a70SDouglas Gregor   if (Tok.is(MMToken::ExplicitKeyword)) {
677e7ab3669SDouglas Gregor     ExplicitLoc = consumeToken();
678f2161a70SDouglas Gregor     Explicit = true;
679f2161a70SDouglas Gregor   }
680f2161a70SDouglas Gregor 
681f2161a70SDouglas Gregor   // Parse 'framework' keyword, if present.
682755b2055SDouglas Gregor   if (Tok.is(MMToken::FrameworkKeyword)) {
683755b2055SDouglas Gregor     consumeToken();
684755b2055SDouglas Gregor     Framework = true;
685755b2055SDouglas Gregor   }
686718292f2SDouglas Gregor 
687718292f2SDouglas Gregor   // Parse 'module' keyword.
688718292f2SDouglas Gregor   if (!Tok.is(MMToken::ModuleKeyword)) {
689d6343c99SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
690718292f2SDouglas Gregor     consumeToken();
691718292f2SDouglas Gregor     HadError = true;
692718292f2SDouglas Gregor     return;
693718292f2SDouglas Gregor   }
694718292f2SDouglas Gregor   consumeToken(); // 'module' keyword
695718292f2SDouglas Gregor 
69673441091SDouglas Gregor   // If we have a wildcard for the module name, this is an inferred submodule.
69773441091SDouglas Gregor   // Parse it.
69873441091SDouglas Gregor   if (Tok.is(MMToken::Star))
69973441091SDouglas Gregor     return parseInferredSubmoduleDecl(Explicit);
70073441091SDouglas Gregor 
701718292f2SDouglas Gregor   // Parse the module name.
702e7ab3669SDouglas Gregor   ModuleId Id;
703e7ab3669SDouglas Gregor   if (parseModuleId(Id)) {
704718292f2SDouglas Gregor     HadError = true;
705718292f2SDouglas Gregor     return;
706718292f2SDouglas Gregor   }
707e7ab3669SDouglas Gregor 
708e7ab3669SDouglas Gregor   if (ActiveModule) {
709e7ab3669SDouglas Gregor     if (Id.size() > 1) {
710e7ab3669SDouglas Gregor       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
711e7ab3669SDouglas Gregor         << SourceRange(Id.front().second, Id.back().second);
712e7ab3669SDouglas Gregor 
713e7ab3669SDouglas Gregor       HadError = true;
714e7ab3669SDouglas Gregor       return;
715e7ab3669SDouglas Gregor     }
716e7ab3669SDouglas Gregor   } else if (Id.size() == 1 && Explicit) {
717e7ab3669SDouglas Gregor     // Top-level modules can't be explicit.
718e7ab3669SDouglas Gregor     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
719e7ab3669SDouglas Gregor     Explicit = false;
720e7ab3669SDouglas Gregor     ExplicitLoc = SourceLocation();
721e7ab3669SDouglas Gregor     HadError = true;
722e7ab3669SDouglas Gregor   }
723e7ab3669SDouglas Gregor 
724e7ab3669SDouglas Gregor   Module *PreviousActiveModule = ActiveModule;
725e7ab3669SDouglas Gregor   if (Id.size() > 1) {
726e7ab3669SDouglas Gregor     // This module map defines a submodule. Go find the module of which it
727e7ab3669SDouglas Gregor     // is a submodule.
728e7ab3669SDouglas Gregor     ActiveModule = 0;
729e7ab3669SDouglas Gregor     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
730e7ab3669SDouglas Gregor       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
731e7ab3669SDouglas Gregor         ActiveModule = Next;
732e7ab3669SDouglas Gregor         continue;
733e7ab3669SDouglas Gregor       }
734e7ab3669SDouglas Gregor 
735e7ab3669SDouglas Gregor       if (ActiveModule) {
736e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
737e7ab3669SDouglas Gregor           << Id[I].first << ActiveModule->getTopLevelModule();
738e7ab3669SDouglas Gregor       } else {
739e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
740e7ab3669SDouglas Gregor       }
741e7ab3669SDouglas Gregor       HadError = true;
742e7ab3669SDouglas Gregor       return;
743e7ab3669SDouglas Gregor     }
744e7ab3669SDouglas Gregor   }
745e7ab3669SDouglas Gregor 
746e7ab3669SDouglas Gregor   StringRef ModuleName = Id.back().first;
747e7ab3669SDouglas Gregor   SourceLocation ModuleNameLoc = Id.back().second;
748718292f2SDouglas Gregor 
749718292f2SDouglas Gregor   // Parse the opening brace.
750718292f2SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
751718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
752718292f2SDouglas Gregor       << ModuleName;
753718292f2SDouglas Gregor     HadError = true;
754718292f2SDouglas Gregor     return;
755718292f2SDouglas Gregor   }
756718292f2SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
757718292f2SDouglas Gregor 
758718292f2SDouglas Gregor   // Determine whether this (sub)module has already been defined.
759718292f2SDouglas Gregor   llvm::StringMap<Module *> &ModuleSpace
760718292f2SDouglas Gregor     = ActiveModule? ActiveModule->SubModules : Map.Modules;
761718292f2SDouglas Gregor   llvm::StringMap<Module *>::iterator ExistingModule
762718292f2SDouglas Gregor     = ModuleSpace.find(ModuleName);
763718292f2SDouglas Gregor   if (ExistingModule != ModuleSpace.end()) {
764718292f2SDouglas Gregor     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
765718292f2SDouglas Gregor       << ModuleName;
766718292f2SDouglas Gregor     Diags.Report(ExistingModule->getValue()->DefinitionLoc,
767718292f2SDouglas Gregor                  diag::note_mmap_prev_definition);
768718292f2SDouglas Gregor 
769718292f2SDouglas Gregor     // Skip the module definition.
770718292f2SDouglas Gregor     skipUntil(MMToken::RBrace);
771718292f2SDouglas Gregor     if (Tok.is(MMToken::RBrace))
772718292f2SDouglas Gregor       consumeToken();
773718292f2SDouglas Gregor 
774718292f2SDouglas Gregor     HadError = true;
775718292f2SDouglas Gregor     return;
776718292f2SDouglas Gregor   }
777718292f2SDouglas Gregor 
778718292f2SDouglas Gregor   // Start defining this module.
779755b2055SDouglas Gregor   ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework,
780755b2055SDouglas Gregor                             Explicit);
781718292f2SDouglas Gregor   ModuleSpace[ModuleName] = ActiveModule;
782718292f2SDouglas Gregor 
783718292f2SDouglas Gregor   bool Done = false;
784718292f2SDouglas Gregor   do {
785718292f2SDouglas Gregor     switch (Tok.Kind) {
786718292f2SDouglas Gregor     case MMToken::EndOfFile:
787718292f2SDouglas Gregor     case MMToken::RBrace:
788718292f2SDouglas Gregor       Done = true;
789718292f2SDouglas Gregor       break;
790718292f2SDouglas Gregor 
791718292f2SDouglas Gregor     case MMToken::ExplicitKeyword:
792f2161a70SDouglas Gregor     case MMToken::FrameworkKeyword:
793718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
794718292f2SDouglas Gregor       parseModuleDecl();
795718292f2SDouglas Gregor       break;
796718292f2SDouglas Gregor 
7972b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
7982b82c2a5SDouglas Gregor       parseExportDecl();
7992b82c2a5SDouglas Gregor       break;
8002b82c2a5SDouglas Gregor 
801718292f2SDouglas Gregor     case MMToken::HeaderKeyword:
802718292f2SDouglas Gregor       parseHeaderDecl();
803718292f2SDouglas Gregor       break;
804718292f2SDouglas Gregor 
805718292f2SDouglas Gregor     case MMToken::UmbrellaKeyword:
806718292f2SDouglas Gregor       parseUmbrellaDecl();
807718292f2SDouglas Gregor       break;
808718292f2SDouglas Gregor 
809718292f2SDouglas Gregor     default:
810718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
811718292f2SDouglas Gregor       consumeToken();
812718292f2SDouglas Gregor       break;
813718292f2SDouglas Gregor     }
814718292f2SDouglas Gregor   } while (!Done);
815718292f2SDouglas Gregor 
816718292f2SDouglas Gregor   if (Tok.is(MMToken::RBrace))
817718292f2SDouglas Gregor     consumeToken();
818718292f2SDouglas Gregor   else {
819718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
820718292f2SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
821718292f2SDouglas Gregor     HadError = true;
822718292f2SDouglas Gregor   }
823718292f2SDouglas Gregor 
824e7ab3669SDouglas Gregor   // We're done parsing this module. Pop back to the previous module.
825e7ab3669SDouglas Gregor   ActiveModule = PreviousActiveModule;
826718292f2SDouglas Gregor }
827718292f2SDouglas Gregor 
828f2161a70SDouglas Gregor /// \brief Append to \p Paths the set of paths needed to get to the
829f2161a70SDouglas Gregor /// subframework in which the given module lives.
830f2161a70SDouglas Gregor void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) {
831f2161a70SDouglas Gregor   // Collect the framework names from the given module to the top-level module.
832f2161a70SDouglas Gregor   llvm::SmallVector<StringRef, 2> Paths;
833f2161a70SDouglas Gregor   for (; Mod; Mod = Mod->Parent) {
834f2161a70SDouglas Gregor     if (Mod->IsFramework)
835f2161a70SDouglas Gregor       Paths.push_back(Mod->Name);
836f2161a70SDouglas Gregor   }
837f2161a70SDouglas Gregor 
838f2161a70SDouglas Gregor   if (Paths.empty())
839f2161a70SDouglas Gregor     return;
840f2161a70SDouglas Gregor 
841f2161a70SDouglas Gregor   // Add Frameworks/Name.framework for each subframework.
842f2161a70SDouglas Gregor   for (unsigned I = Paths.size() - 1; I != 0; --I) {
843f2161a70SDouglas Gregor     llvm::sys::path::append(Path, "Frameworks");
844f2161a70SDouglas Gregor     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
845f2161a70SDouglas Gregor   }
846f2161a70SDouglas Gregor }
847f2161a70SDouglas Gregor 
848718292f2SDouglas Gregor /// \brief Parse an umbrella header declaration.
849718292f2SDouglas Gregor ///
850718292f2SDouglas Gregor ///   umbrella-declaration:
851718292f2SDouglas Gregor ///     'umbrella' string-literal
852718292f2SDouglas Gregor void ModuleMapParser::parseUmbrellaDecl() {
853718292f2SDouglas Gregor   assert(Tok.is(MMToken::UmbrellaKeyword));
854718292f2SDouglas Gregor   SourceLocation UmbrellaLoc = consumeToken();
855718292f2SDouglas Gregor 
856718292f2SDouglas Gregor   // Parse the header name.
857718292f2SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
858718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
859718292f2SDouglas Gregor       << "umbrella";
860718292f2SDouglas Gregor     HadError = true;
861718292f2SDouglas Gregor     return;
862718292f2SDouglas Gregor   }
863e7ab3669SDouglas Gregor   std::string FileName = Tok.getString();
864718292f2SDouglas Gregor   SourceLocation FileNameLoc = consumeToken();
865718292f2SDouglas Gregor 
8665257fc63SDouglas Gregor   // Check whether we already have an umbrella header.
8675257fc63SDouglas Gregor   if (ActiveModule->UmbrellaHeader) {
8685257fc63SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict)
8695257fc63SDouglas Gregor       << ActiveModule->getFullModuleName()
8705257fc63SDouglas Gregor       << ActiveModule->UmbrellaHeader->getName();
8715257fc63SDouglas Gregor     HadError = true;
8725257fc63SDouglas Gregor     return;
8735257fc63SDouglas Gregor   }
8745257fc63SDouglas Gregor 
8755257fc63SDouglas Gregor   // Look for this file.
8765257fc63SDouglas Gregor   llvm::SmallString<128> PathName;
877f545f67dSDouglas Gregor   const FileEntry *File = 0;
878f545f67dSDouglas Gregor 
879f545f67dSDouglas Gregor   if (llvm::sys::path::is_absolute(FileName)) {
880f545f67dSDouglas Gregor     PathName = FileName;
881f545f67dSDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
882f545f67dSDouglas Gregor   } else {
883f545f67dSDouglas Gregor     // Search for the header file within the search directory.
8845257fc63SDouglas Gregor     PathName += Directory->getName();
885755b2055SDouglas Gregor     unsigned PathLength = PathName.size();
886f2161a70SDouglas Gregor 
887755b2055SDouglas Gregor     if (ActiveModule->isPartOfFramework()) {
888f2161a70SDouglas Gregor       appendSubframeworkPaths(ActiveModule, PathName);
889f2161a70SDouglas Gregor 
890755b2055SDouglas Gregor       // Check whether this file is in the public headers.
891755b2055SDouglas Gregor       llvm::sys::path::append(PathName, "Headers");
8925257fc63SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
893755b2055SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
894755b2055SDouglas Gregor 
895755b2055SDouglas Gregor       if (!File) {
896755b2055SDouglas Gregor         // Check whether this file is in the private headers.
897755b2055SDouglas Gregor         PathName.resize(PathLength);
898755b2055SDouglas Gregor         llvm::sys::path::append(PathName, "PrivateHeaders");
899755b2055SDouglas Gregor         llvm::sys::path::append(PathName, FileName);
900755b2055SDouglas Gregor         File = SourceMgr.getFileManager().getFile(PathName);
901755b2055SDouglas Gregor       }
902755b2055SDouglas Gregor     } else {
903755b2055SDouglas Gregor       // Lookup for normal headers.
904755b2055SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
905755b2055SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
906755b2055SDouglas Gregor     }
907f545f67dSDouglas Gregor   }
9085257fc63SDouglas Gregor 
9095257fc63SDouglas Gregor   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
9105257fc63SDouglas Gregor   // Come up with a lazy way to do this.
911755b2055SDouglas Gregor   if (File) {
912a89c5ac4SDouglas Gregor     const DirectoryEntry *UmbrellaDir = File->getDir();
913a89c5ac4SDouglas Gregor     if (ActiveModule->IsFramework) {
914a89c5ac4SDouglas Gregor       // For framework modules, use the framework directory as the umbrella
915a89c5ac4SDouglas Gregor       // directory.
916a89c5ac4SDouglas Gregor       UmbrellaDir = SourceMgr.getFileManager().getDirectory(
917a89c5ac4SDouglas Gregor                       llvm::sys::path::parent_path(UmbrellaDir->getName()));
918a89c5ac4SDouglas Gregor     }
919a89c5ac4SDouglas Gregor 
9205257fc63SDouglas Gregor     if (const Module *OwningModule = Map.Headers[File]) {
9215257fc63SDouglas Gregor       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
9225257fc63SDouglas Gregor         << FileName << OwningModule->getFullModuleName();
9235257fc63SDouglas Gregor       HadError = true;
924a89c5ac4SDouglas Gregor     } else if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) {
925b65dbfffSDouglas Gregor       Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
926b65dbfffSDouglas Gregor         << OwningModule->getFullModuleName();
927b65dbfffSDouglas Gregor       HadError = true;
9285257fc63SDouglas Gregor     } else {
9295257fc63SDouglas Gregor       // Record this umbrella header.
930a89c5ac4SDouglas Gregor       Map.setUmbrellaHeader(ActiveModule, File);
9315257fc63SDouglas Gregor     }
9325257fc63SDouglas Gregor   } else {
9335257fc63SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
9345257fc63SDouglas Gregor       << true << FileName;
9355257fc63SDouglas Gregor     HadError = true;
9365257fc63SDouglas Gregor   }
937718292f2SDouglas Gregor }
938718292f2SDouglas Gregor 
939718292f2SDouglas Gregor /// \brief Parse a header declaration.
940718292f2SDouglas Gregor ///
941718292f2SDouglas Gregor ///   header-declaration:
942718292f2SDouglas Gregor ///     'header' string-literal
943718292f2SDouglas Gregor void ModuleMapParser::parseHeaderDecl() {
944718292f2SDouglas Gregor   assert(Tok.is(MMToken::HeaderKeyword));
9451871ed3dSBenjamin Kramer   consumeToken();
946718292f2SDouglas Gregor 
947718292f2SDouglas Gregor   // Parse the header name.
948718292f2SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
949718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
950718292f2SDouglas Gregor       << "header";
951718292f2SDouglas Gregor     HadError = true;
952718292f2SDouglas Gregor     return;
953718292f2SDouglas Gregor   }
954e7ab3669SDouglas Gregor   std::string FileName = Tok.getString();
955718292f2SDouglas Gregor   SourceLocation FileNameLoc = consumeToken();
956718292f2SDouglas Gregor 
9575257fc63SDouglas Gregor   // Look for this file.
958e7ab3669SDouglas Gregor   const FileEntry *File = 0;
9595257fc63SDouglas Gregor   llvm::SmallString<128> PathName;
960e7ab3669SDouglas Gregor   if (llvm::sys::path::is_absolute(FileName)) {
961e7ab3669SDouglas Gregor     PathName = FileName;
962e7ab3669SDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
963e7ab3669SDouglas Gregor   } else {
964e7ab3669SDouglas Gregor     // Search for the header file within the search directory.
9655257fc63SDouglas Gregor     PathName += Directory->getName();
966e7ab3669SDouglas Gregor     unsigned PathLength = PathName.size();
967755b2055SDouglas Gregor 
968f2161a70SDouglas Gregor     if (ActiveModule->isPartOfFramework()) {
969f2161a70SDouglas Gregor       appendSubframeworkPaths(ActiveModule, PathName);
970755b2055SDouglas Gregor 
971e7ab3669SDouglas Gregor       // Check whether this file is in the public headers.
972e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, "Headers");
9735257fc63SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
974e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
975e7ab3669SDouglas Gregor 
976e7ab3669SDouglas Gregor       if (!File) {
977e7ab3669SDouglas Gregor         // Check whether this file is in the private headers.
978e7ab3669SDouglas Gregor         PathName.resize(PathLength);
979e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, "PrivateHeaders");
980e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, FileName);
981e7ab3669SDouglas Gregor         File = SourceMgr.getFileManager().getFile(PathName);
982e7ab3669SDouglas Gregor       }
983e7ab3669SDouglas Gregor     } else {
984e7ab3669SDouglas Gregor       // Lookup for normal headers.
985e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
986e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
987e7ab3669SDouglas Gregor     }
988e7ab3669SDouglas Gregor   }
9895257fc63SDouglas Gregor 
9905257fc63SDouglas Gregor   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
9915257fc63SDouglas Gregor   // Come up with a lazy way to do this.
992e7ab3669SDouglas Gregor   if (File) {
9935257fc63SDouglas Gregor     if (const Module *OwningModule = Map.Headers[File]) {
9945257fc63SDouglas Gregor       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
9955257fc63SDouglas Gregor         << FileName << OwningModule->getFullModuleName();
9965257fc63SDouglas Gregor       HadError = true;
9975257fc63SDouglas Gregor     } else {
9985257fc63SDouglas Gregor       // Record this file.
999a89c5ac4SDouglas Gregor       Map.addHeader(ActiveModule, File);
10005257fc63SDouglas Gregor     }
10015257fc63SDouglas Gregor   } else {
10025257fc63SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
10035257fc63SDouglas Gregor       << false << FileName;
10045257fc63SDouglas Gregor     HadError = true;
10055257fc63SDouglas Gregor   }
1006718292f2SDouglas Gregor }
1007718292f2SDouglas Gregor 
10082b82c2a5SDouglas Gregor /// \brief Parse a module export declaration.
10092b82c2a5SDouglas Gregor ///
10102b82c2a5SDouglas Gregor ///   export-declaration:
10112b82c2a5SDouglas Gregor ///     'export' wildcard-module-id
10122b82c2a5SDouglas Gregor ///
10132b82c2a5SDouglas Gregor ///   wildcard-module-id:
10142b82c2a5SDouglas Gregor ///     identifier
10152b82c2a5SDouglas Gregor ///     '*'
10162b82c2a5SDouglas Gregor ///     identifier '.' wildcard-module-id
10172b82c2a5SDouglas Gregor void ModuleMapParser::parseExportDecl() {
10182b82c2a5SDouglas Gregor   assert(Tok.is(MMToken::ExportKeyword));
10192b82c2a5SDouglas Gregor   SourceLocation ExportLoc = consumeToken();
10202b82c2a5SDouglas Gregor 
10212b82c2a5SDouglas Gregor   // Parse the module-id with an optional wildcard at the end.
10222b82c2a5SDouglas Gregor   ModuleId ParsedModuleId;
10232b82c2a5SDouglas Gregor   bool Wildcard = false;
10242b82c2a5SDouglas Gregor   do {
10252b82c2a5SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
10262b82c2a5SDouglas Gregor       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
10272b82c2a5SDouglas Gregor                                               Tok.getLocation()));
10282b82c2a5SDouglas Gregor       consumeToken();
10292b82c2a5SDouglas Gregor 
10302b82c2a5SDouglas Gregor       if (Tok.is(MMToken::Period)) {
10312b82c2a5SDouglas Gregor         consumeToken();
10322b82c2a5SDouglas Gregor         continue;
10332b82c2a5SDouglas Gregor       }
10342b82c2a5SDouglas Gregor 
10352b82c2a5SDouglas Gregor       break;
10362b82c2a5SDouglas Gregor     }
10372b82c2a5SDouglas Gregor 
10382b82c2a5SDouglas Gregor     if(Tok.is(MMToken::Star)) {
10392b82c2a5SDouglas Gregor       Wildcard = true;
1040f5eedd05SDouglas Gregor       consumeToken();
10412b82c2a5SDouglas Gregor       break;
10422b82c2a5SDouglas Gregor     }
10432b82c2a5SDouglas Gregor 
10442b82c2a5SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
10452b82c2a5SDouglas Gregor     HadError = true;
10462b82c2a5SDouglas Gregor     return;
10472b82c2a5SDouglas Gregor   } while (true);
10482b82c2a5SDouglas Gregor 
10492b82c2a5SDouglas Gregor   Module::UnresolvedExportDecl Unresolved = {
10502b82c2a5SDouglas Gregor     ExportLoc, ParsedModuleId, Wildcard
10512b82c2a5SDouglas Gregor   };
10522b82c2a5SDouglas Gregor   ActiveModule->UnresolvedExports.push_back(Unresolved);
10532b82c2a5SDouglas Gregor }
10542b82c2a5SDouglas Gregor 
105573441091SDouglas Gregor void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) {
105673441091SDouglas Gregor   assert(Tok.is(MMToken::Star));
105773441091SDouglas Gregor   SourceLocation StarLoc = consumeToken();
105873441091SDouglas Gregor   bool Failed = false;
105973441091SDouglas Gregor 
106073441091SDouglas Gregor   // Inferred modules must be submodules.
106173441091SDouglas Gregor   if (!ActiveModule) {
106273441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
106373441091SDouglas Gregor     Failed = true;
106473441091SDouglas Gregor   }
106573441091SDouglas Gregor 
106673441091SDouglas Gregor   // Inferred modules must have umbrella headers.
1067dd005f69SDouglas Gregor   if (!Failed && !ActiveModule->UmbrellaHeader) {
106873441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
106973441091SDouglas Gregor     Failed = true;
107073441091SDouglas Gregor   }
107173441091SDouglas Gregor 
107273441091SDouglas Gregor   // Check for redefinition of an inferred module.
1073dd005f69SDouglas Gregor   if (!Failed && ActiveModule->InferSubmodules) {
107473441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1075dd005f69SDouglas Gregor     if (ActiveModule->InferredSubmoduleLoc.isValid())
1076dd005f69SDouglas Gregor       Diags.Report(ActiveModule->InferredSubmoduleLoc,
107773441091SDouglas Gregor                    diag::note_mmap_prev_definition);
107873441091SDouglas Gregor     Failed = true;
107973441091SDouglas Gregor   }
108073441091SDouglas Gregor 
108173441091SDouglas Gregor   // If there were any problems with this inferred submodule, skip its body.
108273441091SDouglas Gregor   if (Failed) {
108373441091SDouglas Gregor     if (Tok.is(MMToken::LBrace)) {
108473441091SDouglas Gregor       consumeToken();
108573441091SDouglas Gregor       skipUntil(MMToken::RBrace);
108673441091SDouglas Gregor       if (Tok.is(MMToken::RBrace))
108773441091SDouglas Gregor         consumeToken();
108873441091SDouglas Gregor     }
108973441091SDouglas Gregor     HadError = true;
109073441091SDouglas Gregor     return;
109173441091SDouglas Gregor   }
109273441091SDouglas Gregor 
109373441091SDouglas Gregor   // Note that we have an inferred submodule.
1094dd005f69SDouglas Gregor   ActiveModule->InferSubmodules = true;
1095dd005f69SDouglas Gregor   ActiveModule->InferredSubmoduleLoc = StarLoc;
1096dd005f69SDouglas Gregor   ActiveModule->InferExplicitSubmodules = Explicit;
109773441091SDouglas Gregor 
109873441091SDouglas Gregor   // Parse the opening brace.
109973441091SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
110073441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
110173441091SDouglas Gregor     HadError = true;
110273441091SDouglas Gregor     return;
110373441091SDouglas Gregor   }
110473441091SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
110573441091SDouglas Gregor 
110673441091SDouglas Gregor   // Parse the body of the inferred submodule.
110773441091SDouglas Gregor   bool Done = false;
110873441091SDouglas Gregor   do {
110973441091SDouglas Gregor     switch (Tok.Kind) {
111073441091SDouglas Gregor     case MMToken::EndOfFile:
111173441091SDouglas Gregor     case MMToken::RBrace:
111273441091SDouglas Gregor       Done = true;
111373441091SDouglas Gregor       break;
111473441091SDouglas Gregor 
111573441091SDouglas Gregor     case MMToken::ExportKeyword: {
111673441091SDouglas Gregor       consumeToken();
111773441091SDouglas Gregor       if (Tok.is(MMToken::Star))
1118dd005f69SDouglas Gregor         ActiveModule->InferExportWildcard = true;
111973441091SDouglas Gregor       else
112073441091SDouglas Gregor         Diags.Report(Tok.getLocation(),
112173441091SDouglas Gregor                      diag::err_mmap_expected_export_wildcard);
112273441091SDouglas Gregor       consumeToken();
112373441091SDouglas Gregor       break;
112473441091SDouglas Gregor     }
112573441091SDouglas Gregor 
112673441091SDouglas Gregor     case MMToken::ExplicitKeyword:
112773441091SDouglas Gregor     case MMToken::ModuleKeyword:
112873441091SDouglas Gregor     case MMToken::HeaderKeyword:
112973441091SDouglas Gregor     case MMToken::UmbrellaKeyword:
113073441091SDouglas Gregor     default:
113173441091SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member);
113273441091SDouglas Gregor       consumeToken();
113373441091SDouglas Gregor       break;
113473441091SDouglas Gregor     }
113573441091SDouglas Gregor   } while (!Done);
113673441091SDouglas Gregor 
113773441091SDouglas Gregor   if (Tok.is(MMToken::RBrace))
113873441091SDouglas Gregor     consumeToken();
113973441091SDouglas Gregor   else {
114073441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
114173441091SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
114273441091SDouglas Gregor     HadError = true;
114373441091SDouglas Gregor   }
114473441091SDouglas Gregor }
114573441091SDouglas Gregor 
1146718292f2SDouglas Gregor /// \brief Parse a module map file.
1147718292f2SDouglas Gregor ///
1148718292f2SDouglas Gregor ///   module-map-file:
1149718292f2SDouglas Gregor ///     module-declaration*
1150718292f2SDouglas Gregor bool ModuleMapParser::parseModuleMapFile() {
1151718292f2SDouglas Gregor   do {
1152718292f2SDouglas Gregor     switch (Tok.Kind) {
1153718292f2SDouglas Gregor     case MMToken::EndOfFile:
1154718292f2SDouglas Gregor       return HadError;
1155718292f2SDouglas Gregor 
1156e7ab3669SDouglas Gregor     case MMToken::ExplicitKeyword:
1157718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
1158755b2055SDouglas Gregor     case MMToken::FrameworkKeyword:
1159718292f2SDouglas Gregor       parseModuleDecl();
1160718292f2SDouglas Gregor       break;
1161718292f2SDouglas Gregor 
11622b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
1163718292f2SDouglas Gregor     case MMToken::HeaderKeyword:
1164718292f2SDouglas Gregor     case MMToken::Identifier:
1165718292f2SDouglas Gregor     case MMToken::LBrace:
11662b82c2a5SDouglas Gregor     case MMToken::Period:
1167718292f2SDouglas Gregor     case MMToken::RBrace:
11682b82c2a5SDouglas Gregor     case MMToken::Star:
1169718292f2SDouglas Gregor     case MMToken::StringLiteral:
1170718292f2SDouglas Gregor     case MMToken::UmbrellaKeyword:
1171718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1172718292f2SDouglas Gregor       HadError = true;
1173718292f2SDouglas Gregor       consumeToken();
1174718292f2SDouglas Gregor       break;
1175718292f2SDouglas Gregor     }
1176718292f2SDouglas Gregor   } while (true);
1177718292f2SDouglas Gregor 
1178718292f2SDouglas Gregor   return HadError;
1179718292f2SDouglas Gregor }
1180718292f2SDouglas Gregor 
1181718292f2SDouglas Gregor bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1182718292f2SDouglas Gregor   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1183718292f2SDouglas Gregor   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1184718292f2SDouglas Gregor   if (!Buffer)
1185718292f2SDouglas Gregor     return true;
1186718292f2SDouglas Gregor 
1187718292f2SDouglas Gregor   // Parse this module map file.
1188718292f2SDouglas Gregor   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts);
1189718292f2SDouglas Gregor   Diags->getClient()->BeginSourceFile(LangOpts);
11905257fc63SDouglas Gregor   ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir());
1191718292f2SDouglas Gregor   bool Result = Parser.parseModuleMapFile();
1192718292f2SDouglas Gregor   Diags->getClient()->EndSourceFile();
1193718292f2SDouglas Gregor 
1194718292f2SDouglas Gregor   return Result;
1195718292f2SDouglas Gregor }
1196