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"
21b146baabSArgyrios Kyrtzidis #include "clang/Lex/HeaderSearch.h"
223a02247dSChandler Carruth #include "clang/Lex/LexDiagnostic.h"
233a02247dSChandler Carruth #include "clang/Lex/Lexer.h"
243a02247dSChandler Carruth #include "clang/Lex/LiteralSupport.h"
253a02247dSChandler Carruth #include "llvm/ADT/StringRef.h"
263a02247dSChandler Carruth #include "llvm/ADT/StringSwitch.h"
27718292f2SDouglas Gregor #include "llvm/Support/Allocator.h"
28e89dbc1dSDouglas Gregor #include "llvm/Support/FileSystem.h"
29718292f2SDouglas Gregor #include "llvm/Support/Host.h"
30552c169eSRafael Espindola #include "llvm/Support/Path.h"
31718292f2SDouglas Gregor #include "llvm/Support/raw_ostream.h"
3207c22b78SDouglas Gregor #include <stdlib.h>
3301c7cfa2SDouglas Gregor #if defined(LLVM_ON_UNIX)
34eadae014SDmitri Gribenko #include <limits.h>
3501c7cfa2SDouglas Gregor #endif
36718292f2SDouglas Gregor using namespace clang;
37718292f2SDouglas Gregor 
382b82c2a5SDouglas Gregor Module::ExportDecl
392b82c2a5SDouglas Gregor ModuleMap::resolveExport(Module *Mod,
402b82c2a5SDouglas Gregor                          const Module::UnresolvedExportDecl &Unresolved,
41e4412640SArgyrios Kyrtzidis                          bool Complain) const {
42f5eedd05SDouglas Gregor   // We may have just a wildcard.
43f5eedd05SDouglas Gregor   if (Unresolved.Id.empty()) {
44f5eedd05SDouglas Gregor     assert(Unresolved.Wildcard && "Invalid unresolved export");
45f5eedd05SDouglas Gregor     return Module::ExportDecl(0, true);
46f5eedd05SDouglas Gregor   }
47f5eedd05SDouglas Gregor 
48fb912657SDouglas Gregor   // Resolve the module-id.
49fb912657SDouglas Gregor   Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
50fb912657SDouglas Gregor   if (!Context)
51fb912657SDouglas Gregor     return Module::ExportDecl();
52fb912657SDouglas Gregor 
53fb912657SDouglas Gregor   return Module::ExportDecl(Context, Unresolved.Wildcard);
54fb912657SDouglas Gregor }
55fb912657SDouglas Gregor 
56fb912657SDouglas Gregor Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
57fb912657SDouglas Gregor                                    bool Complain) const {
582b82c2a5SDouglas Gregor   // Find the starting module.
59fb912657SDouglas Gregor   Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
602b82c2a5SDouglas Gregor   if (!Context) {
612b82c2a5SDouglas Gregor     if (Complain)
62fb912657SDouglas Gregor       Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
63fb912657SDouglas Gregor       << Id[0].first << Mod->getFullModuleName();
642b82c2a5SDouglas Gregor 
65fb912657SDouglas Gregor     return 0;
662b82c2a5SDouglas Gregor   }
672b82c2a5SDouglas Gregor 
682b82c2a5SDouglas Gregor   // Dig into the module path.
69fb912657SDouglas Gregor   for (unsigned I = 1, N = Id.size(); I != N; ++I) {
70fb912657SDouglas Gregor     Module *Sub = lookupModuleQualified(Id[I].first, Context);
712b82c2a5SDouglas Gregor     if (!Sub) {
722b82c2a5SDouglas Gregor       if (Complain)
73fb912657SDouglas Gregor         Diags->Report(Id[I].second, diag::err_mmap_missing_module_qualified)
74fb912657SDouglas Gregor         << Id[I].first << Context->getFullModuleName()
75fb912657SDouglas Gregor         << SourceRange(Id[0].second, Id[I-1].second);
762b82c2a5SDouglas Gregor 
77fb912657SDouglas Gregor       return 0;
782b82c2a5SDouglas Gregor     }
792b82c2a5SDouglas Gregor 
802b82c2a5SDouglas Gregor     Context = Sub;
812b82c2a5SDouglas Gregor   }
822b82c2a5SDouglas Gregor 
83fb912657SDouglas Gregor   return Context;
842b82c2a5SDouglas Gregor }
852b82c2a5SDouglas Gregor 
861f76c4e8SManuel Klimek ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticConsumer &DC,
87b146baabSArgyrios Kyrtzidis                      const LangOptions &LangOpts, const TargetInfo *Target,
88b146baabSArgyrios Kyrtzidis                      HeaderSearch &HeaderInfo)
891f76c4e8SManuel Klimek     : SourceMgr(SourceMgr), LangOpts(LangOpts), Target(Target),
901f76c4e8SManuel Klimek       HeaderInfo(HeaderInfo), BuiltinIncludeDir(0), CompilingModule(0),
911f76c4e8SManuel Klimek       SourceModule(0) {
92c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
93c95d8192SDylan Noblesmith   Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
94811db4eaSDouglas Gregor             new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
956b930967SDouglas Gregor   Diags->setClient(new ForwardingDiagnosticConsumer(DC),
966b930967SDouglas Gregor                    /*ShouldOwnClient=*/true);
971f76c4e8SManuel Klimek   Diags->setSourceManager(&SourceMgr);
98718292f2SDouglas Gregor }
99718292f2SDouglas Gregor 
100718292f2SDouglas Gregor ModuleMap::~ModuleMap() {
1015acdf59eSDouglas Gregor   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
1025acdf59eSDouglas Gregor                                         IEnd = Modules.end();
1035acdf59eSDouglas Gregor        I != IEnd; ++I) {
1045acdf59eSDouglas Gregor     delete I->getValue();
1055acdf59eSDouglas Gregor   }
106718292f2SDouglas Gregor }
107718292f2SDouglas Gregor 
10889929282SDouglas Gregor void ModuleMap::setTarget(const TargetInfo &Target) {
10989929282SDouglas Gregor   assert((!this->Target || this->Target == &Target) &&
11089929282SDouglas Gregor          "Improper target override");
11189929282SDouglas Gregor   this->Target = &Target;
11289929282SDouglas Gregor }
11389929282SDouglas Gregor 
114056396aeSDouglas Gregor /// \brief "Sanitize" a filename so that it can be used as an identifier.
115056396aeSDouglas Gregor static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
116056396aeSDouglas Gregor                                               SmallVectorImpl<char> &Buffer) {
117056396aeSDouglas Gregor   if (Name.empty())
118056396aeSDouglas Gregor     return Name;
119056396aeSDouglas Gregor 
120a7d03840SJordan Rose   if (!isValidIdentifier(Name)) {
121056396aeSDouglas Gregor     // If we don't already have something with the form of an identifier,
122056396aeSDouglas Gregor     // create a buffer with the sanitized name.
123056396aeSDouglas Gregor     Buffer.clear();
124a7d03840SJordan Rose     if (isDigit(Name[0]))
125056396aeSDouglas Gregor       Buffer.push_back('_');
126056396aeSDouglas Gregor     Buffer.reserve(Buffer.size() + Name.size());
127056396aeSDouglas Gregor     for (unsigned I = 0, N = Name.size(); I != N; ++I) {
128a7d03840SJordan Rose       if (isIdentifierBody(Name[I]))
129056396aeSDouglas Gregor         Buffer.push_back(Name[I]);
130056396aeSDouglas Gregor       else
131056396aeSDouglas Gregor         Buffer.push_back('_');
132056396aeSDouglas Gregor     }
133056396aeSDouglas Gregor 
134056396aeSDouglas Gregor     Name = StringRef(Buffer.data(), Buffer.size());
135056396aeSDouglas Gregor   }
136056396aeSDouglas Gregor 
137056396aeSDouglas Gregor   while (llvm::StringSwitch<bool>(Name)
138056396aeSDouglas Gregor #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
139056396aeSDouglas Gregor #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
140056396aeSDouglas Gregor #include "clang/Basic/TokenKinds.def"
141056396aeSDouglas Gregor            .Default(false)) {
142056396aeSDouglas Gregor     if (Name.data() != Buffer.data())
143056396aeSDouglas Gregor       Buffer.append(Name.begin(), Name.end());
144056396aeSDouglas Gregor     Buffer.push_back('_');
145056396aeSDouglas Gregor     Name = StringRef(Buffer.data(), Buffer.size());
146056396aeSDouglas Gregor   }
147056396aeSDouglas Gregor 
148056396aeSDouglas Gregor   return Name;
149056396aeSDouglas Gregor }
150056396aeSDouglas Gregor 
15134d52749SDouglas Gregor /// \brief Determine whether the given file name is the name of a builtin
15234d52749SDouglas Gregor /// header, supplied by Clang to replace, override, or augment existing system
15334d52749SDouglas Gregor /// headers.
15434d52749SDouglas Gregor static bool isBuiltinHeader(StringRef FileName) {
15534d52749SDouglas Gregor   return llvm::StringSwitch<bool>(FileName)
15634d52749SDouglas Gregor            .Case("float.h", true)
15734d52749SDouglas Gregor            .Case("iso646.h", true)
15834d52749SDouglas Gregor            .Case("limits.h", true)
15934d52749SDouglas Gregor            .Case("stdalign.h", true)
16034d52749SDouglas Gregor            .Case("stdarg.h", true)
16134d52749SDouglas Gregor            .Case("stdbool.h", true)
16234d52749SDouglas Gregor            .Case("stddef.h", true)
16334d52749SDouglas Gregor            .Case("stdint.h", true)
16434d52749SDouglas Gregor            .Case("tgmath.h", true)
16534d52749SDouglas Gregor            .Case("unwind.h", true)
16634d52749SDouglas Gregor            .Default(false);
16734d52749SDouglas Gregor }
16834d52749SDouglas Gregor 
16997da9178SDaniel Jasper ModuleMap::KnownHeader
17097da9178SDaniel Jasper ModuleMap::findModuleForHeader(const FileEntry *File,
171*4eaf0a6cSDaniel Jasper                                Module *RequestingModule,
172*4eaf0a6cSDaniel Jasper                                bool *FoundInModule) {
17359527666SDouglas Gregor   HeadersMap::iterator Known = Headers.find(File);
174*4eaf0a6cSDaniel Jasper 
175*4eaf0a6cSDaniel Jasper   // If we've found a builtin header within Clang's builtin include directory,
176*4eaf0a6cSDaniel Jasper   // load all of the module maps to see if it will get associated with a
177*4eaf0a6cSDaniel Jasper   // specific module (e.g., in /usr/include).
178*4eaf0a6cSDaniel Jasper   if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
179*4eaf0a6cSDaniel Jasper       isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
180*4eaf0a6cSDaniel Jasper     HeaderInfo.loadTopLevelSystemModules();
181*4eaf0a6cSDaniel Jasper     Known = Headers.find(File);
182*4eaf0a6cSDaniel Jasper   }
183*4eaf0a6cSDaniel Jasper 
1841fb5c3a6SDouglas Gregor   if (Known != Headers.end()) {
18597da9178SDaniel Jasper     ModuleMap::KnownHeader Result = KnownHeader();
1861fb5c3a6SDouglas Gregor 
18797da9178SDaniel Jasper     // Iterate over all modules that 'File' is part of to find the best fit.
18897da9178SDaniel Jasper     for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
18997da9178SDaniel Jasper                                                 E = Known->second.end();
19097da9178SDaniel Jasper          I != E; ++I) {
191*4eaf0a6cSDaniel Jasper       // Cannot use a module if the header is excluded in it.
192*4eaf0a6cSDaniel Jasper       if (I->getRole() == ModuleMap::ExcludedHeader)
193*4eaf0a6cSDaniel Jasper         continue;
194*4eaf0a6cSDaniel Jasper 
195*4eaf0a6cSDaniel Jasper       if (FoundInModule)
196*4eaf0a6cSDaniel Jasper         *FoundInModule = true;
197*4eaf0a6cSDaniel Jasper 
198*4eaf0a6cSDaniel Jasper       // Cannot use a module if it is unavailable.
199*4eaf0a6cSDaniel Jasper       if (!I->getModule()->isAvailable())
20097da9178SDaniel Jasper         continue;
20197da9178SDaniel Jasper 
20297da9178SDaniel Jasper       // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
20397da9178SDaniel Jasper       // module we are looking for.
20497da9178SDaniel Jasper       if (I->getModule() == RequestingModule)
20597da9178SDaniel Jasper         return *I;
20697da9178SDaniel Jasper 
20797da9178SDaniel Jasper       // If uses need to be specified explicitly, we are only allowed to return
20897da9178SDaniel Jasper       // modules that are explicitly used by the requesting module.
20997da9178SDaniel Jasper       if (RequestingModule && LangOpts.ModulesDeclUse &&
21097da9178SDaniel Jasper           std::find(RequestingModule->DirectUses.begin(),
21197da9178SDaniel Jasper                     RequestingModule->DirectUses.end(),
21297da9178SDaniel Jasper                     I->getModule()) == RequestingModule->DirectUses.end())
21397da9178SDaniel Jasper         continue;
214*4eaf0a6cSDaniel Jasper 
21597da9178SDaniel Jasper       Result = *I;
21697da9178SDaniel Jasper       // If 'File' is a public header of this module, this is as good as we
21797da9178SDaniel Jasper       // are going to get.
21897da9178SDaniel Jasper       if (I->getRole() == ModuleMap::NormalHeader)
21997da9178SDaniel Jasper         break;
22097da9178SDaniel Jasper     }
22197da9178SDaniel Jasper     return Result;
2221fb5c3a6SDouglas Gregor   }
223ab0c8a84SDouglas Gregor 
224b65dbfffSDouglas Gregor   const DirectoryEntry *Dir = File->getDir();
225f857950dSDmitri Gribenko   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
226e00c8b20SDouglas Gregor 
22774260502SDouglas Gregor   // Note: as an egregious but useful hack we use the real path here, because
22874260502SDouglas Gregor   // frameworks moving from top-level frameworks to embedded frameworks tend
22974260502SDouglas Gregor   // to be symlinked from the top-level location to the embedded location,
23074260502SDouglas Gregor   // and we need to resolve lookups as if we had found the embedded location.
2311f76c4e8SManuel Klimek   StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
232a89c5ac4SDouglas Gregor 
233a89c5ac4SDouglas Gregor   // Keep walking up the directory hierarchy, looking for a directory with
234a89c5ac4SDouglas Gregor   // an umbrella header.
235b65dbfffSDouglas Gregor   do {
236a89c5ac4SDouglas Gregor     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
237a89c5ac4SDouglas Gregor       = UmbrellaDirs.find(Dir);
238a89c5ac4SDouglas Gregor     if (KnownDir != UmbrellaDirs.end()) {
239a89c5ac4SDouglas Gregor       Module *Result = KnownDir->second;
240930a85ccSDouglas Gregor 
241930a85ccSDouglas Gregor       // Search up the module stack until we find a module with an umbrella
24273141fa9SDouglas Gregor       // directory.
243930a85ccSDouglas Gregor       Module *UmbrellaModule = Result;
24473141fa9SDouglas Gregor       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
245930a85ccSDouglas Gregor         UmbrellaModule = UmbrellaModule->Parent;
246930a85ccSDouglas Gregor 
247930a85ccSDouglas Gregor       if (UmbrellaModule->InferSubmodules) {
248a89c5ac4SDouglas Gregor         // Infer submodules for each of the directories we found between
249a89c5ac4SDouglas Gregor         // the directory of the umbrella header and the directory where
250a89c5ac4SDouglas Gregor         // the actual header is located.
2519458f82dSDouglas Gregor         bool Explicit = UmbrellaModule->InferExplicitSubmodules;
2529458f82dSDouglas Gregor 
2537033127bSDouglas Gregor         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
254a89c5ac4SDouglas Gregor           // Find or create the module that corresponds to this directory name.
255056396aeSDouglas Gregor           SmallString<32> NameBuf;
256056396aeSDouglas Gregor           StringRef Name = sanitizeFilenameAsIdentifier(
257056396aeSDouglas Gregor                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
258056396aeSDouglas Gregor                              NameBuf);
259a89c5ac4SDouglas Gregor           Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
2609458f82dSDouglas Gregor                                       Explicit).first;
261a89c5ac4SDouglas Gregor 
262a89c5ac4SDouglas Gregor           // Associate the module and the directory.
263a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I-1]] = Result;
264a89c5ac4SDouglas Gregor 
265a89c5ac4SDouglas Gregor           // If inferred submodules export everything they import, add a
266a89c5ac4SDouglas Gregor           // wildcard to the set of exports.
267930a85ccSDouglas Gregor           if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
268a89c5ac4SDouglas Gregor             Result->Exports.push_back(Module::ExportDecl(0, true));
269a89c5ac4SDouglas Gregor         }
270a89c5ac4SDouglas Gregor 
271a89c5ac4SDouglas Gregor         // Infer a submodule with the same name as this header file.
272056396aeSDouglas Gregor         SmallString<32> NameBuf;
273056396aeSDouglas Gregor         StringRef Name = sanitizeFilenameAsIdentifier(
274056396aeSDouglas Gregor                            llvm::sys::path::stem(File->getName()), NameBuf);
275a89c5ac4SDouglas Gregor         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
2769458f82dSDouglas Gregor                                     Explicit).first;
2773c5305c1SArgyrios Kyrtzidis         Result->addTopHeader(File);
278a89c5ac4SDouglas Gregor 
279a89c5ac4SDouglas Gregor         // If inferred submodules export everything they import, add a
280a89c5ac4SDouglas Gregor         // wildcard to the set of exports.
281930a85ccSDouglas Gregor         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
282a89c5ac4SDouglas Gregor           Result->Exports.push_back(Module::ExportDecl(0, true));
283a89c5ac4SDouglas Gregor       } else {
284a89c5ac4SDouglas Gregor         // Record each of the directories we stepped through as being part of
285a89c5ac4SDouglas Gregor         // the module we found, since the umbrella header covers them all.
286a89c5ac4SDouglas Gregor         for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
287a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I]] = Result;
288a89c5ac4SDouglas Gregor       }
289a89c5ac4SDouglas Gregor 
29097da9178SDaniel Jasper       Headers[File].push_back(KnownHeader(Result, NormalHeader));
2911fb5c3a6SDouglas Gregor 
2921fb5c3a6SDouglas Gregor       // If a header corresponds to an unavailable module, don't report
2931fb5c3a6SDouglas Gregor       // that it maps to anything.
2941fb5c3a6SDouglas Gregor       if (!Result->isAvailable())
295b53e5483SLawrence Crowl         return KnownHeader();
2961fb5c3a6SDouglas Gregor 
29797da9178SDaniel Jasper       return Headers[File].back();
298a89c5ac4SDouglas Gregor     }
299a89c5ac4SDouglas Gregor 
300a89c5ac4SDouglas Gregor     SkippedDirs.push_back(Dir);
301a89c5ac4SDouglas Gregor 
302b65dbfffSDouglas Gregor     // Retrieve our parent path.
303b65dbfffSDouglas Gregor     DirName = llvm::sys::path::parent_path(DirName);
304b65dbfffSDouglas Gregor     if (DirName.empty())
305b65dbfffSDouglas Gregor       break;
306b65dbfffSDouglas Gregor 
307b65dbfffSDouglas Gregor     // Resolve the parent path to a directory entry.
3081f76c4e8SManuel Klimek     Dir = SourceMgr.getFileManager().getDirectory(DirName);
309a89c5ac4SDouglas Gregor   } while (Dir);
310b65dbfffSDouglas Gregor 
311b53e5483SLawrence Crowl   return KnownHeader();
312ab0c8a84SDouglas Gregor }
313ab0c8a84SDouglas Gregor 
314e4412640SArgyrios Kyrtzidis bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
315e4412640SArgyrios Kyrtzidis   HeadersMap::const_iterator Known = Headers.find(Header);
31697da9178SDaniel Jasper   if (Known != Headers.end()) {
31797da9178SDaniel Jasper     for (SmallVectorImpl<KnownHeader>::const_iterator
31897da9178SDaniel Jasper              I = Known->second.begin(),
31997da9178SDaniel Jasper              E = Known->second.end();
32097da9178SDaniel Jasper          I != E; ++I) {
32197da9178SDaniel Jasper       if (I->isAvailable())
32297da9178SDaniel Jasper         return false;
32397da9178SDaniel Jasper     }
32497da9178SDaniel Jasper     return true;
32597da9178SDaniel Jasper   }
3261fb5c3a6SDouglas Gregor 
3271fb5c3a6SDouglas Gregor   const DirectoryEntry *Dir = Header->getDir();
328f857950dSDmitri Gribenko   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
3291fb5c3a6SDouglas Gregor   StringRef DirName = Dir->getName();
3301fb5c3a6SDouglas Gregor 
3311fb5c3a6SDouglas Gregor   // Keep walking up the directory hierarchy, looking for a directory with
3321fb5c3a6SDouglas Gregor   // an umbrella header.
3331fb5c3a6SDouglas Gregor   do {
334e4412640SArgyrios Kyrtzidis     llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
3351fb5c3a6SDouglas Gregor       = UmbrellaDirs.find(Dir);
3361fb5c3a6SDouglas Gregor     if (KnownDir != UmbrellaDirs.end()) {
3371fb5c3a6SDouglas Gregor       Module *Found = KnownDir->second;
3381fb5c3a6SDouglas Gregor       if (!Found->isAvailable())
3391fb5c3a6SDouglas Gregor         return true;
3401fb5c3a6SDouglas Gregor 
3411fb5c3a6SDouglas Gregor       // Search up the module stack until we find a module with an umbrella
3421fb5c3a6SDouglas Gregor       // directory.
3431fb5c3a6SDouglas Gregor       Module *UmbrellaModule = Found;
3441fb5c3a6SDouglas Gregor       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
3451fb5c3a6SDouglas Gregor         UmbrellaModule = UmbrellaModule->Parent;
3461fb5c3a6SDouglas Gregor 
3471fb5c3a6SDouglas Gregor       if (UmbrellaModule->InferSubmodules) {
3481fb5c3a6SDouglas Gregor         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
3491fb5c3a6SDouglas Gregor           // Find or create the module that corresponds to this directory name.
350056396aeSDouglas Gregor           SmallString<32> NameBuf;
351056396aeSDouglas Gregor           StringRef Name = sanitizeFilenameAsIdentifier(
352056396aeSDouglas Gregor                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
353056396aeSDouglas Gregor                              NameBuf);
3541fb5c3a6SDouglas Gregor           Found = lookupModuleQualified(Name, Found);
3551fb5c3a6SDouglas Gregor           if (!Found)
3561fb5c3a6SDouglas Gregor             return false;
3571fb5c3a6SDouglas Gregor           if (!Found->isAvailable())
3581fb5c3a6SDouglas Gregor             return true;
3591fb5c3a6SDouglas Gregor         }
3601fb5c3a6SDouglas Gregor 
3611fb5c3a6SDouglas Gregor         // Infer a submodule with the same name as this header file.
362056396aeSDouglas Gregor         SmallString<32> NameBuf;
363056396aeSDouglas Gregor         StringRef Name = sanitizeFilenameAsIdentifier(
364056396aeSDouglas Gregor                            llvm::sys::path::stem(Header->getName()),
365056396aeSDouglas Gregor                            NameBuf);
3661fb5c3a6SDouglas Gregor         Found = lookupModuleQualified(Name, Found);
3671fb5c3a6SDouglas Gregor         if (!Found)
3681fb5c3a6SDouglas Gregor           return false;
3691fb5c3a6SDouglas Gregor       }
3701fb5c3a6SDouglas Gregor 
3711fb5c3a6SDouglas Gregor       return !Found->isAvailable();
3721fb5c3a6SDouglas Gregor     }
3731fb5c3a6SDouglas Gregor 
3741fb5c3a6SDouglas Gregor     SkippedDirs.push_back(Dir);
3751fb5c3a6SDouglas Gregor 
3761fb5c3a6SDouglas Gregor     // Retrieve our parent path.
3771fb5c3a6SDouglas Gregor     DirName = llvm::sys::path::parent_path(DirName);
3781fb5c3a6SDouglas Gregor     if (DirName.empty())
3791fb5c3a6SDouglas Gregor       break;
3801fb5c3a6SDouglas Gregor 
3811fb5c3a6SDouglas Gregor     // Resolve the parent path to a directory entry.
3821f76c4e8SManuel Klimek     Dir = SourceMgr.getFileManager().getDirectory(DirName);
3831fb5c3a6SDouglas Gregor   } while (Dir);
3841fb5c3a6SDouglas Gregor 
3851fb5c3a6SDouglas Gregor   return false;
3861fb5c3a6SDouglas Gregor }
3871fb5c3a6SDouglas Gregor 
388e4412640SArgyrios Kyrtzidis Module *ModuleMap::findModule(StringRef Name) const {
389e4412640SArgyrios Kyrtzidis   llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
39088bdfb0eSDouglas Gregor   if (Known != Modules.end())
39188bdfb0eSDouglas Gregor     return Known->getValue();
39288bdfb0eSDouglas Gregor 
39388bdfb0eSDouglas Gregor   return 0;
39488bdfb0eSDouglas Gregor }
39588bdfb0eSDouglas Gregor 
396e4412640SArgyrios Kyrtzidis Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
397e4412640SArgyrios Kyrtzidis                                            Module *Context) const {
3982b82c2a5SDouglas Gregor   for(; Context; Context = Context->Parent) {
3992b82c2a5SDouglas Gregor     if (Module *Sub = lookupModuleQualified(Name, Context))
4002b82c2a5SDouglas Gregor       return Sub;
4012b82c2a5SDouglas Gregor   }
4022b82c2a5SDouglas Gregor 
4032b82c2a5SDouglas Gregor   return findModule(Name);
4042b82c2a5SDouglas Gregor }
4052b82c2a5SDouglas Gregor 
406e4412640SArgyrios Kyrtzidis Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
4072b82c2a5SDouglas Gregor   if (!Context)
4082b82c2a5SDouglas Gregor     return findModule(Name);
4092b82c2a5SDouglas Gregor 
410eb90e830SDouglas Gregor   return Context->findSubmodule(Name);
4112b82c2a5SDouglas Gregor }
4122b82c2a5SDouglas Gregor 
413de3ef502SDouglas Gregor std::pair<Module *, bool>
41469021974SDouglas Gregor ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
41569021974SDouglas Gregor                               bool IsExplicit) {
41669021974SDouglas Gregor   // Try to find an existing module with this name.
417eb90e830SDouglas Gregor   if (Module *Sub = lookupModuleQualified(Name, Parent))
418eb90e830SDouglas Gregor     return std::make_pair(Sub, false);
41969021974SDouglas Gregor 
42069021974SDouglas Gregor   // Create a new module with this name.
42169021974SDouglas Gregor   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
42269021974SDouglas Gregor                               IsExplicit);
423ba7f2f71SDaniel Jasper   if (LangOpts.CurrentModule == Name) {
424ba7f2f71SDaniel Jasper     SourceModule = Result;
425ba7f2f71SDaniel Jasper     SourceModuleName = Name;
426ba7f2f71SDaniel Jasper   }
4276f722b4eSArgyrios Kyrtzidis   if (!Parent) {
42869021974SDouglas Gregor     Modules[Name] = Result;
4296f722b4eSArgyrios Kyrtzidis     if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
4306f722b4eSArgyrios Kyrtzidis         Name == LangOpts.CurrentModule) {
4316f722b4eSArgyrios Kyrtzidis       CompilingModule = Result;
4326f722b4eSArgyrios Kyrtzidis     }
4336f722b4eSArgyrios Kyrtzidis   }
43469021974SDouglas Gregor   return std::make_pair(Result, true);
43569021974SDouglas Gregor }
43669021974SDouglas Gregor 
4379194a91dSDouglas Gregor bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
438e4412640SArgyrios Kyrtzidis                                         StringRef Name, bool &IsSystem) const {
4399194a91dSDouglas Gregor   // Check whether we have already looked into the parent directory
4409194a91dSDouglas Gregor   // for a module map.
441e4412640SArgyrios Kyrtzidis   llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
4429194a91dSDouglas Gregor     inferred = InferredDirectories.find(ParentDir);
4439194a91dSDouglas Gregor   if (inferred == InferredDirectories.end())
4449194a91dSDouglas Gregor     return false;
4459194a91dSDouglas Gregor 
4469194a91dSDouglas Gregor   if (!inferred->second.InferModules)
4479194a91dSDouglas Gregor     return false;
4489194a91dSDouglas Gregor 
4499194a91dSDouglas Gregor   // We're allowed to infer for this directory, but make sure it's okay
4509194a91dSDouglas Gregor   // to infer this particular module.
4519194a91dSDouglas Gregor   bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
4529194a91dSDouglas Gregor                             inferred->second.ExcludedModules.end(),
4539194a91dSDouglas Gregor                             Name) == inferred->second.ExcludedModules.end();
4549194a91dSDouglas Gregor 
4559194a91dSDouglas Gregor   if (canInfer && inferred->second.InferSystemModules)
4569194a91dSDouglas Gregor     IsSystem = true;
4579194a91dSDouglas Gregor 
4589194a91dSDouglas Gregor   return canInfer;
4599194a91dSDouglas Gregor }
4609194a91dSDouglas Gregor 
46111dfe6feSDouglas Gregor /// \brief For a framework module, infer the framework against which we
46211dfe6feSDouglas Gregor /// should link.
46311dfe6feSDouglas Gregor static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
46411dfe6feSDouglas Gregor                                FileManager &FileMgr) {
46511dfe6feSDouglas Gregor   assert(Mod->IsFramework && "Can only infer linking for framework modules");
46611dfe6feSDouglas Gregor   assert(!Mod->isSubFramework() &&
46711dfe6feSDouglas Gregor          "Can only infer linking for top-level frameworks");
46811dfe6feSDouglas Gregor 
46911dfe6feSDouglas Gregor   SmallString<128> LibName;
47011dfe6feSDouglas Gregor   LibName += FrameworkDir->getName();
47111dfe6feSDouglas Gregor   llvm::sys::path::append(LibName, Mod->Name);
47211dfe6feSDouglas Gregor   if (FileMgr.getFile(LibName)) {
47311dfe6feSDouglas Gregor     Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
47411dfe6feSDouglas Gregor                                                      /*IsFramework=*/true));
47511dfe6feSDouglas Gregor   }
47611dfe6feSDouglas Gregor }
47711dfe6feSDouglas Gregor 
478de3ef502SDouglas Gregor Module *
47956c64013SDouglas Gregor ModuleMap::inferFrameworkModule(StringRef ModuleName,
480e89dbc1dSDouglas Gregor                                 const DirectoryEntry *FrameworkDir,
481a686e1b0SDouglas Gregor                                 bool IsSystem,
482e89dbc1dSDouglas Gregor                                 Module *Parent) {
48356c64013SDouglas Gregor   // Check whether we've already found this module.
484e89dbc1dSDouglas Gregor   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
485e89dbc1dSDouglas Gregor     return Mod;
486e89dbc1dSDouglas Gregor 
4871f76c4e8SManuel Klimek   FileManager &FileMgr = SourceMgr.getFileManager();
48856c64013SDouglas Gregor 
4899194a91dSDouglas Gregor   // If the framework has a parent path from which we're allowed to infer
4909194a91dSDouglas Gregor   // a framework module, do so.
4919194a91dSDouglas Gregor   if (!Parent) {
4924ddf2221SDouglas Gregor     // Determine whether we're allowed to infer a module map.
493e00c8b20SDouglas Gregor 
4944ddf2221SDouglas Gregor     // Note: as an egregious but useful hack we use the real path here, because
4954ddf2221SDouglas Gregor     // we might be looking at an embedded framework that symlinks out to a
4964ddf2221SDouglas Gregor     // top-level framework, and we need to infer as if we were naming the
4974ddf2221SDouglas Gregor     // top-level framework.
498e00c8b20SDouglas Gregor     StringRef FrameworkDirName
4991f76c4e8SManuel Klimek       = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
5004ddf2221SDouglas Gregor 
5019194a91dSDouglas Gregor     bool canInfer = false;
5024ddf2221SDouglas Gregor     if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
5039194a91dSDouglas Gregor       // Figure out the parent path.
5044ddf2221SDouglas Gregor       StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
5059194a91dSDouglas Gregor       if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
5069194a91dSDouglas Gregor         // Check whether we have already looked into the parent directory
5079194a91dSDouglas Gregor         // for a module map.
508e4412640SArgyrios Kyrtzidis         llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
5099194a91dSDouglas Gregor           inferred = InferredDirectories.find(ParentDir);
5109194a91dSDouglas Gregor         if (inferred == InferredDirectories.end()) {
5119194a91dSDouglas Gregor           // We haven't looked here before. Load a module map, if there is
5129194a91dSDouglas Gregor           // one.
5139194a91dSDouglas Gregor           SmallString<128> ModMapPath = Parent;
5149194a91dSDouglas Gregor           llvm::sys::path::append(ModMapPath, "module.map");
5159194a91dSDouglas Gregor           if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
516963c5535SDouglas Gregor             parseModuleMapFile(ModMapFile, IsSystem);
5179194a91dSDouglas Gregor             inferred = InferredDirectories.find(ParentDir);
5189194a91dSDouglas Gregor           }
5199194a91dSDouglas Gregor 
5209194a91dSDouglas Gregor           if (inferred == InferredDirectories.end())
5219194a91dSDouglas Gregor             inferred = InferredDirectories.insert(
5229194a91dSDouglas Gregor                          std::make_pair(ParentDir, InferredDirectory())).first;
5239194a91dSDouglas Gregor         }
5249194a91dSDouglas Gregor 
5259194a91dSDouglas Gregor         if (inferred->second.InferModules) {
5269194a91dSDouglas Gregor           // We're allowed to infer for this directory, but make sure it's okay
5279194a91dSDouglas Gregor           // to infer this particular module.
5284ddf2221SDouglas Gregor           StringRef Name = llvm::sys::path::stem(FrameworkDirName);
5299194a91dSDouglas Gregor           canInfer = std::find(inferred->second.ExcludedModules.begin(),
5309194a91dSDouglas Gregor                                inferred->second.ExcludedModules.end(),
5319194a91dSDouglas Gregor                                Name) == inferred->second.ExcludedModules.end();
5329194a91dSDouglas Gregor 
5339194a91dSDouglas Gregor           if (inferred->second.InferSystemModules)
5349194a91dSDouglas Gregor             IsSystem = true;
5359194a91dSDouglas Gregor         }
5369194a91dSDouglas Gregor       }
5379194a91dSDouglas Gregor     }
5389194a91dSDouglas Gregor 
5399194a91dSDouglas Gregor     // If we're not allowed to infer a framework module, don't.
5409194a91dSDouglas Gregor     if (!canInfer)
5419194a91dSDouglas Gregor       return 0;
5429194a91dSDouglas Gregor   }
5439194a91dSDouglas Gregor 
5449194a91dSDouglas Gregor 
54556c64013SDouglas Gregor   // Look for an umbrella header.
5462c1dd271SDylan Noblesmith   SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
54717381a06SBenjamin Kramer   llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
548e89dbc1dSDouglas Gregor   const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
54956c64013SDouglas Gregor 
55056c64013SDouglas Gregor   // FIXME: If there's no umbrella header, we could probably scan the
55156c64013SDouglas Gregor   // framework to load *everything*. But, it's not clear that this is a good
55256c64013SDouglas Gregor   // idea.
55356c64013SDouglas Gregor   if (!UmbrellaHeader)
55456c64013SDouglas Gregor     return 0;
55556c64013SDouglas Gregor 
556e89dbc1dSDouglas Gregor   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
557e89dbc1dSDouglas Gregor                               /*IsFramework=*/true, /*IsExplicit=*/false);
558ba7f2f71SDaniel Jasper   if (LangOpts.CurrentModule == ModuleName) {
559ba7f2f71SDaniel Jasper     SourceModule = Result;
560ba7f2f71SDaniel Jasper     SourceModuleName = ModuleName;
561ba7f2f71SDaniel Jasper   }
562a686e1b0SDouglas Gregor   if (IsSystem)
563a686e1b0SDouglas Gregor     Result->IsSystem = IsSystem;
564a686e1b0SDouglas Gregor 
565eb90e830SDouglas Gregor   if (!Parent)
566e89dbc1dSDouglas Gregor     Modules[ModuleName] = Result;
567e89dbc1dSDouglas Gregor 
568322f633cSDouglas Gregor   // umbrella header "umbrella-header-name"
56973141fa9SDouglas Gregor   Result->Umbrella = UmbrellaHeader;
57097da9178SDaniel Jasper   Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
5714dc71835SDouglas Gregor   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
572d8bd7537SDouglas Gregor 
573d8bd7537SDouglas Gregor   // export *
574d8bd7537SDouglas Gregor   Result->Exports.push_back(Module::ExportDecl(0, true));
575d8bd7537SDouglas Gregor 
576a89c5ac4SDouglas Gregor   // module * { export * }
577a89c5ac4SDouglas Gregor   Result->InferSubmodules = true;
578a89c5ac4SDouglas Gregor   Result->InferExportWildcard = true;
579a89c5ac4SDouglas Gregor 
580e89dbc1dSDouglas Gregor   // Look for subframeworks.
581e89dbc1dSDouglas Gregor   llvm::error_code EC;
5822c1dd271SDylan Noblesmith   SmallString<128> SubframeworksDirName
583ddaa69cbSDouglas Gregor     = StringRef(FrameworkDir->getName());
584e89dbc1dSDouglas Gregor   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
5852d4d8cb3SBenjamin Kramer   llvm::sys::path::native(SubframeworksDirName);
586ddaa69cbSDouglas Gregor   for (llvm::sys::fs::directory_iterator
5872d4d8cb3SBenjamin Kramer          Dir(SubframeworksDirName.str(), EC), DirEnd;
588e89dbc1dSDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
589e89dbc1dSDouglas Gregor     if (!StringRef(Dir->path()).endswith(".framework"))
590e89dbc1dSDouglas Gregor       continue;
591f2161a70SDouglas Gregor 
592e89dbc1dSDouglas Gregor     if (const DirectoryEntry *SubframeworkDir
593e89dbc1dSDouglas Gregor           = FileMgr.getDirectory(Dir->path())) {
59407c22b78SDouglas Gregor       // Note: as an egregious but useful hack, we use the real path here and
59507c22b78SDouglas Gregor       // check whether it is actually a subdirectory of the parent directory.
59607c22b78SDouglas Gregor       // This will not be the case if the 'subframework' is actually a symlink
59707c22b78SDouglas Gregor       // out to a top-level framework.
598e00c8b20SDouglas Gregor       StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
59907c22b78SDouglas Gregor       bool FoundParent = false;
60007c22b78SDouglas Gregor       do {
60107c22b78SDouglas Gregor         // Get the parent directory name.
60207c22b78SDouglas Gregor         SubframeworkDirName
60307c22b78SDouglas Gregor           = llvm::sys::path::parent_path(SubframeworkDirName);
60407c22b78SDouglas Gregor         if (SubframeworkDirName.empty())
60507c22b78SDouglas Gregor           break;
60607c22b78SDouglas Gregor 
60707c22b78SDouglas Gregor         if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
60807c22b78SDouglas Gregor           FoundParent = true;
60907c22b78SDouglas Gregor           break;
61007c22b78SDouglas Gregor         }
61107c22b78SDouglas Gregor       } while (true);
61207c22b78SDouglas Gregor 
61307c22b78SDouglas Gregor       if (!FoundParent)
61407c22b78SDouglas Gregor         continue;
61507c22b78SDouglas Gregor 
616e89dbc1dSDouglas Gregor       // FIXME: Do we want to warn about subframeworks without umbrella headers?
617056396aeSDouglas Gregor       SmallString<32> NameBuf;
618056396aeSDouglas Gregor       inferFrameworkModule(sanitizeFilenameAsIdentifier(
619056396aeSDouglas Gregor                              llvm::sys::path::stem(Dir->path()), NameBuf),
620056396aeSDouglas Gregor                            SubframeworkDir, IsSystem, Result);
621e89dbc1dSDouglas Gregor     }
622e89dbc1dSDouglas Gregor   }
623e89dbc1dSDouglas Gregor 
62411dfe6feSDouglas Gregor   // If the module is a top-level framework, automatically link against the
62511dfe6feSDouglas Gregor   // framework.
62611dfe6feSDouglas Gregor   if (!Result->isSubFramework()) {
62711dfe6feSDouglas Gregor     inferFrameworkLink(Result, FrameworkDir, FileMgr);
62811dfe6feSDouglas Gregor   }
62911dfe6feSDouglas Gregor 
63056c64013SDouglas Gregor   return Result;
63156c64013SDouglas Gregor }
63256c64013SDouglas Gregor 
633a89c5ac4SDouglas Gregor void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
63497da9178SDaniel Jasper   Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
63573141fa9SDouglas Gregor   Mod->Umbrella = UmbrellaHeader;
6367033127bSDouglas Gregor   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
637a89c5ac4SDouglas Gregor }
638a89c5ac4SDouglas Gregor 
639524e33e1SDouglas Gregor void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
640524e33e1SDouglas Gregor   Mod->Umbrella = UmbrellaDir;
641524e33e1SDouglas Gregor   UmbrellaDirs[UmbrellaDir] = Mod;
642524e33e1SDouglas Gregor }
643524e33e1SDouglas Gregor 
64459527666SDouglas Gregor void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
645b53e5483SLawrence Crowl                           ModuleHeaderRole Role) {
646b53e5483SLawrence Crowl   if (Role == ExcludedHeader) {
64759527666SDouglas Gregor     Mod->ExcludedHeaders.push_back(Header);
648b146baabSArgyrios Kyrtzidis   } else {
649b53e5483SLawrence Crowl     if (Role == PrivateHeader)
650b53e5483SLawrence Crowl       Mod->PrivateHeaders.push_back(Header);
651b53e5483SLawrence Crowl     else
652b53e5483SLawrence Crowl       Mod->NormalHeaders.push_back(Header);
6536f722b4eSArgyrios Kyrtzidis     bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
654b53e5483SLawrence Crowl     HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
655b146baabSArgyrios Kyrtzidis   }
65697da9178SDaniel Jasper   Headers[Header].push_back(KnownHeader(Mod, Role));
657a89c5ac4SDouglas Gregor }
658a89c5ac4SDouglas Gregor 
659514b636aSDouglas Gregor const FileEntry *
660e4412640SArgyrios Kyrtzidis ModuleMap::getContainingModuleMapFile(Module *Module) const {
6611f76c4e8SManuel Klimek   if (Module->DefinitionLoc.isInvalid())
662514b636aSDouglas Gregor     return 0;
663514b636aSDouglas Gregor 
6641f76c4e8SManuel Klimek   return SourceMgr.getFileEntryForID(
6651f76c4e8SManuel Klimek            SourceMgr.getFileID(Module->DefinitionLoc));
666514b636aSDouglas Gregor }
667514b636aSDouglas Gregor 
668718292f2SDouglas Gregor void ModuleMap::dump() {
669718292f2SDouglas Gregor   llvm::errs() << "Modules:";
670718292f2SDouglas Gregor   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
671718292f2SDouglas Gregor                                         MEnd = Modules.end();
672718292f2SDouglas Gregor        M != MEnd; ++M)
673d28d1b8dSDouglas Gregor     M->getValue()->print(llvm::errs(), 2);
674718292f2SDouglas Gregor 
675718292f2SDouglas Gregor   llvm::errs() << "Headers:";
67659527666SDouglas Gregor   for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
677718292f2SDouglas Gregor        H != HEnd; ++H) {
67897da9178SDaniel Jasper     llvm::errs() << "  \"" << H->first->getName() << "\" -> ";
67997da9178SDaniel Jasper     for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
68097da9178SDaniel Jasper                                                       E = H->second.end();
68197da9178SDaniel Jasper          I != E; ++I) {
68297da9178SDaniel Jasper       if (I != H->second.begin())
68397da9178SDaniel Jasper         llvm::errs() << ",";
68497da9178SDaniel Jasper       llvm::errs() << I->getModule()->getFullModuleName();
68597da9178SDaniel Jasper     }
68697da9178SDaniel Jasper     llvm::errs() << "\n";
687718292f2SDouglas Gregor   }
688718292f2SDouglas Gregor }
689718292f2SDouglas Gregor 
6902b82c2a5SDouglas Gregor bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
6912b82c2a5SDouglas Gregor   bool HadError = false;
6922b82c2a5SDouglas Gregor   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
6932b82c2a5SDouglas Gregor     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
6942b82c2a5SDouglas Gregor                                               Complain);
695f5eedd05SDouglas Gregor     if (Export.getPointer() || Export.getInt())
6962b82c2a5SDouglas Gregor       Mod->Exports.push_back(Export);
6972b82c2a5SDouglas Gregor     else
6982b82c2a5SDouglas Gregor       HadError = true;
6992b82c2a5SDouglas Gregor   }
7002b82c2a5SDouglas Gregor   Mod->UnresolvedExports.clear();
7012b82c2a5SDouglas Gregor   return HadError;
7022b82c2a5SDouglas Gregor }
7032b82c2a5SDouglas Gregor 
704ba7f2f71SDaniel Jasper bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
705ba7f2f71SDaniel Jasper   bool HadError = false;
706ba7f2f71SDaniel Jasper   for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
707ba7f2f71SDaniel Jasper     Module *DirectUse =
708ba7f2f71SDaniel Jasper         resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
709ba7f2f71SDaniel Jasper     if (DirectUse)
710ba7f2f71SDaniel Jasper       Mod->DirectUses.push_back(DirectUse);
711ba7f2f71SDaniel Jasper     else
712ba7f2f71SDaniel Jasper       HadError = true;
713ba7f2f71SDaniel Jasper   }
714ba7f2f71SDaniel Jasper   Mod->UnresolvedDirectUses.clear();
715ba7f2f71SDaniel Jasper   return HadError;
716ba7f2f71SDaniel Jasper }
717ba7f2f71SDaniel Jasper 
718fb912657SDouglas Gregor bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
719fb912657SDouglas Gregor   bool HadError = false;
720fb912657SDouglas Gregor   for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
721fb912657SDouglas Gregor     Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
722fb912657SDouglas Gregor                                        Mod, Complain);
723fb912657SDouglas Gregor     if (!OtherMod) {
724fb912657SDouglas Gregor       HadError = true;
725fb912657SDouglas Gregor       continue;
726fb912657SDouglas Gregor     }
727fb912657SDouglas Gregor 
728fb912657SDouglas Gregor     Module::Conflict Conflict;
729fb912657SDouglas Gregor     Conflict.Other = OtherMod;
730fb912657SDouglas Gregor     Conflict.Message = Mod->UnresolvedConflicts[I].Message;
731fb912657SDouglas Gregor     Mod->Conflicts.push_back(Conflict);
732fb912657SDouglas Gregor   }
733fb912657SDouglas Gregor   Mod->UnresolvedConflicts.clear();
734fb912657SDouglas Gregor   return HadError;
735fb912657SDouglas Gregor }
736fb912657SDouglas Gregor 
7370093b3c7SDouglas Gregor Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
7380093b3c7SDouglas Gregor   if (Loc.isInvalid())
7390093b3c7SDouglas Gregor     return 0;
7400093b3c7SDouglas Gregor 
7410093b3c7SDouglas Gregor   // Use the expansion location to determine which module we're in.
7420093b3c7SDouglas Gregor   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
7430093b3c7SDouglas Gregor   if (!ExpansionLoc.isFileID())
7440093b3c7SDouglas Gregor     return 0;
7450093b3c7SDouglas Gregor 
7460093b3c7SDouglas Gregor 
7470093b3c7SDouglas Gregor   const SourceManager &SrcMgr = Loc.getManager();
7480093b3c7SDouglas Gregor   FileID ExpansionFileID = ExpansionLoc.getFileID();
749224d8a74SDouglas Gregor 
750224d8a74SDouglas Gregor   while (const FileEntry *ExpansionFile
751224d8a74SDouglas Gregor            = SrcMgr.getFileEntryForID(ExpansionFileID)) {
752224d8a74SDouglas Gregor     // Find the module that owns this header (if any).
753b53e5483SLawrence Crowl     if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
754224d8a74SDouglas Gregor       return Mod;
755224d8a74SDouglas Gregor 
756224d8a74SDouglas Gregor     // No module owns this header, so look up the inclusion chain to see if
757224d8a74SDouglas Gregor     // any included header has an associated module.
758224d8a74SDouglas Gregor     SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
759224d8a74SDouglas Gregor     if (IncludeLoc.isInvalid())
7600093b3c7SDouglas Gregor       return 0;
7610093b3c7SDouglas Gregor 
762224d8a74SDouglas Gregor     ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
763224d8a74SDouglas Gregor   }
764224d8a74SDouglas Gregor 
765224d8a74SDouglas Gregor   return 0;
7660093b3c7SDouglas Gregor }
7670093b3c7SDouglas Gregor 
768718292f2SDouglas Gregor //----------------------------------------------------------------------------//
769718292f2SDouglas Gregor // Module map file parser
770718292f2SDouglas Gregor //----------------------------------------------------------------------------//
771718292f2SDouglas Gregor 
772718292f2SDouglas Gregor namespace clang {
773718292f2SDouglas Gregor   /// \brief A token in a module map file.
774718292f2SDouglas Gregor   struct MMToken {
775718292f2SDouglas Gregor     enum TokenKind {
7761fb5c3a6SDouglas Gregor       Comma,
77735b13eceSDouglas Gregor       ConfigMacros,
778fb912657SDouglas Gregor       Conflict,
779718292f2SDouglas Gregor       EndOfFile,
780718292f2SDouglas Gregor       HeaderKeyword,
781718292f2SDouglas Gregor       Identifier,
782a3feee2aSRichard Smith       Exclaim,
78359527666SDouglas Gregor       ExcludeKeyword,
784718292f2SDouglas Gregor       ExplicitKeyword,
7852b82c2a5SDouglas Gregor       ExportKeyword,
78697292843SDaniel Jasper       ExternKeyword,
787755b2055SDouglas Gregor       FrameworkKeyword,
7886ddfca91SDouglas Gregor       LinkKeyword,
789718292f2SDouglas Gregor       ModuleKeyword,
7902b82c2a5SDouglas Gregor       Period,
791b53e5483SLawrence Crowl       PrivateKeyword,
792718292f2SDouglas Gregor       UmbrellaKeyword,
793ba7f2f71SDaniel Jasper       UseKeyword,
7941fb5c3a6SDouglas Gregor       RequiresKeyword,
7952b82c2a5SDouglas Gregor       Star,
796718292f2SDouglas Gregor       StringLiteral,
797718292f2SDouglas Gregor       LBrace,
798a686e1b0SDouglas Gregor       RBrace,
799a686e1b0SDouglas Gregor       LSquare,
800a686e1b0SDouglas Gregor       RSquare
801718292f2SDouglas Gregor     } Kind;
802718292f2SDouglas Gregor 
803718292f2SDouglas Gregor     unsigned Location;
804718292f2SDouglas Gregor     unsigned StringLength;
805718292f2SDouglas Gregor     const char *StringData;
806718292f2SDouglas Gregor 
807718292f2SDouglas Gregor     void clear() {
808718292f2SDouglas Gregor       Kind = EndOfFile;
809718292f2SDouglas Gregor       Location = 0;
810718292f2SDouglas Gregor       StringLength = 0;
811718292f2SDouglas Gregor       StringData = 0;
812718292f2SDouglas Gregor     }
813718292f2SDouglas Gregor 
814718292f2SDouglas Gregor     bool is(TokenKind K) const { return Kind == K; }
815718292f2SDouglas Gregor 
816718292f2SDouglas Gregor     SourceLocation getLocation() const {
817718292f2SDouglas Gregor       return SourceLocation::getFromRawEncoding(Location);
818718292f2SDouglas Gregor     }
819718292f2SDouglas Gregor 
820718292f2SDouglas Gregor     StringRef getString() const {
821718292f2SDouglas Gregor       return StringRef(StringData, StringLength);
822718292f2SDouglas Gregor     }
823718292f2SDouglas Gregor   };
824718292f2SDouglas Gregor 
8259194a91dSDouglas Gregor   /// \brief The set of attributes that can be attached to a module.
8264442605fSBill Wendling   struct Attributes {
82735b13eceSDouglas Gregor     Attributes() : IsSystem(), IsExhaustive() { }
8289194a91dSDouglas Gregor 
8299194a91dSDouglas Gregor     /// \brief Whether this is a system module.
8309194a91dSDouglas Gregor     unsigned IsSystem : 1;
83135b13eceSDouglas Gregor 
83235b13eceSDouglas Gregor     /// \brief Whether this is an exhaustive set of configuration macros.
83335b13eceSDouglas Gregor     unsigned IsExhaustive : 1;
8349194a91dSDouglas Gregor   };
8359194a91dSDouglas Gregor 
8369194a91dSDouglas Gregor 
837718292f2SDouglas Gregor   class ModuleMapParser {
838718292f2SDouglas Gregor     Lexer &L;
839718292f2SDouglas Gregor     SourceManager &SourceMgr;
840bc10b9fbSDouglas Gregor 
841bc10b9fbSDouglas Gregor     /// \brief Default target information, used only for string literal
842bc10b9fbSDouglas Gregor     /// parsing.
843bc10b9fbSDouglas Gregor     const TargetInfo *Target;
844bc10b9fbSDouglas Gregor 
845718292f2SDouglas Gregor     DiagnosticsEngine &Diags;
846718292f2SDouglas Gregor     ModuleMap &Map;
847718292f2SDouglas Gregor 
8485257fc63SDouglas Gregor     /// \brief The directory that this module map resides in.
8495257fc63SDouglas Gregor     const DirectoryEntry *Directory;
8505257fc63SDouglas Gregor 
8513ec6663bSDouglas Gregor     /// \brief The directory containing Clang-supplied headers.
8523ec6663bSDouglas Gregor     const DirectoryEntry *BuiltinIncludeDir;
8533ec6663bSDouglas Gregor 
854963c5535SDouglas Gregor     /// \brief Whether this module map is in a system header directory.
855963c5535SDouglas Gregor     bool IsSystem;
856963c5535SDouglas Gregor 
857718292f2SDouglas Gregor     /// \brief Whether an error occurred.
858718292f2SDouglas Gregor     bool HadError;
859718292f2SDouglas Gregor 
860718292f2SDouglas Gregor     /// \brief Stores string data for the various string literals referenced
861718292f2SDouglas Gregor     /// during parsing.
862718292f2SDouglas Gregor     llvm::BumpPtrAllocator StringData;
863718292f2SDouglas Gregor 
864718292f2SDouglas Gregor     /// \brief The current token.
865718292f2SDouglas Gregor     MMToken Tok;
866718292f2SDouglas Gregor 
867718292f2SDouglas Gregor     /// \brief The active module.
868de3ef502SDouglas Gregor     Module *ActiveModule;
869718292f2SDouglas Gregor 
870718292f2SDouglas Gregor     /// \brief Consume the current token and return its location.
871718292f2SDouglas Gregor     SourceLocation consumeToken();
872718292f2SDouglas Gregor 
873718292f2SDouglas Gregor     /// \brief Skip tokens until we reach the a token with the given kind
874718292f2SDouglas Gregor     /// (or the end of the file).
875718292f2SDouglas Gregor     void skipUntil(MMToken::TokenKind K);
876718292f2SDouglas Gregor 
877f857950dSDmitri Gribenko     typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
878e7ab3669SDouglas Gregor     bool parseModuleId(ModuleId &Id);
879718292f2SDouglas Gregor     void parseModuleDecl();
88097292843SDaniel Jasper     void parseExternModuleDecl();
8811fb5c3a6SDouglas Gregor     void parseRequiresDecl();
882b53e5483SLawrence Crowl     void parseHeaderDecl(clang::MMToken::TokenKind,
883b53e5483SLawrence Crowl                          SourceLocation LeadingLoc);
884524e33e1SDouglas Gregor     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
8852b82c2a5SDouglas Gregor     void parseExportDecl();
886ba7f2f71SDaniel Jasper     void parseUseDecl();
8876ddfca91SDouglas Gregor     void parseLinkDecl();
88835b13eceSDouglas Gregor     void parseConfigMacros();
889fb912657SDouglas Gregor     void parseConflict();
8909194a91dSDouglas Gregor     void parseInferredModuleDecl(bool Framework, bool Explicit);
8914442605fSBill Wendling     bool parseOptionalAttributes(Attributes &Attrs);
892718292f2SDouglas Gregor 
8937033127bSDouglas Gregor     const DirectoryEntry *getOverriddenHeaderSearchDir();
8947033127bSDouglas Gregor 
895718292f2SDouglas Gregor   public:
896718292f2SDouglas Gregor     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
897bc10b9fbSDouglas Gregor                              const TargetInfo *Target,
898718292f2SDouglas Gregor                              DiagnosticsEngine &Diags,
8995257fc63SDouglas Gregor                              ModuleMap &Map,
9003ec6663bSDouglas Gregor                              const DirectoryEntry *Directory,
901963c5535SDouglas Gregor                              const DirectoryEntry *BuiltinIncludeDir,
902963c5535SDouglas Gregor                              bool IsSystem)
903bc10b9fbSDouglas Gregor       : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
9043ec6663bSDouglas Gregor         Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
905963c5535SDouglas Gregor         IsSystem(IsSystem), HadError(false), ActiveModule(0)
906718292f2SDouglas Gregor     {
907718292f2SDouglas Gregor       Tok.clear();
908718292f2SDouglas Gregor       consumeToken();
909718292f2SDouglas Gregor     }
910718292f2SDouglas Gregor 
911718292f2SDouglas Gregor     bool parseModuleMapFile();
912718292f2SDouglas Gregor   };
913718292f2SDouglas Gregor }
914718292f2SDouglas Gregor 
915718292f2SDouglas Gregor SourceLocation ModuleMapParser::consumeToken() {
916718292f2SDouglas Gregor retry:
917718292f2SDouglas Gregor   SourceLocation Result = Tok.getLocation();
918718292f2SDouglas Gregor   Tok.clear();
919718292f2SDouglas Gregor 
920718292f2SDouglas Gregor   Token LToken;
921718292f2SDouglas Gregor   L.LexFromRawLexer(LToken);
922718292f2SDouglas Gregor   Tok.Location = LToken.getLocation().getRawEncoding();
923718292f2SDouglas Gregor   switch (LToken.getKind()) {
924718292f2SDouglas Gregor   case tok::raw_identifier:
925718292f2SDouglas Gregor     Tok.StringData = LToken.getRawIdentifierData();
926718292f2SDouglas Gregor     Tok.StringLength = LToken.getLength();
927718292f2SDouglas Gregor     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
92835b13eceSDouglas Gregor                  .Case("config_macros", MMToken::ConfigMacros)
929fb912657SDouglas Gregor                  .Case("conflict", MMToken::Conflict)
93059527666SDouglas Gregor                  .Case("exclude", MMToken::ExcludeKeyword)
931718292f2SDouglas Gregor                  .Case("explicit", MMToken::ExplicitKeyword)
9322b82c2a5SDouglas Gregor                  .Case("export", MMToken::ExportKeyword)
93397292843SDaniel Jasper                  .Case("extern", MMToken::ExternKeyword)
934755b2055SDouglas Gregor                  .Case("framework", MMToken::FrameworkKeyword)
93535b13eceSDouglas Gregor                  .Case("header", MMToken::HeaderKeyword)
9366ddfca91SDouglas Gregor                  .Case("link", MMToken::LinkKeyword)
937718292f2SDouglas Gregor                  .Case("module", MMToken::ModuleKeyword)
938b53e5483SLawrence Crowl                  .Case("private", MMToken::PrivateKeyword)
9391fb5c3a6SDouglas Gregor                  .Case("requires", MMToken::RequiresKeyword)
940718292f2SDouglas Gregor                  .Case("umbrella", MMToken::UmbrellaKeyword)
941ba7f2f71SDaniel Jasper                  .Case("use", MMToken::UseKeyword)
942718292f2SDouglas Gregor                  .Default(MMToken::Identifier);
943718292f2SDouglas Gregor     break;
944718292f2SDouglas Gregor 
9451fb5c3a6SDouglas Gregor   case tok::comma:
9461fb5c3a6SDouglas Gregor     Tok.Kind = MMToken::Comma;
9471fb5c3a6SDouglas Gregor     break;
9481fb5c3a6SDouglas Gregor 
949718292f2SDouglas Gregor   case tok::eof:
950718292f2SDouglas Gregor     Tok.Kind = MMToken::EndOfFile;
951718292f2SDouglas Gregor     break;
952718292f2SDouglas Gregor 
953718292f2SDouglas Gregor   case tok::l_brace:
954718292f2SDouglas Gregor     Tok.Kind = MMToken::LBrace;
955718292f2SDouglas Gregor     break;
956718292f2SDouglas Gregor 
957a686e1b0SDouglas Gregor   case tok::l_square:
958a686e1b0SDouglas Gregor     Tok.Kind = MMToken::LSquare;
959a686e1b0SDouglas Gregor     break;
960a686e1b0SDouglas Gregor 
9612b82c2a5SDouglas Gregor   case tok::period:
9622b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Period;
9632b82c2a5SDouglas Gregor     break;
9642b82c2a5SDouglas Gregor 
965718292f2SDouglas Gregor   case tok::r_brace:
966718292f2SDouglas Gregor     Tok.Kind = MMToken::RBrace;
967718292f2SDouglas Gregor     break;
968718292f2SDouglas Gregor 
969a686e1b0SDouglas Gregor   case tok::r_square:
970a686e1b0SDouglas Gregor     Tok.Kind = MMToken::RSquare;
971a686e1b0SDouglas Gregor     break;
972a686e1b0SDouglas Gregor 
9732b82c2a5SDouglas Gregor   case tok::star:
9742b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Star;
9752b82c2a5SDouglas Gregor     break;
9762b82c2a5SDouglas Gregor 
977a3feee2aSRichard Smith   case tok::exclaim:
978a3feee2aSRichard Smith     Tok.Kind = MMToken::Exclaim;
979a3feee2aSRichard Smith     break;
980a3feee2aSRichard Smith 
981718292f2SDouglas Gregor   case tok::string_literal: {
982d67aea28SRichard Smith     if (LToken.hasUDSuffix()) {
983d67aea28SRichard Smith       Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
984d67aea28SRichard Smith       HadError = true;
985d67aea28SRichard Smith       goto retry;
986d67aea28SRichard Smith     }
987d67aea28SRichard Smith 
988718292f2SDouglas Gregor     // Parse the string literal.
989718292f2SDouglas Gregor     LangOptions LangOpts;
990718292f2SDouglas Gregor     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
991718292f2SDouglas Gregor     if (StringLiteral.hadError)
992718292f2SDouglas Gregor       goto retry;
993718292f2SDouglas Gregor 
994718292f2SDouglas Gregor     // Copy the string literal into our string data allocator.
995718292f2SDouglas Gregor     unsigned Length = StringLiteral.GetStringLength();
996718292f2SDouglas Gregor     char *Saved = StringData.Allocate<char>(Length + 1);
997718292f2SDouglas Gregor     memcpy(Saved, StringLiteral.GetString().data(), Length);
998718292f2SDouglas Gregor     Saved[Length] = 0;
999718292f2SDouglas Gregor 
1000718292f2SDouglas Gregor     // Form the token.
1001718292f2SDouglas Gregor     Tok.Kind = MMToken::StringLiteral;
1002718292f2SDouglas Gregor     Tok.StringData = Saved;
1003718292f2SDouglas Gregor     Tok.StringLength = Length;
1004718292f2SDouglas Gregor     break;
1005718292f2SDouglas Gregor   }
1006718292f2SDouglas Gregor 
1007718292f2SDouglas Gregor   case tok::comment:
1008718292f2SDouglas Gregor     goto retry;
1009718292f2SDouglas Gregor 
1010718292f2SDouglas Gregor   default:
1011718292f2SDouglas Gregor     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1012718292f2SDouglas Gregor     HadError = true;
1013718292f2SDouglas Gregor     goto retry;
1014718292f2SDouglas Gregor   }
1015718292f2SDouglas Gregor 
1016718292f2SDouglas Gregor   return Result;
1017718292f2SDouglas Gregor }
1018718292f2SDouglas Gregor 
1019718292f2SDouglas Gregor void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1020718292f2SDouglas Gregor   unsigned braceDepth = 0;
1021a686e1b0SDouglas Gregor   unsigned squareDepth = 0;
1022718292f2SDouglas Gregor   do {
1023718292f2SDouglas Gregor     switch (Tok.Kind) {
1024718292f2SDouglas Gregor     case MMToken::EndOfFile:
1025718292f2SDouglas Gregor       return;
1026718292f2SDouglas Gregor 
1027718292f2SDouglas Gregor     case MMToken::LBrace:
1028a686e1b0SDouglas Gregor       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1029718292f2SDouglas Gregor         return;
1030718292f2SDouglas Gregor 
1031718292f2SDouglas Gregor       ++braceDepth;
1032718292f2SDouglas Gregor       break;
1033718292f2SDouglas Gregor 
1034a686e1b0SDouglas Gregor     case MMToken::LSquare:
1035a686e1b0SDouglas Gregor       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1036a686e1b0SDouglas Gregor         return;
1037a686e1b0SDouglas Gregor 
1038a686e1b0SDouglas Gregor       ++squareDepth;
1039a686e1b0SDouglas Gregor       break;
1040a686e1b0SDouglas Gregor 
1041718292f2SDouglas Gregor     case MMToken::RBrace:
1042718292f2SDouglas Gregor       if (braceDepth > 0)
1043718292f2SDouglas Gregor         --braceDepth;
1044718292f2SDouglas Gregor       else if (Tok.is(K))
1045718292f2SDouglas Gregor         return;
1046718292f2SDouglas Gregor       break;
1047718292f2SDouglas Gregor 
1048a686e1b0SDouglas Gregor     case MMToken::RSquare:
1049a686e1b0SDouglas Gregor       if (squareDepth > 0)
1050a686e1b0SDouglas Gregor         --squareDepth;
1051a686e1b0SDouglas Gregor       else if (Tok.is(K))
1052a686e1b0SDouglas Gregor         return;
1053a686e1b0SDouglas Gregor       break;
1054a686e1b0SDouglas Gregor 
1055718292f2SDouglas Gregor     default:
1056a686e1b0SDouglas Gregor       if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1057718292f2SDouglas Gregor         return;
1058718292f2SDouglas Gregor       break;
1059718292f2SDouglas Gregor     }
1060718292f2SDouglas Gregor 
1061718292f2SDouglas Gregor    consumeToken();
1062718292f2SDouglas Gregor   } while (true);
1063718292f2SDouglas Gregor }
1064718292f2SDouglas Gregor 
1065e7ab3669SDouglas Gregor /// \brief Parse a module-id.
1066e7ab3669SDouglas Gregor ///
1067e7ab3669SDouglas Gregor ///   module-id:
1068e7ab3669SDouglas Gregor ///     identifier
1069e7ab3669SDouglas Gregor ///     identifier '.' module-id
1070e7ab3669SDouglas Gregor ///
1071e7ab3669SDouglas Gregor /// \returns true if an error occurred, false otherwise.
1072e7ab3669SDouglas Gregor bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1073e7ab3669SDouglas Gregor   Id.clear();
1074e7ab3669SDouglas Gregor   do {
10753cd34c76SDaniel Jasper     if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
1076e7ab3669SDouglas Gregor       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1077e7ab3669SDouglas Gregor       consumeToken();
1078e7ab3669SDouglas Gregor     } else {
1079e7ab3669SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1080e7ab3669SDouglas Gregor       return true;
1081e7ab3669SDouglas Gregor     }
1082e7ab3669SDouglas Gregor 
1083e7ab3669SDouglas Gregor     if (!Tok.is(MMToken::Period))
1084e7ab3669SDouglas Gregor       break;
1085e7ab3669SDouglas Gregor 
1086e7ab3669SDouglas Gregor     consumeToken();
1087e7ab3669SDouglas Gregor   } while (true);
1088e7ab3669SDouglas Gregor 
1089e7ab3669SDouglas Gregor   return false;
1090e7ab3669SDouglas Gregor }
1091e7ab3669SDouglas Gregor 
1092a686e1b0SDouglas Gregor namespace {
1093a686e1b0SDouglas Gregor   /// \brief Enumerates the known attributes.
1094a686e1b0SDouglas Gregor   enum AttributeKind {
1095a686e1b0SDouglas Gregor     /// \brief An unknown attribute.
1096a686e1b0SDouglas Gregor     AT_unknown,
1097a686e1b0SDouglas Gregor     /// \brief The 'system' attribute.
109835b13eceSDouglas Gregor     AT_system,
109935b13eceSDouglas Gregor     /// \brief The 'exhaustive' attribute.
110035b13eceSDouglas Gregor     AT_exhaustive
1101a686e1b0SDouglas Gregor   };
1102a686e1b0SDouglas Gregor }
1103a686e1b0SDouglas Gregor 
1104718292f2SDouglas Gregor /// \brief Parse a module declaration.
1105718292f2SDouglas Gregor ///
1106718292f2SDouglas Gregor ///   module-declaration:
110797292843SDaniel Jasper ///     'extern' 'module' module-id string-literal
1108a686e1b0SDouglas Gregor ///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1109a686e1b0SDouglas Gregor ///       { module-member* }
1110a686e1b0SDouglas Gregor ///
1111718292f2SDouglas Gregor ///   module-member:
11121fb5c3a6SDouglas Gregor ///     requires-declaration
1113718292f2SDouglas Gregor ///     header-declaration
1114e7ab3669SDouglas Gregor ///     submodule-declaration
11152b82c2a5SDouglas Gregor ///     export-declaration
11166ddfca91SDouglas Gregor ///     link-declaration
111773441091SDouglas Gregor ///
111873441091SDouglas Gregor ///   submodule-declaration:
111973441091SDouglas Gregor ///     module-declaration
112073441091SDouglas Gregor ///     inferred-submodule-declaration
1121718292f2SDouglas Gregor void ModuleMapParser::parseModuleDecl() {
1122755b2055SDouglas Gregor   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
112397292843SDaniel Jasper          Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
112497292843SDaniel Jasper   if (Tok.is(MMToken::ExternKeyword)) {
112597292843SDaniel Jasper     parseExternModuleDecl();
112697292843SDaniel Jasper     return;
112797292843SDaniel Jasper   }
112897292843SDaniel Jasper 
1129f2161a70SDouglas Gregor   // Parse 'explicit' or 'framework' keyword, if present.
1130e7ab3669SDouglas Gregor   SourceLocation ExplicitLoc;
1131718292f2SDouglas Gregor   bool Explicit = false;
1132f2161a70SDouglas Gregor   bool Framework = false;
1133755b2055SDouglas Gregor 
1134f2161a70SDouglas Gregor   // Parse 'explicit' keyword, if present.
1135f2161a70SDouglas Gregor   if (Tok.is(MMToken::ExplicitKeyword)) {
1136e7ab3669SDouglas Gregor     ExplicitLoc = consumeToken();
1137f2161a70SDouglas Gregor     Explicit = true;
1138f2161a70SDouglas Gregor   }
1139f2161a70SDouglas Gregor 
1140f2161a70SDouglas Gregor   // Parse 'framework' keyword, if present.
1141755b2055SDouglas Gregor   if (Tok.is(MMToken::FrameworkKeyword)) {
1142755b2055SDouglas Gregor     consumeToken();
1143755b2055SDouglas Gregor     Framework = true;
1144755b2055SDouglas Gregor   }
1145718292f2SDouglas Gregor 
1146718292f2SDouglas Gregor   // Parse 'module' keyword.
1147718292f2SDouglas Gregor   if (!Tok.is(MMToken::ModuleKeyword)) {
1148d6343c99SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1149718292f2SDouglas Gregor     consumeToken();
1150718292f2SDouglas Gregor     HadError = true;
1151718292f2SDouglas Gregor     return;
1152718292f2SDouglas Gregor   }
1153718292f2SDouglas Gregor   consumeToken(); // 'module' keyword
1154718292f2SDouglas Gregor 
115573441091SDouglas Gregor   // If we have a wildcard for the module name, this is an inferred submodule.
115673441091SDouglas Gregor   // Parse it.
115773441091SDouglas Gregor   if (Tok.is(MMToken::Star))
11589194a91dSDouglas Gregor     return parseInferredModuleDecl(Framework, Explicit);
115973441091SDouglas Gregor 
1160718292f2SDouglas Gregor   // Parse the module name.
1161e7ab3669SDouglas Gregor   ModuleId Id;
1162e7ab3669SDouglas Gregor   if (parseModuleId(Id)) {
1163718292f2SDouglas Gregor     HadError = true;
1164718292f2SDouglas Gregor     return;
1165718292f2SDouglas Gregor   }
1166e7ab3669SDouglas Gregor 
1167e7ab3669SDouglas Gregor   if (ActiveModule) {
1168e7ab3669SDouglas Gregor     if (Id.size() > 1) {
1169e7ab3669SDouglas Gregor       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1170e7ab3669SDouglas Gregor         << SourceRange(Id.front().second, Id.back().second);
1171e7ab3669SDouglas Gregor 
1172e7ab3669SDouglas Gregor       HadError = true;
1173e7ab3669SDouglas Gregor       return;
1174e7ab3669SDouglas Gregor     }
1175e7ab3669SDouglas Gregor   } else if (Id.size() == 1 && Explicit) {
1176e7ab3669SDouglas Gregor     // Top-level modules can't be explicit.
1177e7ab3669SDouglas Gregor     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1178e7ab3669SDouglas Gregor     Explicit = false;
1179e7ab3669SDouglas Gregor     ExplicitLoc = SourceLocation();
1180e7ab3669SDouglas Gregor     HadError = true;
1181e7ab3669SDouglas Gregor   }
1182e7ab3669SDouglas Gregor 
1183e7ab3669SDouglas Gregor   Module *PreviousActiveModule = ActiveModule;
1184e7ab3669SDouglas Gregor   if (Id.size() > 1) {
1185e7ab3669SDouglas Gregor     // This module map defines a submodule. Go find the module of which it
1186e7ab3669SDouglas Gregor     // is a submodule.
1187e7ab3669SDouglas Gregor     ActiveModule = 0;
1188e7ab3669SDouglas Gregor     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1189e7ab3669SDouglas Gregor       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1190e7ab3669SDouglas Gregor         ActiveModule = Next;
1191e7ab3669SDouglas Gregor         continue;
1192e7ab3669SDouglas Gregor       }
1193e7ab3669SDouglas Gregor 
1194e7ab3669SDouglas Gregor       if (ActiveModule) {
1195e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1196e7ab3669SDouglas Gregor           << Id[I].first << ActiveModule->getTopLevelModule();
1197e7ab3669SDouglas Gregor       } else {
1198e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1199e7ab3669SDouglas Gregor       }
1200e7ab3669SDouglas Gregor       HadError = true;
1201e7ab3669SDouglas Gregor       return;
1202e7ab3669SDouglas Gregor     }
1203e7ab3669SDouglas Gregor   }
1204e7ab3669SDouglas Gregor 
1205e7ab3669SDouglas Gregor   StringRef ModuleName = Id.back().first;
1206e7ab3669SDouglas Gregor   SourceLocation ModuleNameLoc = Id.back().second;
1207718292f2SDouglas Gregor 
1208a686e1b0SDouglas Gregor   // Parse the optional attribute list.
12094442605fSBill Wendling   Attributes Attrs;
12109194a91dSDouglas Gregor   parseOptionalAttributes(Attrs);
1211a686e1b0SDouglas Gregor 
1212718292f2SDouglas Gregor   // Parse the opening brace.
1213718292f2SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
1214718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1215718292f2SDouglas Gregor       << ModuleName;
1216718292f2SDouglas Gregor     HadError = true;
1217718292f2SDouglas Gregor     return;
1218718292f2SDouglas Gregor   }
1219718292f2SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
1220718292f2SDouglas Gregor 
1221718292f2SDouglas Gregor   // Determine whether this (sub)module has already been defined.
1222eb90e830SDouglas Gregor   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1223fcc54a3bSDouglas Gregor     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1224fcc54a3bSDouglas Gregor       // Skip the module definition.
1225fcc54a3bSDouglas Gregor       skipUntil(MMToken::RBrace);
1226fcc54a3bSDouglas Gregor       if (Tok.is(MMToken::RBrace))
1227fcc54a3bSDouglas Gregor         consumeToken();
1228fcc54a3bSDouglas Gregor       else {
1229fcc54a3bSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1230fcc54a3bSDouglas Gregor         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1231fcc54a3bSDouglas Gregor         HadError = true;
1232fcc54a3bSDouglas Gregor       }
1233fcc54a3bSDouglas Gregor       return;
1234fcc54a3bSDouglas Gregor     }
1235fcc54a3bSDouglas Gregor 
1236718292f2SDouglas Gregor     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1237718292f2SDouglas Gregor       << ModuleName;
1238eb90e830SDouglas Gregor     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1239718292f2SDouglas Gregor 
1240718292f2SDouglas Gregor     // Skip the module definition.
1241718292f2SDouglas Gregor     skipUntil(MMToken::RBrace);
1242718292f2SDouglas Gregor     if (Tok.is(MMToken::RBrace))
1243718292f2SDouglas Gregor       consumeToken();
1244718292f2SDouglas Gregor 
1245718292f2SDouglas Gregor     HadError = true;
1246718292f2SDouglas Gregor     return;
1247718292f2SDouglas Gregor   }
1248718292f2SDouglas Gregor 
1249718292f2SDouglas Gregor   // Start defining this module.
1250eb90e830SDouglas Gregor   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1251eb90e830SDouglas Gregor                                         Explicit).first;
1252eb90e830SDouglas Gregor   ActiveModule->DefinitionLoc = ModuleNameLoc;
1253963c5535SDouglas Gregor   if (Attrs.IsSystem || IsSystem)
1254a686e1b0SDouglas Gregor     ActiveModule->IsSystem = true;
1255718292f2SDouglas Gregor 
1256718292f2SDouglas Gregor   bool Done = false;
1257718292f2SDouglas Gregor   do {
1258718292f2SDouglas Gregor     switch (Tok.Kind) {
1259718292f2SDouglas Gregor     case MMToken::EndOfFile:
1260718292f2SDouglas Gregor     case MMToken::RBrace:
1261718292f2SDouglas Gregor       Done = true;
1262718292f2SDouglas Gregor       break;
1263718292f2SDouglas Gregor 
126435b13eceSDouglas Gregor     case MMToken::ConfigMacros:
126535b13eceSDouglas Gregor       parseConfigMacros();
126635b13eceSDouglas Gregor       break;
126735b13eceSDouglas Gregor 
1268fb912657SDouglas Gregor     case MMToken::Conflict:
1269fb912657SDouglas Gregor       parseConflict();
1270fb912657SDouglas Gregor       break;
1271fb912657SDouglas Gregor 
1272718292f2SDouglas Gregor     case MMToken::ExplicitKeyword:
127397292843SDaniel Jasper     case MMToken::ExternKeyword:
1274f2161a70SDouglas Gregor     case MMToken::FrameworkKeyword:
1275718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
1276718292f2SDouglas Gregor       parseModuleDecl();
1277718292f2SDouglas Gregor       break;
1278718292f2SDouglas Gregor 
12792b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
12802b82c2a5SDouglas Gregor       parseExportDecl();
12812b82c2a5SDouglas Gregor       break;
12822b82c2a5SDouglas Gregor 
1283ba7f2f71SDaniel Jasper     case MMToken::UseKeyword:
1284ba7f2f71SDaniel Jasper       parseUseDecl();
1285ba7f2f71SDaniel Jasper       break;
1286ba7f2f71SDaniel Jasper 
12871fb5c3a6SDouglas Gregor     case MMToken::RequiresKeyword:
12881fb5c3a6SDouglas Gregor       parseRequiresDecl();
12891fb5c3a6SDouglas Gregor       break;
12901fb5c3a6SDouglas Gregor 
1291524e33e1SDouglas Gregor     case MMToken::UmbrellaKeyword: {
1292524e33e1SDouglas Gregor       SourceLocation UmbrellaLoc = consumeToken();
1293524e33e1SDouglas Gregor       if (Tok.is(MMToken::HeaderKeyword))
1294b53e5483SLawrence Crowl         parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
1295524e33e1SDouglas Gregor       else
1296524e33e1SDouglas Gregor         parseUmbrellaDirDecl(UmbrellaLoc);
1297718292f2SDouglas Gregor       break;
1298524e33e1SDouglas Gregor     }
1299718292f2SDouglas Gregor 
130059527666SDouglas Gregor     case MMToken::ExcludeKeyword: {
130159527666SDouglas Gregor       SourceLocation ExcludeLoc = consumeToken();
130259527666SDouglas Gregor       if (Tok.is(MMToken::HeaderKeyword)) {
1303b53e5483SLawrence Crowl         parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
130459527666SDouglas Gregor       } else {
130559527666SDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
130659527666SDouglas Gregor           << "exclude";
130759527666SDouglas Gregor       }
130859527666SDouglas Gregor       break;
130959527666SDouglas Gregor     }
131059527666SDouglas Gregor 
1311b53e5483SLawrence Crowl     case MMToken::PrivateKeyword: {
1312b53e5483SLawrence Crowl       SourceLocation PrivateLoc = consumeToken();
1313b53e5483SLawrence Crowl       if (Tok.is(MMToken::HeaderKeyword)) {
1314b53e5483SLawrence Crowl         parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1315b53e5483SLawrence Crowl       } else {
1316b53e5483SLawrence Crowl         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1317b53e5483SLawrence Crowl           << "private";
1318b53e5483SLawrence Crowl       }
1319b53e5483SLawrence Crowl       break;
1320b53e5483SLawrence Crowl     }
1321b53e5483SLawrence Crowl 
1322322f633cSDouglas Gregor     case MMToken::HeaderKeyword:
1323b53e5483SLawrence Crowl       parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
1324718292f2SDouglas Gregor       break;
1325718292f2SDouglas Gregor 
13266ddfca91SDouglas Gregor     case MMToken::LinkKeyword:
13276ddfca91SDouglas Gregor       parseLinkDecl();
13286ddfca91SDouglas Gregor       break;
13296ddfca91SDouglas Gregor 
1330718292f2SDouglas Gregor     default:
1331718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1332718292f2SDouglas Gregor       consumeToken();
1333718292f2SDouglas Gregor       break;
1334718292f2SDouglas Gregor     }
1335718292f2SDouglas Gregor   } while (!Done);
1336718292f2SDouglas Gregor 
1337718292f2SDouglas Gregor   if (Tok.is(MMToken::RBrace))
1338718292f2SDouglas Gregor     consumeToken();
1339718292f2SDouglas Gregor   else {
1340718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1341718292f2SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1342718292f2SDouglas Gregor     HadError = true;
1343718292f2SDouglas Gregor   }
1344718292f2SDouglas Gregor 
134511dfe6feSDouglas Gregor   // If the active module is a top-level framework, and there are no link
134611dfe6feSDouglas Gregor   // libraries, automatically link against the framework.
134711dfe6feSDouglas Gregor   if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
134811dfe6feSDouglas Gregor       ActiveModule->LinkLibraries.empty()) {
134911dfe6feSDouglas Gregor     inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
135011dfe6feSDouglas Gregor   }
135111dfe6feSDouglas Gregor 
1352e7ab3669SDouglas Gregor   // We're done parsing this module. Pop back to the previous module.
1353e7ab3669SDouglas Gregor   ActiveModule = PreviousActiveModule;
1354718292f2SDouglas Gregor }
1355718292f2SDouglas Gregor 
135697292843SDaniel Jasper /// \brief Parse an extern module declaration.
135797292843SDaniel Jasper ///
135897292843SDaniel Jasper ///   extern module-declaration:
135997292843SDaniel Jasper ///     'extern' 'module' module-id string-literal
136097292843SDaniel Jasper void ModuleMapParser::parseExternModuleDecl() {
136197292843SDaniel Jasper   assert(Tok.is(MMToken::ExternKeyword));
136297292843SDaniel Jasper   consumeToken(); // 'extern' keyword
136397292843SDaniel Jasper 
136497292843SDaniel Jasper   // Parse 'module' keyword.
136597292843SDaniel Jasper   if (!Tok.is(MMToken::ModuleKeyword)) {
136697292843SDaniel Jasper     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
136797292843SDaniel Jasper     consumeToken();
136897292843SDaniel Jasper     HadError = true;
136997292843SDaniel Jasper     return;
137097292843SDaniel Jasper   }
137197292843SDaniel Jasper   consumeToken(); // 'module' keyword
137297292843SDaniel Jasper 
137397292843SDaniel Jasper   // Parse the module name.
137497292843SDaniel Jasper   ModuleId Id;
137597292843SDaniel Jasper   if (parseModuleId(Id)) {
137697292843SDaniel Jasper     HadError = true;
137797292843SDaniel Jasper     return;
137897292843SDaniel Jasper   }
137997292843SDaniel Jasper 
138097292843SDaniel Jasper   // Parse the referenced module map file name.
138197292843SDaniel Jasper   if (!Tok.is(MMToken::StringLiteral)) {
138297292843SDaniel Jasper     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
138397292843SDaniel Jasper     HadError = true;
138497292843SDaniel Jasper     return;
138597292843SDaniel Jasper   }
138697292843SDaniel Jasper   std::string FileName = Tok.getString();
138797292843SDaniel Jasper   consumeToken(); // filename
138897292843SDaniel Jasper 
138997292843SDaniel Jasper   StringRef FileNameRef = FileName;
139097292843SDaniel Jasper   SmallString<128> ModuleMapFileName;
139197292843SDaniel Jasper   if (llvm::sys::path::is_relative(FileNameRef)) {
139297292843SDaniel Jasper     ModuleMapFileName += Directory->getName();
139397292843SDaniel Jasper     llvm::sys::path::append(ModuleMapFileName, FileName);
139497292843SDaniel Jasper     FileNameRef = ModuleMapFileName.str();
139597292843SDaniel Jasper   }
139697292843SDaniel Jasper   if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
139797292843SDaniel Jasper     Map.parseModuleMapFile(File, /*IsSystem=*/false);
139897292843SDaniel Jasper }
139997292843SDaniel Jasper 
14001fb5c3a6SDouglas Gregor /// \brief Parse a requires declaration.
14011fb5c3a6SDouglas Gregor ///
14021fb5c3a6SDouglas Gregor ///   requires-declaration:
14031fb5c3a6SDouglas Gregor ///     'requires' feature-list
14041fb5c3a6SDouglas Gregor ///
14051fb5c3a6SDouglas Gregor ///   feature-list:
1406a3feee2aSRichard Smith ///     feature ',' feature-list
1407a3feee2aSRichard Smith ///     feature
1408a3feee2aSRichard Smith ///
1409a3feee2aSRichard Smith ///   feature:
1410a3feee2aSRichard Smith ///     '!'[opt] identifier
14111fb5c3a6SDouglas Gregor void ModuleMapParser::parseRequiresDecl() {
14121fb5c3a6SDouglas Gregor   assert(Tok.is(MMToken::RequiresKeyword));
14131fb5c3a6SDouglas Gregor 
14141fb5c3a6SDouglas Gregor   // Parse 'requires' keyword.
14151fb5c3a6SDouglas Gregor   consumeToken();
14161fb5c3a6SDouglas Gregor 
14171fb5c3a6SDouglas Gregor   // Parse the feature-list.
14181fb5c3a6SDouglas Gregor   do {
1419a3feee2aSRichard Smith     bool RequiredState = true;
1420a3feee2aSRichard Smith     if (Tok.is(MMToken::Exclaim)) {
1421a3feee2aSRichard Smith       RequiredState = false;
1422a3feee2aSRichard Smith       consumeToken();
1423a3feee2aSRichard Smith     }
1424a3feee2aSRichard Smith 
14251fb5c3a6SDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
14261fb5c3a6SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
14271fb5c3a6SDouglas Gregor       HadError = true;
14281fb5c3a6SDouglas Gregor       return;
14291fb5c3a6SDouglas Gregor     }
14301fb5c3a6SDouglas Gregor 
14311fb5c3a6SDouglas Gregor     // Consume the feature name.
14321fb5c3a6SDouglas Gregor     std::string Feature = Tok.getString();
14331fb5c3a6SDouglas Gregor     consumeToken();
14341fb5c3a6SDouglas Gregor 
14351fb5c3a6SDouglas Gregor     // Add this feature.
1436a3feee2aSRichard Smith     ActiveModule->addRequirement(Feature, RequiredState,
1437a3feee2aSRichard Smith                                  Map.LangOpts, *Map.Target);
14381fb5c3a6SDouglas Gregor 
14391fb5c3a6SDouglas Gregor     if (!Tok.is(MMToken::Comma))
14401fb5c3a6SDouglas Gregor       break;
14411fb5c3a6SDouglas Gregor 
14421fb5c3a6SDouglas Gregor     // Consume the comma.
14431fb5c3a6SDouglas Gregor     consumeToken();
14441fb5c3a6SDouglas Gregor   } while (true);
14451fb5c3a6SDouglas Gregor }
14461fb5c3a6SDouglas Gregor 
1447f2161a70SDouglas Gregor /// \brief Append to \p Paths the set of paths needed to get to the
1448f2161a70SDouglas Gregor /// subframework in which the given module lives.
1449bf8da9d7SBenjamin Kramer static void appendSubframeworkPaths(Module *Mod,
1450f857950dSDmitri Gribenko                                     SmallVectorImpl<char> &Path) {
1451f2161a70SDouglas Gregor   // Collect the framework names from the given module to the top-level module.
1452f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Paths;
1453f2161a70SDouglas Gregor   for (; Mod; Mod = Mod->Parent) {
1454f2161a70SDouglas Gregor     if (Mod->IsFramework)
1455f2161a70SDouglas Gregor       Paths.push_back(Mod->Name);
1456f2161a70SDouglas Gregor   }
1457f2161a70SDouglas Gregor 
1458f2161a70SDouglas Gregor   if (Paths.empty())
1459f2161a70SDouglas Gregor     return;
1460f2161a70SDouglas Gregor 
1461f2161a70SDouglas Gregor   // Add Frameworks/Name.framework for each subframework.
146217381a06SBenjamin Kramer   for (unsigned I = Paths.size() - 1; I != 0; --I)
146317381a06SBenjamin Kramer     llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
1464f2161a70SDouglas Gregor }
1465f2161a70SDouglas Gregor 
1466718292f2SDouglas Gregor /// \brief Parse a header declaration.
1467718292f2SDouglas Gregor ///
1468718292f2SDouglas Gregor ///   header-declaration:
1469322f633cSDouglas Gregor ///     'umbrella'[opt] 'header' string-literal
147059527666SDouglas Gregor ///     'exclude'[opt] 'header' string-literal
1471b53e5483SLawrence Crowl void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1472b53e5483SLawrence Crowl                                       SourceLocation LeadingLoc) {
1473718292f2SDouglas Gregor   assert(Tok.is(MMToken::HeaderKeyword));
14741871ed3dSBenjamin Kramer   consumeToken();
1475718292f2SDouglas Gregor 
1476718292f2SDouglas Gregor   // Parse the header name.
1477718292f2SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
1478718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1479718292f2SDouglas Gregor       << "header";
1480718292f2SDouglas Gregor     HadError = true;
1481718292f2SDouglas Gregor     return;
1482718292f2SDouglas Gregor   }
1483e7ab3669SDouglas Gregor   std::string FileName = Tok.getString();
1484718292f2SDouglas Gregor   SourceLocation FileNameLoc = consumeToken();
1485718292f2SDouglas Gregor 
1486524e33e1SDouglas Gregor   // Check whether we already have an umbrella.
1487b53e5483SLawrence Crowl   if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
1488524e33e1SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1489524e33e1SDouglas Gregor       << ActiveModule->getFullModuleName();
1490322f633cSDouglas Gregor     HadError = true;
1491322f633cSDouglas Gregor     return;
1492322f633cSDouglas Gregor   }
1493322f633cSDouglas Gregor 
14945257fc63SDouglas Gregor   // Look for this file.
1495e7ab3669SDouglas Gregor   const FileEntry *File = 0;
14963ec6663bSDouglas Gregor   const FileEntry *BuiltinFile = 0;
14972c1dd271SDylan Noblesmith   SmallString<128> PathName;
1498e7ab3669SDouglas Gregor   if (llvm::sys::path::is_absolute(FileName)) {
1499e7ab3669SDouglas Gregor     PathName = FileName;
1500e7ab3669SDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
15017033127bSDouglas Gregor   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
15027033127bSDouglas Gregor     PathName = Dir->getName();
15037033127bSDouglas Gregor     llvm::sys::path::append(PathName, FileName);
15047033127bSDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
1505e7ab3669SDouglas Gregor   } else {
1506e7ab3669SDouglas Gregor     // Search for the header file within the search directory.
15077033127bSDouglas Gregor     PathName = Directory->getName();
1508e7ab3669SDouglas Gregor     unsigned PathLength = PathName.size();
1509755b2055SDouglas Gregor 
1510f2161a70SDouglas Gregor     if (ActiveModule->isPartOfFramework()) {
1511f2161a70SDouglas Gregor       appendSubframeworkPaths(ActiveModule, PathName);
1512755b2055SDouglas Gregor 
1513e7ab3669SDouglas Gregor       // Check whether this file is in the public headers.
151417381a06SBenjamin Kramer       llvm::sys::path::append(PathName, "Headers", FileName);
1515e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
1516e7ab3669SDouglas Gregor 
1517e7ab3669SDouglas Gregor       if (!File) {
1518e7ab3669SDouglas Gregor         // Check whether this file is in the private headers.
1519e7ab3669SDouglas Gregor         PathName.resize(PathLength);
152017381a06SBenjamin Kramer         llvm::sys::path::append(PathName, "PrivateHeaders", FileName);
1521e7ab3669SDouglas Gregor         File = SourceMgr.getFileManager().getFile(PathName);
1522e7ab3669SDouglas Gregor       }
1523e7ab3669SDouglas Gregor     } else {
1524e7ab3669SDouglas Gregor       // Lookup for normal headers.
1525e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
1526e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
15273ec6663bSDouglas Gregor 
15283ec6663bSDouglas Gregor       // If this is a system module with a top-level header, this header
15293ec6663bSDouglas Gregor       // may have a counterpart (or replacement) in the set of headers
15303ec6663bSDouglas Gregor       // supplied by Clang. Find that builtin header.
1531b53e5483SLawrence Crowl       if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1532b53e5483SLawrence Crowl           BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1533b53e5483SLawrence Crowl           isBuiltinHeader(FileName)) {
15342c1dd271SDylan Noblesmith         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
15353ec6663bSDouglas Gregor         llvm::sys::path::append(BuiltinPathName, FileName);
15363ec6663bSDouglas Gregor         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
15373ec6663bSDouglas Gregor 
15383ec6663bSDouglas Gregor         // If Clang supplies this header but the underlying system does not,
15393ec6663bSDouglas Gregor         // just silently swap in our builtin version. Otherwise, we'll end
15403ec6663bSDouglas Gregor         // up adding both (later).
15413ec6663bSDouglas Gregor         if (!File && BuiltinFile) {
15423ec6663bSDouglas Gregor           File = BuiltinFile;
15433ec6663bSDouglas Gregor           BuiltinFile = 0;
15443ec6663bSDouglas Gregor         }
15453ec6663bSDouglas Gregor       }
1546e7ab3669SDouglas Gregor     }
1547e7ab3669SDouglas Gregor   }
15485257fc63SDouglas Gregor 
15495257fc63SDouglas Gregor   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
15505257fc63SDouglas Gregor   // Come up with a lazy way to do this.
1551e7ab3669SDouglas Gregor   if (File) {
155297da9178SDaniel Jasper     if (LeadingToken == MMToken::UmbrellaKeyword) {
1553322f633cSDouglas Gregor       const DirectoryEntry *UmbrellaDir = File->getDir();
155459527666SDouglas Gregor       if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1555b53e5483SLawrence Crowl         Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
155659527666SDouglas Gregor           << UmbrellaModule->getFullModuleName();
1557322f633cSDouglas Gregor         HadError = true;
15585257fc63SDouglas Gregor       } else {
1559322f633cSDouglas Gregor         // Record this umbrella header.
1560322f633cSDouglas Gregor         Map.setUmbrellaHeader(ActiveModule, File);
1561322f633cSDouglas Gregor       }
1562322f633cSDouglas Gregor     } else {
1563322f633cSDouglas Gregor       // Record this header.
1564b53e5483SLawrence Crowl       ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1565b53e5483SLawrence Crowl       if (LeadingToken == MMToken::ExcludeKeyword)
1566b53e5483SLawrence Crowl         Role = ModuleMap::ExcludedHeader;
1567b53e5483SLawrence Crowl       else if (LeadingToken == MMToken::PrivateKeyword)
1568b53e5483SLawrence Crowl         Role = ModuleMap::PrivateHeader;
1569b53e5483SLawrence Crowl       else
1570b53e5483SLawrence Crowl         assert(LeadingToken == MMToken::HeaderKeyword);
1571b53e5483SLawrence Crowl 
1572b53e5483SLawrence Crowl       Map.addHeader(ActiveModule, File, Role);
15733ec6663bSDouglas Gregor 
15743ec6663bSDouglas Gregor       // If there is a builtin counterpart to this file, add it now.
15753ec6663bSDouglas Gregor       if (BuiltinFile)
1576b53e5483SLawrence Crowl         Map.addHeader(ActiveModule, BuiltinFile, Role);
15775257fc63SDouglas Gregor     }
1578b53e5483SLawrence Crowl   } else if (LeadingToken != MMToken::ExcludeKeyword) {
15794b27a64bSDouglas Gregor     // Ignore excluded header files. They're optional anyway.
15804b27a64bSDouglas Gregor 
15815257fc63SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1582b53e5483SLawrence Crowl       << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
15835257fc63SDouglas Gregor     HadError = true;
15845257fc63SDouglas Gregor   }
1585718292f2SDouglas Gregor }
1586718292f2SDouglas Gregor 
1587524e33e1SDouglas Gregor /// \brief Parse an umbrella directory declaration.
1588524e33e1SDouglas Gregor ///
1589524e33e1SDouglas Gregor ///   umbrella-dir-declaration:
1590524e33e1SDouglas Gregor ///     umbrella string-literal
1591524e33e1SDouglas Gregor void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1592524e33e1SDouglas Gregor   // Parse the directory name.
1593524e33e1SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
1594524e33e1SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1595524e33e1SDouglas Gregor       << "umbrella";
1596524e33e1SDouglas Gregor     HadError = true;
1597524e33e1SDouglas Gregor     return;
1598524e33e1SDouglas Gregor   }
1599524e33e1SDouglas Gregor 
1600524e33e1SDouglas Gregor   std::string DirName = Tok.getString();
1601524e33e1SDouglas Gregor   SourceLocation DirNameLoc = consumeToken();
1602524e33e1SDouglas Gregor 
1603524e33e1SDouglas Gregor   // Check whether we already have an umbrella.
1604524e33e1SDouglas Gregor   if (ActiveModule->Umbrella) {
1605524e33e1SDouglas Gregor     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1606524e33e1SDouglas Gregor       << ActiveModule->getFullModuleName();
1607524e33e1SDouglas Gregor     HadError = true;
1608524e33e1SDouglas Gregor     return;
1609524e33e1SDouglas Gregor   }
1610524e33e1SDouglas Gregor 
1611524e33e1SDouglas Gregor   // Look for this file.
1612524e33e1SDouglas Gregor   const DirectoryEntry *Dir = 0;
1613524e33e1SDouglas Gregor   if (llvm::sys::path::is_absolute(DirName))
1614524e33e1SDouglas Gregor     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1615524e33e1SDouglas Gregor   else {
16162c1dd271SDylan Noblesmith     SmallString<128> PathName;
1617524e33e1SDouglas Gregor     PathName = Directory->getName();
1618524e33e1SDouglas Gregor     llvm::sys::path::append(PathName, DirName);
1619524e33e1SDouglas Gregor     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1620524e33e1SDouglas Gregor   }
1621524e33e1SDouglas Gregor 
1622524e33e1SDouglas Gregor   if (!Dir) {
1623524e33e1SDouglas Gregor     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1624524e33e1SDouglas Gregor       << DirName;
1625524e33e1SDouglas Gregor     HadError = true;
1626524e33e1SDouglas Gregor     return;
1627524e33e1SDouglas Gregor   }
1628524e33e1SDouglas Gregor 
1629524e33e1SDouglas Gregor   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1630524e33e1SDouglas Gregor     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1631524e33e1SDouglas Gregor       << OwningModule->getFullModuleName();
1632524e33e1SDouglas Gregor     HadError = true;
1633524e33e1SDouglas Gregor     return;
1634524e33e1SDouglas Gregor   }
1635524e33e1SDouglas Gregor 
1636524e33e1SDouglas Gregor   // Record this umbrella directory.
1637524e33e1SDouglas Gregor   Map.setUmbrellaDir(ActiveModule, Dir);
1638524e33e1SDouglas Gregor }
1639524e33e1SDouglas Gregor 
16402b82c2a5SDouglas Gregor /// \brief Parse a module export declaration.
16412b82c2a5SDouglas Gregor ///
16422b82c2a5SDouglas Gregor ///   export-declaration:
16432b82c2a5SDouglas Gregor ///     'export' wildcard-module-id
16442b82c2a5SDouglas Gregor ///
16452b82c2a5SDouglas Gregor ///   wildcard-module-id:
16462b82c2a5SDouglas Gregor ///     identifier
16472b82c2a5SDouglas Gregor ///     '*'
16482b82c2a5SDouglas Gregor ///     identifier '.' wildcard-module-id
16492b82c2a5SDouglas Gregor void ModuleMapParser::parseExportDecl() {
16502b82c2a5SDouglas Gregor   assert(Tok.is(MMToken::ExportKeyword));
16512b82c2a5SDouglas Gregor   SourceLocation ExportLoc = consumeToken();
16522b82c2a5SDouglas Gregor 
16532b82c2a5SDouglas Gregor   // Parse the module-id with an optional wildcard at the end.
16542b82c2a5SDouglas Gregor   ModuleId ParsedModuleId;
16552b82c2a5SDouglas Gregor   bool Wildcard = false;
16562b82c2a5SDouglas Gregor   do {
16572b82c2a5SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
16582b82c2a5SDouglas Gregor       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
16592b82c2a5SDouglas Gregor                                               Tok.getLocation()));
16602b82c2a5SDouglas Gregor       consumeToken();
16612b82c2a5SDouglas Gregor 
16622b82c2a5SDouglas Gregor       if (Tok.is(MMToken::Period)) {
16632b82c2a5SDouglas Gregor         consumeToken();
16642b82c2a5SDouglas Gregor         continue;
16652b82c2a5SDouglas Gregor       }
16662b82c2a5SDouglas Gregor 
16672b82c2a5SDouglas Gregor       break;
16682b82c2a5SDouglas Gregor     }
16692b82c2a5SDouglas Gregor 
16702b82c2a5SDouglas Gregor     if(Tok.is(MMToken::Star)) {
16712b82c2a5SDouglas Gregor       Wildcard = true;
1672f5eedd05SDouglas Gregor       consumeToken();
16732b82c2a5SDouglas Gregor       break;
16742b82c2a5SDouglas Gregor     }
16752b82c2a5SDouglas Gregor 
1676ba7f2f71SDaniel Jasper     Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
16772b82c2a5SDouglas Gregor     HadError = true;
16782b82c2a5SDouglas Gregor     return;
16792b82c2a5SDouglas Gregor   } while (true);
16802b82c2a5SDouglas Gregor 
16812b82c2a5SDouglas Gregor   Module::UnresolvedExportDecl Unresolved = {
16822b82c2a5SDouglas Gregor     ExportLoc, ParsedModuleId, Wildcard
16832b82c2a5SDouglas Gregor   };
16842b82c2a5SDouglas Gregor   ActiveModule->UnresolvedExports.push_back(Unresolved);
16852b82c2a5SDouglas Gregor }
16862b82c2a5SDouglas Gregor 
1687ba7f2f71SDaniel Jasper /// \brief Parse a module uses declaration.
1688ba7f2f71SDaniel Jasper ///
1689ba7f2f71SDaniel Jasper ///   uses-declaration:
1690ba7f2f71SDaniel Jasper ///     'uses' wildcard-module-id
1691ba7f2f71SDaniel Jasper void ModuleMapParser::parseUseDecl() {
1692ba7f2f71SDaniel Jasper   assert(Tok.is(MMToken::UseKeyword));
1693ba7f2f71SDaniel Jasper   consumeToken();
1694ba7f2f71SDaniel Jasper   // Parse the module-id.
1695ba7f2f71SDaniel Jasper   ModuleId ParsedModuleId;
16963cd34c76SDaniel Jasper   parseModuleId(ParsedModuleId);
1697ba7f2f71SDaniel Jasper 
1698ba7f2f71SDaniel Jasper   ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1699ba7f2f71SDaniel Jasper }
1700ba7f2f71SDaniel Jasper 
17016ddfca91SDouglas Gregor /// \brief Parse a link declaration.
17026ddfca91SDouglas Gregor ///
17036ddfca91SDouglas Gregor ///   module-declaration:
17046ddfca91SDouglas Gregor ///     'link' 'framework'[opt] string-literal
17056ddfca91SDouglas Gregor void ModuleMapParser::parseLinkDecl() {
17066ddfca91SDouglas Gregor   assert(Tok.is(MMToken::LinkKeyword));
17076ddfca91SDouglas Gregor   SourceLocation LinkLoc = consumeToken();
17086ddfca91SDouglas Gregor 
17096ddfca91SDouglas Gregor   // Parse the optional 'framework' keyword.
17106ddfca91SDouglas Gregor   bool IsFramework = false;
17116ddfca91SDouglas Gregor   if (Tok.is(MMToken::FrameworkKeyword)) {
17126ddfca91SDouglas Gregor     consumeToken();
17136ddfca91SDouglas Gregor     IsFramework = true;
17146ddfca91SDouglas Gregor   }
17156ddfca91SDouglas Gregor 
17166ddfca91SDouglas Gregor   // Parse the library name
17176ddfca91SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
17186ddfca91SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
17196ddfca91SDouglas Gregor       << IsFramework << SourceRange(LinkLoc);
17206ddfca91SDouglas Gregor     HadError = true;
17216ddfca91SDouglas Gregor     return;
17226ddfca91SDouglas Gregor   }
17236ddfca91SDouglas Gregor 
17246ddfca91SDouglas Gregor   std::string LibraryName = Tok.getString();
17256ddfca91SDouglas Gregor   consumeToken();
17266ddfca91SDouglas Gregor   ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
17276ddfca91SDouglas Gregor                                                             IsFramework));
17286ddfca91SDouglas Gregor }
17296ddfca91SDouglas Gregor 
173035b13eceSDouglas Gregor /// \brief Parse a configuration macro declaration.
173135b13eceSDouglas Gregor ///
173235b13eceSDouglas Gregor ///   module-declaration:
173335b13eceSDouglas Gregor ///     'config_macros' attributes[opt] config-macro-list?
173435b13eceSDouglas Gregor ///
173535b13eceSDouglas Gregor ///   config-macro-list:
173635b13eceSDouglas Gregor ///     identifier (',' identifier)?
173735b13eceSDouglas Gregor void ModuleMapParser::parseConfigMacros() {
173835b13eceSDouglas Gregor   assert(Tok.is(MMToken::ConfigMacros));
173935b13eceSDouglas Gregor   SourceLocation ConfigMacrosLoc = consumeToken();
174035b13eceSDouglas Gregor 
174135b13eceSDouglas Gregor   // Only top-level modules can have configuration macros.
174235b13eceSDouglas Gregor   if (ActiveModule->Parent) {
174335b13eceSDouglas Gregor     Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
174435b13eceSDouglas Gregor   }
174535b13eceSDouglas Gregor 
174635b13eceSDouglas Gregor   // Parse the optional attributes.
174735b13eceSDouglas Gregor   Attributes Attrs;
174835b13eceSDouglas Gregor   parseOptionalAttributes(Attrs);
174935b13eceSDouglas Gregor   if (Attrs.IsExhaustive && !ActiveModule->Parent) {
175035b13eceSDouglas Gregor     ActiveModule->ConfigMacrosExhaustive = true;
175135b13eceSDouglas Gregor   }
175235b13eceSDouglas Gregor 
175335b13eceSDouglas Gregor   // If we don't have an identifier, we're done.
175435b13eceSDouglas Gregor   if (!Tok.is(MMToken::Identifier))
175535b13eceSDouglas Gregor     return;
175635b13eceSDouglas Gregor 
175735b13eceSDouglas Gregor   // Consume the first identifier.
175835b13eceSDouglas Gregor   if (!ActiveModule->Parent) {
175935b13eceSDouglas Gregor     ActiveModule->ConfigMacros.push_back(Tok.getString().str());
176035b13eceSDouglas Gregor   }
176135b13eceSDouglas Gregor   consumeToken();
176235b13eceSDouglas Gregor 
176335b13eceSDouglas Gregor   do {
176435b13eceSDouglas Gregor     // If there's a comma, consume it.
176535b13eceSDouglas Gregor     if (!Tok.is(MMToken::Comma))
176635b13eceSDouglas Gregor       break;
176735b13eceSDouglas Gregor     consumeToken();
176835b13eceSDouglas Gregor 
176935b13eceSDouglas Gregor     // We expect to see a macro name here.
177035b13eceSDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
177135b13eceSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
177235b13eceSDouglas Gregor       break;
177335b13eceSDouglas Gregor     }
177435b13eceSDouglas Gregor 
177535b13eceSDouglas Gregor     // Consume the macro name.
177635b13eceSDouglas Gregor     if (!ActiveModule->Parent) {
177735b13eceSDouglas Gregor       ActiveModule->ConfigMacros.push_back(Tok.getString().str());
177835b13eceSDouglas Gregor     }
177935b13eceSDouglas Gregor     consumeToken();
178035b13eceSDouglas Gregor   } while (true);
178135b13eceSDouglas Gregor }
178235b13eceSDouglas Gregor 
1783fb912657SDouglas Gregor /// \brief Format a module-id into a string.
1784fb912657SDouglas Gregor static std::string formatModuleId(const ModuleId &Id) {
1785fb912657SDouglas Gregor   std::string result;
1786fb912657SDouglas Gregor   {
1787fb912657SDouglas Gregor     llvm::raw_string_ostream OS(result);
1788fb912657SDouglas Gregor 
1789fb912657SDouglas Gregor     for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1790fb912657SDouglas Gregor       if (I)
1791fb912657SDouglas Gregor         OS << ".";
1792fb912657SDouglas Gregor       OS << Id[I].first;
1793fb912657SDouglas Gregor     }
1794fb912657SDouglas Gregor   }
1795fb912657SDouglas Gregor 
1796fb912657SDouglas Gregor   return result;
1797fb912657SDouglas Gregor }
1798fb912657SDouglas Gregor 
1799fb912657SDouglas Gregor /// \brief Parse a conflict declaration.
1800fb912657SDouglas Gregor ///
1801fb912657SDouglas Gregor ///   module-declaration:
1802fb912657SDouglas Gregor ///     'conflict' module-id ',' string-literal
1803fb912657SDouglas Gregor void ModuleMapParser::parseConflict() {
1804fb912657SDouglas Gregor   assert(Tok.is(MMToken::Conflict));
1805fb912657SDouglas Gregor   SourceLocation ConflictLoc = consumeToken();
1806fb912657SDouglas Gregor   Module::UnresolvedConflict Conflict;
1807fb912657SDouglas Gregor 
1808fb912657SDouglas Gregor   // Parse the module-id.
1809fb912657SDouglas Gregor   if (parseModuleId(Conflict.Id))
1810fb912657SDouglas Gregor     return;
1811fb912657SDouglas Gregor 
1812fb912657SDouglas Gregor   // Parse the ','.
1813fb912657SDouglas Gregor   if (!Tok.is(MMToken::Comma)) {
1814fb912657SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1815fb912657SDouglas Gregor       << SourceRange(ConflictLoc);
1816fb912657SDouglas Gregor     return;
1817fb912657SDouglas Gregor   }
1818fb912657SDouglas Gregor   consumeToken();
1819fb912657SDouglas Gregor 
1820fb912657SDouglas Gregor   // Parse the message.
1821fb912657SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
1822fb912657SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1823fb912657SDouglas Gregor       << formatModuleId(Conflict.Id);
1824fb912657SDouglas Gregor     return;
1825fb912657SDouglas Gregor   }
1826fb912657SDouglas Gregor   Conflict.Message = Tok.getString().str();
1827fb912657SDouglas Gregor   consumeToken();
1828fb912657SDouglas Gregor 
1829fb912657SDouglas Gregor   // Add this unresolved conflict.
1830fb912657SDouglas Gregor   ActiveModule->UnresolvedConflicts.push_back(Conflict);
1831fb912657SDouglas Gregor }
1832fb912657SDouglas Gregor 
18336ddfca91SDouglas Gregor /// \brief Parse an inferred module declaration (wildcard modules).
18349194a91dSDouglas Gregor ///
18359194a91dSDouglas Gregor ///   module-declaration:
18369194a91dSDouglas Gregor ///     'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
18379194a91dSDouglas Gregor ///       { inferred-module-member* }
18389194a91dSDouglas Gregor ///
18399194a91dSDouglas Gregor ///   inferred-module-member:
18409194a91dSDouglas Gregor ///     'export' '*'
18419194a91dSDouglas Gregor ///     'exclude' identifier
18429194a91dSDouglas Gregor void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
184373441091SDouglas Gregor   assert(Tok.is(MMToken::Star));
184473441091SDouglas Gregor   SourceLocation StarLoc = consumeToken();
184573441091SDouglas Gregor   bool Failed = false;
184673441091SDouglas Gregor 
184773441091SDouglas Gregor   // Inferred modules must be submodules.
18489194a91dSDouglas Gregor   if (!ActiveModule && !Framework) {
184973441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
185073441091SDouglas Gregor     Failed = true;
185173441091SDouglas Gregor   }
185273441091SDouglas Gregor 
18539194a91dSDouglas Gregor   if (ActiveModule) {
1854524e33e1SDouglas Gregor     // Inferred modules must have umbrella directories.
1855524e33e1SDouglas Gregor     if (!Failed && !ActiveModule->getUmbrellaDir()) {
185673441091SDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
185773441091SDouglas Gregor       Failed = true;
185873441091SDouglas Gregor     }
185973441091SDouglas Gregor 
186073441091SDouglas Gregor     // Check for redefinition of an inferred module.
1861dd005f69SDouglas Gregor     if (!Failed && ActiveModule->InferSubmodules) {
186273441091SDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1863dd005f69SDouglas Gregor       if (ActiveModule->InferredSubmoduleLoc.isValid())
1864dd005f69SDouglas Gregor         Diags.Report(ActiveModule->InferredSubmoduleLoc,
186573441091SDouglas Gregor                      diag::note_mmap_prev_definition);
186673441091SDouglas Gregor       Failed = true;
186773441091SDouglas Gregor     }
186873441091SDouglas Gregor 
18699194a91dSDouglas Gregor     // Check for the 'framework' keyword, which is not permitted here.
18709194a91dSDouglas Gregor     if (Framework) {
18719194a91dSDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
18729194a91dSDouglas Gregor       Framework = false;
18739194a91dSDouglas Gregor     }
18749194a91dSDouglas Gregor   } else if (Explicit) {
18759194a91dSDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
18769194a91dSDouglas Gregor     Explicit = false;
18779194a91dSDouglas Gregor   }
18789194a91dSDouglas Gregor 
187973441091SDouglas Gregor   // If there were any problems with this inferred submodule, skip its body.
188073441091SDouglas Gregor   if (Failed) {
188173441091SDouglas Gregor     if (Tok.is(MMToken::LBrace)) {
188273441091SDouglas Gregor       consumeToken();
188373441091SDouglas Gregor       skipUntil(MMToken::RBrace);
188473441091SDouglas Gregor       if (Tok.is(MMToken::RBrace))
188573441091SDouglas Gregor         consumeToken();
188673441091SDouglas Gregor     }
188773441091SDouglas Gregor     HadError = true;
188873441091SDouglas Gregor     return;
188973441091SDouglas Gregor   }
189073441091SDouglas Gregor 
18919194a91dSDouglas Gregor   // Parse optional attributes.
18924442605fSBill Wendling   Attributes Attrs;
18939194a91dSDouglas Gregor   parseOptionalAttributes(Attrs);
18949194a91dSDouglas Gregor 
18959194a91dSDouglas Gregor   if (ActiveModule) {
189673441091SDouglas Gregor     // Note that we have an inferred submodule.
1897dd005f69SDouglas Gregor     ActiveModule->InferSubmodules = true;
1898dd005f69SDouglas Gregor     ActiveModule->InferredSubmoduleLoc = StarLoc;
1899dd005f69SDouglas Gregor     ActiveModule->InferExplicitSubmodules = Explicit;
19009194a91dSDouglas Gregor   } else {
19019194a91dSDouglas Gregor     // We'll be inferring framework modules for this directory.
19029194a91dSDouglas Gregor     Map.InferredDirectories[Directory].InferModules = true;
19039194a91dSDouglas Gregor     Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
19049194a91dSDouglas Gregor   }
190573441091SDouglas Gregor 
190673441091SDouglas Gregor   // Parse the opening brace.
190773441091SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
190873441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
190973441091SDouglas Gregor     HadError = true;
191073441091SDouglas Gregor     return;
191173441091SDouglas Gregor   }
191273441091SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
191373441091SDouglas Gregor 
191473441091SDouglas Gregor   // Parse the body of the inferred submodule.
191573441091SDouglas Gregor   bool Done = false;
191673441091SDouglas Gregor   do {
191773441091SDouglas Gregor     switch (Tok.Kind) {
191873441091SDouglas Gregor     case MMToken::EndOfFile:
191973441091SDouglas Gregor     case MMToken::RBrace:
192073441091SDouglas Gregor       Done = true;
192173441091SDouglas Gregor       break;
192273441091SDouglas Gregor 
19239194a91dSDouglas Gregor     case MMToken::ExcludeKeyword: {
19249194a91dSDouglas Gregor       if (ActiveModule) {
19259194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1926162405daSDouglas Gregor           << (ActiveModule != 0);
19279194a91dSDouglas Gregor         consumeToken();
19289194a91dSDouglas Gregor         break;
19299194a91dSDouglas Gregor       }
19309194a91dSDouglas Gregor 
19319194a91dSDouglas Gregor       consumeToken();
19329194a91dSDouglas Gregor       if (!Tok.is(MMToken::Identifier)) {
19339194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
19349194a91dSDouglas Gregor         break;
19359194a91dSDouglas Gregor       }
19369194a91dSDouglas Gregor 
19379194a91dSDouglas Gregor       Map.InferredDirectories[Directory].ExcludedModules
19389194a91dSDouglas Gregor         .push_back(Tok.getString());
19399194a91dSDouglas Gregor       consumeToken();
19409194a91dSDouglas Gregor       break;
19419194a91dSDouglas Gregor     }
19429194a91dSDouglas Gregor 
19439194a91dSDouglas Gregor     case MMToken::ExportKeyword:
19449194a91dSDouglas Gregor       if (!ActiveModule) {
19459194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1946162405daSDouglas Gregor           << (ActiveModule != 0);
19479194a91dSDouglas Gregor         consumeToken();
19489194a91dSDouglas Gregor         break;
19499194a91dSDouglas Gregor       }
19509194a91dSDouglas Gregor 
195173441091SDouglas Gregor       consumeToken();
195273441091SDouglas Gregor       if (Tok.is(MMToken::Star))
1953dd005f69SDouglas Gregor         ActiveModule->InferExportWildcard = true;
195473441091SDouglas Gregor       else
195573441091SDouglas Gregor         Diags.Report(Tok.getLocation(),
195673441091SDouglas Gregor                      diag::err_mmap_expected_export_wildcard);
195773441091SDouglas Gregor       consumeToken();
195873441091SDouglas Gregor       break;
195973441091SDouglas Gregor 
196073441091SDouglas Gregor     case MMToken::ExplicitKeyword:
196173441091SDouglas Gregor     case MMToken::ModuleKeyword:
196273441091SDouglas Gregor     case MMToken::HeaderKeyword:
1963b53e5483SLawrence Crowl     case MMToken::PrivateKeyword:
196473441091SDouglas Gregor     case MMToken::UmbrellaKeyword:
196573441091SDouglas Gregor     default:
19669194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1967162405daSDouglas Gregor           << (ActiveModule != 0);
196873441091SDouglas Gregor       consumeToken();
196973441091SDouglas Gregor       break;
197073441091SDouglas Gregor     }
197173441091SDouglas Gregor   } while (!Done);
197273441091SDouglas Gregor 
197373441091SDouglas Gregor   if (Tok.is(MMToken::RBrace))
197473441091SDouglas Gregor     consumeToken();
197573441091SDouglas Gregor   else {
197673441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
197773441091SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
197873441091SDouglas Gregor     HadError = true;
197973441091SDouglas Gregor   }
198073441091SDouglas Gregor }
198173441091SDouglas Gregor 
19829194a91dSDouglas Gregor /// \brief Parse optional attributes.
19839194a91dSDouglas Gregor ///
19849194a91dSDouglas Gregor ///   attributes:
19859194a91dSDouglas Gregor ///     attribute attributes
19869194a91dSDouglas Gregor ///     attribute
19879194a91dSDouglas Gregor ///
19889194a91dSDouglas Gregor ///   attribute:
19899194a91dSDouglas Gregor ///     [ identifier ]
19909194a91dSDouglas Gregor ///
19919194a91dSDouglas Gregor /// \param Attrs Will be filled in with the parsed attributes.
19929194a91dSDouglas Gregor ///
19939194a91dSDouglas Gregor /// \returns true if an error occurred, false otherwise.
19944442605fSBill Wendling bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
19959194a91dSDouglas Gregor   bool HadError = false;
19969194a91dSDouglas Gregor 
19979194a91dSDouglas Gregor   while (Tok.is(MMToken::LSquare)) {
19989194a91dSDouglas Gregor     // Consume the '['.
19999194a91dSDouglas Gregor     SourceLocation LSquareLoc = consumeToken();
20009194a91dSDouglas Gregor 
20019194a91dSDouglas Gregor     // Check whether we have an attribute name here.
20029194a91dSDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
20039194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
20049194a91dSDouglas Gregor       skipUntil(MMToken::RSquare);
20059194a91dSDouglas Gregor       if (Tok.is(MMToken::RSquare))
20069194a91dSDouglas Gregor         consumeToken();
20079194a91dSDouglas Gregor       HadError = true;
20089194a91dSDouglas Gregor     }
20099194a91dSDouglas Gregor 
20109194a91dSDouglas Gregor     // Decode the attribute name.
20119194a91dSDouglas Gregor     AttributeKind Attribute
20129194a91dSDouglas Gregor       = llvm::StringSwitch<AttributeKind>(Tok.getString())
201335b13eceSDouglas Gregor           .Case("exhaustive", AT_exhaustive)
20149194a91dSDouglas Gregor           .Case("system", AT_system)
20159194a91dSDouglas Gregor           .Default(AT_unknown);
20169194a91dSDouglas Gregor     switch (Attribute) {
20179194a91dSDouglas Gregor     case AT_unknown:
20189194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
20199194a91dSDouglas Gregor         << Tok.getString();
20209194a91dSDouglas Gregor       break;
20219194a91dSDouglas Gregor 
20229194a91dSDouglas Gregor     case AT_system:
20239194a91dSDouglas Gregor       Attrs.IsSystem = true;
20249194a91dSDouglas Gregor       break;
202535b13eceSDouglas Gregor 
202635b13eceSDouglas Gregor     case AT_exhaustive:
202735b13eceSDouglas Gregor       Attrs.IsExhaustive = true;
202835b13eceSDouglas Gregor       break;
20299194a91dSDouglas Gregor     }
20309194a91dSDouglas Gregor     consumeToken();
20319194a91dSDouglas Gregor 
20329194a91dSDouglas Gregor     // Consume the ']'.
20339194a91dSDouglas Gregor     if (!Tok.is(MMToken::RSquare)) {
20349194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
20359194a91dSDouglas Gregor       Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
20369194a91dSDouglas Gregor       skipUntil(MMToken::RSquare);
20379194a91dSDouglas Gregor       HadError = true;
20389194a91dSDouglas Gregor     }
20399194a91dSDouglas Gregor 
20409194a91dSDouglas Gregor     if (Tok.is(MMToken::RSquare))
20419194a91dSDouglas Gregor       consumeToken();
20429194a91dSDouglas Gregor   }
20439194a91dSDouglas Gregor 
20449194a91dSDouglas Gregor   return HadError;
20459194a91dSDouglas Gregor }
20469194a91dSDouglas Gregor 
20477033127bSDouglas Gregor /// \brief If there is a specific header search directory due the presence
20487033127bSDouglas Gregor /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
20497033127bSDouglas Gregor const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
20507033127bSDouglas Gregor   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
20517033127bSDouglas Gregor     // If we have an umbrella directory, use that.
20527033127bSDouglas Gregor     if (Mod->hasUmbrellaDir())
20537033127bSDouglas Gregor       return Mod->getUmbrellaDir();
20547033127bSDouglas Gregor 
20557033127bSDouglas Gregor     // If we have a framework directory, stop looking.
20567033127bSDouglas Gregor     if (Mod->IsFramework)
20577033127bSDouglas Gregor       return 0;
20587033127bSDouglas Gregor   }
20597033127bSDouglas Gregor 
20607033127bSDouglas Gregor   return 0;
20617033127bSDouglas Gregor }
20627033127bSDouglas Gregor 
2063718292f2SDouglas Gregor /// \brief Parse a module map file.
2064718292f2SDouglas Gregor ///
2065718292f2SDouglas Gregor ///   module-map-file:
2066718292f2SDouglas Gregor ///     module-declaration*
2067718292f2SDouglas Gregor bool ModuleMapParser::parseModuleMapFile() {
2068718292f2SDouglas Gregor   do {
2069718292f2SDouglas Gregor     switch (Tok.Kind) {
2070718292f2SDouglas Gregor     case MMToken::EndOfFile:
2071718292f2SDouglas Gregor       return HadError;
2072718292f2SDouglas Gregor 
2073e7ab3669SDouglas Gregor     case MMToken::ExplicitKeyword:
207497292843SDaniel Jasper     case MMToken::ExternKeyword:
2075718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
2076755b2055SDouglas Gregor     case MMToken::FrameworkKeyword:
2077718292f2SDouglas Gregor       parseModuleDecl();
2078718292f2SDouglas Gregor       break;
2079718292f2SDouglas Gregor 
20801fb5c3a6SDouglas Gregor     case MMToken::Comma:
208135b13eceSDouglas Gregor     case MMToken::ConfigMacros:
2082fb912657SDouglas Gregor     case MMToken::Conflict:
2083a3feee2aSRichard Smith     case MMToken::Exclaim:
208459527666SDouglas Gregor     case MMToken::ExcludeKeyword:
20852b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
2086718292f2SDouglas Gregor     case MMToken::HeaderKeyword:
2087718292f2SDouglas Gregor     case MMToken::Identifier:
2088718292f2SDouglas Gregor     case MMToken::LBrace:
20896ddfca91SDouglas Gregor     case MMToken::LinkKeyword:
2090a686e1b0SDouglas Gregor     case MMToken::LSquare:
20912b82c2a5SDouglas Gregor     case MMToken::Period:
2092b53e5483SLawrence Crowl     case MMToken::PrivateKeyword:
2093718292f2SDouglas Gregor     case MMToken::RBrace:
2094a686e1b0SDouglas Gregor     case MMToken::RSquare:
20951fb5c3a6SDouglas Gregor     case MMToken::RequiresKeyword:
20962b82c2a5SDouglas Gregor     case MMToken::Star:
2097718292f2SDouglas Gregor     case MMToken::StringLiteral:
2098718292f2SDouglas Gregor     case MMToken::UmbrellaKeyword:
2099ba7f2f71SDaniel Jasper     case MMToken::UseKeyword:
2100718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2101718292f2SDouglas Gregor       HadError = true;
2102718292f2SDouglas Gregor       consumeToken();
2103718292f2SDouglas Gregor       break;
2104718292f2SDouglas Gregor     }
2105718292f2SDouglas Gregor   } while (true);
2106718292f2SDouglas Gregor }
2107718292f2SDouglas Gregor 
2108963c5535SDouglas Gregor bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
21094ddf2221SDouglas Gregor   llvm::DenseMap<const FileEntry *, bool>::iterator Known
21104ddf2221SDouglas Gregor     = ParsedModuleMap.find(File);
21114ddf2221SDouglas Gregor   if (Known != ParsedModuleMap.end())
21124ddf2221SDouglas Gregor     return Known->second;
21134ddf2221SDouglas Gregor 
211489929282SDouglas Gregor   assert(Target != 0 && "Missing target information");
21151f76c4e8SManuel Klimek   FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
21161f76c4e8SManuel Klimek   const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2117718292f2SDouglas Gregor   if (!Buffer)
21184ddf2221SDouglas Gregor     return ParsedModuleMap[File] = true;
2119718292f2SDouglas Gregor 
2120718292f2SDouglas Gregor   // Parse this module map file.
21211f76c4e8SManuel Klimek   Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
21221fb5c3a6SDouglas Gregor   Diags->getClient()->BeginSourceFile(MMapLangOpts);
21231f76c4e8SManuel Klimek   ModuleMapParser Parser(L, SourceMgr, Target, *Diags, *this, File->getDir(),
2124963c5535SDouglas Gregor                          BuiltinIncludeDir, IsSystem);
2125718292f2SDouglas Gregor   bool Result = Parser.parseModuleMapFile();
2126718292f2SDouglas Gregor   Diags->getClient()->EndSourceFile();
21274ddf2221SDouglas Gregor   ParsedModuleMap[File] = Result;
2128718292f2SDouglas Gregor   return Result;
2129718292f2SDouglas Gregor }
2130