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"
15a7d03840SJordan Rose #include "clang/Basic/CharInfo.h"
16718292f2SDouglas Gregor #include "clang/Basic/Diagnostic.h"
17811db4eaSDouglas Gregor #include "clang/Basic/DiagnosticOptions.h"
18718292f2SDouglas Gregor #include "clang/Basic/FileManager.h"
19718292f2SDouglas Gregor #include "clang/Basic/TargetInfo.h"
20718292f2SDouglas Gregor #include "clang/Basic/TargetOptions.h"
213a02247dSChandler Carruth #include "clang/Lex/LexDiagnostic.h"
223a02247dSChandler Carruth #include "clang/Lex/Lexer.h"
233a02247dSChandler Carruth #include "clang/Lex/LiteralSupport.h"
243a02247dSChandler Carruth #include "llvm/ADT/StringRef.h"
253a02247dSChandler Carruth #include "llvm/ADT/StringSwitch.h"
26718292f2SDouglas Gregor #include "llvm/Support/Allocator.h"
27e89dbc1dSDouglas Gregor #include "llvm/Support/FileSystem.h"
28718292f2SDouglas Gregor #include "llvm/Support/Host.h"
295257fc63SDouglas Gregor #include "llvm/Support/PathV2.h"
30718292f2SDouglas Gregor #include "llvm/Support/raw_ostream.h"
3107c22b78SDouglas Gregor #include <stdlib.h>
3201c7cfa2SDouglas Gregor #if defined(LLVM_ON_UNIX)
33eadae014SDmitri Gribenko #include <limits.h>
3401c7cfa2SDouglas Gregor #endif
35718292f2SDouglas Gregor using namespace clang;
36718292f2SDouglas Gregor 
372b82c2a5SDouglas Gregor Module::ExportDecl
382b82c2a5SDouglas Gregor ModuleMap::resolveExport(Module *Mod,
392b82c2a5SDouglas Gregor                          const Module::UnresolvedExportDecl &Unresolved,
40*e4412640SArgyrios Kyrtzidis                          bool Complain) const {
41f5eedd05SDouglas Gregor   // We may have just a wildcard.
42f5eedd05SDouglas Gregor   if (Unresolved.Id.empty()) {
43f5eedd05SDouglas Gregor     assert(Unresolved.Wildcard && "Invalid unresolved export");
44f5eedd05SDouglas Gregor     return Module::ExportDecl(0, true);
45f5eedd05SDouglas Gregor   }
46f5eedd05SDouglas Gregor 
472b82c2a5SDouglas Gregor   // Find the starting module.
482b82c2a5SDouglas Gregor   Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
492b82c2a5SDouglas Gregor   if (!Context) {
502b82c2a5SDouglas Gregor     if (Complain)
512b82c2a5SDouglas Gregor       Diags->Report(Unresolved.Id[0].second,
522b82c2a5SDouglas Gregor                     diag::err_mmap_missing_module_unqualified)
532b82c2a5SDouglas Gregor         << Unresolved.Id[0].first << Mod->getFullModuleName();
542b82c2a5SDouglas Gregor 
552b82c2a5SDouglas Gregor     return Module::ExportDecl();
562b82c2a5SDouglas Gregor   }
572b82c2a5SDouglas Gregor 
582b82c2a5SDouglas Gregor   // Dig into the module path.
592b82c2a5SDouglas Gregor   for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
602b82c2a5SDouglas Gregor     Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
612b82c2a5SDouglas Gregor                                         Context);
622b82c2a5SDouglas Gregor     if (!Sub) {
632b82c2a5SDouglas Gregor       if (Complain)
642b82c2a5SDouglas Gregor         Diags->Report(Unresolved.Id[I].second,
652b82c2a5SDouglas Gregor                       diag::err_mmap_missing_module_qualified)
662b82c2a5SDouglas Gregor           << Unresolved.Id[I].first << Context->getFullModuleName()
672b82c2a5SDouglas Gregor           << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
682b82c2a5SDouglas Gregor 
692b82c2a5SDouglas Gregor       return Module::ExportDecl();
702b82c2a5SDouglas Gregor     }
712b82c2a5SDouglas Gregor 
722b82c2a5SDouglas Gregor     Context = Sub;
732b82c2a5SDouglas Gregor   }
742b82c2a5SDouglas Gregor 
752b82c2a5SDouglas Gregor   return Module::ExportDecl(Context, Unresolved.Wildcard);
762b82c2a5SDouglas Gregor }
772b82c2a5SDouglas Gregor 
781fb5c3a6SDouglas Gregor ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
7989929282SDouglas Gregor                      const LangOptions &LangOpts, const TargetInfo *Target)
803ec6663bSDouglas Gregor   : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0)
811fb5c3a6SDouglas Gregor {
82c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
83c95d8192SDylan Noblesmith   Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
84811db4eaSDouglas Gregor             new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
85718292f2SDouglas Gregor   Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
86718292f2SDouglas Gregor   SourceMgr = new SourceManager(*Diags, FileMgr);
87718292f2SDouglas Gregor }
88718292f2SDouglas Gregor 
89718292f2SDouglas Gregor ModuleMap::~ModuleMap() {
905acdf59eSDouglas Gregor   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
915acdf59eSDouglas Gregor                                         IEnd = Modules.end();
925acdf59eSDouglas Gregor        I != IEnd; ++I) {
935acdf59eSDouglas Gregor     delete I->getValue();
945acdf59eSDouglas Gregor   }
955acdf59eSDouglas Gregor 
96718292f2SDouglas Gregor   delete SourceMgr;
97718292f2SDouglas Gregor }
98718292f2SDouglas Gregor 
9989929282SDouglas Gregor void ModuleMap::setTarget(const TargetInfo &Target) {
10089929282SDouglas Gregor   assert((!this->Target || this->Target == &Target) &&
10189929282SDouglas Gregor          "Improper target override");
10289929282SDouglas Gregor   this->Target = &Target;
10389929282SDouglas Gregor }
10489929282SDouglas Gregor 
105056396aeSDouglas Gregor /// \brief "Sanitize" a filename so that it can be used as an identifier.
106056396aeSDouglas Gregor static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
107056396aeSDouglas Gregor                                               SmallVectorImpl<char> &Buffer) {
108056396aeSDouglas Gregor   if (Name.empty())
109056396aeSDouglas Gregor     return Name;
110056396aeSDouglas Gregor 
111a7d03840SJordan Rose   if (!isValidIdentifier(Name)) {
112056396aeSDouglas Gregor     // If we don't already have something with the form of an identifier,
113056396aeSDouglas Gregor     // create a buffer with the sanitized name.
114056396aeSDouglas Gregor     Buffer.clear();
115a7d03840SJordan Rose     if (isDigit(Name[0]))
116056396aeSDouglas Gregor       Buffer.push_back('_');
117056396aeSDouglas Gregor     Buffer.reserve(Buffer.size() + Name.size());
118056396aeSDouglas Gregor     for (unsigned I = 0, N = Name.size(); I != N; ++I) {
119a7d03840SJordan Rose       if (isIdentifierBody(Name[I]))
120056396aeSDouglas Gregor         Buffer.push_back(Name[I]);
121056396aeSDouglas Gregor       else
122056396aeSDouglas Gregor         Buffer.push_back('_');
123056396aeSDouglas Gregor     }
124056396aeSDouglas Gregor 
125056396aeSDouglas Gregor     Name = StringRef(Buffer.data(), Buffer.size());
126056396aeSDouglas Gregor   }
127056396aeSDouglas Gregor 
128056396aeSDouglas Gregor   while (llvm::StringSwitch<bool>(Name)
129056396aeSDouglas Gregor #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
130056396aeSDouglas Gregor #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
131056396aeSDouglas Gregor #include "clang/Basic/TokenKinds.def"
132056396aeSDouglas Gregor            .Default(false)) {
133056396aeSDouglas Gregor     if (Name.data() != Buffer.data())
134056396aeSDouglas Gregor       Buffer.append(Name.begin(), Name.end());
135056396aeSDouglas Gregor     Buffer.push_back('_');
136056396aeSDouglas Gregor     Name = StringRef(Buffer.data(), Buffer.size());
137056396aeSDouglas Gregor   }
138056396aeSDouglas Gregor 
139056396aeSDouglas Gregor   return Name;
140056396aeSDouglas Gregor }
141056396aeSDouglas Gregor 
142de3ef502SDouglas Gregor Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
14359527666SDouglas Gregor   HeadersMap::iterator Known = Headers.find(File);
1441fb5c3a6SDouglas Gregor   if (Known != Headers.end()) {
14559527666SDouglas Gregor     // If a header is not available, don't report that it maps to anything.
14659527666SDouglas Gregor     if (!Known->second.isAvailable())
1471fb5c3a6SDouglas Gregor       return 0;
1481fb5c3a6SDouglas Gregor 
14959527666SDouglas Gregor     return Known->second.getModule();
1501fb5c3a6SDouglas Gregor   }
151ab0c8a84SDouglas Gregor 
152b65dbfffSDouglas Gregor   const DirectoryEntry *Dir = File->getDir();
153f857950dSDmitri Gribenko   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
154e00c8b20SDouglas Gregor 
15574260502SDouglas Gregor   // Note: as an egregious but useful hack we use the real path here, because
15674260502SDouglas Gregor   // frameworks moving from top-level frameworks to embedded frameworks tend
15774260502SDouglas Gregor   // to be symlinked from the top-level location to the embedded location,
15874260502SDouglas Gregor   // and we need to resolve lookups as if we had found the embedded location.
159e00c8b20SDouglas Gregor   StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
160a89c5ac4SDouglas Gregor 
161a89c5ac4SDouglas Gregor   // Keep walking up the directory hierarchy, looking for a directory with
162a89c5ac4SDouglas Gregor   // an umbrella header.
163b65dbfffSDouglas Gregor   do {
164a89c5ac4SDouglas Gregor     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
165a89c5ac4SDouglas Gregor       = UmbrellaDirs.find(Dir);
166a89c5ac4SDouglas Gregor     if (KnownDir != UmbrellaDirs.end()) {
167a89c5ac4SDouglas Gregor       Module *Result = KnownDir->second;
168930a85ccSDouglas Gregor 
169930a85ccSDouglas Gregor       // Search up the module stack until we find a module with an umbrella
17073141fa9SDouglas Gregor       // directory.
171930a85ccSDouglas Gregor       Module *UmbrellaModule = Result;
17273141fa9SDouglas Gregor       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
173930a85ccSDouglas Gregor         UmbrellaModule = UmbrellaModule->Parent;
174930a85ccSDouglas Gregor 
175930a85ccSDouglas Gregor       if (UmbrellaModule->InferSubmodules) {
176a89c5ac4SDouglas Gregor         // Infer submodules for each of the directories we found between
177a89c5ac4SDouglas Gregor         // the directory of the umbrella header and the directory where
178a89c5ac4SDouglas Gregor         // the actual header is located.
1799458f82dSDouglas Gregor         bool Explicit = UmbrellaModule->InferExplicitSubmodules;
1809458f82dSDouglas Gregor 
1817033127bSDouglas Gregor         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
182a89c5ac4SDouglas Gregor           // Find or create the module that corresponds to this directory name.
183056396aeSDouglas Gregor           SmallString<32> NameBuf;
184056396aeSDouglas Gregor           StringRef Name = sanitizeFilenameAsIdentifier(
185056396aeSDouglas Gregor                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
186056396aeSDouglas Gregor                              NameBuf);
187a89c5ac4SDouglas Gregor           Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
1889458f82dSDouglas Gregor                                       Explicit).first;
189a89c5ac4SDouglas Gregor 
190a89c5ac4SDouglas Gregor           // Associate the module and the directory.
191a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I-1]] = Result;
192a89c5ac4SDouglas Gregor 
193a89c5ac4SDouglas Gregor           // If inferred submodules export everything they import, add a
194a89c5ac4SDouglas Gregor           // wildcard to the set of exports.
195930a85ccSDouglas Gregor           if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
196a89c5ac4SDouglas Gregor             Result->Exports.push_back(Module::ExportDecl(0, true));
197a89c5ac4SDouglas Gregor         }
198a89c5ac4SDouglas Gregor 
199a89c5ac4SDouglas Gregor         // Infer a submodule with the same name as this header file.
200056396aeSDouglas Gregor         SmallString<32> NameBuf;
201056396aeSDouglas Gregor         StringRef Name = sanitizeFilenameAsIdentifier(
202056396aeSDouglas Gregor                            llvm::sys::path::stem(File->getName()), NameBuf);
203a89c5ac4SDouglas Gregor         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
2049458f82dSDouglas Gregor                                     Explicit).first;
205c597c8c4SArgyrios Kyrtzidis         Result->TopHeaders.insert(File);
206a89c5ac4SDouglas Gregor 
207a89c5ac4SDouglas Gregor         // If inferred submodules export everything they import, add a
208a89c5ac4SDouglas Gregor         // wildcard to the set of exports.
209930a85ccSDouglas Gregor         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
210a89c5ac4SDouglas Gregor           Result->Exports.push_back(Module::ExportDecl(0, true));
211a89c5ac4SDouglas Gregor       } else {
212a89c5ac4SDouglas Gregor         // Record each of the directories we stepped through as being part of
213a89c5ac4SDouglas Gregor         // the module we found, since the umbrella header covers them all.
214a89c5ac4SDouglas Gregor         for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
215a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I]] = Result;
216a89c5ac4SDouglas Gregor       }
217a89c5ac4SDouglas Gregor 
21859527666SDouglas Gregor       Headers[File] = KnownHeader(Result, /*Excluded=*/false);
2191fb5c3a6SDouglas Gregor 
2201fb5c3a6SDouglas Gregor       // If a header corresponds to an unavailable module, don't report
2211fb5c3a6SDouglas Gregor       // that it maps to anything.
2221fb5c3a6SDouglas Gregor       if (!Result->isAvailable())
2231fb5c3a6SDouglas Gregor         return 0;
2241fb5c3a6SDouglas Gregor 
225a89c5ac4SDouglas Gregor       return Result;
226a89c5ac4SDouglas Gregor     }
227a89c5ac4SDouglas Gregor 
228a89c5ac4SDouglas Gregor     SkippedDirs.push_back(Dir);
229a89c5ac4SDouglas Gregor 
230b65dbfffSDouglas Gregor     // Retrieve our parent path.
231b65dbfffSDouglas Gregor     DirName = llvm::sys::path::parent_path(DirName);
232b65dbfffSDouglas Gregor     if (DirName.empty())
233b65dbfffSDouglas Gregor       break;
234b65dbfffSDouglas Gregor 
235b65dbfffSDouglas Gregor     // Resolve the parent path to a directory entry.
236b65dbfffSDouglas Gregor     Dir = SourceMgr->getFileManager().getDirectory(DirName);
237a89c5ac4SDouglas Gregor   } while (Dir);
238b65dbfffSDouglas Gregor 
239ab0c8a84SDouglas Gregor   return 0;
240ab0c8a84SDouglas Gregor }
241ab0c8a84SDouglas Gregor 
242*e4412640SArgyrios Kyrtzidis bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
243*e4412640SArgyrios Kyrtzidis   HeadersMap::const_iterator Known = Headers.find(Header);
2441fb5c3a6SDouglas Gregor   if (Known != Headers.end())
24559527666SDouglas Gregor     return !Known->second.isAvailable();
2461fb5c3a6SDouglas Gregor 
2471fb5c3a6SDouglas Gregor   const DirectoryEntry *Dir = Header->getDir();
248f857950dSDmitri Gribenko   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
2491fb5c3a6SDouglas Gregor   StringRef DirName = Dir->getName();
2501fb5c3a6SDouglas Gregor 
2511fb5c3a6SDouglas Gregor   // Keep walking up the directory hierarchy, looking for a directory with
2521fb5c3a6SDouglas Gregor   // an umbrella header.
2531fb5c3a6SDouglas Gregor   do {
254*e4412640SArgyrios Kyrtzidis     llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
2551fb5c3a6SDouglas Gregor       = UmbrellaDirs.find(Dir);
2561fb5c3a6SDouglas Gregor     if (KnownDir != UmbrellaDirs.end()) {
2571fb5c3a6SDouglas Gregor       Module *Found = KnownDir->second;
2581fb5c3a6SDouglas Gregor       if (!Found->isAvailable())
2591fb5c3a6SDouglas Gregor         return true;
2601fb5c3a6SDouglas Gregor 
2611fb5c3a6SDouglas Gregor       // Search up the module stack until we find a module with an umbrella
2621fb5c3a6SDouglas Gregor       // directory.
2631fb5c3a6SDouglas Gregor       Module *UmbrellaModule = Found;
2641fb5c3a6SDouglas Gregor       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
2651fb5c3a6SDouglas Gregor         UmbrellaModule = UmbrellaModule->Parent;
2661fb5c3a6SDouglas Gregor 
2671fb5c3a6SDouglas Gregor       if (UmbrellaModule->InferSubmodules) {
2681fb5c3a6SDouglas Gregor         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
2691fb5c3a6SDouglas Gregor           // Find or create the module that corresponds to this directory name.
270056396aeSDouglas Gregor           SmallString<32> NameBuf;
271056396aeSDouglas Gregor           StringRef Name = sanitizeFilenameAsIdentifier(
272056396aeSDouglas Gregor                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
273056396aeSDouglas Gregor                              NameBuf);
2741fb5c3a6SDouglas Gregor           Found = lookupModuleQualified(Name, Found);
2751fb5c3a6SDouglas Gregor           if (!Found)
2761fb5c3a6SDouglas Gregor             return false;
2771fb5c3a6SDouglas Gregor           if (!Found->isAvailable())
2781fb5c3a6SDouglas Gregor             return true;
2791fb5c3a6SDouglas Gregor         }
2801fb5c3a6SDouglas Gregor 
2811fb5c3a6SDouglas Gregor         // Infer a submodule with the same name as this header file.
282056396aeSDouglas Gregor         SmallString<32> NameBuf;
283056396aeSDouglas Gregor         StringRef Name = sanitizeFilenameAsIdentifier(
284056396aeSDouglas Gregor                            llvm::sys::path::stem(Header->getName()),
285056396aeSDouglas Gregor                            NameBuf);
2861fb5c3a6SDouglas Gregor         Found = lookupModuleQualified(Name, Found);
2871fb5c3a6SDouglas Gregor         if (!Found)
2881fb5c3a6SDouglas Gregor           return false;
2891fb5c3a6SDouglas Gregor       }
2901fb5c3a6SDouglas Gregor 
2911fb5c3a6SDouglas Gregor       return !Found->isAvailable();
2921fb5c3a6SDouglas Gregor     }
2931fb5c3a6SDouglas Gregor 
2941fb5c3a6SDouglas Gregor     SkippedDirs.push_back(Dir);
2951fb5c3a6SDouglas Gregor 
2961fb5c3a6SDouglas Gregor     // Retrieve our parent path.
2971fb5c3a6SDouglas Gregor     DirName = llvm::sys::path::parent_path(DirName);
2981fb5c3a6SDouglas Gregor     if (DirName.empty())
2991fb5c3a6SDouglas Gregor       break;
3001fb5c3a6SDouglas Gregor 
3011fb5c3a6SDouglas Gregor     // Resolve the parent path to a directory entry.
3021fb5c3a6SDouglas Gregor     Dir = SourceMgr->getFileManager().getDirectory(DirName);
3031fb5c3a6SDouglas Gregor   } while (Dir);
3041fb5c3a6SDouglas Gregor 
3051fb5c3a6SDouglas Gregor   return false;
3061fb5c3a6SDouglas Gregor }
3071fb5c3a6SDouglas Gregor 
308*e4412640SArgyrios Kyrtzidis Module *ModuleMap::findModule(StringRef Name) const {
309*e4412640SArgyrios Kyrtzidis   llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
31088bdfb0eSDouglas Gregor   if (Known != Modules.end())
31188bdfb0eSDouglas Gregor     return Known->getValue();
31288bdfb0eSDouglas Gregor 
31388bdfb0eSDouglas Gregor   return 0;
31488bdfb0eSDouglas Gregor }
31588bdfb0eSDouglas Gregor 
316*e4412640SArgyrios Kyrtzidis Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
317*e4412640SArgyrios Kyrtzidis                                            Module *Context) const {
3182b82c2a5SDouglas Gregor   for(; Context; Context = Context->Parent) {
3192b82c2a5SDouglas Gregor     if (Module *Sub = lookupModuleQualified(Name, Context))
3202b82c2a5SDouglas Gregor       return Sub;
3212b82c2a5SDouglas Gregor   }
3222b82c2a5SDouglas Gregor 
3232b82c2a5SDouglas Gregor   return findModule(Name);
3242b82c2a5SDouglas Gregor }
3252b82c2a5SDouglas Gregor 
326*e4412640SArgyrios Kyrtzidis Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
3272b82c2a5SDouglas Gregor   if (!Context)
3282b82c2a5SDouglas Gregor     return findModule(Name);
3292b82c2a5SDouglas Gregor 
330eb90e830SDouglas Gregor   return Context->findSubmodule(Name);
3312b82c2a5SDouglas Gregor }
3322b82c2a5SDouglas Gregor 
333de3ef502SDouglas Gregor std::pair<Module *, bool>
33469021974SDouglas Gregor ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
33569021974SDouglas Gregor                               bool IsExplicit) {
33669021974SDouglas Gregor   // Try to find an existing module with this name.
337eb90e830SDouglas Gregor   if (Module *Sub = lookupModuleQualified(Name, Parent))
338eb90e830SDouglas Gregor     return std::make_pair(Sub, false);
33969021974SDouglas Gregor 
34069021974SDouglas Gregor   // Create a new module with this name.
34169021974SDouglas Gregor   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
34269021974SDouglas Gregor                               IsExplicit);
343eb90e830SDouglas Gregor   if (!Parent)
34469021974SDouglas Gregor     Modules[Name] = Result;
34569021974SDouglas Gregor   return std::make_pair(Result, true);
34669021974SDouglas Gregor }
34769021974SDouglas Gregor 
3489194a91dSDouglas Gregor bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
349*e4412640SArgyrios Kyrtzidis                                         StringRef Name, bool &IsSystem) const {
3509194a91dSDouglas Gregor   // Check whether we have already looked into the parent directory
3519194a91dSDouglas Gregor   // for a module map.
352*e4412640SArgyrios Kyrtzidis   llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
3539194a91dSDouglas Gregor     inferred = InferredDirectories.find(ParentDir);
3549194a91dSDouglas Gregor   if (inferred == InferredDirectories.end())
3559194a91dSDouglas Gregor     return false;
3569194a91dSDouglas Gregor 
3579194a91dSDouglas Gregor   if (!inferred->second.InferModules)
3589194a91dSDouglas Gregor     return false;
3599194a91dSDouglas Gregor 
3609194a91dSDouglas Gregor   // We're allowed to infer for this directory, but make sure it's okay
3619194a91dSDouglas Gregor   // to infer this particular module.
3629194a91dSDouglas Gregor   bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
3639194a91dSDouglas Gregor                             inferred->second.ExcludedModules.end(),
3649194a91dSDouglas Gregor                             Name) == inferred->second.ExcludedModules.end();
3659194a91dSDouglas Gregor 
3669194a91dSDouglas Gregor   if (canInfer && inferred->second.InferSystemModules)
3679194a91dSDouglas Gregor     IsSystem = true;
3689194a91dSDouglas Gregor 
3699194a91dSDouglas Gregor   return canInfer;
3709194a91dSDouglas Gregor }
3719194a91dSDouglas Gregor 
37211dfe6feSDouglas Gregor /// \brief For a framework module, infer the framework against which we
37311dfe6feSDouglas Gregor /// should link.
37411dfe6feSDouglas Gregor static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
37511dfe6feSDouglas Gregor                                FileManager &FileMgr) {
37611dfe6feSDouglas Gregor   assert(Mod->IsFramework && "Can only infer linking for framework modules");
37711dfe6feSDouglas Gregor   assert(!Mod->isSubFramework() &&
37811dfe6feSDouglas Gregor          "Can only infer linking for top-level frameworks");
37911dfe6feSDouglas Gregor 
38011dfe6feSDouglas Gregor   SmallString<128> LibName;
38111dfe6feSDouglas Gregor   LibName += FrameworkDir->getName();
38211dfe6feSDouglas Gregor   llvm::sys::path::append(LibName, Mod->Name);
38311dfe6feSDouglas Gregor   if (FileMgr.getFile(LibName)) {
38411dfe6feSDouglas Gregor     Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
38511dfe6feSDouglas Gregor                                                      /*IsFramework=*/true));
38611dfe6feSDouglas Gregor   }
38711dfe6feSDouglas Gregor }
38811dfe6feSDouglas Gregor 
389de3ef502SDouglas Gregor Module *
39056c64013SDouglas Gregor ModuleMap::inferFrameworkModule(StringRef ModuleName,
391e89dbc1dSDouglas Gregor                                 const DirectoryEntry *FrameworkDir,
392a686e1b0SDouglas Gregor                                 bool IsSystem,
393e89dbc1dSDouglas Gregor                                 Module *Parent) {
39456c64013SDouglas Gregor   // Check whether we've already found this module.
395e89dbc1dSDouglas Gregor   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
396e89dbc1dSDouglas Gregor     return Mod;
397e89dbc1dSDouglas Gregor 
398e89dbc1dSDouglas Gregor   FileManager &FileMgr = SourceMgr->getFileManager();
39956c64013SDouglas Gregor 
4009194a91dSDouglas Gregor   // If the framework has a parent path from which we're allowed to infer
4019194a91dSDouglas Gregor   // a framework module, do so.
4029194a91dSDouglas Gregor   if (!Parent) {
4034ddf2221SDouglas Gregor     // Determine whether we're allowed to infer a module map.
404e00c8b20SDouglas Gregor 
4054ddf2221SDouglas Gregor     // Note: as an egregious but useful hack we use the real path here, because
4064ddf2221SDouglas Gregor     // we might be looking at an embedded framework that symlinks out to a
4074ddf2221SDouglas Gregor     // top-level framework, and we need to infer as if we were naming the
4084ddf2221SDouglas Gregor     // top-level framework.
409e00c8b20SDouglas Gregor     StringRef FrameworkDirName
410e00c8b20SDouglas Gregor       = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
4114ddf2221SDouglas Gregor 
4129194a91dSDouglas Gregor     bool canInfer = false;
4134ddf2221SDouglas Gregor     if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
4149194a91dSDouglas Gregor       // Figure out the parent path.
4154ddf2221SDouglas Gregor       StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
4169194a91dSDouglas Gregor       if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
4179194a91dSDouglas Gregor         // Check whether we have already looked into the parent directory
4189194a91dSDouglas Gregor         // for a module map.
419*e4412640SArgyrios Kyrtzidis         llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
4209194a91dSDouglas Gregor           inferred = InferredDirectories.find(ParentDir);
4219194a91dSDouglas Gregor         if (inferred == InferredDirectories.end()) {
4229194a91dSDouglas Gregor           // We haven't looked here before. Load a module map, if there is
4239194a91dSDouglas Gregor           // one.
4249194a91dSDouglas Gregor           SmallString<128> ModMapPath = Parent;
4259194a91dSDouglas Gregor           llvm::sys::path::append(ModMapPath, "module.map");
4269194a91dSDouglas Gregor           if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
4279194a91dSDouglas Gregor             parseModuleMapFile(ModMapFile);
4289194a91dSDouglas Gregor             inferred = InferredDirectories.find(ParentDir);
4299194a91dSDouglas Gregor           }
4309194a91dSDouglas Gregor 
4319194a91dSDouglas Gregor           if (inferred == InferredDirectories.end())
4329194a91dSDouglas Gregor             inferred = InferredDirectories.insert(
4339194a91dSDouglas Gregor                          std::make_pair(ParentDir, InferredDirectory())).first;
4349194a91dSDouglas Gregor         }
4359194a91dSDouglas Gregor 
4369194a91dSDouglas Gregor         if (inferred->second.InferModules) {
4379194a91dSDouglas Gregor           // We're allowed to infer for this directory, but make sure it's okay
4389194a91dSDouglas Gregor           // to infer this particular module.
4394ddf2221SDouglas Gregor           StringRef Name = llvm::sys::path::stem(FrameworkDirName);
4409194a91dSDouglas Gregor           canInfer = std::find(inferred->second.ExcludedModules.begin(),
4419194a91dSDouglas Gregor                                inferred->second.ExcludedModules.end(),
4429194a91dSDouglas Gregor                                Name) == inferred->second.ExcludedModules.end();
4439194a91dSDouglas Gregor 
4449194a91dSDouglas Gregor           if (inferred->second.InferSystemModules)
4459194a91dSDouglas Gregor             IsSystem = true;
4469194a91dSDouglas Gregor         }
4479194a91dSDouglas Gregor       }
4489194a91dSDouglas Gregor     }
4499194a91dSDouglas Gregor 
4509194a91dSDouglas Gregor     // If we're not allowed to infer a framework module, don't.
4519194a91dSDouglas Gregor     if (!canInfer)
4529194a91dSDouglas Gregor       return 0;
4539194a91dSDouglas Gregor   }
4549194a91dSDouglas Gregor 
4559194a91dSDouglas Gregor 
45656c64013SDouglas Gregor   // Look for an umbrella header.
4572c1dd271SDylan Noblesmith   SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
45856c64013SDouglas Gregor   llvm::sys::path::append(UmbrellaName, "Headers");
45956c64013SDouglas Gregor   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
460e89dbc1dSDouglas Gregor   const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
46156c64013SDouglas Gregor 
46256c64013SDouglas Gregor   // FIXME: If there's no umbrella header, we could probably scan the
46356c64013SDouglas Gregor   // framework to load *everything*. But, it's not clear that this is a good
46456c64013SDouglas Gregor   // idea.
46556c64013SDouglas Gregor   if (!UmbrellaHeader)
46656c64013SDouglas Gregor     return 0;
46756c64013SDouglas Gregor 
468e89dbc1dSDouglas Gregor   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
469e89dbc1dSDouglas Gregor                               /*IsFramework=*/true, /*IsExplicit=*/false);
470a686e1b0SDouglas Gregor   if (IsSystem)
471a686e1b0SDouglas Gregor     Result->IsSystem = IsSystem;
472a686e1b0SDouglas Gregor 
473eb90e830SDouglas Gregor   if (!Parent)
474e89dbc1dSDouglas Gregor     Modules[ModuleName] = Result;
475e89dbc1dSDouglas Gregor 
476322f633cSDouglas Gregor   // umbrella header "umbrella-header-name"
47773141fa9SDouglas Gregor   Result->Umbrella = UmbrellaHeader;
47859527666SDouglas Gregor   Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
4794dc71835SDouglas Gregor   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
480d8bd7537SDouglas Gregor 
481d8bd7537SDouglas Gregor   // export *
482d8bd7537SDouglas Gregor   Result->Exports.push_back(Module::ExportDecl(0, true));
483d8bd7537SDouglas Gregor 
484a89c5ac4SDouglas Gregor   // module * { export * }
485a89c5ac4SDouglas Gregor   Result->InferSubmodules = true;
486a89c5ac4SDouglas Gregor   Result->InferExportWildcard = true;
487a89c5ac4SDouglas Gregor 
488e89dbc1dSDouglas Gregor   // Look for subframeworks.
489e89dbc1dSDouglas Gregor   llvm::error_code EC;
4902c1dd271SDylan Noblesmith   SmallString<128> SubframeworksDirName
491ddaa69cbSDouglas Gregor     = StringRef(FrameworkDir->getName());
492e89dbc1dSDouglas Gregor   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
4932c1dd271SDylan Noblesmith   SmallString<128> SubframeworksDirNameNative;
494ddaa69cbSDouglas Gregor   llvm::sys::path::native(SubframeworksDirName.str(),
495ddaa69cbSDouglas Gregor                           SubframeworksDirNameNative);
496ddaa69cbSDouglas Gregor   for (llvm::sys::fs::directory_iterator
497ddaa69cbSDouglas Gregor          Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
498e89dbc1dSDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
499e89dbc1dSDouglas Gregor     if (!StringRef(Dir->path()).endswith(".framework"))
500e89dbc1dSDouglas Gregor       continue;
501f2161a70SDouglas Gregor 
502e89dbc1dSDouglas Gregor     if (const DirectoryEntry *SubframeworkDir
503e89dbc1dSDouglas Gregor           = FileMgr.getDirectory(Dir->path())) {
50407c22b78SDouglas Gregor       // Note: as an egregious but useful hack, we use the real path here and
50507c22b78SDouglas Gregor       // check whether it is actually a subdirectory of the parent directory.
50607c22b78SDouglas Gregor       // This will not be the case if the 'subframework' is actually a symlink
50707c22b78SDouglas Gregor       // out to a top-level framework.
508e00c8b20SDouglas Gregor       StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
50907c22b78SDouglas Gregor       bool FoundParent = false;
51007c22b78SDouglas Gregor       do {
51107c22b78SDouglas Gregor         // Get the parent directory name.
51207c22b78SDouglas Gregor         SubframeworkDirName
51307c22b78SDouglas Gregor           = llvm::sys::path::parent_path(SubframeworkDirName);
51407c22b78SDouglas Gregor         if (SubframeworkDirName.empty())
51507c22b78SDouglas Gregor           break;
51607c22b78SDouglas Gregor 
51707c22b78SDouglas Gregor         if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
51807c22b78SDouglas Gregor           FoundParent = true;
51907c22b78SDouglas Gregor           break;
52007c22b78SDouglas Gregor         }
52107c22b78SDouglas Gregor       } while (true);
52207c22b78SDouglas Gregor 
52307c22b78SDouglas Gregor       if (!FoundParent)
52407c22b78SDouglas Gregor         continue;
52507c22b78SDouglas Gregor 
526e89dbc1dSDouglas Gregor       // FIXME: Do we want to warn about subframeworks without umbrella headers?
527056396aeSDouglas Gregor       SmallString<32> NameBuf;
528056396aeSDouglas Gregor       inferFrameworkModule(sanitizeFilenameAsIdentifier(
529056396aeSDouglas Gregor                              llvm::sys::path::stem(Dir->path()), NameBuf),
530056396aeSDouglas Gregor                            SubframeworkDir, IsSystem, Result);
531e89dbc1dSDouglas Gregor     }
532e89dbc1dSDouglas Gregor   }
533e89dbc1dSDouglas Gregor 
53411dfe6feSDouglas Gregor   // If the module is a top-level framework, automatically link against the
53511dfe6feSDouglas Gregor   // framework.
53611dfe6feSDouglas Gregor   if (!Result->isSubFramework()) {
53711dfe6feSDouglas Gregor     inferFrameworkLink(Result, FrameworkDir, FileMgr);
53811dfe6feSDouglas Gregor   }
53911dfe6feSDouglas Gregor 
54056c64013SDouglas Gregor   return Result;
54156c64013SDouglas Gregor }
54256c64013SDouglas Gregor 
543a89c5ac4SDouglas Gregor void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
54459527666SDouglas Gregor   Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
54573141fa9SDouglas Gregor   Mod->Umbrella = UmbrellaHeader;
5467033127bSDouglas Gregor   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
547a89c5ac4SDouglas Gregor }
548a89c5ac4SDouglas Gregor 
549524e33e1SDouglas Gregor void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
550524e33e1SDouglas Gregor   Mod->Umbrella = UmbrellaDir;
551524e33e1SDouglas Gregor   UmbrellaDirs[UmbrellaDir] = Mod;
552524e33e1SDouglas Gregor }
553524e33e1SDouglas Gregor 
55459527666SDouglas Gregor void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
55559527666SDouglas Gregor                           bool Excluded) {
55659527666SDouglas Gregor   if (Excluded)
55759527666SDouglas Gregor     Mod->ExcludedHeaders.push_back(Header);
55859527666SDouglas Gregor   else
559a89c5ac4SDouglas Gregor     Mod->Headers.push_back(Header);
56059527666SDouglas Gregor   Headers[Header] = KnownHeader(Mod, Excluded);
561a89c5ac4SDouglas Gregor }
562a89c5ac4SDouglas Gregor 
563514b636aSDouglas Gregor const FileEntry *
564*e4412640SArgyrios Kyrtzidis ModuleMap::getContainingModuleMapFile(Module *Module) const {
565514b636aSDouglas Gregor   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
566514b636aSDouglas Gregor     return 0;
567514b636aSDouglas Gregor 
568514b636aSDouglas Gregor   return SourceMgr->getFileEntryForID(
569514b636aSDouglas Gregor            SourceMgr->getFileID(Module->DefinitionLoc));
570514b636aSDouglas Gregor }
571514b636aSDouglas Gregor 
572718292f2SDouglas Gregor void ModuleMap::dump() {
573718292f2SDouglas Gregor   llvm::errs() << "Modules:";
574718292f2SDouglas Gregor   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
575718292f2SDouglas Gregor                                         MEnd = Modules.end();
576718292f2SDouglas Gregor        M != MEnd; ++M)
577d28d1b8dSDouglas Gregor     M->getValue()->print(llvm::errs(), 2);
578718292f2SDouglas Gregor 
579718292f2SDouglas Gregor   llvm::errs() << "Headers:";
58059527666SDouglas Gregor   for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
581718292f2SDouglas Gregor        H != HEnd; ++H) {
582718292f2SDouglas Gregor     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
58359527666SDouglas Gregor                  << H->second.getModule()->getFullModuleName() << "\n";
584718292f2SDouglas Gregor   }
585718292f2SDouglas Gregor }
586718292f2SDouglas Gregor 
5872b82c2a5SDouglas Gregor bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
5882b82c2a5SDouglas Gregor   bool HadError = false;
5892b82c2a5SDouglas Gregor   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
5902b82c2a5SDouglas Gregor     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
5912b82c2a5SDouglas Gregor                                               Complain);
592f5eedd05SDouglas Gregor     if (Export.getPointer() || Export.getInt())
5932b82c2a5SDouglas Gregor       Mod->Exports.push_back(Export);
5942b82c2a5SDouglas Gregor     else
5952b82c2a5SDouglas Gregor       HadError = true;
5962b82c2a5SDouglas Gregor   }
5972b82c2a5SDouglas Gregor   Mod->UnresolvedExports.clear();
5982b82c2a5SDouglas Gregor   return HadError;
5992b82c2a5SDouglas Gregor }
6002b82c2a5SDouglas Gregor 
6010093b3c7SDouglas Gregor Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
6020093b3c7SDouglas Gregor   if (Loc.isInvalid())
6030093b3c7SDouglas Gregor     return 0;
6040093b3c7SDouglas Gregor 
6050093b3c7SDouglas Gregor   // Use the expansion location to determine which module we're in.
6060093b3c7SDouglas Gregor   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
6070093b3c7SDouglas Gregor   if (!ExpansionLoc.isFileID())
6080093b3c7SDouglas Gregor     return 0;
6090093b3c7SDouglas Gregor 
6100093b3c7SDouglas Gregor 
6110093b3c7SDouglas Gregor   const SourceManager &SrcMgr = Loc.getManager();
6120093b3c7SDouglas Gregor   FileID ExpansionFileID = ExpansionLoc.getFileID();
613224d8a74SDouglas Gregor 
614224d8a74SDouglas Gregor   while (const FileEntry *ExpansionFile
615224d8a74SDouglas Gregor            = SrcMgr.getFileEntryForID(ExpansionFileID)) {
616224d8a74SDouglas Gregor     // Find the module that owns this header (if any).
617224d8a74SDouglas Gregor     if (Module *Mod = findModuleForHeader(ExpansionFile))
618224d8a74SDouglas Gregor       return Mod;
619224d8a74SDouglas Gregor 
620224d8a74SDouglas Gregor     // No module owns this header, so look up the inclusion chain to see if
621224d8a74SDouglas Gregor     // any included header has an associated module.
622224d8a74SDouglas Gregor     SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
623224d8a74SDouglas Gregor     if (IncludeLoc.isInvalid())
6240093b3c7SDouglas Gregor       return 0;
6250093b3c7SDouglas Gregor 
626224d8a74SDouglas Gregor     ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
627224d8a74SDouglas Gregor   }
628224d8a74SDouglas Gregor 
629224d8a74SDouglas Gregor   return 0;
6300093b3c7SDouglas Gregor }
6310093b3c7SDouglas Gregor 
632718292f2SDouglas Gregor //----------------------------------------------------------------------------//
633718292f2SDouglas Gregor // Module map file parser
634718292f2SDouglas Gregor //----------------------------------------------------------------------------//
635718292f2SDouglas Gregor 
636718292f2SDouglas Gregor namespace clang {
637718292f2SDouglas Gregor   /// \brief A token in a module map file.
638718292f2SDouglas Gregor   struct MMToken {
639718292f2SDouglas Gregor     enum TokenKind {
6401fb5c3a6SDouglas Gregor       Comma,
641718292f2SDouglas Gregor       EndOfFile,
642718292f2SDouglas Gregor       HeaderKeyword,
643718292f2SDouglas Gregor       Identifier,
64459527666SDouglas Gregor       ExcludeKeyword,
645718292f2SDouglas Gregor       ExplicitKeyword,
6462b82c2a5SDouglas Gregor       ExportKeyword,
647755b2055SDouglas Gregor       FrameworkKeyword,
6486ddfca91SDouglas Gregor       LinkKeyword,
649718292f2SDouglas Gregor       ModuleKeyword,
6502b82c2a5SDouglas Gregor       Period,
651718292f2SDouglas Gregor       UmbrellaKeyword,
6521fb5c3a6SDouglas Gregor       RequiresKeyword,
6532b82c2a5SDouglas Gregor       Star,
654718292f2SDouglas Gregor       StringLiteral,
655718292f2SDouglas Gregor       LBrace,
656a686e1b0SDouglas Gregor       RBrace,
657a686e1b0SDouglas Gregor       LSquare,
658a686e1b0SDouglas Gregor       RSquare
659718292f2SDouglas Gregor     } Kind;
660718292f2SDouglas Gregor 
661718292f2SDouglas Gregor     unsigned Location;
662718292f2SDouglas Gregor     unsigned StringLength;
663718292f2SDouglas Gregor     const char *StringData;
664718292f2SDouglas Gregor 
665718292f2SDouglas Gregor     void clear() {
666718292f2SDouglas Gregor       Kind = EndOfFile;
667718292f2SDouglas Gregor       Location = 0;
668718292f2SDouglas Gregor       StringLength = 0;
669718292f2SDouglas Gregor       StringData = 0;
670718292f2SDouglas Gregor     }
671718292f2SDouglas Gregor 
672718292f2SDouglas Gregor     bool is(TokenKind K) const { return Kind == K; }
673718292f2SDouglas Gregor 
674718292f2SDouglas Gregor     SourceLocation getLocation() const {
675718292f2SDouglas Gregor       return SourceLocation::getFromRawEncoding(Location);
676718292f2SDouglas Gregor     }
677718292f2SDouglas Gregor 
678718292f2SDouglas Gregor     StringRef getString() const {
679718292f2SDouglas Gregor       return StringRef(StringData, StringLength);
680718292f2SDouglas Gregor     }
681718292f2SDouglas Gregor   };
682718292f2SDouglas Gregor 
6839194a91dSDouglas Gregor   /// \brief The set of attributes that can be attached to a module.
6844442605fSBill Wendling   struct Attributes {
6854442605fSBill Wendling     Attributes() : IsSystem() { }
6869194a91dSDouglas Gregor 
6879194a91dSDouglas Gregor     /// \brief Whether this is a system module.
6889194a91dSDouglas Gregor     unsigned IsSystem : 1;
6899194a91dSDouglas Gregor   };
6909194a91dSDouglas Gregor 
6919194a91dSDouglas Gregor 
692718292f2SDouglas Gregor   class ModuleMapParser {
693718292f2SDouglas Gregor     Lexer &L;
694718292f2SDouglas Gregor     SourceManager &SourceMgr;
695bc10b9fbSDouglas Gregor 
696bc10b9fbSDouglas Gregor     /// \brief Default target information, used only for string literal
697bc10b9fbSDouglas Gregor     /// parsing.
698bc10b9fbSDouglas Gregor     const TargetInfo *Target;
699bc10b9fbSDouglas Gregor 
700718292f2SDouglas Gregor     DiagnosticsEngine &Diags;
701718292f2SDouglas Gregor     ModuleMap &Map;
702718292f2SDouglas Gregor 
7035257fc63SDouglas Gregor     /// \brief The directory that this module map resides in.
7045257fc63SDouglas Gregor     const DirectoryEntry *Directory;
7055257fc63SDouglas Gregor 
7063ec6663bSDouglas Gregor     /// \brief The directory containing Clang-supplied headers.
7073ec6663bSDouglas Gregor     const DirectoryEntry *BuiltinIncludeDir;
7083ec6663bSDouglas Gregor 
709718292f2SDouglas Gregor     /// \brief Whether an error occurred.
710718292f2SDouglas Gregor     bool HadError;
711718292f2SDouglas Gregor 
712718292f2SDouglas Gregor     /// \brief Stores string data for the various string literals referenced
713718292f2SDouglas Gregor     /// during parsing.
714718292f2SDouglas Gregor     llvm::BumpPtrAllocator StringData;
715718292f2SDouglas Gregor 
716718292f2SDouglas Gregor     /// \brief The current token.
717718292f2SDouglas Gregor     MMToken Tok;
718718292f2SDouglas Gregor 
719718292f2SDouglas Gregor     /// \brief The active module.
720de3ef502SDouglas Gregor     Module *ActiveModule;
721718292f2SDouglas Gregor 
722718292f2SDouglas Gregor     /// \brief Consume the current token and return its location.
723718292f2SDouglas Gregor     SourceLocation consumeToken();
724718292f2SDouglas Gregor 
725718292f2SDouglas Gregor     /// \brief Skip tokens until we reach the a token with the given kind
726718292f2SDouglas Gregor     /// (or the end of the file).
727718292f2SDouglas Gregor     void skipUntil(MMToken::TokenKind K);
728718292f2SDouglas Gregor 
729f857950dSDmitri Gribenko     typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
730e7ab3669SDouglas Gregor     bool parseModuleId(ModuleId &Id);
731718292f2SDouglas Gregor     void parseModuleDecl();
7321fb5c3a6SDouglas Gregor     void parseRequiresDecl();
73359527666SDouglas Gregor     void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
734524e33e1SDouglas Gregor     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
7352b82c2a5SDouglas Gregor     void parseExportDecl();
7366ddfca91SDouglas Gregor     void parseLinkDecl();
7379194a91dSDouglas Gregor     void parseInferredModuleDecl(bool Framework, bool Explicit);
7384442605fSBill Wendling     bool parseOptionalAttributes(Attributes &Attrs);
739718292f2SDouglas Gregor 
7407033127bSDouglas Gregor     const DirectoryEntry *getOverriddenHeaderSearchDir();
7417033127bSDouglas Gregor 
742718292f2SDouglas Gregor   public:
743718292f2SDouglas Gregor     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
744bc10b9fbSDouglas Gregor                              const TargetInfo *Target,
745718292f2SDouglas Gregor                              DiagnosticsEngine &Diags,
7465257fc63SDouglas Gregor                              ModuleMap &Map,
7473ec6663bSDouglas Gregor                              const DirectoryEntry *Directory,
7483ec6663bSDouglas Gregor                              const DirectoryEntry *BuiltinIncludeDir)
749bc10b9fbSDouglas Gregor       : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
7503ec6663bSDouglas Gregor         Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
7513ec6663bSDouglas Gregor         HadError(false), ActiveModule(0)
752718292f2SDouglas Gregor     {
753718292f2SDouglas Gregor       Tok.clear();
754718292f2SDouglas Gregor       consumeToken();
755718292f2SDouglas Gregor     }
756718292f2SDouglas Gregor 
757718292f2SDouglas Gregor     bool parseModuleMapFile();
758718292f2SDouglas Gregor   };
759718292f2SDouglas Gregor }
760718292f2SDouglas Gregor 
761718292f2SDouglas Gregor SourceLocation ModuleMapParser::consumeToken() {
762718292f2SDouglas Gregor retry:
763718292f2SDouglas Gregor   SourceLocation Result = Tok.getLocation();
764718292f2SDouglas Gregor   Tok.clear();
765718292f2SDouglas Gregor 
766718292f2SDouglas Gregor   Token LToken;
767718292f2SDouglas Gregor   L.LexFromRawLexer(LToken);
768718292f2SDouglas Gregor   Tok.Location = LToken.getLocation().getRawEncoding();
769718292f2SDouglas Gregor   switch (LToken.getKind()) {
770718292f2SDouglas Gregor   case tok::raw_identifier:
771718292f2SDouglas Gregor     Tok.StringData = LToken.getRawIdentifierData();
772718292f2SDouglas Gregor     Tok.StringLength = LToken.getLength();
773718292f2SDouglas Gregor     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
774718292f2SDouglas Gregor                  .Case("header", MMToken::HeaderKeyword)
77559527666SDouglas Gregor                  .Case("exclude", MMToken::ExcludeKeyword)
776718292f2SDouglas Gregor                  .Case("explicit", MMToken::ExplicitKeyword)
7772b82c2a5SDouglas Gregor                  .Case("export", MMToken::ExportKeyword)
778755b2055SDouglas Gregor                  .Case("framework", MMToken::FrameworkKeyword)
7796ddfca91SDouglas Gregor                  .Case("link", MMToken::LinkKeyword)
780718292f2SDouglas Gregor                  .Case("module", MMToken::ModuleKeyword)
7811fb5c3a6SDouglas Gregor                  .Case("requires", MMToken::RequiresKeyword)
782718292f2SDouglas Gregor                  .Case("umbrella", MMToken::UmbrellaKeyword)
783718292f2SDouglas Gregor                  .Default(MMToken::Identifier);
784718292f2SDouglas Gregor     break;
785718292f2SDouglas Gregor 
7861fb5c3a6SDouglas Gregor   case tok::comma:
7871fb5c3a6SDouglas Gregor     Tok.Kind = MMToken::Comma;
7881fb5c3a6SDouglas Gregor     break;
7891fb5c3a6SDouglas Gregor 
790718292f2SDouglas Gregor   case tok::eof:
791718292f2SDouglas Gregor     Tok.Kind = MMToken::EndOfFile;
792718292f2SDouglas Gregor     break;
793718292f2SDouglas Gregor 
794718292f2SDouglas Gregor   case tok::l_brace:
795718292f2SDouglas Gregor     Tok.Kind = MMToken::LBrace;
796718292f2SDouglas Gregor     break;
797718292f2SDouglas Gregor 
798a686e1b0SDouglas Gregor   case tok::l_square:
799a686e1b0SDouglas Gregor     Tok.Kind = MMToken::LSquare;
800a686e1b0SDouglas Gregor     break;
801a686e1b0SDouglas Gregor 
8022b82c2a5SDouglas Gregor   case tok::period:
8032b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Period;
8042b82c2a5SDouglas Gregor     break;
8052b82c2a5SDouglas Gregor 
806718292f2SDouglas Gregor   case tok::r_brace:
807718292f2SDouglas Gregor     Tok.Kind = MMToken::RBrace;
808718292f2SDouglas Gregor     break;
809718292f2SDouglas Gregor 
810a686e1b0SDouglas Gregor   case tok::r_square:
811a686e1b0SDouglas Gregor     Tok.Kind = MMToken::RSquare;
812a686e1b0SDouglas Gregor     break;
813a686e1b0SDouglas Gregor 
8142b82c2a5SDouglas Gregor   case tok::star:
8152b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Star;
8162b82c2a5SDouglas Gregor     break;
8172b82c2a5SDouglas Gregor 
818718292f2SDouglas Gregor   case tok::string_literal: {
819d67aea28SRichard Smith     if (LToken.hasUDSuffix()) {
820d67aea28SRichard Smith       Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
821d67aea28SRichard Smith       HadError = true;
822d67aea28SRichard Smith       goto retry;
823d67aea28SRichard Smith     }
824d67aea28SRichard Smith 
825718292f2SDouglas Gregor     // Parse the string literal.
826718292f2SDouglas Gregor     LangOptions LangOpts;
827718292f2SDouglas Gregor     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
828718292f2SDouglas Gregor     if (StringLiteral.hadError)
829718292f2SDouglas Gregor       goto retry;
830718292f2SDouglas Gregor 
831718292f2SDouglas Gregor     // Copy the string literal into our string data allocator.
832718292f2SDouglas Gregor     unsigned Length = StringLiteral.GetStringLength();
833718292f2SDouglas Gregor     char *Saved = StringData.Allocate<char>(Length + 1);
834718292f2SDouglas Gregor     memcpy(Saved, StringLiteral.GetString().data(), Length);
835718292f2SDouglas Gregor     Saved[Length] = 0;
836718292f2SDouglas Gregor 
837718292f2SDouglas Gregor     // Form the token.
838718292f2SDouglas Gregor     Tok.Kind = MMToken::StringLiteral;
839718292f2SDouglas Gregor     Tok.StringData = Saved;
840718292f2SDouglas Gregor     Tok.StringLength = Length;
841718292f2SDouglas Gregor     break;
842718292f2SDouglas Gregor   }
843718292f2SDouglas Gregor 
844718292f2SDouglas Gregor   case tok::comment:
845718292f2SDouglas Gregor     goto retry;
846718292f2SDouglas Gregor 
847718292f2SDouglas Gregor   default:
848718292f2SDouglas Gregor     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
849718292f2SDouglas Gregor     HadError = true;
850718292f2SDouglas Gregor     goto retry;
851718292f2SDouglas Gregor   }
852718292f2SDouglas Gregor 
853718292f2SDouglas Gregor   return Result;
854718292f2SDouglas Gregor }
855718292f2SDouglas Gregor 
856718292f2SDouglas Gregor void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
857718292f2SDouglas Gregor   unsigned braceDepth = 0;
858a686e1b0SDouglas Gregor   unsigned squareDepth = 0;
859718292f2SDouglas Gregor   do {
860718292f2SDouglas Gregor     switch (Tok.Kind) {
861718292f2SDouglas Gregor     case MMToken::EndOfFile:
862718292f2SDouglas Gregor       return;
863718292f2SDouglas Gregor 
864718292f2SDouglas Gregor     case MMToken::LBrace:
865a686e1b0SDouglas Gregor       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
866718292f2SDouglas Gregor         return;
867718292f2SDouglas Gregor 
868718292f2SDouglas Gregor       ++braceDepth;
869718292f2SDouglas Gregor       break;
870718292f2SDouglas Gregor 
871a686e1b0SDouglas Gregor     case MMToken::LSquare:
872a686e1b0SDouglas Gregor       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
873a686e1b0SDouglas Gregor         return;
874a686e1b0SDouglas Gregor 
875a686e1b0SDouglas Gregor       ++squareDepth;
876a686e1b0SDouglas Gregor       break;
877a686e1b0SDouglas Gregor 
878718292f2SDouglas Gregor     case MMToken::RBrace:
879718292f2SDouglas Gregor       if (braceDepth > 0)
880718292f2SDouglas Gregor         --braceDepth;
881718292f2SDouglas Gregor       else if (Tok.is(K))
882718292f2SDouglas Gregor         return;
883718292f2SDouglas Gregor       break;
884718292f2SDouglas Gregor 
885a686e1b0SDouglas Gregor     case MMToken::RSquare:
886a686e1b0SDouglas Gregor       if (squareDepth > 0)
887a686e1b0SDouglas Gregor         --squareDepth;
888a686e1b0SDouglas Gregor       else if (Tok.is(K))
889a686e1b0SDouglas Gregor         return;
890a686e1b0SDouglas Gregor       break;
891a686e1b0SDouglas Gregor 
892718292f2SDouglas Gregor     default:
893a686e1b0SDouglas Gregor       if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
894718292f2SDouglas Gregor         return;
895718292f2SDouglas Gregor       break;
896718292f2SDouglas Gregor     }
897718292f2SDouglas Gregor 
898718292f2SDouglas Gregor    consumeToken();
899718292f2SDouglas Gregor   } while (true);
900718292f2SDouglas Gregor }
901718292f2SDouglas Gregor 
902e7ab3669SDouglas Gregor /// \brief Parse a module-id.
903e7ab3669SDouglas Gregor ///
904e7ab3669SDouglas Gregor ///   module-id:
905e7ab3669SDouglas Gregor ///     identifier
906e7ab3669SDouglas Gregor ///     identifier '.' module-id
907e7ab3669SDouglas Gregor ///
908e7ab3669SDouglas Gregor /// \returns true if an error occurred, false otherwise.
909e7ab3669SDouglas Gregor bool ModuleMapParser::parseModuleId(ModuleId &Id) {
910e7ab3669SDouglas Gregor   Id.clear();
911e7ab3669SDouglas Gregor   do {
912e7ab3669SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
913e7ab3669SDouglas Gregor       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
914e7ab3669SDouglas Gregor       consumeToken();
915e7ab3669SDouglas Gregor     } else {
916e7ab3669SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
917e7ab3669SDouglas Gregor       return true;
918e7ab3669SDouglas Gregor     }
919e7ab3669SDouglas Gregor 
920e7ab3669SDouglas Gregor     if (!Tok.is(MMToken::Period))
921e7ab3669SDouglas Gregor       break;
922e7ab3669SDouglas Gregor 
923e7ab3669SDouglas Gregor     consumeToken();
924e7ab3669SDouglas Gregor   } while (true);
925e7ab3669SDouglas Gregor 
926e7ab3669SDouglas Gregor   return false;
927e7ab3669SDouglas Gregor }
928e7ab3669SDouglas Gregor 
929a686e1b0SDouglas Gregor namespace {
930a686e1b0SDouglas Gregor   /// \brief Enumerates the known attributes.
931a686e1b0SDouglas Gregor   enum AttributeKind {
932a686e1b0SDouglas Gregor     /// \brief An unknown attribute.
933a686e1b0SDouglas Gregor     AT_unknown,
934a686e1b0SDouglas Gregor     /// \brief The 'system' attribute.
935a686e1b0SDouglas Gregor     AT_system
936a686e1b0SDouglas Gregor   };
937a686e1b0SDouglas Gregor }
938a686e1b0SDouglas Gregor 
939718292f2SDouglas Gregor /// \brief Parse a module declaration.
940718292f2SDouglas Gregor ///
941718292f2SDouglas Gregor ///   module-declaration:
942a686e1b0SDouglas Gregor ///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
943a686e1b0SDouglas Gregor ///       { module-member* }
944a686e1b0SDouglas Gregor ///
945718292f2SDouglas Gregor ///   module-member:
9461fb5c3a6SDouglas Gregor ///     requires-declaration
947718292f2SDouglas Gregor ///     header-declaration
948e7ab3669SDouglas Gregor ///     submodule-declaration
9492b82c2a5SDouglas Gregor ///     export-declaration
9506ddfca91SDouglas Gregor ///     link-declaration
95173441091SDouglas Gregor ///
95273441091SDouglas Gregor ///   submodule-declaration:
95373441091SDouglas Gregor ///     module-declaration
95473441091SDouglas Gregor ///     inferred-submodule-declaration
955718292f2SDouglas Gregor void ModuleMapParser::parseModuleDecl() {
956755b2055SDouglas Gregor   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
957755b2055SDouglas Gregor          Tok.is(MMToken::FrameworkKeyword));
958f2161a70SDouglas Gregor   // Parse 'explicit' or 'framework' keyword, if present.
959e7ab3669SDouglas Gregor   SourceLocation ExplicitLoc;
960718292f2SDouglas Gregor   bool Explicit = false;
961f2161a70SDouglas Gregor   bool Framework = false;
962755b2055SDouglas Gregor 
963f2161a70SDouglas Gregor   // Parse 'explicit' keyword, if present.
964f2161a70SDouglas Gregor   if (Tok.is(MMToken::ExplicitKeyword)) {
965e7ab3669SDouglas Gregor     ExplicitLoc = consumeToken();
966f2161a70SDouglas Gregor     Explicit = true;
967f2161a70SDouglas Gregor   }
968f2161a70SDouglas Gregor 
969f2161a70SDouglas Gregor   // Parse 'framework' keyword, if present.
970755b2055SDouglas Gregor   if (Tok.is(MMToken::FrameworkKeyword)) {
971755b2055SDouglas Gregor     consumeToken();
972755b2055SDouglas Gregor     Framework = true;
973755b2055SDouglas Gregor   }
974718292f2SDouglas Gregor 
975718292f2SDouglas Gregor   // Parse 'module' keyword.
976718292f2SDouglas Gregor   if (!Tok.is(MMToken::ModuleKeyword)) {
977d6343c99SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
978718292f2SDouglas Gregor     consumeToken();
979718292f2SDouglas Gregor     HadError = true;
980718292f2SDouglas Gregor     return;
981718292f2SDouglas Gregor   }
982718292f2SDouglas Gregor   consumeToken(); // 'module' keyword
983718292f2SDouglas Gregor 
98473441091SDouglas Gregor   // If we have a wildcard for the module name, this is an inferred submodule.
98573441091SDouglas Gregor   // Parse it.
98673441091SDouglas Gregor   if (Tok.is(MMToken::Star))
9879194a91dSDouglas Gregor     return parseInferredModuleDecl(Framework, Explicit);
98873441091SDouglas Gregor 
989718292f2SDouglas Gregor   // Parse the module name.
990e7ab3669SDouglas Gregor   ModuleId Id;
991e7ab3669SDouglas Gregor   if (parseModuleId(Id)) {
992718292f2SDouglas Gregor     HadError = true;
993718292f2SDouglas Gregor     return;
994718292f2SDouglas Gregor   }
995e7ab3669SDouglas Gregor 
996e7ab3669SDouglas Gregor   if (ActiveModule) {
997e7ab3669SDouglas Gregor     if (Id.size() > 1) {
998e7ab3669SDouglas Gregor       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
999e7ab3669SDouglas Gregor         << SourceRange(Id.front().second, Id.back().second);
1000e7ab3669SDouglas Gregor 
1001e7ab3669SDouglas Gregor       HadError = true;
1002e7ab3669SDouglas Gregor       return;
1003e7ab3669SDouglas Gregor     }
1004e7ab3669SDouglas Gregor   } else if (Id.size() == 1 && Explicit) {
1005e7ab3669SDouglas Gregor     // Top-level modules can't be explicit.
1006e7ab3669SDouglas Gregor     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1007e7ab3669SDouglas Gregor     Explicit = false;
1008e7ab3669SDouglas Gregor     ExplicitLoc = SourceLocation();
1009e7ab3669SDouglas Gregor     HadError = true;
1010e7ab3669SDouglas Gregor   }
1011e7ab3669SDouglas Gregor 
1012e7ab3669SDouglas Gregor   Module *PreviousActiveModule = ActiveModule;
1013e7ab3669SDouglas Gregor   if (Id.size() > 1) {
1014e7ab3669SDouglas Gregor     // This module map defines a submodule. Go find the module of which it
1015e7ab3669SDouglas Gregor     // is a submodule.
1016e7ab3669SDouglas Gregor     ActiveModule = 0;
1017e7ab3669SDouglas Gregor     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1018e7ab3669SDouglas Gregor       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1019e7ab3669SDouglas Gregor         ActiveModule = Next;
1020e7ab3669SDouglas Gregor         continue;
1021e7ab3669SDouglas Gregor       }
1022e7ab3669SDouglas Gregor 
1023e7ab3669SDouglas Gregor       if (ActiveModule) {
1024e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1025e7ab3669SDouglas Gregor           << Id[I].first << ActiveModule->getTopLevelModule();
1026e7ab3669SDouglas Gregor       } else {
1027e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1028e7ab3669SDouglas Gregor       }
1029e7ab3669SDouglas Gregor       HadError = true;
1030e7ab3669SDouglas Gregor       return;
1031e7ab3669SDouglas Gregor     }
1032e7ab3669SDouglas Gregor   }
1033e7ab3669SDouglas Gregor 
1034e7ab3669SDouglas Gregor   StringRef ModuleName = Id.back().first;
1035e7ab3669SDouglas Gregor   SourceLocation ModuleNameLoc = Id.back().second;
1036718292f2SDouglas Gregor 
1037a686e1b0SDouglas Gregor   // Parse the optional attribute list.
10384442605fSBill Wendling   Attributes Attrs;
10399194a91dSDouglas Gregor   parseOptionalAttributes(Attrs);
1040a686e1b0SDouglas Gregor 
1041718292f2SDouglas Gregor   // Parse the opening brace.
1042718292f2SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
1043718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1044718292f2SDouglas Gregor       << ModuleName;
1045718292f2SDouglas Gregor     HadError = true;
1046718292f2SDouglas Gregor     return;
1047718292f2SDouglas Gregor   }
1048718292f2SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
1049718292f2SDouglas Gregor 
1050718292f2SDouglas Gregor   // Determine whether this (sub)module has already been defined.
1051eb90e830SDouglas Gregor   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1052fcc54a3bSDouglas Gregor     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1053fcc54a3bSDouglas Gregor       // Skip the module definition.
1054fcc54a3bSDouglas Gregor       skipUntil(MMToken::RBrace);
1055fcc54a3bSDouglas Gregor       if (Tok.is(MMToken::RBrace))
1056fcc54a3bSDouglas Gregor         consumeToken();
1057fcc54a3bSDouglas Gregor       else {
1058fcc54a3bSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1059fcc54a3bSDouglas Gregor         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1060fcc54a3bSDouglas Gregor         HadError = true;
1061fcc54a3bSDouglas Gregor       }
1062fcc54a3bSDouglas Gregor       return;
1063fcc54a3bSDouglas Gregor     }
1064fcc54a3bSDouglas Gregor 
1065718292f2SDouglas Gregor     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1066718292f2SDouglas Gregor       << ModuleName;
1067eb90e830SDouglas Gregor     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1068718292f2SDouglas Gregor 
1069718292f2SDouglas Gregor     // Skip the module definition.
1070718292f2SDouglas Gregor     skipUntil(MMToken::RBrace);
1071718292f2SDouglas Gregor     if (Tok.is(MMToken::RBrace))
1072718292f2SDouglas Gregor       consumeToken();
1073718292f2SDouglas Gregor 
1074718292f2SDouglas Gregor     HadError = true;
1075718292f2SDouglas Gregor     return;
1076718292f2SDouglas Gregor   }
1077718292f2SDouglas Gregor 
1078718292f2SDouglas Gregor   // Start defining this module.
1079eb90e830SDouglas Gregor   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1080eb90e830SDouglas Gregor                                         Explicit).first;
1081eb90e830SDouglas Gregor   ActiveModule->DefinitionLoc = ModuleNameLoc;
10829194a91dSDouglas Gregor   if (Attrs.IsSystem)
1083a686e1b0SDouglas Gregor     ActiveModule->IsSystem = true;
1084718292f2SDouglas Gregor 
1085718292f2SDouglas Gregor   bool Done = false;
1086718292f2SDouglas Gregor   do {
1087718292f2SDouglas Gregor     switch (Tok.Kind) {
1088718292f2SDouglas Gregor     case MMToken::EndOfFile:
1089718292f2SDouglas Gregor     case MMToken::RBrace:
1090718292f2SDouglas Gregor       Done = true;
1091718292f2SDouglas Gregor       break;
1092718292f2SDouglas Gregor 
1093718292f2SDouglas Gregor     case MMToken::ExplicitKeyword:
1094f2161a70SDouglas Gregor     case MMToken::FrameworkKeyword:
1095718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
1096718292f2SDouglas Gregor       parseModuleDecl();
1097718292f2SDouglas Gregor       break;
1098718292f2SDouglas Gregor 
10992b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
11002b82c2a5SDouglas Gregor       parseExportDecl();
11012b82c2a5SDouglas Gregor       break;
11022b82c2a5SDouglas Gregor 
11031fb5c3a6SDouglas Gregor     case MMToken::RequiresKeyword:
11041fb5c3a6SDouglas Gregor       parseRequiresDecl();
11051fb5c3a6SDouglas Gregor       break;
11061fb5c3a6SDouglas Gregor 
1107524e33e1SDouglas Gregor     case MMToken::UmbrellaKeyword: {
1108524e33e1SDouglas Gregor       SourceLocation UmbrellaLoc = consumeToken();
1109524e33e1SDouglas Gregor       if (Tok.is(MMToken::HeaderKeyword))
111059527666SDouglas Gregor         parseHeaderDecl(UmbrellaLoc, SourceLocation());
1111524e33e1SDouglas Gregor       else
1112524e33e1SDouglas Gregor         parseUmbrellaDirDecl(UmbrellaLoc);
1113718292f2SDouglas Gregor       break;
1114524e33e1SDouglas Gregor     }
1115718292f2SDouglas Gregor 
111659527666SDouglas Gregor     case MMToken::ExcludeKeyword: {
111759527666SDouglas Gregor       SourceLocation ExcludeLoc = consumeToken();
111859527666SDouglas Gregor       if (Tok.is(MMToken::HeaderKeyword)) {
111959527666SDouglas Gregor         parseHeaderDecl(SourceLocation(), ExcludeLoc);
112059527666SDouglas Gregor       } else {
112159527666SDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
112259527666SDouglas Gregor           << "exclude";
112359527666SDouglas Gregor       }
112459527666SDouglas Gregor       break;
112559527666SDouglas Gregor     }
112659527666SDouglas Gregor 
1127322f633cSDouglas Gregor     case MMToken::HeaderKeyword:
112859527666SDouglas Gregor       parseHeaderDecl(SourceLocation(), SourceLocation());
1129718292f2SDouglas Gregor       break;
1130718292f2SDouglas Gregor 
11316ddfca91SDouglas Gregor     case MMToken::LinkKeyword:
11326ddfca91SDouglas Gregor       parseLinkDecl();
11336ddfca91SDouglas Gregor       break;
11346ddfca91SDouglas Gregor 
1135718292f2SDouglas Gregor     default:
1136718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1137718292f2SDouglas Gregor       consumeToken();
1138718292f2SDouglas Gregor       break;
1139718292f2SDouglas Gregor     }
1140718292f2SDouglas Gregor   } while (!Done);
1141718292f2SDouglas Gregor 
1142718292f2SDouglas Gregor   if (Tok.is(MMToken::RBrace))
1143718292f2SDouglas Gregor     consumeToken();
1144718292f2SDouglas Gregor   else {
1145718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1146718292f2SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1147718292f2SDouglas Gregor     HadError = true;
1148718292f2SDouglas Gregor   }
1149718292f2SDouglas Gregor 
115011dfe6feSDouglas Gregor   // If the active module is a top-level framework, and there are no link
115111dfe6feSDouglas Gregor   // libraries, automatically link against the framework.
115211dfe6feSDouglas Gregor   if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
115311dfe6feSDouglas Gregor       ActiveModule->LinkLibraries.empty()) {
115411dfe6feSDouglas Gregor     inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
115511dfe6feSDouglas Gregor   }
115611dfe6feSDouglas Gregor 
1157e7ab3669SDouglas Gregor   // We're done parsing this module. Pop back to the previous module.
1158e7ab3669SDouglas Gregor   ActiveModule = PreviousActiveModule;
1159718292f2SDouglas Gregor }
1160718292f2SDouglas Gregor 
11611fb5c3a6SDouglas Gregor /// \brief Parse a requires declaration.
11621fb5c3a6SDouglas Gregor ///
11631fb5c3a6SDouglas Gregor ///   requires-declaration:
11641fb5c3a6SDouglas Gregor ///     'requires' feature-list
11651fb5c3a6SDouglas Gregor ///
11661fb5c3a6SDouglas Gregor ///   feature-list:
11671fb5c3a6SDouglas Gregor ///     identifier ',' feature-list
11681fb5c3a6SDouglas Gregor ///     identifier
11691fb5c3a6SDouglas Gregor void ModuleMapParser::parseRequiresDecl() {
11701fb5c3a6SDouglas Gregor   assert(Tok.is(MMToken::RequiresKeyword));
11711fb5c3a6SDouglas Gregor 
11721fb5c3a6SDouglas Gregor   // Parse 'requires' keyword.
11731fb5c3a6SDouglas Gregor   consumeToken();
11741fb5c3a6SDouglas Gregor 
11751fb5c3a6SDouglas Gregor   // Parse the feature-list.
11761fb5c3a6SDouglas Gregor   do {
11771fb5c3a6SDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
11781fb5c3a6SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
11791fb5c3a6SDouglas Gregor       HadError = true;
11801fb5c3a6SDouglas Gregor       return;
11811fb5c3a6SDouglas Gregor     }
11821fb5c3a6SDouglas Gregor 
11831fb5c3a6SDouglas Gregor     // Consume the feature name.
11841fb5c3a6SDouglas Gregor     std::string Feature = Tok.getString();
11851fb5c3a6SDouglas Gregor     consumeToken();
11861fb5c3a6SDouglas Gregor 
11871fb5c3a6SDouglas Gregor     // Add this feature.
118889929282SDouglas Gregor     ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
11891fb5c3a6SDouglas Gregor 
11901fb5c3a6SDouglas Gregor     if (!Tok.is(MMToken::Comma))
11911fb5c3a6SDouglas Gregor       break;
11921fb5c3a6SDouglas Gregor 
11931fb5c3a6SDouglas Gregor     // Consume the comma.
11941fb5c3a6SDouglas Gregor     consumeToken();
11951fb5c3a6SDouglas Gregor   } while (true);
11961fb5c3a6SDouglas Gregor }
11971fb5c3a6SDouglas Gregor 
1198f2161a70SDouglas Gregor /// \brief Append to \p Paths the set of paths needed to get to the
1199f2161a70SDouglas Gregor /// subframework in which the given module lives.
1200bf8da9d7SBenjamin Kramer static void appendSubframeworkPaths(Module *Mod,
1201f857950dSDmitri Gribenko                                     SmallVectorImpl<char> &Path) {
1202f2161a70SDouglas Gregor   // Collect the framework names from the given module to the top-level module.
1203f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Paths;
1204f2161a70SDouglas Gregor   for (; Mod; Mod = Mod->Parent) {
1205f2161a70SDouglas Gregor     if (Mod->IsFramework)
1206f2161a70SDouglas Gregor       Paths.push_back(Mod->Name);
1207f2161a70SDouglas Gregor   }
1208f2161a70SDouglas Gregor 
1209f2161a70SDouglas Gregor   if (Paths.empty())
1210f2161a70SDouglas Gregor     return;
1211f2161a70SDouglas Gregor 
1212f2161a70SDouglas Gregor   // Add Frameworks/Name.framework for each subframework.
1213f2161a70SDouglas Gregor   for (unsigned I = Paths.size() - 1; I != 0; --I) {
1214f2161a70SDouglas Gregor     llvm::sys::path::append(Path, "Frameworks");
1215f2161a70SDouglas Gregor     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1216f2161a70SDouglas Gregor   }
1217f2161a70SDouglas Gregor }
1218f2161a70SDouglas Gregor 
12193ec6663bSDouglas Gregor /// \brief Determine whether the given file name is the name of a builtin
12203ec6663bSDouglas Gregor /// header, supplied by Clang to replace, override, or augment existing system
12213ec6663bSDouglas Gregor /// headers.
12223ec6663bSDouglas Gregor static bool isBuiltinHeader(StringRef FileName) {
12233ec6663bSDouglas Gregor   return llvm::StringSwitch<bool>(FileName)
12243ec6663bSDouglas Gregor       .Case("float.h", true)
12253ec6663bSDouglas Gregor       .Case("iso646.h", true)
12263ec6663bSDouglas Gregor       .Case("limits.h", true)
12273ec6663bSDouglas Gregor       .Case("stdalign.h", true)
12283ec6663bSDouglas Gregor       .Case("stdarg.h", true)
12293ec6663bSDouglas Gregor       .Case("stdbool.h", true)
12303ec6663bSDouglas Gregor       .Case("stddef.h", true)
12313ec6663bSDouglas Gregor       .Case("stdint.h", true)
12323ec6663bSDouglas Gregor       .Case("tgmath.h", true)
12333ec6663bSDouglas Gregor       .Case("unwind.h", true)
12343ec6663bSDouglas Gregor       .Default(false);
12353ec6663bSDouglas Gregor }
12363ec6663bSDouglas Gregor 
1237718292f2SDouglas Gregor /// \brief Parse a header declaration.
1238718292f2SDouglas Gregor ///
1239718292f2SDouglas Gregor ///   header-declaration:
1240322f633cSDouglas Gregor ///     'umbrella'[opt] 'header' string-literal
124159527666SDouglas Gregor ///     'exclude'[opt] 'header' string-literal
124259527666SDouglas Gregor void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
124359527666SDouglas Gregor                                       SourceLocation ExcludeLoc) {
1244718292f2SDouglas Gregor   assert(Tok.is(MMToken::HeaderKeyword));
12451871ed3dSBenjamin Kramer   consumeToken();
1246718292f2SDouglas Gregor 
1247322f633cSDouglas Gregor   bool Umbrella = UmbrellaLoc.isValid();
124859527666SDouglas Gregor   bool Exclude = ExcludeLoc.isValid();
124959527666SDouglas Gregor   assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
1250718292f2SDouglas Gregor   // Parse the header name.
1251718292f2SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
1252718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1253718292f2SDouglas Gregor       << "header";
1254718292f2SDouglas Gregor     HadError = true;
1255718292f2SDouglas Gregor     return;
1256718292f2SDouglas Gregor   }
1257e7ab3669SDouglas Gregor   std::string FileName = Tok.getString();
1258718292f2SDouglas Gregor   SourceLocation FileNameLoc = consumeToken();
1259718292f2SDouglas Gregor 
1260524e33e1SDouglas Gregor   // Check whether we already have an umbrella.
1261524e33e1SDouglas Gregor   if (Umbrella && ActiveModule->Umbrella) {
1262524e33e1SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1263524e33e1SDouglas Gregor       << ActiveModule->getFullModuleName();
1264322f633cSDouglas Gregor     HadError = true;
1265322f633cSDouglas Gregor     return;
1266322f633cSDouglas Gregor   }
1267322f633cSDouglas Gregor 
12685257fc63SDouglas Gregor   // Look for this file.
1269e7ab3669SDouglas Gregor   const FileEntry *File = 0;
12703ec6663bSDouglas Gregor   const FileEntry *BuiltinFile = 0;
12712c1dd271SDylan Noblesmith   SmallString<128> PathName;
1272e7ab3669SDouglas Gregor   if (llvm::sys::path::is_absolute(FileName)) {
1273e7ab3669SDouglas Gregor     PathName = FileName;
1274e7ab3669SDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
12757033127bSDouglas Gregor   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
12767033127bSDouglas Gregor     PathName = Dir->getName();
12777033127bSDouglas Gregor     llvm::sys::path::append(PathName, FileName);
12787033127bSDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
1279e7ab3669SDouglas Gregor   } else {
1280e7ab3669SDouglas Gregor     // Search for the header file within the search directory.
12817033127bSDouglas Gregor     PathName = Directory->getName();
1282e7ab3669SDouglas Gregor     unsigned PathLength = PathName.size();
1283755b2055SDouglas Gregor 
1284f2161a70SDouglas Gregor     if (ActiveModule->isPartOfFramework()) {
1285f2161a70SDouglas Gregor       appendSubframeworkPaths(ActiveModule, PathName);
1286755b2055SDouglas Gregor 
1287e7ab3669SDouglas Gregor       // Check whether this file is in the public headers.
1288e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, "Headers");
12895257fc63SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
1290e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
1291e7ab3669SDouglas Gregor 
1292e7ab3669SDouglas Gregor       if (!File) {
1293e7ab3669SDouglas Gregor         // Check whether this file is in the private headers.
1294e7ab3669SDouglas Gregor         PathName.resize(PathLength);
1295e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, "PrivateHeaders");
1296e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, FileName);
1297e7ab3669SDouglas Gregor         File = SourceMgr.getFileManager().getFile(PathName);
1298e7ab3669SDouglas Gregor       }
1299e7ab3669SDouglas Gregor     } else {
1300e7ab3669SDouglas Gregor       // Lookup for normal headers.
1301e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
1302e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
13033ec6663bSDouglas Gregor 
13043ec6663bSDouglas Gregor       // If this is a system module with a top-level header, this header
13053ec6663bSDouglas Gregor       // may have a counterpart (or replacement) in the set of headers
13063ec6663bSDouglas Gregor       // supplied by Clang. Find that builtin header.
13073ec6663bSDouglas Gregor       if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
13083ec6663bSDouglas Gregor           BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
13092c1dd271SDylan Noblesmith         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
13103ec6663bSDouglas Gregor         llvm::sys::path::append(BuiltinPathName, FileName);
13113ec6663bSDouglas Gregor         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
13123ec6663bSDouglas Gregor 
13133ec6663bSDouglas Gregor         // If Clang supplies this header but the underlying system does not,
13143ec6663bSDouglas Gregor         // just silently swap in our builtin version. Otherwise, we'll end
13153ec6663bSDouglas Gregor         // up adding both (later).
13163ec6663bSDouglas Gregor         if (!File && BuiltinFile) {
13173ec6663bSDouglas Gregor           File = BuiltinFile;
13183ec6663bSDouglas Gregor           BuiltinFile = 0;
13193ec6663bSDouglas Gregor         }
13203ec6663bSDouglas Gregor       }
1321e7ab3669SDouglas Gregor     }
1322e7ab3669SDouglas Gregor   }
13235257fc63SDouglas Gregor 
13245257fc63SDouglas Gregor   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
13255257fc63SDouglas Gregor   // Come up with a lazy way to do this.
1326e7ab3669SDouglas Gregor   if (File) {
132759527666SDouglas Gregor     if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
13285257fc63SDouglas Gregor       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
132959527666SDouglas Gregor         << FileName << OwningModule.getModule()->getFullModuleName();
13305257fc63SDouglas Gregor       HadError = true;
1331322f633cSDouglas Gregor     } else if (Umbrella) {
1332322f633cSDouglas Gregor       const DirectoryEntry *UmbrellaDir = File->getDir();
133359527666SDouglas Gregor       if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1334322f633cSDouglas Gregor         Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
133559527666SDouglas Gregor           << UmbrellaModule->getFullModuleName();
1336322f633cSDouglas Gregor         HadError = true;
13375257fc63SDouglas Gregor       } else {
1338322f633cSDouglas Gregor         // Record this umbrella header.
1339322f633cSDouglas Gregor         Map.setUmbrellaHeader(ActiveModule, File);
1340322f633cSDouglas Gregor       }
1341322f633cSDouglas Gregor     } else {
1342322f633cSDouglas Gregor       // Record this header.
134359527666SDouglas Gregor       Map.addHeader(ActiveModule, File, Exclude);
13443ec6663bSDouglas Gregor 
13453ec6663bSDouglas Gregor       // If there is a builtin counterpart to this file, add it now.
13463ec6663bSDouglas Gregor       if (BuiltinFile)
134759527666SDouglas Gregor         Map.addHeader(ActiveModule, BuiltinFile, Exclude);
13485257fc63SDouglas Gregor     }
13494b27a64bSDouglas Gregor   } else if (!Exclude) {
13504b27a64bSDouglas Gregor     // Ignore excluded header files. They're optional anyway.
13514b27a64bSDouglas Gregor 
13525257fc63SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1353524e33e1SDouglas Gregor       << Umbrella << FileName;
13545257fc63SDouglas Gregor     HadError = true;
13555257fc63SDouglas Gregor   }
1356718292f2SDouglas Gregor }
1357718292f2SDouglas Gregor 
1358524e33e1SDouglas Gregor /// \brief Parse an umbrella directory declaration.
1359524e33e1SDouglas Gregor ///
1360524e33e1SDouglas Gregor ///   umbrella-dir-declaration:
1361524e33e1SDouglas Gregor ///     umbrella string-literal
1362524e33e1SDouglas Gregor void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1363524e33e1SDouglas Gregor   // Parse the directory name.
1364524e33e1SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
1365524e33e1SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1366524e33e1SDouglas Gregor       << "umbrella";
1367524e33e1SDouglas Gregor     HadError = true;
1368524e33e1SDouglas Gregor     return;
1369524e33e1SDouglas Gregor   }
1370524e33e1SDouglas Gregor 
1371524e33e1SDouglas Gregor   std::string DirName = Tok.getString();
1372524e33e1SDouglas Gregor   SourceLocation DirNameLoc = consumeToken();
1373524e33e1SDouglas Gregor 
1374524e33e1SDouglas Gregor   // Check whether we already have an umbrella.
1375524e33e1SDouglas Gregor   if (ActiveModule->Umbrella) {
1376524e33e1SDouglas Gregor     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1377524e33e1SDouglas Gregor       << ActiveModule->getFullModuleName();
1378524e33e1SDouglas Gregor     HadError = true;
1379524e33e1SDouglas Gregor     return;
1380524e33e1SDouglas Gregor   }
1381524e33e1SDouglas Gregor 
1382524e33e1SDouglas Gregor   // Look for this file.
1383524e33e1SDouglas Gregor   const DirectoryEntry *Dir = 0;
1384524e33e1SDouglas Gregor   if (llvm::sys::path::is_absolute(DirName))
1385524e33e1SDouglas Gregor     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1386524e33e1SDouglas Gregor   else {
13872c1dd271SDylan Noblesmith     SmallString<128> PathName;
1388524e33e1SDouglas Gregor     PathName = Directory->getName();
1389524e33e1SDouglas Gregor     llvm::sys::path::append(PathName, DirName);
1390524e33e1SDouglas Gregor     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1391524e33e1SDouglas Gregor   }
1392524e33e1SDouglas Gregor 
1393524e33e1SDouglas Gregor   if (!Dir) {
1394524e33e1SDouglas Gregor     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1395524e33e1SDouglas Gregor       << DirName;
1396524e33e1SDouglas Gregor     HadError = true;
1397524e33e1SDouglas Gregor     return;
1398524e33e1SDouglas Gregor   }
1399524e33e1SDouglas Gregor 
1400524e33e1SDouglas Gregor   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1401524e33e1SDouglas Gregor     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1402524e33e1SDouglas Gregor       << OwningModule->getFullModuleName();
1403524e33e1SDouglas Gregor     HadError = true;
1404524e33e1SDouglas Gregor     return;
1405524e33e1SDouglas Gregor   }
1406524e33e1SDouglas Gregor 
1407524e33e1SDouglas Gregor   // Record this umbrella directory.
1408524e33e1SDouglas Gregor   Map.setUmbrellaDir(ActiveModule, Dir);
1409524e33e1SDouglas Gregor }
1410524e33e1SDouglas Gregor 
14112b82c2a5SDouglas Gregor /// \brief Parse a module export declaration.
14122b82c2a5SDouglas Gregor ///
14132b82c2a5SDouglas Gregor ///   export-declaration:
14142b82c2a5SDouglas Gregor ///     'export' wildcard-module-id
14152b82c2a5SDouglas Gregor ///
14162b82c2a5SDouglas Gregor ///   wildcard-module-id:
14172b82c2a5SDouglas Gregor ///     identifier
14182b82c2a5SDouglas Gregor ///     '*'
14192b82c2a5SDouglas Gregor ///     identifier '.' wildcard-module-id
14202b82c2a5SDouglas Gregor void ModuleMapParser::parseExportDecl() {
14212b82c2a5SDouglas Gregor   assert(Tok.is(MMToken::ExportKeyword));
14222b82c2a5SDouglas Gregor   SourceLocation ExportLoc = consumeToken();
14232b82c2a5SDouglas Gregor 
14242b82c2a5SDouglas Gregor   // Parse the module-id with an optional wildcard at the end.
14252b82c2a5SDouglas Gregor   ModuleId ParsedModuleId;
14262b82c2a5SDouglas Gregor   bool Wildcard = false;
14272b82c2a5SDouglas Gregor   do {
14282b82c2a5SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
14292b82c2a5SDouglas Gregor       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
14302b82c2a5SDouglas Gregor                                               Tok.getLocation()));
14312b82c2a5SDouglas Gregor       consumeToken();
14322b82c2a5SDouglas Gregor 
14332b82c2a5SDouglas Gregor       if (Tok.is(MMToken::Period)) {
14342b82c2a5SDouglas Gregor         consumeToken();
14352b82c2a5SDouglas Gregor         continue;
14362b82c2a5SDouglas Gregor       }
14372b82c2a5SDouglas Gregor 
14382b82c2a5SDouglas Gregor       break;
14392b82c2a5SDouglas Gregor     }
14402b82c2a5SDouglas Gregor 
14412b82c2a5SDouglas Gregor     if(Tok.is(MMToken::Star)) {
14422b82c2a5SDouglas Gregor       Wildcard = true;
1443f5eedd05SDouglas Gregor       consumeToken();
14442b82c2a5SDouglas Gregor       break;
14452b82c2a5SDouglas Gregor     }
14462b82c2a5SDouglas Gregor 
14472b82c2a5SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
14482b82c2a5SDouglas Gregor     HadError = true;
14492b82c2a5SDouglas Gregor     return;
14502b82c2a5SDouglas Gregor   } while (true);
14512b82c2a5SDouglas Gregor 
14522b82c2a5SDouglas Gregor   Module::UnresolvedExportDecl Unresolved = {
14532b82c2a5SDouglas Gregor     ExportLoc, ParsedModuleId, Wildcard
14542b82c2a5SDouglas Gregor   };
14552b82c2a5SDouglas Gregor   ActiveModule->UnresolvedExports.push_back(Unresolved);
14562b82c2a5SDouglas Gregor }
14572b82c2a5SDouglas Gregor 
14586ddfca91SDouglas Gregor /// \brief Parse a link declaration.
14596ddfca91SDouglas Gregor ///
14606ddfca91SDouglas Gregor ///   module-declaration:
14616ddfca91SDouglas Gregor ///     'link' 'framework'[opt] string-literal
14626ddfca91SDouglas Gregor void ModuleMapParser::parseLinkDecl() {
14636ddfca91SDouglas Gregor   assert(Tok.is(MMToken::LinkKeyword));
14646ddfca91SDouglas Gregor   SourceLocation LinkLoc = consumeToken();
14656ddfca91SDouglas Gregor 
14666ddfca91SDouglas Gregor   // Parse the optional 'framework' keyword.
14676ddfca91SDouglas Gregor   bool IsFramework = false;
14686ddfca91SDouglas Gregor   if (Tok.is(MMToken::FrameworkKeyword)) {
14696ddfca91SDouglas Gregor     consumeToken();
14706ddfca91SDouglas Gregor     IsFramework = true;
14716ddfca91SDouglas Gregor   }
14726ddfca91SDouglas Gregor 
14736ddfca91SDouglas Gregor   // Parse the library name
14746ddfca91SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
14756ddfca91SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
14766ddfca91SDouglas Gregor       << IsFramework << SourceRange(LinkLoc);
14776ddfca91SDouglas Gregor     HadError = true;
14786ddfca91SDouglas Gregor     return;
14796ddfca91SDouglas Gregor   }
14806ddfca91SDouglas Gregor 
14816ddfca91SDouglas Gregor   std::string LibraryName = Tok.getString();
14826ddfca91SDouglas Gregor   consumeToken();
14836ddfca91SDouglas Gregor   ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
14846ddfca91SDouglas Gregor                                                             IsFramework));
14856ddfca91SDouglas Gregor }
14866ddfca91SDouglas Gregor 
14876ddfca91SDouglas Gregor /// \brief Parse an inferred module declaration (wildcard modules).
14889194a91dSDouglas Gregor ///
14899194a91dSDouglas Gregor ///   module-declaration:
14909194a91dSDouglas Gregor ///     'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
14919194a91dSDouglas Gregor ///       { inferred-module-member* }
14929194a91dSDouglas Gregor ///
14939194a91dSDouglas Gregor ///   inferred-module-member:
14949194a91dSDouglas Gregor ///     'export' '*'
14959194a91dSDouglas Gregor ///     'exclude' identifier
14969194a91dSDouglas Gregor void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
149773441091SDouglas Gregor   assert(Tok.is(MMToken::Star));
149873441091SDouglas Gregor   SourceLocation StarLoc = consumeToken();
149973441091SDouglas Gregor   bool Failed = false;
150073441091SDouglas Gregor 
150173441091SDouglas Gregor   // Inferred modules must be submodules.
15029194a91dSDouglas Gregor   if (!ActiveModule && !Framework) {
150373441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
150473441091SDouglas Gregor     Failed = true;
150573441091SDouglas Gregor   }
150673441091SDouglas Gregor 
15079194a91dSDouglas Gregor   if (ActiveModule) {
1508524e33e1SDouglas Gregor     // Inferred modules must have umbrella directories.
1509524e33e1SDouglas Gregor     if (!Failed && !ActiveModule->getUmbrellaDir()) {
151073441091SDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
151173441091SDouglas Gregor       Failed = true;
151273441091SDouglas Gregor     }
151373441091SDouglas Gregor 
151473441091SDouglas Gregor     // Check for redefinition of an inferred module.
1515dd005f69SDouglas Gregor     if (!Failed && ActiveModule->InferSubmodules) {
151673441091SDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1517dd005f69SDouglas Gregor       if (ActiveModule->InferredSubmoduleLoc.isValid())
1518dd005f69SDouglas Gregor         Diags.Report(ActiveModule->InferredSubmoduleLoc,
151973441091SDouglas Gregor                      diag::note_mmap_prev_definition);
152073441091SDouglas Gregor       Failed = true;
152173441091SDouglas Gregor     }
152273441091SDouglas Gregor 
15239194a91dSDouglas Gregor     // Check for the 'framework' keyword, which is not permitted here.
15249194a91dSDouglas Gregor     if (Framework) {
15259194a91dSDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
15269194a91dSDouglas Gregor       Framework = false;
15279194a91dSDouglas Gregor     }
15289194a91dSDouglas Gregor   } else if (Explicit) {
15299194a91dSDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
15309194a91dSDouglas Gregor     Explicit = false;
15319194a91dSDouglas Gregor   }
15329194a91dSDouglas Gregor 
153373441091SDouglas Gregor   // If there were any problems with this inferred submodule, skip its body.
153473441091SDouglas Gregor   if (Failed) {
153573441091SDouglas Gregor     if (Tok.is(MMToken::LBrace)) {
153673441091SDouglas Gregor       consumeToken();
153773441091SDouglas Gregor       skipUntil(MMToken::RBrace);
153873441091SDouglas Gregor       if (Tok.is(MMToken::RBrace))
153973441091SDouglas Gregor         consumeToken();
154073441091SDouglas Gregor     }
154173441091SDouglas Gregor     HadError = true;
154273441091SDouglas Gregor     return;
154373441091SDouglas Gregor   }
154473441091SDouglas Gregor 
15459194a91dSDouglas Gregor   // Parse optional attributes.
15464442605fSBill Wendling   Attributes Attrs;
15479194a91dSDouglas Gregor   parseOptionalAttributes(Attrs);
15489194a91dSDouglas Gregor 
15499194a91dSDouglas Gregor   if (ActiveModule) {
155073441091SDouglas Gregor     // Note that we have an inferred submodule.
1551dd005f69SDouglas Gregor     ActiveModule->InferSubmodules = true;
1552dd005f69SDouglas Gregor     ActiveModule->InferredSubmoduleLoc = StarLoc;
1553dd005f69SDouglas Gregor     ActiveModule->InferExplicitSubmodules = Explicit;
15549194a91dSDouglas Gregor   } else {
15559194a91dSDouglas Gregor     // We'll be inferring framework modules for this directory.
15569194a91dSDouglas Gregor     Map.InferredDirectories[Directory].InferModules = true;
15579194a91dSDouglas Gregor     Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
15589194a91dSDouglas Gregor   }
155973441091SDouglas Gregor 
156073441091SDouglas Gregor   // Parse the opening brace.
156173441091SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
156273441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
156373441091SDouglas Gregor     HadError = true;
156473441091SDouglas Gregor     return;
156573441091SDouglas Gregor   }
156673441091SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
156773441091SDouglas Gregor 
156873441091SDouglas Gregor   // Parse the body of the inferred submodule.
156973441091SDouglas Gregor   bool Done = false;
157073441091SDouglas Gregor   do {
157173441091SDouglas Gregor     switch (Tok.Kind) {
157273441091SDouglas Gregor     case MMToken::EndOfFile:
157373441091SDouglas Gregor     case MMToken::RBrace:
157473441091SDouglas Gregor       Done = true;
157573441091SDouglas Gregor       break;
157673441091SDouglas Gregor 
15779194a91dSDouglas Gregor     case MMToken::ExcludeKeyword: {
15789194a91dSDouglas Gregor       if (ActiveModule) {
15799194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1580162405daSDouglas Gregor           << (ActiveModule != 0);
15819194a91dSDouglas Gregor         consumeToken();
15829194a91dSDouglas Gregor         break;
15839194a91dSDouglas Gregor       }
15849194a91dSDouglas Gregor 
15859194a91dSDouglas Gregor       consumeToken();
15869194a91dSDouglas Gregor       if (!Tok.is(MMToken::Identifier)) {
15879194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
15889194a91dSDouglas Gregor         break;
15899194a91dSDouglas Gregor       }
15909194a91dSDouglas Gregor 
15919194a91dSDouglas Gregor       Map.InferredDirectories[Directory].ExcludedModules
15929194a91dSDouglas Gregor         .push_back(Tok.getString());
15939194a91dSDouglas Gregor       consumeToken();
15949194a91dSDouglas Gregor       break;
15959194a91dSDouglas Gregor     }
15969194a91dSDouglas Gregor 
15979194a91dSDouglas Gregor     case MMToken::ExportKeyword:
15989194a91dSDouglas Gregor       if (!ActiveModule) {
15999194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1600162405daSDouglas Gregor           << (ActiveModule != 0);
16019194a91dSDouglas Gregor         consumeToken();
16029194a91dSDouglas Gregor         break;
16039194a91dSDouglas Gregor       }
16049194a91dSDouglas Gregor 
160573441091SDouglas Gregor       consumeToken();
160673441091SDouglas Gregor       if (Tok.is(MMToken::Star))
1607dd005f69SDouglas Gregor         ActiveModule->InferExportWildcard = true;
160873441091SDouglas Gregor       else
160973441091SDouglas Gregor         Diags.Report(Tok.getLocation(),
161073441091SDouglas Gregor                      diag::err_mmap_expected_export_wildcard);
161173441091SDouglas Gregor       consumeToken();
161273441091SDouglas Gregor       break;
161373441091SDouglas Gregor 
161473441091SDouglas Gregor     case MMToken::ExplicitKeyword:
161573441091SDouglas Gregor     case MMToken::ModuleKeyword:
161673441091SDouglas Gregor     case MMToken::HeaderKeyword:
161773441091SDouglas Gregor     case MMToken::UmbrellaKeyword:
161873441091SDouglas Gregor     default:
16199194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1620162405daSDouglas Gregor           << (ActiveModule != 0);
162173441091SDouglas Gregor       consumeToken();
162273441091SDouglas Gregor       break;
162373441091SDouglas Gregor     }
162473441091SDouglas Gregor   } while (!Done);
162573441091SDouglas Gregor 
162673441091SDouglas Gregor   if (Tok.is(MMToken::RBrace))
162773441091SDouglas Gregor     consumeToken();
162873441091SDouglas Gregor   else {
162973441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
163073441091SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
163173441091SDouglas Gregor     HadError = true;
163273441091SDouglas Gregor   }
163373441091SDouglas Gregor }
163473441091SDouglas Gregor 
16359194a91dSDouglas Gregor /// \brief Parse optional attributes.
16369194a91dSDouglas Gregor ///
16379194a91dSDouglas Gregor ///   attributes:
16389194a91dSDouglas Gregor ///     attribute attributes
16399194a91dSDouglas Gregor ///     attribute
16409194a91dSDouglas Gregor ///
16419194a91dSDouglas Gregor ///   attribute:
16429194a91dSDouglas Gregor ///     [ identifier ]
16439194a91dSDouglas Gregor ///
16449194a91dSDouglas Gregor /// \param Attrs Will be filled in with the parsed attributes.
16459194a91dSDouglas Gregor ///
16469194a91dSDouglas Gregor /// \returns true if an error occurred, false otherwise.
16474442605fSBill Wendling bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
16489194a91dSDouglas Gregor   bool HadError = false;
16499194a91dSDouglas Gregor 
16509194a91dSDouglas Gregor   while (Tok.is(MMToken::LSquare)) {
16519194a91dSDouglas Gregor     // Consume the '['.
16529194a91dSDouglas Gregor     SourceLocation LSquareLoc = consumeToken();
16539194a91dSDouglas Gregor 
16549194a91dSDouglas Gregor     // Check whether we have an attribute name here.
16559194a91dSDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
16569194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
16579194a91dSDouglas Gregor       skipUntil(MMToken::RSquare);
16589194a91dSDouglas Gregor       if (Tok.is(MMToken::RSquare))
16599194a91dSDouglas Gregor         consumeToken();
16609194a91dSDouglas Gregor       HadError = true;
16619194a91dSDouglas Gregor     }
16629194a91dSDouglas Gregor 
16639194a91dSDouglas Gregor     // Decode the attribute name.
16649194a91dSDouglas Gregor     AttributeKind Attribute
16659194a91dSDouglas Gregor       = llvm::StringSwitch<AttributeKind>(Tok.getString())
16669194a91dSDouglas Gregor           .Case("system", AT_system)
16679194a91dSDouglas Gregor           .Default(AT_unknown);
16689194a91dSDouglas Gregor     switch (Attribute) {
16699194a91dSDouglas Gregor     case AT_unknown:
16709194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
16719194a91dSDouglas Gregor         << Tok.getString();
16729194a91dSDouglas Gregor       break;
16739194a91dSDouglas Gregor 
16749194a91dSDouglas Gregor     case AT_system:
16759194a91dSDouglas Gregor       Attrs.IsSystem = true;
16769194a91dSDouglas Gregor       break;
16779194a91dSDouglas Gregor     }
16789194a91dSDouglas Gregor     consumeToken();
16799194a91dSDouglas Gregor 
16809194a91dSDouglas Gregor     // Consume the ']'.
16819194a91dSDouglas Gregor     if (!Tok.is(MMToken::RSquare)) {
16829194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
16839194a91dSDouglas Gregor       Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
16849194a91dSDouglas Gregor       skipUntil(MMToken::RSquare);
16859194a91dSDouglas Gregor       HadError = true;
16869194a91dSDouglas Gregor     }
16879194a91dSDouglas Gregor 
16889194a91dSDouglas Gregor     if (Tok.is(MMToken::RSquare))
16899194a91dSDouglas Gregor       consumeToken();
16909194a91dSDouglas Gregor   }
16919194a91dSDouglas Gregor 
16929194a91dSDouglas Gregor   return HadError;
16939194a91dSDouglas Gregor }
16949194a91dSDouglas Gregor 
16957033127bSDouglas Gregor /// \brief If there is a specific header search directory due the presence
16967033127bSDouglas Gregor /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
16977033127bSDouglas Gregor const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
16987033127bSDouglas Gregor   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
16997033127bSDouglas Gregor     // If we have an umbrella directory, use that.
17007033127bSDouglas Gregor     if (Mod->hasUmbrellaDir())
17017033127bSDouglas Gregor       return Mod->getUmbrellaDir();
17027033127bSDouglas Gregor 
17037033127bSDouglas Gregor     // If we have a framework directory, stop looking.
17047033127bSDouglas Gregor     if (Mod->IsFramework)
17057033127bSDouglas Gregor       return 0;
17067033127bSDouglas Gregor   }
17077033127bSDouglas Gregor 
17087033127bSDouglas Gregor   return 0;
17097033127bSDouglas Gregor }
17107033127bSDouglas Gregor 
1711718292f2SDouglas Gregor /// \brief Parse a module map file.
1712718292f2SDouglas Gregor ///
1713718292f2SDouglas Gregor ///   module-map-file:
1714718292f2SDouglas Gregor ///     module-declaration*
1715718292f2SDouglas Gregor bool ModuleMapParser::parseModuleMapFile() {
1716718292f2SDouglas Gregor   do {
1717718292f2SDouglas Gregor     switch (Tok.Kind) {
1718718292f2SDouglas Gregor     case MMToken::EndOfFile:
1719718292f2SDouglas Gregor       return HadError;
1720718292f2SDouglas Gregor 
1721e7ab3669SDouglas Gregor     case MMToken::ExplicitKeyword:
1722718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
1723755b2055SDouglas Gregor     case MMToken::FrameworkKeyword:
1724718292f2SDouglas Gregor       parseModuleDecl();
1725718292f2SDouglas Gregor       break;
1726718292f2SDouglas Gregor 
17271fb5c3a6SDouglas Gregor     case MMToken::Comma:
172859527666SDouglas Gregor     case MMToken::ExcludeKeyword:
17292b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
1730718292f2SDouglas Gregor     case MMToken::HeaderKeyword:
1731718292f2SDouglas Gregor     case MMToken::Identifier:
1732718292f2SDouglas Gregor     case MMToken::LBrace:
17336ddfca91SDouglas Gregor     case MMToken::LinkKeyword:
1734a686e1b0SDouglas Gregor     case MMToken::LSquare:
17352b82c2a5SDouglas Gregor     case MMToken::Period:
1736718292f2SDouglas Gregor     case MMToken::RBrace:
1737a686e1b0SDouglas Gregor     case MMToken::RSquare:
17381fb5c3a6SDouglas Gregor     case MMToken::RequiresKeyword:
17392b82c2a5SDouglas Gregor     case MMToken::Star:
1740718292f2SDouglas Gregor     case MMToken::StringLiteral:
1741718292f2SDouglas Gregor     case MMToken::UmbrellaKeyword:
1742718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1743718292f2SDouglas Gregor       HadError = true;
1744718292f2SDouglas Gregor       consumeToken();
1745718292f2SDouglas Gregor       break;
1746718292f2SDouglas Gregor     }
1747718292f2SDouglas Gregor   } while (true);
1748718292f2SDouglas Gregor }
1749718292f2SDouglas Gregor 
1750718292f2SDouglas Gregor bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
17514ddf2221SDouglas Gregor   llvm::DenseMap<const FileEntry *, bool>::iterator Known
17524ddf2221SDouglas Gregor     = ParsedModuleMap.find(File);
17534ddf2221SDouglas Gregor   if (Known != ParsedModuleMap.end())
17544ddf2221SDouglas Gregor     return Known->second;
17554ddf2221SDouglas Gregor 
175689929282SDouglas Gregor   assert(Target != 0 && "Missing target information");
1757718292f2SDouglas Gregor   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1758718292f2SDouglas Gregor   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1759718292f2SDouglas Gregor   if (!Buffer)
17604ddf2221SDouglas Gregor     return ParsedModuleMap[File] = true;
1761718292f2SDouglas Gregor 
1762718292f2SDouglas Gregor   // Parse this module map file.
17631fb5c3a6SDouglas Gregor   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
17641fb5c3a6SDouglas Gregor   Diags->getClient()->BeginSourceFile(MMapLangOpts);
1765bc10b9fbSDouglas Gregor   ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
17663ec6663bSDouglas Gregor                          BuiltinIncludeDir);
1767718292f2SDouglas Gregor   bool Result = Parser.parseModuleMapFile();
1768718292f2SDouglas Gregor   Diags->getClient()->EndSourceFile();
17694ddf2221SDouglas Gregor   ParsedModuleMap[File] = Result;
1770718292f2SDouglas Gregor   return Result;
1771718292f2SDouglas Gregor }
1772