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".
121*9458f82dSDouglas Gregor         bool Explicit = UmbrellaModule->InferExplicitSubmodules;
122a89c5ac4SDouglas Gregor         unsigned LastSkippedDir = SkippedDirs.size();
123*9458f82dSDouglas Gregor         if (LastSkippedDir && UmbrellaModule->IsFramework) {
124*9458f82dSDouglas Gregor           if (llvm::sys::path::filename(SkippedDirs.back()->getName())
125*9458f82dSDouglas Gregor                 == "PrivateHeaders") {
126*9458f82dSDouglas Gregor             // For private headers, add an explicit "Private" module.
127*9458f82dSDouglas Gregor             // FIXME: This feels somewhat hackish. Do we want to introduce
128*9458f82dSDouglas Gregor             // some kind of "umbrella directory" here?
129*9458f82dSDouglas Gregor             Result = findOrCreateModule("Private", Result,
130*9458f82dSDouglas Gregor                                         /*IsFramework=*/false,
131*9458f82dSDouglas Gregor                                         /*IsExplicit=*/true).first;
132*9458f82dSDouglas Gregor             Explicit = true;
133*9458f82dSDouglas Gregor           }
134*9458f82dSDouglas Gregor 
135a89c5ac4SDouglas Gregor           --LastSkippedDir;
136*9458f82dSDouglas 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,
142*9458f82dSDouglas 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,
156*9458f82dSDouglas 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;
276e89dbc1dSDouglas Gregor   llvm::SmallString<128> SubframeworksDirName = StringRef(FrameworkDir->getName());
277e89dbc1dSDouglas Gregor   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
278e89dbc1dSDouglas Gregor   for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName.str(), EC),
279e89dbc1dSDouglas Gregor                                          DirEnd;
280e89dbc1dSDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
281e89dbc1dSDouglas Gregor     if (!StringRef(Dir->path()).endswith(".framework"))
282e89dbc1dSDouglas Gregor       continue;
283f2161a70SDouglas Gregor 
284e89dbc1dSDouglas Gregor     if (const DirectoryEntry *SubframeworkDir
285e89dbc1dSDouglas Gregor           = FileMgr.getDirectory(Dir->path())) {
286e89dbc1dSDouglas Gregor       // FIXME: Do we want to warn about subframeworks without umbrella headers?
287e89dbc1dSDouglas Gregor       inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir,
288e89dbc1dSDouglas Gregor                            Result);
289e89dbc1dSDouglas Gregor     }
290e89dbc1dSDouglas Gregor   }
291e89dbc1dSDouglas Gregor 
292*9458f82dSDouglas Gregor   // Look for private headers.
293*9458f82dSDouglas Gregor   Module *ModulePrivate = 0;
294*9458f82dSDouglas Gregor   llvm::SmallString<128> PrivateHeadersDirName(FrameworkDir->getName());
295*9458f82dSDouglas Gregor   llvm::sys::path::append(PrivateHeadersDirName, "PrivateHeaders");
296*9458f82dSDouglas Gregor   for (llvm::sys::fs::directory_iterator Dir(PrivateHeadersDirName.str(), EC),
297*9458f82dSDouglas Gregor        DirEnd;
298*9458f82dSDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
299*9458f82dSDouglas Gregor     // Check whether this entry has an extension typically associated with
300*9458f82dSDouglas Gregor     // headers.
301*9458f82dSDouglas Gregor     if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path()))
302*9458f82dSDouglas Gregor            .Cases(".h", ".H", ".hh", ".hpp", true)
303*9458f82dSDouglas Gregor            .Default(false))
304*9458f82dSDouglas Gregor       continue;
305*9458f82dSDouglas Gregor 
306*9458f82dSDouglas Gregor     if (const FileEntry *PrivateHeader = FileMgr.getFile(Dir->path())) {
307*9458f82dSDouglas Gregor       // Create the "private" submodule, if we haven't done so already.
308*9458f82dSDouglas Gregor       if (!ModulePrivate) {
309*9458f82dSDouglas Gregor         ModulePrivate = findOrCreateModule("Private", Result,
310*9458f82dSDouglas Gregor                                            /*IsFramework=*/false,
311*9458f82dSDouglas Gregor                                            /*IsExplicit=*/true).first;
312*9458f82dSDouglas Gregor       }
313*9458f82dSDouglas Gregor 
314*9458f82dSDouglas Gregor       Module *Sub = findOrCreateModule(llvm::sys::path::stem(Dir->path()),
315*9458f82dSDouglas Gregor                                        ModulePrivate, /*IsFramework=*/false,
316*9458f82dSDouglas Gregor                                        /*IsExplicit=*/true).first;
317*9458f82dSDouglas Gregor       // header "the private header"
318*9458f82dSDouglas Gregor       Sub->Headers.push_back(PrivateHeader);
319*9458f82dSDouglas Gregor 
320*9458f82dSDouglas Gregor       // export *
321*9458f82dSDouglas Gregor       Sub->Exports.push_back(Module::ExportDecl(0, true));
322*9458f82dSDouglas Gregor 
323*9458f82dSDouglas Gregor       Headers[PrivateHeader] = Sub;
324*9458f82dSDouglas Gregor     }
325*9458f82dSDouglas Gregor   }
326*9458f82dSDouglas Gregor 
32756c64013SDouglas Gregor   return Result;
32856c64013SDouglas Gregor }
32956c64013SDouglas Gregor 
330a89c5ac4SDouglas Gregor void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
331a89c5ac4SDouglas Gregor   Headers[UmbrellaHeader] = Mod;
332a89c5ac4SDouglas Gregor   Mod->UmbrellaHeader = UmbrellaHeader;
333a89c5ac4SDouglas Gregor 
334a89c5ac4SDouglas Gregor   const DirectoryEntry *UmbrellaDir = UmbrellaHeader->getDir();
335a89c5ac4SDouglas Gregor   if (Mod->IsFramework)
336a89c5ac4SDouglas Gregor     UmbrellaDir = SourceMgr->getFileManager().getDirectory(
337a89c5ac4SDouglas Gregor                     llvm::sys::path::parent_path(UmbrellaDir->getName()));
338a89c5ac4SDouglas Gregor 
339a89c5ac4SDouglas Gregor   UmbrellaDirs[UmbrellaDir] = Mod;
340a89c5ac4SDouglas Gregor }
341a89c5ac4SDouglas Gregor 
342a89c5ac4SDouglas Gregor void ModuleMap::addHeader(Module *Mod, const FileEntry *Header) {
343a89c5ac4SDouglas Gregor   Mod->Headers.push_back(Header);
344a89c5ac4SDouglas Gregor   Headers[Header] = Mod;
345a89c5ac4SDouglas Gregor }
346a89c5ac4SDouglas Gregor 
347514b636aSDouglas Gregor const FileEntry *
348de3ef502SDouglas Gregor ModuleMap::getContainingModuleMapFile(Module *Module) {
349514b636aSDouglas Gregor   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
350514b636aSDouglas Gregor     return 0;
351514b636aSDouglas Gregor 
352514b636aSDouglas Gregor   return SourceMgr->getFileEntryForID(
353514b636aSDouglas Gregor            SourceMgr->getFileID(Module->DefinitionLoc));
354514b636aSDouglas Gregor }
355514b636aSDouglas Gregor 
356718292f2SDouglas Gregor void ModuleMap::dump() {
357718292f2SDouglas Gregor   llvm::errs() << "Modules:";
358718292f2SDouglas Gregor   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
359718292f2SDouglas Gregor                                         MEnd = Modules.end();
360718292f2SDouglas Gregor        M != MEnd; ++M)
361d28d1b8dSDouglas Gregor     M->getValue()->print(llvm::errs(), 2);
362718292f2SDouglas Gregor 
363718292f2SDouglas Gregor   llvm::errs() << "Headers:";
364718292f2SDouglas Gregor   for (llvm::DenseMap<const FileEntry *, Module *>::iterator
365718292f2SDouglas Gregor             H = Headers.begin(),
366718292f2SDouglas Gregor          HEnd = Headers.end();
367718292f2SDouglas Gregor        H != HEnd; ++H) {
368718292f2SDouglas Gregor     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
369718292f2SDouglas Gregor                  << H->second->getFullModuleName() << "\n";
370718292f2SDouglas Gregor   }
371718292f2SDouglas Gregor }
372718292f2SDouglas Gregor 
3732b82c2a5SDouglas Gregor bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
3742b82c2a5SDouglas Gregor   bool HadError = false;
3752b82c2a5SDouglas Gregor   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
3762b82c2a5SDouglas Gregor     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
3772b82c2a5SDouglas Gregor                                               Complain);
378f5eedd05SDouglas Gregor     if (Export.getPointer() || Export.getInt())
3792b82c2a5SDouglas Gregor       Mod->Exports.push_back(Export);
3802b82c2a5SDouglas Gregor     else
3812b82c2a5SDouglas Gregor       HadError = true;
3822b82c2a5SDouglas Gregor   }
3832b82c2a5SDouglas Gregor   Mod->UnresolvedExports.clear();
3842b82c2a5SDouglas Gregor   return HadError;
3852b82c2a5SDouglas Gregor }
3862b82c2a5SDouglas Gregor 
3870093b3c7SDouglas Gregor Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
3880093b3c7SDouglas Gregor   if (Loc.isInvalid())
3890093b3c7SDouglas Gregor     return 0;
3900093b3c7SDouglas Gregor 
3910093b3c7SDouglas Gregor   // Use the expansion location to determine which module we're in.
3920093b3c7SDouglas Gregor   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
3930093b3c7SDouglas Gregor   if (!ExpansionLoc.isFileID())
3940093b3c7SDouglas Gregor     return 0;
3950093b3c7SDouglas Gregor 
3960093b3c7SDouglas Gregor 
3970093b3c7SDouglas Gregor   const SourceManager &SrcMgr = Loc.getManager();
3980093b3c7SDouglas Gregor   FileID ExpansionFileID = ExpansionLoc.getFileID();
3990093b3c7SDouglas Gregor   const FileEntry *ExpansionFile = SrcMgr.getFileEntryForID(ExpansionFileID);
4000093b3c7SDouglas Gregor   if (!ExpansionFile)
4010093b3c7SDouglas Gregor     return 0;
4020093b3c7SDouglas Gregor 
4030093b3c7SDouglas Gregor   // Find the module that owns this header.
4040093b3c7SDouglas Gregor   return findModuleForHeader(ExpansionFile);
4050093b3c7SDouglas Gregor }
4060093b3c7SDouglas Gregor 
407718292f2SDouglas Gregor //----------------------------------------------------------------------------//
408718292f2SDouglas Gregor // Module map file parser
409718292f2SDouglas Gregor //----------------------------------------------------------------------------//
410718292f2SDouglas Gregor 
411718292f2SDouglas Gregor namespace clang {
412718292f2SDouglas Gregor   /// \brief A token in a module map file.
413718292f2SDouglas Gregor   struct MMToken {
414718292f2SDouglas Gregor     enum TokenKind {
415718292f2SDouglas Gregor       EndOfFile,
416718292f2SDouglas Gregor       HeaderKeyword,
417718292f2SDouglas Gregor       Identifier,
418718292f2SDouglas Gregor       ExplicitKeyword,
4192b82c2a5SDouglas Gregor       ExportKeyword,
420755b2055SDouglas Gregor       FrameworkKeyword,
421718292f2SDouglas Gregor       ModuleKeyword,
4222b82c2a5SDouglas Gregor       Period,
423718292f2SDouglas Gregor       UmbrellaKeyword,
4242b82c2a5SDouglas Gregor       Star,
425718292f2SDouglas Gregor       StringLiteral,
426718292f2SDouglas Gregor       LBrace,
427718292f2SDouglas Gregor       RBrace
428718292f2SDouglas Gregor     } Kind;
429718292f2SDouglas Gregor 
430718292f2SDouglas Gregor     unsigned Location;
431718292f2SDouglas Gregor     unsigned StringLength;
432718292f2SDouglas Gregor     const char *StringData;
433718292f2SDouglas Gregor 
434718292f2SDouglas Gregor     void clear() {
435718292f2SDouglas Gregor       Kind = EndOfFile;
436718292f2SDouglas Gregor       Location = 0;
437718292f2SDouglas Gregor       StringLength = 0;
438718292f2SDouglas Gregor       StringData = 0;
439718292f2SDouglas Gregor     }
440718292f2SDouglas Gregor 
441718292f2SDouglas Gregor     bool is(TokenKind K) const { return Kind == K; }
442718292f2SDouglas Gregor 
443718292f2SDouglas Gregor     SourceLocation getLocation() const {
444718292f2SDouglas Gregor       return SourceLocation::getFromRawEncoding(Location);
445718292f2SDouglas Gregor     }
446718292f2SDouglas Gregor 
447718292f2SDouglas Gregor     StringRef getString() const {
448718292f2SDouglas Gregor       return StringRef(StringData, StringLength);
449718292f2SDouglas Gregor     }
450718292f2SDouglas Gregor   };
451718292f2SDouglas Gregor 
452718292f2SDouglas Gregor   class ModuleMapParser {
453718292f2SDouglas Gregor     Lexer &L;
454718292f2SDouglas Gregor     SourceManager &SourceMgr;
455718292f2SDouglas Gregor     DiagnosticsEngine &Diags;
456718292f2SDouglas Gregor     ModuleMap &Map;
457718292f2SDouglas Gregor 
4585257fc63SDouglas Gregor     /// \brief The directory that this module map resides in.
4595257fc63SDouglas Gregor     const DirectoryEntry *Directory;
4605257fc63SDouglas Gregor 
461718292f2SDouglas Gregor     /// \brief Whether an error occurred.
462718292f2SDouglas Gregor     bool HadError;
463718292f2SDouglas Gregor 
464718292f2SDouglas Gregor     /// \brief Default target information, used only for string literal
465718292f2SDouglas Gregor     /// parsing.
466718292f2SDouglas Gregor     TargetInfo *Target;
467718292f2SDouglas Gregor 
468718292f2SDouglas Gregor     /// \brief Stores string data for the various string literals referenced
469718292f2SDouglas Gregor     /// during parsing.
470718292f2SDouglas Gregor     llvm::BumpPtrAllocator StringData;
471718292f2SDouglas Gregor 
472718292f2SDouglas Gregor     /// \brief The current token.
473718292f2SDouglas Gregor     MMToken Tok;
474718292f2SDouglas Gregor 
475718292f2SDouglas Gregor     /// \brief The active module.
476de3ef502SDouglas Gregor     Module *ActiveModule;
477718292f2SDouglas Gregor 
478718292f2SDouglas Gregor     /// \brief Consume the current token and return its location.
479718292f2SDouglas Gregor     SourceLocation consumeToken();
480718292f2SDouglas Gregor 
481718292f2SDouglas Gregor     /// \brief Skip tokens until we reach the a token with the given kind
482718292f2SDouglas Gregor     /// (or the end of the file).
483718292f2SDouglas Gregor     void skipUntil(MMToken::TokenKind K);
484718292f2SDouglas Gregor 
485e7ab3669SDouglas Gregor     typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
486e7ab3669SDouglas Gregor       ModuleId;
487e7ab3669SDouglas Gregor     bool parseModuleId(ModuleId &Id);
488718292f2SDouglas Gregor     void parseModuleDecl();
489718292f2SDouglas Gregor     void parseUmbrellaDecl();
490718292f2SDouglas Gregor     void parseHeaderDecl();
4912b82c2a5SDouglas Gregor     void parseExportDecl();
49273441091SDouglas Gregor     void parseInferredSubmoduleDecl(bool Explicit);
493718292f2SDouglas Gregor 
494718292f2SDouglas Gregor   public:
495718292f2SDouglas Gregor     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
496718292f2SDouglas Gregor                              DiagnosticsEngine &Diags,
4975257fc63SDouglas Gregor                              ModuleMap &Map,
4985257fc63SDouglas Gregor                              const DirectoryEntry *Directory)
4995257fc63SDouglas Gregor       : L(L), SourceMgr(SourceMgr), Diags(Diags), Map(Map),
5005257fc63SDouglas Gregor         Directory(Directory), HadError(false), ActiveModule(0)
501718292f2SDouglas Gregor     {
502718292f2SDouglas Gregor       TargetOptions TargetOpts;
503718292f2SDouglas Gregor       TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
504718292f2SDouglas Gregor       Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
505718292f2SDouglas Gregor 
506718292f2SDouglas Gregor       Tok.clear();
507718292f2SDouglas Gregor       consumeToken();
508718292f2SDouglas Gregor     }
509718292f2SDouglas Gregor 
510718292f2SDouglas Gregor     bool parseModuleMapFile();
511718292f2SDouglas Gregor   };
512718292f2SDouglas Gregor }
513718292f2SDouglas Gregor 
514718292f2SDouglas Gregor SourceLocation ModuleMapParser::consumeToken() {
515718292f2SDouglas Gregor retry:
516718292f2SDouglas Gregor   SourceLocation Result = Tok.getLocation();
517718292f2SDouglas Gregor   Tok.clear();
518718292f2SDouglas Gregor 
519718292f2SDouglas Gregor   Token LToken;
520718292f2SDouglas Gregor   L.LexFromRawLexer(LToken);
521718292f2SDouglas Gregor   Tok.Location = LToken.getLocation().getRawEncoding();
522718292f2SDouglas Gregor   switch (LToken.getKind()) {
523718292f2SDouglas Gregor   case tok::raw_identifier:
524718292f2SDouglas Gregor     Tok.StringData = LToken.getRawIdentifierData();
525718292f2SDouglas Gregor     Tok.StringLength = LToken.getLength();
526718292f2SDouglas Gregor     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
527718292f2SDouglas Gregor                  .Case("header", MMToken::HeaderKeyword)
528718292f2SDouglas Gregor                  .Case("explicit", MMToken::ExplicitKeyword)
5292b82c2a5SDouglas Gregor                  .Case("export", MMToken::ExportKeyword)
530755b2055SDouglas Gregor                  .Case("framework", MMToken::FrameworkKeyword)
531718292f2SDouglas Gregor                  .Case("module", MMToken::ModuleKeyword)
532718292f2SDouglas Gregor                  .Case("umbrella", MMToken::UmbrellaKeyword)
533718292f2SDouglas Gregor                  .Default(MMToken::Identifier);
534718292f2SDouglas Gregor     break;
535718292f2SDouglas Gregor 
536718292f2SDouglas Gregor   case tok::eof:
537718292f2SDouglas Gregor     Tok.Kind = MMToken::EndOfFile;
538718292f2SDouglas Gregor     break;
539718292f2SDouglas Gregor 
540718292f2SDouglas Gregor   case tok::l_brace:
541718292f2SDouglas Gregor     Tok.Kind = MMToken::LBrace;
542718292f2SDouglas Gregor     break;
543718292f2SDouglas Gregor 
5442b82c2a5SDouglas Gregor   case tok::period:
5452b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Period;
5462b82c2a5SDouglas Gregor     break;
5472b82c2a5SDouglas Gregor 
548718292f2SDouglas Gregor   case tok::r_brace:
549718292f2SDouglas Gregor     Tok.Kind = MMToken::RBrace;
550718292f2SDouglas Gregor     break;
551718292f2SDouglas Gregor 
5522b82c2a5SDouglas Gregor   case tok::star:
5532b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Star;
5542b82c2a5SDouglas Gregor     break;
5552b82c2a5SDouglas Gregor 
556718292f2SDouglas Gregor   case tok::string_literal: {
557718292f2SDouglas Gregor     // Parse the string literal.
558718292f2SDouglas Gregor     LangOptions LangOpts;
559718292f2SDouglas Gregor     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
560718292f2SDouglas Gregor     if (StringLiteral.hadError)
561718292f2SDouglas Gregor       goto retry;
562718292f2SDouglas Gregor 
563718292f2SDouglas Gregor     // Copy the string literal into our string data allocator.
564718292f2SDouglas Gregor     unsigned Length = StringLiteral.GetStringLength();
565718292f2SDouglas Gregor     char *Saved = StringData.Allocate<char>(Length + 1);
566718292f2SDouglas Gregor     memcpy(Saved, StringLiteral.GetString().data(), Length);
567718292f2SDouglas Gregor     Saved[Length] = 0;
568718292f2SDouglas Gregor 
569718292f2SDouglas Gregor     // Form the token.
570718292f2SDouglas Gregor     Tok.Kind = MMToken::StringLiteral;
571718292f2SDouglas Gregor     Tok.StringData = Saved;
572718292f2SDouglas Gregor     Tok.StringLength = Length;
573718292f2SDouglas Gregor     break;
574718292f2SDouglas Gregor   }
575718292f2SDouglas Gregor 
576718292f2SDouglas Gregor   case tok::comment:
577718292f2SDouglas Gregor     goto retry;
578718292f2SDouglas Gregor 
579718292f2SDouglas Gregor   default:
580718292f2SDouglas Gregor     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
581718292f2SDouglas Gregor     HadError = true;
582718292f2SDouglas Gregor     goto retry;
583718292f2SDouglas Gregor   }
584718292f2SDouglas Gregor 
585718292f2SDouglas Gregor   return Result;
586718292f2SDouglas Gregor }
587718292f2SDouglas Gregor 
588718292f2SDouglas Gregor void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
589718292f2SDouglas Gregor   unsigned braceDepth = 0;
590718292f2SDouglas Gregor   do {
591718292f2SDouglas Gregor     switch (Tok.Kind) {
592718292f2SDouglas Gregor     case MMToken::EndOfFile:
593718292f2SDouglas Gregor       return;
594718292f2SDouglas Gregor 
595718292f2SDouglas Gregor     case MMToken::LBrace:
596718292f2SDouglas Gregor       if (Tok.is(K) && braceDepth == 0)
597718292f2SDouglas Gregor         return;
598718292f2SDouglas Gregor 
599718292f2SDouglas Gregor       ++braceDepth;
600718292f2SDouglas Gregor       break;
601718292f2SDouglas Gregor 
602718292f2SDouglas Gregor     case MMToken::RBrace:
603718292f2SDouglas Gregor       if (braceDepth > 0)
604718292f2SDouglas Gregor         --braceDepth;
605718292f2SDouglas Gregor       else if (Tok.is(K))
606718292f2SDouglas Gregor         return;
607718292f2SDouglas Gregor       break;
608718292f2SDouglas Gregor 
609718292f2SDouglas Gregor     default:
610718292f2SDouglas Gregor       if (braceDepth == 0 && Tok.is(K))
611718292f2SDouglas Gregor         return;
612718292f2SDouglas Gregor       break;
613718292f2SDouglas Gregor     }
614718292f2SDouglas Gregor 
615718292f2SDouglas Gregor    consumeToken();
616718292f2SDouglas Gregor   } while (true);
617718292f2SDouglas Gregor }
618718292f2SDouglas Gregor 
619e7ab3669SDouglas Gregor /// \brief Parse a module-id.
620e7ab3669SDouglas Gregor ///
621e7ab3669SDouglas Gregor ///   module-id:
622e7ab3669SDouglas Gregor ///     identifier
623e7ab3669SDouglas Gregor ///     identifier '.' module-id
624e7ab3669SDouglas Gregor ///
625e7ab3669SDouglas Gregor /// \returns true if an error occurred, false otherwise.
626e7ab3669SDouglas Gregor bool ModuleMapParser::parseModuleId(ModuleId &Id) {
627e7ab3669SDouglas Gregor   Id.clear();
628e7ab3669SDouglas Gregor   do {
629e7ab3669SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
630e7ab3669SDouglas Gregor       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
631e7ab3669SDouglas Gregor       consumeToken();
632e7ab3669SDouglas Gregor     } else {
633e7ab3669SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
634e7ab3669SDouglas Gregor       return true;
635e7ab3669SDouglas Gregor     }
636e7ab3669SDouglas Gregor 
637e7ab3669SDouglas Gregor     if (!Tok.is(MMToken::Period))
638e7ab3669SDouglas Gregor       break;
639e7ab3669SDouglas Gregor 
640e7ab3669SDouglas Gregor     consumeToken();
641e7ab3669SDouglas Gregor   } while (true);
642e7ab3669SDouglas Gregor 
643e7ab3669SDouglas Gregor   return false;
644e7ab3669SDouglas Gregor }
645e7ab3669SDouglas Gregor 
646718292f2SDouglas Gregor /// \brief Parse a module declaration.
647718292f2SDouglas Gregor ///
648718292f2SDouglas Gregor ///   module-declaration:
649e7ab3669SDouglas Gregor ///     'explicit'[opt] 'framework'[opt] 'module' module-id { module-member* }
650718292f2SDouglas Gregor ///
651718292f2SDouglas Gregor ///   module-member:
652718292f2SDouglas Gregor ///     umbrella-declaration
653718292f2SDouglas Gregor ///     header-declaration
654e7ab3669SDouglas Gregor ///     submodule-declaration
6552b82c2a5SDouglas Gregor ///     export-declaration
65673441091SDouglas Gregor ///
65773441091SDouglas Gregor ///   submodule-declaration:
65873441091SDouglas Gregor ///     module-declaration
65973441091SDouglas Gregor ///     inferred-submodule-declaration
660718292f2SDouglas Gregor void ModuleMapParser::parseModuleDecl() {
661755b2055SDouglas Gregor   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
662755b2055SDouglas Gregor          Tok.is(MMToken::FrameworkKeyword));
663f2161a70SDouglas Gregor   // Parse 'explicit' or 'framework' keyword, if present.
664e7ab3669SDouglas Gregor   SourceLocation ExplicitLoc;
665718292f2SDouglas Gregor   bool Explicit = false;
666f2161a70SDouglas Gregor   bool Framework = false;
667755b2055SDouglas Gregor 
668f2161a70SDouglas Gregor   // Parse 'explicit' keyword, if present.
669f2161a70SDouglas Gregor   if (Tok.is(MMToken::ExplicitKeyword)) {
670e7ab3669SDouglas Gregor     ExplicitLoc = consumeToken();
671f2161a70SDouglas Gregor     Explicit = true;
672f2161a70SDouglas Gregor   }
673f2161a70SDouglas Gregor 
674f2161a70SDouglas Gregor   // Parse 'framework' keyword, if present.
675755b2055SDouglas Gregor   if (Tok.is(MMToken::FrameworkKeyword)) {
676755b2055SDouglas Gregor     consumeToken();
677755b2055SDouglas Gregor     Framework = true;
678755b2055SDouglas Gregor   }
679718292f2SDouglas Gregor 
680718292f2SDouglas Gregor   // Parse 'module' keyword.
681718292f2SDouglas Gregor   if (!Tok.is(MMToken::ModuleKeyword)) {
682d6343c99SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
683718292f2SDouglas Gregor     consumeToken();
684718292f2SDouglas Gregor     HadError = true;
685718292f2SDouglas Gregor     return;
686718292f2SDouglas Gregor   }
687718292f2SDouglas Gregor   consumeToken(); // 'module' keyword
688718292f2SDouglas Gregor 
68973441091SDouglas Gregor   // If we have a wildcard for the module name, this is an inferred submodule.
69073441091SDouglas Gregor   // Parse it.
69173441091SDouglas Gregor   if (Tok.is(MMToken::Star))
69273441091SDouglas Gregor     return parseInferredSubmoduleDecl(Explicit);
69373441091SDouglas Gregor 
694718292f2SDouglas Gregor   // Parse the module name.
695e7ab3669SDouglas Gregor   ModuleId Id;
696e7ab3669SDouglas Gregor   if (parseModuleId(Id)) {
697718292f2SDouglas Gregor     HadError = true;
698718292f2SDouglas Gregor     return;
699718292f2SDouglas Gregor   }
700e7ab3669SDouglas Gregor 
701e7ab3669SDouglas Gregor   if (ActiveModule) {
702e7ab3669SDouglas Gregor     if (Id.size() > 1) {
703e7ab3669SDouglas Gregor       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
704e7ab3669SDouglas Gregor         << SourceRange(Id.front().second, Id.back().second);
705e7ab3669SDouglas Gregor 
706e7ab3669SDouglas Gregor       HadError = true;
707e7ab3669SDouglas Gregor       return;
708e7ab3669SDouglas Gregor     }
709e7ab3669SDouglas Gregor   } else if (Id.size() == 1 && Explicit) {
710e7ab3669SDouglas Gregor     // Top-level modules can't be explicit.
711e7ab3669SDouglas Gregor     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
712e7ab3669SDouglas Gregor     Explicit = false;
713e7ab3669SDouglas Gregor     ExplicitLoc = SourceLocation();
714e7ab3669SDouglas Gregor     HadError = true;
715e7ab3669SDouglas Gregor   }
716e7ab3669SDouglas Gregor 
717e7ab3669SDouglas Gregor   Module *PreviousActiveModule = ActiveModule;
718e7ab3669SDouglas Gregor   if (Id.size() > 1) {
719e7ab3669SDouglas Gregor     // This module map defines a submodule. Go find the module of which it
720e7ab3669SDouglas Gregor     // is a submodule.
721e7ab3669SDouglas Gregor     ActiveModule = 0;
722e7ab3669SDouglas Gregor     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
723e7ab3669SDouglas Gregor       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
724e7ab3669SDouglas Gregor         ActiveModule = Next;
725e7ab3669SDouglas Gregor         continue;
726e7ab3669SDouglas Gregor       }
727e7ab3669SDouglas Gregor 
728e7ab3669SDouglas Gregor       if (ActiveModule) {
729e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
730e7ab3669SDouglas Gregor           << Id[I].first << ActiveModule->getTopLevelModule();
731e7ab3669SDouglas Gregor       } else {
732e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
733e7ab3669SDouglas Gregor       }
734e7ab3669SDouglas Gregor       HadError = true;
735e7ab3669SDouglas Gregor       return;
736e7ab3669SDouglas Gregor     }
737e7ab3669SDouglas Gregor   }
738e7ab3669SDouglas Gregor 
739e7ab3669SDouglas Gregor   StringRef ModuleName = Id.back().first;
740e7ab3669SDouglas Gregor   SourceLocation ModuleNameLoc = Id.back().second;
741718292f2SDouglas Gregor 
742718292f2SDouglas Gregor   // Parse the opening brace.
743718292f2SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
744718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
745718292f2SDouglas Gregor       << ModuleName;
746718292f2SDouglas Gregor     HadError = true;
747718292f2SDouglas Gregor     return;
748718292f2SDouglas Gregor   }
749718292f2SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
750718292f2SDouglas Gregor 
751718292f2SDouglas Gregor   // Determine whether this (sub)module has already been defined.
752718292f2SDouglas Gregor   llvm::StringMap<Module *> &ModuleSpace
753718292f2SDouglas Gregor     = ActiveModule? ActiveModule->SubModules : Map.Modules;
754718292f2SDouglas Gregor   llvm::StringMap<Module *>::iterator ExistingModule
755718292f2SDouglas Gregor     = ModuleSpace.find(ModuleName);
756718292f2SDouglas Gregor   if (ExistingModule != ModuleSpace.end()) {
757718292f2SDouglas Gregor     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
758718292f2SDouglas Gregor       << ModuleName;
759718292f2SDouglas Gregor     Diags.Report(ExistingModule->getValue()->DefinitionLoc,
760718292f2SDouglas Gregor                  diag::note_mmap_prev_definition);
761718292f2SDouglas Gregor 
762718292f2SDouglas Gregor     // Skip the module definition.
763718292f2SDouglas Gregor     skipUntil(MMToken::RBrace);
764718292f2SDouglas Gregor     if (Tok.is(MMToken::RBrace))
765718292f2SDouglas Gregor       consumeToken();
766718292f2SDouglas Gregor 
767718292f2SDouglas Gregor     HadError = true;
768718292f2SDouglas Gregor     return;
769718292f2SDouglas Gregor   }
770718292f2SDouglas Gregor 
771718292f2SDouglas Gregor   // Start defining this module.
772755b2055SDouglas Gregor   ActiveModule = new Module(ModuleName, ModuleNameLoc, ActiveModule, Framework,
773755b2055SDouglas Gregor                             Explicit);
774718292f2SDouglas Gregor   ModuleSpace[ModuleName] = ActiveModule;
775718292f2SDouglas Gregor 
776718292f2SDouglas Gregor   bool Done = false;
777718292f2SDouglas Gregor   do {
778718292f2SDouglas Gregor     switch (Tok.Kind) {
779718292f2SDouglas Gregor     case MMToken::EndOfFile:
780718292f2SDouglas Gregor     case MMToken::RBrace:
781718292f2SDouglas Gregor       Done = true;
782718292f2SDouglas Gregor       break;
783718292f2SDouglas Gregor 
784718292f2SDouglas Gregor     case MMToken::ExplicitKeyword:
785f2161a70SDouglas Gregor     case MMToken::FrameworkKeyword:
786718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
787718292f2SDouglas Gregor       parseModuleDecl();
788718292f2SDouglas Gregor       break;
789718292f2SDouglas Gregor 
7902b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
7912b82c2a5SDouglas Gregor       parseExportDecl();
7922b82c2a5SDouglas Gregor       break;
7932b82c2a5SDouglas Gregor 
794718292f2SDouglas Gregor     case MMToken::HeaderKeyword:
795718292f2SDouglas Gregor       parseHeaderDecl();
796718292f2SDouglas Gregor       break;
797718292f2SDouglas Gregor 
798718292f2SDouglas Gregor     case MMToken::UmbrellaKeyword:
799718292f2SDouglas Gregor       parseUmbrellaDecl();
800718292f2SDouglas Gregor       break;
801718292f2SDouglas Gregor 
802718292f2SDouglas Gregor     default:
803718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
804718292f2SDouglas Gregor       consumeToken();
805718292f2SDouglas Gregor       break;
806718292f2SDouglas Gregor     }
807718292f2SDouglas Gregor   } while (!Done);
808718292f2SDouglas Gregor 
809718292f2SDouglas Gregor   if (Tok.is(MMToken::RBrace))
810718292f2SDouglas Gregor     consumeToken();
811718292f2SDouglas Gregor   else {
812718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
813718292f2SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
814718292f2SDouglas Gregor     HadError = true;
815718292f2SDouglas Gregor   }
816718292f2SDouglas Gregor 
817e7ab3669SDouglas Gregor   // We're done parsing this module. Pop back to the previous module.
818e7ab3669SDouglas Gregor   ActiveModule = PreviousActiveModule;
819718292f2SDouglas Gregor }
820718292f2SDouglas Gregor 
821f2161a70SDouglas Gregor /// \brief Append to \p Paths the set of paths needed to get to the
822f2161a70SDouglas Gregor /// subframework in which the given module lives.
823f2161a70SDouglas Gregor void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) {
824f2161a70SDouglas Gregor   // Collect the framework names from the given module to the top-level module.
825f2161a70SDouglas Gregor   llvm::SmallVector<StringRef, 2> Paths;
826f2161a70SDouglas Gregor   for (; Mod; Mod = Mod->Parent) {
827f2161a70SDouglas Gregor     if (Mod->IsFramework)
828f2161a70SDouglas Gregor       Paths.push_back(Mod->Name);
829f2161a70SDouglas Gregor   }
830f2161a70SDouglas Gregor 
831f2161a70SDouglas Gregor   if (Paths.empty())
832f2161a70SDouglas Gregor     return;
833f2161a70SDouglas Gregor 
834f2161a70SDouglas Gregor   // Add Frameworks/Name.framework for each subframework.
835f2161a70SDouglas Gregor   for (unsigned I = Paths.size() - 1; I != 0; --I) {
836f2161a70SDouglas Gregor     llvm::sys::path::append(Path, "Frameworks");
837f2161a70SDouglas Gregor     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
838f2161a70SDouglas Gregor   }
839f2161a70SDouglas Gregor }
840f2161a70SDouglas Gregor 
841718292f2SDouglas Gregor /// \brief Parse an umbrella header declaration.
842718292f2SDouglas Gregor ///
843718292f2SDouglas Gregor ///   umbrella-declaration:
844718292f2SDouglas Gregor ///     'umbrella' string-literal
845718292f2SDouglas Gregor void ModuleMapParser::parseUmbrellaDecl() {
846718292f2SDouglas Gregor   assert(Tok.is(MMToken::UmbrellaKeyword));
847718292f2SDouglas Gregor   SourceLocation UmbrellaLoc = consumeToken();
848718292f2SDouglas Gregor 
849718292f2SDouglas Gregor   // Parse the header name.
850718292f2SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
851718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
852718292f2SDouglas Gregor       << "umbrella";
853718292f2SDouglas Gregor     HadError = true;
854718292f2SDouglas Gregor     return;
855718292f2SDouglas Gregor   }
856e7ab3669SDouglas Gregor   std::string FileName = Tok.getString();
857718292f2SDouglas Gregor   SourceLocation FileNameLoc = consumeToken();
858718292f2SDouglas Gregor 
8595257fc63SDouglas Gregor   // Check whether we already have an umbrella header.
8605257fc63SDouglas Gregor   if (ActiveModule->UmbrellaHeader) {
8615257fc63SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict)
8625257fc63SDouglas Gregor       << ActiveModule->getFullModuleName()
8635257fc63SDouglas Gregor       << ActiveModule->UmbrellaHeader->getName();
8645257fc63SDouglas Gregor     HadError = true;
8655257fc63SDouglas Gregor     return;
8665257fc63SDouglas Gregor   }
8675257fc63SDouglas Gregor 
8685257fc63SDouglas Gregor   // Look for this file.
8695257fc63SDouglas Gregor   llvm::SmallString<128> PathName;
870f545f67dSDouglas Gregor   const FileEntry *File = 0;
871f545f67dSDouglas Gregor 
872f545f67dSDouglas Gregor   if (llvm::sys::path::is_absolute(FileName)) {
873f545f67dSDouglas Gregor     PathName = FileName;
874f545f67dSDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
875f545f67dSDouglas Gregor   } else {
876f545f67dSDouglas Gregor     // Search for the header file within the search directory.
8775257fc63SDouglas Gregor     PathName += Directory->getName();
878755b2055SDouglas Gregor     unsigned PathLength = PathName.size();
879f2161a70SDouglas Gregor 
880755b2055SDouglas Gregor     if (ActiveModule->isPartOfFramework()) {
881f2161a70SDouglas Gregor       appendSubframeworkPaths(ActiveModule, PathName);
882f2161a70SDouglas Gregor 
883755b2055SDouglas Gregor       // Check whether this file is in the public headers.
884755b2055SDouglas Gregor       llvm::sys::path::append(PathName, "Headers");
8855257fc63SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
886755b2055SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
887755b2055SDouglas Gregor 
888755b2055SDouglas Gregor       if (!File) {
889755b2055SDouglas Gregor         // Check whether this file is in the private headers.
890755b2055SDouglas Gregor         PathName.resize(PathLength);
891755b2055SDouglas Gregor         llvm::sys::path::append(PathName, "PrivateHeaders");
892755b2055SDouglas Gregor         llvm::sys::path::append(PathName, FileName);
893755b2055SDouglas Gregor         File = SourceMgr.getFileManager().getFile(PathName);
894755b2055SDouglas Gregor       }
895755b2055SDouglas Gregor     } else {
896755b2055SDouglas Gregor       // Lookup for normal headers.
897755b2055SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
898755b2055SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
899755b2055SDouglas Gregor     }
900f545f67dSDouglas Gregor   }
9015257fc63SDouglas Gregor 
9025257fc63SDouglas Gregor   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
9035257fc63SDouglas Gregor   // Come up with a lazy way to do this.
904755b2055SDouglas Gregor   if (File) {
905a89c5ac4SDouglas Gregor     const DirectoryEntry *UmbrellaDir = File->getDir();
906a89c5ac4SDouglas Gregor     if (ActiveModule->IsFramework) {
907a89c5ac4SDouglas Gregor       // For framework modules, use the framework directory as the umbrella
908a89c5ac4SDouglas Gregor       // directory.
909a89c5ac4SDouglas Gregor       UmbrellaDir = SourceMgr.getFileManager().getDirectory(
910a89c5ac4SDouglas Gregor                       llvm::sys::path::parent_path(UmbrellaDir->getName()));
911a89c5ac4SDouglas Gregor     }
912a89c5ac4SDouglas Gregor 
9135257fc63SDouglas Gregor     if (const Module *OwningModule = Map.Headers[File]) {
9145257fc63SDouglas Gregor       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
9155257fc63SDouglas Gregor         << FileName << OwningModule->getFullModuleName();
9165257fc63SDouglas Gregor       HadError = true;
917a89c5ac4SDouglas Gregor     } else if ((OwningModule = Map.UmbrellaDirs[UmbrellaDir])) {
918b65dbfffSDouglas Gregor       Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
919b65dbfffSDouglas Gregor         << OwningModule->getFullModuleName();
920b65dbfffSDouglas Gregor       HadError = true;
9215257fc63SDouglas Gregor     } else {
9225257fc63SDouglas Gregor       // Record this umbrella header.
923a89c5ac4SDouglas Gregor       Map.setUmbrellaHeader(ActiveModule, File);
9245257fc63SDouglas Gregor     }
9255257fc63SDouglas Gregor   } else {
9265257fc63SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
9275257fc63SDouglas Gregor       << true << FileName;
9285257fc63SDouglas Gregor     HadError = true;
9295257fc63SDouglas Gregor   }
930718292f2SDouglas Gregor }
931718292f2SDouglas Gregor 
932718292f2SDouglas Gregor /// \brief Parse a header declaration.
933718292f2SDouglas Gregor ///
934718292f2SDouglas Gregor ///   header-declaration:
935718292f2SDouglas Gregor ///     'header' string-literal
936718292f2SDouglas Gregor void ModuleMapParser::parseHeaderDecl() {
937718292f2SDouglas Gregor   assert(Tok.is(MMToken::HeaderKeyword));
9381871ed3dSBenjamin Kramer   consumeToken();
939718292f2SDouglas Gregor 
940718292f2SDouglas Gregor   // Parse the header name.
941718292f2SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
942718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
943718292f2SDouglas Gregor       << "header";
944718292f2SDouglas Gregor     HadError = true;
945718292f2SDouglas Gregor     return;
946718292f2SDouglas Gregor   }
947e7ab3669SDouglas Gregor   std::string FileName = Tok.getString();
948718292f2SDouglas Gregor   SourceLocation FileNameLoc = consumeToken();
949718292f2SDouglas Gregor 
9505257fc63SDouglas Gregor   // Look for this file.
951e7ab3669SDouglas Gregor   const FileEntry *File = 0;
9525257fc63SDouglas Gregor   llvm::SmallString<128> PathName;
953e7ab3669SDouglas Gregor   if (llvm::sys::path::is_absolute(FileName)) {
954e7ab3669SDouglas Gregor     PathName = FileName;
955e7ab3669SDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
956e7ab3669SDouglas Gregor   } else {
957e7ab3669SDouglas Gregor     // Search for the header file within the search directory.
9585257fc63SDouglas Gregor     PathName += Directory->getName();
959e7ab3669SDouglas Gregor     unsigned PathLength = PathName.size();
960755b2055SDouglas Gregor 
961f2161a70SDouglas Gregor     if (ActiveModule->isPartOfFramework()) {
962f2161a70SDouglas Gregor       appendSubframeworkPaths(ActiveModule, PathName);
963755b2055SDouglas Gregor 
964e7ab3669SDouglas Gregor       // Check whether this file is in the public headers.
965e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, "Headers");
9665257fc63SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
967e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
968e7ab3669SDouglas Gregor 
969e7ab3669SDouglas Gregor       if (!File) {
970e7ab3669SDouglas Gregor         // Check whether this file is in the private headers.
971e7ab3669SDouglas Gregor         PathName.resize(PathLength);
972e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, "PrivateHeaders");
973e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, FileName);
974e7ab3669SDouglas Gregor         File = SourceMgr.getFileManager().getFile(PathName);
975e7ab3669SDouglas Gregor       }
976e7ab3669SDouglas Gregor     } else {
977e7ab3669SDouglas Gregor       // Lookup for normal headers.
978e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
979e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
980e7ab3669SDouglas Gregor     }
981e7ab3669SDouglas Gregor   }
9825257fc63SDouglas Gregor 
9835257fc63SDouglas Gregor   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
9845257fc63SDouglas Gregor   // Come up with a lazy way to do this.
985e7ab3669SDouglas Gregor   if (File) {
9865257fc63SDouglas Gregor     if (const Module *OwningModule = Map.Headers[File]) {
9875257fc63SDouglas Gregor       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
9885257fc63SDouglas Gregor         << FileName << OwningModule->getFullModuleName();
9895257fc63SDouglas Gregor       HadError = true;
9905257fc63SDouglas Gregor     } else {
9915257fc63SDouglas Gregor       // Record this file.
992a89c5ac4SDouglas Gregor       Map.addHeader(ActiveModule, File);
9935257fc63SDouglas Gregor     }
9945257fc63SDouglas Gregor   } else {
9955257fc63SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
9965257fc63SDouglas Gregor       << false << FileName;
9975257fc63SDouglas Gregor     HadError = true;
9985257fc63SDouglas Gregor   }
999718292f2SDouglas Gregor }
1000718292f2SDouglas Gregor 
10012b82c2a5SDouglas Gregor /// \brief Parse a module export declaration.
10022b82c2a5SDouglas Gregor ///
10032b82c2a5SDouglas Gregor ///   export-declaration:
10042b82c2a5SDouglas Gregor ///     'export' wildcard-module-id
10052b82c2a5SDouglas Gregor ///
10062b82c2a5SDouglas Gregor ///   wildcard-module-id:
10072b82c2a5SDouglas Gregor ///     identifier
10082b82c2a5SDouglas Gregor ///     '*'
10092b82c2a5SDouglas Gregor ///     identifier '.' wildcard-module-id
10102b82c2a5SDouglas Gregor void ModuleMapParser::parseExportDecl() {
10112b82c2a5SDouglas Gregor   assert(Tok.is(MMToken::ExportKeyword));
10122b82c2a5SDouglas Gregor   SourceLocation ExportLoc = consumeToken();
10132b82c2a5SDouglas Gregor 
10142b82c2a5SDouglas Gregor   // Parse the module-id with an optional wildcard at the end.
10152b82c2a5SDouglas Gregor   ModuleId ParsedModuleId;
10162b82c2a5SDouglas Gregor   bool Wildcard = false;
10172b82c2a5SDouglas Gregor   do {
10182b82c2a5SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
10192b82c2a5SDouglas Gregor       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
10202b82c2a5SDouglas Gregor                                               Tok.getLocation()));
10212b82c2a5SDouglas Gregor       consumeToken();
10222b82c2a5SDouglas Gregor 
10232b82c2a5SDouglas Gregor       if (Tok.is(MMToken::Period)) {
10242b82c2a5SDouglas Gregor         consumeToken();
10252b82c2a5SDouglas Gregor         continue;
10262b82c2a5SDouglas Gregor       }
10272b82c2a5SDouglas Gregor 
10282b82c2a5SDouglas Gregor       break;
10292b82c2a5SDouglas Gregor     }
10302b82c2a5SDouglas Gregor 
10312b82c2a5SDouglas Gregor     if(Tok.is(MMToken::Star)) {
10322b82c2a5SDouglas Gregor       Wildcard = true;
1033f5eedd05SDouglas Gregor       consumeToken();
10342b82c2a5SDouglas Gregor       break;
10352b82c2a5SDouglas Gregor     }
10362b82c2a5SDouglas Gregor 
10372b82c2a5SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
10382b82c2a5SDouglas Gregor     HadError = true;
10392b82c2a5SDouglas Gregor     return;
10402b82c2a5SDouglas Gregor   } while (true);
10412b82c2a5SDouglas Gregor 
10422b82c2a5SDouglas Gregor   Module::UnresolvedExportDecl Unresolved = {
10432b82c2a5SDouglas Gregor     ExportLoc, ParsedModuleId, Wildcard
10442b82c2a5SDouglas Gregor   };
10452b82c2a5SDouglas Gregor   ActiveModule->UnresolvedExports.push_back(Unresolved);
10462b82c2a5SDouglas Gregor }
10472b82c2a5SDouglas Gregor 
104873441091SDouglas Gregor void ModuleMapParser::parseInferredSubmoduleDecl(bool Explicit) {
104973441091SDouglas Gregor   assert(Tok.is(MMToken::Star));
105073441091SDouglas Gregor   SourceLocation StarLoc = consumeToken();
105173441091SDouglas Gregor   bool Failed = false;
105273441091SDouglas Gregor 
105373441091SDouglas Gregor   // Inferred modules must be submodules.
105473441091SDouglas Gregor   if (!ActiveModule) {
105573441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
105673441091SDouglas Gregor     Failed = true;
105773441091SDouglas Gregor   }
105873441091SDouglas Gregor 
105973441091SDouglas Gregor   // Inferred modules must have umbrella headers.
1060dd005f69SDouglas Gregor   if (!Failed && !ActiveModule->UmbrellaHeader) {
106173441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
106273441091SDouglas Gregor     Failed = true;
106373441091SDouglas Gregor   }
106473441091SDouglas Gregor 
106573441091SDouglas Gregor   // Check for redefinition of an inferred module.
1066dd005f69SDouglas Gregor   if (!Failed && ActiveModule->InferSubmodules) {
106773441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1068dd005f69SDouglas Gregor     if (ActiveModule->InferredSubmoduleLoc.isValid())
1069dd005f69SDouglas Gregor       Diags.Report(ActiveModule->InferredSubmoduleLoc,
107073441091SDouglas Gregor                    diag::note_mmap_prev_definition);
107173441091SDouglas Gregor     Failed = true;
107273441091SDouglas Gregor   }
107373441091SDouglas Gregor 
107473441091SDouglas Gregor   // If there were any problems with this inferred submodule, skip its body.
107573441091SDouglas Gregor   if (Failed) {
107673441091SDouglas Gregor     if (Tok.is(MMToken::LBrace)) {
107773441091SDouglas Gregor       consumeToken();
107873441091SDouglas Gregor       skipUntil(MMToken::RBrace);
107973441091SDouglas Gregor       if (Tok.is(MMToken::RBrace))
108073441091SDouglas Gregor         consumeToken();
108173441091SDouglas Gregor     }
108273441091SDouglas Gregor     HadError = true;
108373441091SDouglas Gregor     return;
108473441091SDouglas Gregor   }
108573441091SDouglas Gregor 
108673441091SDouglas Gregor   // Note that we have an inferred submodule.
1087dd005f69SDouglas Gregor   ActiveModule->InferSubmodules = true;
1088dd005f69SDouglas Gregor   ActiveModule->InferredSubmoduleLoc = StarLoc;
1089dd005f69SDouglas Gregor   ActiveModule->InferExplicitSubmodules = Explicit;
109073441091SDouglas Gregor 
109173441091SDouglas Gregor   // Parse the opening brace.
109273441091SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
109373441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
109473441091SDouglas Gregor     HadError = true;
109573441091SDouglas Gregor     return;
109673441091SDouglas Gregor   }
109773441091SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
109873441091SDouglas Gregor 
109973441091SDouglas Gregor   // Parse the body of the inferred submodule.
110073441091SDouglas Gregor   bool Done = false;
110173441091SDouglas Gregor   do {
110273441091SDouglas Gregor     switch (Tok.Kind) {
110373441091SDouglas Gregor     case MMToken::EndOfFile:
110473441091SDouglas Gregor     case MMToken::RBrace:
110573441091SDouglas Gregor       Done = true;
110673441091SDouglas Gregor       break;
110773441091SDouglas Gregor 
110873441091SDouglas Gregor     case MMToken::ExportKeyword: {
110973441091SDouglas Gregor       consumeToken();
111073441091SDouglas Gregor       if (Tok.is(MMToken::Star))
1111dd005f69SDouglas Gregor         ActiveModule->InferExportWildcard = true;
111273441091SDouglas Gregor       else
111373441091SDouglas Gregor         Diags.Report(Tok.getLocation(),
111473441091SDouglas Gregor                      diag::err_mmap_expected_export_wildcard);
111573441091SDouglas Gregor       consumeToken();
111673441091SDouglas Gregor       break;
111773441091SDouglas Gregor     }
111873441091SDouglas Gregor 
111973441091SDouglas Gregor     case MMToken::ExplicitKeyword:
112073441091SDouglas Gregor     case MMToken::ModuleKeyword:
112173441091SDouglas Gregor     case MMToken::HeaderKeyword:
112273441091SDouglas Gregor     case MMToken::UmbrellaKeyword:
112373441091SDouglas Gregor     default:
112473441091SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_wildcard_member);
112573441091SDouglas Gregor       consumeToken();
112673441091SDouglas Gregor       break;
112773441091SDouglas Gregor     }
112873441091SDouglas Gregor   } while (!Done);
112973441091SDouglas Gregor 
113073441091SDouglas Gregor   if (Tok.is(MMToken::RBrace))
113173441091SDouglas Gregor     consumeToken();
113273441091SDouglas Gregor   else {
113373441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
113473441091SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
113573441091SDouglas Gregor     HadError = true;
113673441091SDouglas Gregor   }
113773441091SDouglas Gregor }
113873441091SDouglas Gregor 
1139718292f2SDouglas Gregor /// \brief Parse a module map file.
1140718292f2SDouglas Gregor ///
1141718292f2SDouglas Gregor ///   module-map-file:
1142718292f2SDouglas Gregor ///     module-declaration*
1143718292f2SDouglas Gregor bool ModuleMapParser::parseModuleMapFile() {
1144718292f2SDouglas Gregor   do {
1145718292f2SDouglas Gregor     switch (Tok.Kind) {
1146718292f2SDouglas Gregor     case MMToken::EndOfFile:
1147718292f2SDouglas Gregor       return HadError;
1148718292f2SDouglas Gregor 
1149e7ab3669SDouglas Gregor     case MMToken::ExplicitKeyword:
1150718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
1151755b2055SDouglas Gregor     case MMToken::FrameworkKeyword:
1152718292f2SDouglas Gregor       parseModuleDecl();
1153718292f2SDouglas Gregor       break;
1154718292f2SDouglas Gregor 
11552b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
1156718292f2SDouglas Gregor     case MMToken::HeaderKeyword:
1157718292f2SDouglas Gregor     case MMToken::Identifier:
1158718292f2SDouglas Gregor     case MMToken::LBrace:
11592b82c2a5SDouglas Gregor     case MMToken::Period:
1160718292f2SDouglas Gregor     case MMToken::RBrace:
11612b82c2a5SDouglas Gregor     case MMToken::Star:
1162718292f2SDouglas Gregor     case MMToken::StringLiteral:
1163718292f2SDouglas Gregor     case MMToken::UmbrellaKeyword:
1164718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1165718292f2SDouglas Gregor       HadError = true;
1166718292f2SDouglas Gregor       consumeToken();
1167718292f2SDouglas Gregor       break;
1168718292f2SDouglas Gregor     }
1169718292f2SDouglas Gregor   } while (true);
1170718292f2SDouglas Gregor 
1171718292f2SDouglas Gregor   return HadError;
1172718292f2SDouglas Gregor }
1173718292f2SDouglas Gregor 
1174718292f2SDouglas Gregor bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
1175718292f2SDouglas Gregor   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1176718292f2SDouglas Gregor   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1177718292f2SDouglas Gregor   if (!Buffer)
1178718292f2SDouglas Gregor     return true;
1179718292f2SDouglas Gregor 
1180718292f2SDouglas Gregor   // Parse this module map file.
1181718292f2SDouglas Gregor   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, LangOpts);
1182718292f2SDouglas Gregor   Diags->getClient()->BeginSourceFile(LangOpts);
11835257fc63SDouglas Gregor   ModuleMapParser Parser(L, *SourceMgr, *Diags, *this, File->getDir());
1184718292f2SDouglas Gregor   bool Result = Parser.parseModuleMapFile();
1185718292f2SDouglas Gregor   Diags->getClient()->EndSourceFile();
1186718292f2SDouglas Gregor 
1187718292f2SDouglas Gregor   return Result;
1188718292f2SDouglas Gregor }
1189