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"
305257fc63SDouglas Gregor #include "llvm/Support/PathV2.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 
482b82c2a5SDouglas Gregor   // Find the starting module.
492b82c2a5SDouglas Gregor   Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
502b82c2a5SDouglas Gregor   if (!Context) {
512b82c2a5SDouglas Gregor     if (Complain)
522b82c2a5SDouglas Gregor       Diags->Report(Unresolved.Id[0].second,
532b82c2a5SDouglas Gregor                     diag::err_mmap_missing_module_unqualified)
542b82c2a5SDouglas Gregor         << Unresolved.Id[0].first << Mod->getFullModuleName();
552b82c2a5SDouglas Gregor 
562b82c2a5SDouglas Gregor     return Module::ExportDecl();
572b82c2a5SDouglas Gregor   }
582b82c2a5SDouglas Gregor 
592b82c2a5SDouglas Gregor   // Dig into the module path.
602b82c2a5SDouglas Gregor   for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
612b82c2a5SDouglas Gregor     Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
622b82c2a5SDouglas Gregor                                         Context);
632b82c2a5SDouglas Gregor     if (!Sub) {
642b82c2a5SDouglas Gregor       if (Complain)
652b82c2a5SDouglas Gregor         Diags->Report(Unresolved.Id[I].second,
662b82c2a5SDouglas Gregor                       diag::err_mmap_missing_module_qualified)
672b82c2a5SDouglas Gregor           << Unresolved.Id[I].first << Context->getFullModuleName()
682b82c2a5SDouglas Gregor           << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
692b82c2a5SDouglas Gregor 
702b82c2a5SDouglas Gregor       return Module::ExportDecl();
712b82c2a5SDouglas Gregor     }
722b82c2a5SDouglas Gregor 
732b82c2a5SDouglas Gregor     Context = Sub;
742b82c2a5SDouglas Gregor   }
752b82c2a5SDouglas Gregor 
762b82c2a5SDouglas Gregor   return Module::ExportDecl(Context, Unresolved.Wildcard);
772b82c2a5SDouglas Gregor }
782b82c2a5SDouglas Gregor 
791fb5c3a6SDouglas Gregor ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
80b146baabSArgyrios Kyrtzidis                      const LangOptions &LangOpts, const TargetInfo *Target,
81b146baabSArgyrios Kyrtzidis                      HeaderSearch &HeaderInfo)
82b146baabSArgyrios Kyrtzidis   : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
83b146baabSArgyrios Kyrtzidis     BuiltinIncludeDir(0)
841fb5c3a6SDouglas Gregor {
85c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
86c95d8192SDylan Noblesmith   Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
87811db4eaSDouglas Gregor             new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
88718292f2SDouglas Gregor   Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
89718292f2SDouglas Gregor   SourceMgr = new SourceManager(*Diags, FileMgr);
90718292f2SDouglas Gregor }
91718292f2SDouglas Gregor 
92718292f2SDouglas Gregor ModuleMap::~ModuleMap() {
935acdf59eSDouglas Gregor   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
945acdf59eSDouglas Gregor                                         IEnd = Modules.end();
955acdf59eSDouglas Gregor        I != IEnd; ++I) {
965acdf59eSDouglas Gregor     delete I->getValue();
975acdf59eSDouglas Gregor   }
985acdf59eSDouglas Gregor 
99718292f2SDouglas Gregor   delete SourceMgr;
100718292f2SDouglas Gregor }
101718292f2SDouglas Gregor 
10289929282SDouglas Gregor void ModuleMap::setTarget(const TargetInfo &Target) {
10389929282SDouglas Gregor   assert((!this->Target || this->Target == &Target) &&
10489929282SDouglas Gregor          "Improper target override");
10589929282SDouglas Gregor   this->Target = &Target;
10689929282SDouglas Gregor }
10789929282SDouglas Gregor 
108056396aeSDouglas Gregor /// \brief "Sanitize" a filename so that it can be used as an identifier.
109056396aeSDouglas Gregor static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
110056396aeSDouglas Gregor                                               SmallVectorImpl<char> &Buffer) {
111056396aeSDouglas Gregor   if (Name.empty())
112056396aeSDouglas Gregor     return Name;
113056396aeSDouglas Gregor 
114a7d03840SJordan Rose   if (!isValidIdentifier(Name)) {
115056396aeSDouglas Gregor     // If we don't already have something with the form of an identifier,
116056396aeSDouglas Gregor     // create a buffer with the sanitized name.
117056396aeSDouglas Gregor     Buffer.clear();
118a7d03840SJordan Rose     if (isDigit(Name[0]))
119056396aeSDouglas Gregor       Buffer.push_back('_');
120056396aeSDouglas Gregor     Buffer.reserve(Buffer.size() + Name.size());
121056396aeSDouglas Gregor     for (unsigned I = 0, N = Name.size(); I != N; ++I) {
122a7d03840SJordan Rose       if (isIdentifierBody(Name[I]))
123056396aeSDouglas Gregor         Buffer.push_back(Name[I]);
124056396aeSDouglas Gregor       else
125056396aeSDouglas Gregor         Buffer.push_back('_');
126056396aeSDouglas Gregor     }
127056396aeSDouglas Gregor 
128056396aeSDouglas Gregor     Name = StringRef(Buffer.data(), Buffer.size());
129056396aeSDouglas Gregor   }
130056396aeSDouglas Gregor 
131056396aeSDouglas Gregor   while (llvm::StringSwitch<bool>(Name)
132056396aeSDouglas Gregor #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
133056396aeSDouglas Gregor #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
134056396aeSDouglas Gregor #include "clang/Basic/TokenKinds.def"
135056396aeSDouglas Gregor            .Default(false)) {
136056396aeSDouglas Gregor     if (Name.data() != Buffer.data())
137056396aeSDouglas Gregor       Buffer.append(Name.begin(), Name.end());
138056396aeSDouglas Gregor     Buffer.push_back('_');
139056396aeSDouglas Gregor     Name = StringRef(Buffer.data(), Buffer.size());
140056396aeSDouglas Gregor   }
141056396aeSDouglas Gregor 
142056396aeSDouglas Gregor   return Name;
143056396aeSDouglas Gregor }
144056396aeSDouglas Gregor 
145de3ef502SDouglas Gregor Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
14659527666SDouglas Gregor   HeadersMap::iterator Known = Headers.find(File);
1471fb5c3a6SDouglas Gregor   if (Known != Headers.end()) {
14859527666SDouglas Gregor     // If a header is not available, don't report that it maps to anything.
14959527666SDouglas Gregor     if (!Known->second.isAvailable())
1501fb5c3a6SDouglas Gregor       return 0;
1511fb5c3a6SDouglas Gregor 
15259527666SDouglas Gregor     return Known->second.getModule();
1531fb5c3a6SDouglas Gregor   }
154ab0c8a84SDouglas Gregor 
155b65dbfffSDouglas Gregor   const DirectoryEntry *Dir = File->getDir();
156f857950dSDmitri Gribenko   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
157e00c8b20SDouglas Gregor 
15874260502SDouglas Gregor   // Note: as an egregious but useful hack we use the real path here, because
15974260502SDouglas Gregor   // frameworks moving from top-level frameworks to embedded frameworks tend
16074260502SDouglas Gregor   // to be symlinked from the top-level location to the embedded location,
16174260502SDouglas Gregor   // and we need to resolve lookups as if we had found the embedded location.
162e00c8b20SDouglas Gregor   StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
163a89c5ac4SDouglas Gregor 
164a89c5ac4SDouglas Gregor   // Keep walking up the directory hierarchy, looking for a directory with
165a89c5ac4SDouglas Gregor   // an umbrella header.
166b65dbfffSDouglas Gregor   do {
167a89c5ac4SDouglas Gregor     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
168a89c5ac4SDouglas Gregor       = UmbrellaDirs.find(Dir);
169a89c5ac4SDouglas Gregor     if (KnownDir != UmbrellaDirs.end()) {
170a89c5ac4SDouglas Gregor       Module *Result = KnownDir->second;
171930a85ccSDouglas Gregor 
172930a85ccSDouglas Gregor       // Search up the module stack until we find a module with an umbrella
17373141fa9SDouglas Gregor       // directory.
174930a85ccSDouglas Gregor       Module *UmbrellaModule = Result;
17573141fa9SDouglas Gregor       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
176930a85ccSDouglas Gregor         UmbrellaModule = UmbrellaModule->Parent;
177930a85ccSDouglas Gregor 
178930a85ccSDouglas Gregor       if (UmbrellaModule->InferSubmodules) {
179a89c5ac4SDouglas Gregor         // Infer submodules for each of the directories we found between
180a89c5ac4SDouglas Gregor         // the directory of the umbrella header and the directory where
181a89c5ac4SDouglas Gregor         // the actual header is located.
1829458f82dSDouglas Gregor         bool Explicit = UmbrellaModule->InferExplicitSubmodules;
1839458f82dSDouglas Gregor 
1847033127bSDouglas Gregor         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
185a89c5ac4SDouglas Gregor           // Find or create the module that corresponds to this directory name.
186056396aeSDouglas Gregor           SmallString<32> NameBuf;
187056396aeSDouglas Gregor           StringRef Name = sanitizeFilenameAsIdentifier(
188056396aeSDouglas Gregor                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
189056396aeSDouglas Gregor                              NameBuf);
190a89c5ac4SDouglas Gregor           Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
1919458f82dSDouglas Gregor                                       Explicit).first;
192a89c5ac4SDouglas Gregor 
193a89c5ac4SDouglas Gregor           // Associate the module and the directory.
194a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I-1]] = Result;
195a89c5ac4SDouglas Gregor 
196a89c5ac4SDouglas Gregor           // If inferred submodules export everything they import, add a
197a89c5ac4SDouglas Gregor           // wildcard to the set of exports.
198930a85ccSDouglas Gregor           if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
199a89c5ac4SDouglas Gregor             Result->Exports.push_back(Module::ExportDecl(0, true));
200a89c5ac4SDouglas Gregor         }
201a89c5ac4SDouglas Gregor 
202a89c5ac4SDouglas Gregor         // Infer a submodule with the same name as this header file.
203056396aeSDouglas Gregor         SmallString<32> NameBuf;
204056396aeSDouglas Gregor         StringRef Name = sanitizeFilenameAsIdentifier(
205056396aeSDouglas Gregor                            llvm::sys::path::stem(File->getName()), NameBuf);
206a89c5ac4SDouglas Gregor         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
2079458f82dSDouglas Gregor                                     Explicit).first;
2083c5305c1SArgyrios Kyrtzidis         Result->addTopHeader(File);
209a89c5ac4SDouglas Gregor 
210a89c5ac4SDouglas Gregor         // If inferred submodules export everything they import, add a
211a89c5ac4SDouglas Gregor         // wildcard to the set of exports.
212930a85ccSDouglas Gregor         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
213a89c5ac4SDouglas Gregor           Result->Exports.push_back(Module::ExportDecl(0, true));
214a89c5ac4SDouglas Gregor       } else {
215a89c5ac4SDouglas Gregor         // Record each of the directories we stepped through as being part of
216a89c5ac4SDouglas Gregor         // the module we found, since the umbrella header covers them all.
217a89c5ac4SDouglas Gregor         for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
218a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I]] = Result;
219a89c5ac4SDouglas Gregor       }
220a89c5ac4SDouglas Gregor 
22159527666SDouglas Gregor       Headers[File] = KnownHeader(Result, /*Excluded=*/false);
2221fb5c3a6SDouglas Gregor 
2231fb5c3a6SDouglas Gregor       // If a header corresponds to an unavailable module, don't report
2241fb5c3a6SDouglas Gregor       // that it maps to anything.
2251fb5c3a6SDouglas Gregor       if (!Result->isAvailable())
2261fb5c3a6SDouglas Gregor         return 0;
2271fb5c3a6SDouglas Gregor 
228a89c5ac4SDouglas Gregor       return Result;
229a89c5ac4SDouglas Gregor     }
230a89c5ac4SDouglas Gregor 
231a89c5ac4SDouglas Gregor     SkippedDirs.push_back(Dir);
232a89c5ac4SDouglas Gregor 
233b65dbfffSDouglas Gregor     // Retrieve our parent path.
234b65dbfffSDouglas Gregor     DirName = llvm::sys::path::parent_path(DirName);
235b65dbfffSDouglas Gregor     if (DirName.empty())
236b65dbfffSDouglas Gregor       break;
237b65dbfffSDouglas Gregor 
238b65dbfffSDouglas Gregor     // Resolve the parent path to a directory entry.
239b65dbfffSDouglas Gregor     Dir = SourceMgr->getFileManager().getDirectory(DirName);
240a89c5ac4SDouglas Gregor   } while (Dir);
241b65dbfffSDouglas Gregor 
242ab0c8a84SDouglas Gregor   return 0;
243ab0c8a84SDouglas Gregor }
244ab0c8a84SDouglas Gregor 
245e4412640SArgyrios Kyrtzidis bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
246e4412640SArgyrios Kyrtzidis   HeadersMap::const_iterator Known = Headers.find(Header);
2471fb5c3a6SDouglas Gregor   if (Known != Headers.end())
24859527666SDouglas Gregor     return !Known->second.isAvailable();
2491fb5c3a6SDouglas Gregor 
2501fb5c3a6SDouglas Gregor   const DirectoryEntry *Dir = Header->getDir();
251f857950dSDmitri Gribenko   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
2521fb5c3a6SDouglas Gregor   StringRef DirName = Dir->getName();
2531fb5c3a6SDouglas Gregor 
2541fb5c3a6SDouglas Gregor   // Keep walking up the directory hierarchy, looking for a directory with
2551fb5c3a6SDouglas Gregor   // an umbrella header.
2561fb5c3a6SDouglas Gregor   do {
257e4412640SArgyrios Kyrtzidis     llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
2581fb5c3a6SDouglas Gregor       = UmbrellaDirs.find(Dir);
2591fb5c3a6SDouglas Gregor     if (KnownDir != UmbrellaDirs.end()) {
2601fb5c3a6SDouglas Gregor       Module *Found = KnownDir->second;
2611fb5c3a6SDouglas Gregor       if (!Found->isAvailable())
2621fb5c3a6SDouglas Gregor         return true;
2631fb5c3a6SDouglas Gregor 
2641fb5c3a6SDouglas Gregor       // Search up the module stack until we find a module with an umbrella
2651fb5c3a6SDouglas Gregor       // directory.
2661fb5c3a6SDouglas Gregor       Module *UmbrellaModule = Found;
2671fb5c3a6SDouglas Gregor       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
2681fb5c3a6SDouglas Gregor         UmbrellaModule = UmbrellaModule->Parent;
2691fb5c3a6SDouglas Gregor 
2701fb5c3a6SDouglas Gregor       if (UmbrellaModule->InferSubmodules) {
2711fb5c3a6SDouglas Gregor         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
2721fb5c3a6SDouglas Gregor           // Find or create the module that corresponds to this directory name.
273056396aeSDouglas Gregor           SmallString<32> NameBuf;
274056396aeSDouglas Gregor           StringRef Name = sanitizeFilenameAsIdentifier(
275056396aeSDouglas Gregor                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
276056396aeSDouglas Gregor                              NameBuf);
2771fb5c3a6SDouglas Gregor           Found = lookupModuleQualified(Name, Found);
2781fb5c3a6SDouglas Gregor           if (!Found)
2791fb5c3a6SDouglas Gregor             return false;
2801fb5c3a6SDouglas Gregor           if (!Found->isAvailable())
2811fb5c3a6SDouglas Gregor             return true;
2821fb5c3a6SDouglas Gregor         }
2831fb5c3a6SDouglas Gregor 
2841fb5c3a6SDouglas Gregor         // Infer a submodule with the same name as this header file.
285056396aeSDouglas Gregor         SmallString<32> NameBuf;
286056396aeSDouglas Gregor         StringRef Name = sanitizeFilenameAsIdentifier(
287056396aeSDouglas Gregor                            llvm::sys::path::stem(Header->getName()),
288056396aeSDouglas Gregor                            NameBuf);
2891fb5c3a6SDouglas Gregor         Found = lookupModuleQualified(Name, Found);
2901fb5c3a6SDouglas Gregor         if (!Found)
2911fb5c3a6SDouglas Gregor           return false;
2921fb5c3a6SDouglas Gregor       }
2931fb5c3a6SDouglas Gregor 
2941fb5c3a6SDouglas Gregor       return !Found->isAvailable();
2951fb5c3a6SDouglas Gregor     }
2961fb5c3a6SDouglas Gregor 
2971fb5c3a6SDouglas Gregor     SkippedDirs.push_back(Dir);
2981fb5c3a6SDouglas Gregor 
2991fb5c3a6SDouglas Gregor     // Retrieve our parent path.
3001fb5c3a6SDouglas Gregor     DirName = llvm::sys::path::parent_path(DirName);
3011fb5c3a6SDouglas Gregor     if (DirName.empty())
3021fb5c3a6SDouglas Gregor       break;
3031fb5c3a6SDouglas Gregor 
3041fb5c3a6SDouglas Gregor     // Resolve the parent path to a directory entry.
3051fb5c3a6SDouglas Gregor     Dir = SourceMgr->getFileManager().getDirectory(DirName);
3061fb5c3a6SDouglas Gregor   } while (Dir);
3071fb5c3a6SDouglas Gregor 
3081fb5c3a6SDouglas Gregor   return false;
3091fb5c3a6SDouglas Gregor }
3101fb5c3a6SDouglas Gregor 
311e4412640SArgyrios Kyrtzidis Module *ModuleMap::findModule(StringRef Name) const {
312e4412640SArgyrios Kyrtzidis   llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
31388bdfb0eSDouglas Gregor   if (Known != Modules.end())
31488bdfb0eSDouglas Gregor     return Known->getValue();
31588bdfb0eSDouglas Gregor 
31688bdfb0eSDouglas Gregor   return 0;
31788bdfb0eSDouglas Gregor }
31888bdfb0eSDouglas Gregor 
319e4412640SArgyrios Kyrtzidis Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
320e4412640SArgyrios Kyrtzidis                                            Module *Context) const {
3212b82c2a5SDouglas Gregor   for(; Context; Context = Context->Parent) {
3222b82c2a5SDouglas Gregor     if (Module *Sub = lookupModuleQualified(Name, Context))
3232b82c2a5SDouglas Gregor       return Sub;
3242b82c2a5SDouglas Gregor   }
3252b82c2a5SDouglas Gregor 
3262b82c2a5SDouglas Gregor   return findModule(Name);
3272b82c2a5SDouglas Gregor }
3282b82c2a5SDouglas Gregor 
329e4412640SArgyrios Kyrtzidis Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
3302b82c2a5SDouglas Gregor   if (!Context)
3312b82c2a5SDouglas Gregor     return findModule(Name);
3322b82c2a5SDouglas Gregor 
333eb90e830SDouglas Gregor   return Context->findSubmodule(Name);
3342b82c2a5SDouglas Gregor }
3352b82c2a5SDouglas Gregor 
336de3ef502SDouglas Gregor std::pair<Module *, bool>
33769021974SDouglas Gregor ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
33869021974SDouglas Gregor                               bool IsExplicit) {
33969021974SDouglas Gregor   // Try to find an existing module with this name.
340eb90e830SDouglas Gregor   if (Module *Sub = lookupModuleQualified(Name, Parent))
341eb90e830SDouglas Gregor     return std::make_pair(Sub, false);
34269021974SDouglas Gregor 
34369021974SDouglas Gregor   // Create a new module with this name.
34469021974SDouglas Gregor   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
34569021974SDouglas Gregor                               IsExplicit);
346eb90e830SDouglas Gregor   if (!Parent)
34769021974SDouglas Gregor     Modules[Name] = Result;
34869021974SDouglas Gregor   return std::make_pair(Result, true);
34969021974SDouglas Gregor }
35069021974SDouglas Gregor 
3519194a91dSDouglas Gregor bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
352e4412640SArgyrios Kyrtzidis                                         StringRef Name, bool &IsSystem) const {
3539194a91dSDouglas Gregor   // Check whether we have already looked into the parent directory
3549194a91dSDouglas Gregor   // for a module map.
355e4412640SArgyrios Kyrtzidis   llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
3569194a91dSDouglas Gregor     inferred = InferredDirectories.find(ParentDir);
3579194a91dSDouglas Gregor   if (inferred == InferredDirectories.end())
3589194a91dSDouglas Gregor     return false;
3599194a91dSDouglas Gregor 
3609194a91dSDouglas Gregor   if (!inferred->second.InferModules)
3619194a91dSDouglas Gregor     return false;
3629194a91dSDouglas Gregor 
3639194a91dSDouglas Gregor   // We're allowed to infer for this directory, but make sure it's okay
3649194a91dSDouglas Gregor   // to infer this particular module.
3659194a91dSDouglas Gregor   bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
3669194a91dSDouglas Gregor                             inferred->second.ExcludedModules.end(),
3679194a91dSDouglas Gregor                             Name) == inferred->second.ExcludedModules.end();
3689194a91dSDouglas Gregor 
3699194a91dSDouglas Gregor   if (canInfer && inferred->second.InferSystemModules)
3709194a91dSDouglas Gregor     IsSystem = true;
3719194a91dSDouglas Gregor 
3729194a91dSDouglas Gregor   return canInfer;
3739194a91dSDouglas Gregor }
3749194a91dSDouglas Gregor 
37511dfe6feSDouglas Gregor /// \brief For a framework module, infer the framework against which we
37611dfe6feSDouglas Gregor /// should link.
37711dfe6feSDouglas Gregor static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
37811dfe6feSDouglas Gregor                                FileManager &FileMgr) {
37911dfe6feSDouglas Gregor   assert(Mod->IsFramework && "Can only infer linking for framework modules");
38011dfe6feSDouglas Gregor   assert(!Mod->isSubFramework() &&
38111dfe6feSDouglas Gregor          "Can only infer linking for top-level frameworks");
38211dfe6feSDouglas Gregor 
38311dfe6feSDouglas Gregor   SmallString<128> LibName;
38411dfe6feSDouglas Gregor   LibName += FrameworkDir->getName();
38511dfe6feSDouglas Gregor   llvm::sys::path::append(LibName, Mod->Name);
38611dfe6feSDouglas Gregor   if (FileMgr.getFile(LibName)) {
38711dfe6feSDouglas Gregor     Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
38811dfe6feSDouglas Gregor                                                      /*IsFramework=*/true));
38911dfe6feSDouglas Gregor   }
39011dfe6feSDouglas Gregor }
39111dfe6feSDouglas Gregor 
392de3ef502SDouglas Gregor Module *
39356c64013SDouglas Gregor ModuleMap::inferFrameworkModule(StringRef ModuleName,
394e89dbc1dSDouglas Gregor                                 const DirectoryEntry *FrameworkDir,
395a686e1b0SDouglas Gregor                                 bool IsSystem,
396e89dbc1dSDouglas Gregor                                 Module *Parent) {
39756c64013SDouglas Gregor   // Check whether we've already found this module.
398e89dbc1dSDouglas Gregor   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
399e89dbc1dSDouglas Gregor     return Mod;
400e89dbc1dSDouglas Gregor 
401e89dbc1dSDouglas Gregor   FileManager &FileMgr = SourceMgr->getFileManager();
40256c64013SDouglas Gregor 
4039194a91dSDouglas Gregor   // If the framework has a parent path from which we're allowed to infer
4049194a91dSDouglas Gregor   // a framework module, do so.
4059194a91dSDouglas Gregor   if (!Parent) {
4064ddf2221SDouglas Gregor     // Determine whether we're allowed to infer a module map.
407e00c8b20SDouglas Gregor 
4084ddf2221SDouglas Gregor     // Note: as an egregious but useful hack we use the real path here, because
4094ddf2221SDouglas Gregor     // we might be looking at an embedded framework that symlinks out to a
4104ddf2221SDouglas Gregor     // top-level framework, and we need to infer as if we were naming the
4114ddf2221SDouglas Gregor     // top-level framework.
412e00c8b20SDouglas Gregor     StringRef FrameworkDirName
413e00c8b20SDouglas Gregor       = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
4144ddf2221SDouglas Gregor 
4159194a91dSDouglas Gregor     bool canInfer = false;
4164ddf2221SDouglas Gregor     if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
4179194a91dSDouglas Gregor       // Figure out the parent path.
4184ddf2221SDouglas Gregor       StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
4199194a91dSDouglas Gregor       if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
4209194a91dSDouglas Gregor         // Check whether we have already looked into the parent directory
4219194a91dSDouglas Gregor         // for a module map.
422e4412640SArgyrios Kyrtzidis         llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
4239194a91dSDouglas Gregor           inferred = InferredDirectories.find(ParentDir);
4249194a91dSDouglas Gregor         if (inferred == InferredDirectories.end()) {
4259194a91dSDouglas Gregor           // We haven't looked here before. Load a module map, if there is
4269194a91dSDouglas Gregor           // one.
4279194a91dSDouglas Gregor           SmallString<128> ModMapPath = Parent;
4289194a91dSDouglas Gregor           llvm::sys::path::append(ModMapPath, "module.map");
4299194a91dSDouglas Gregor           if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
4309194a91dSDouglas Gregor             parseModuleMapFile(ModMapFile);
4319194a91dSDouglas Gregor             inferred = InferredDirectories.find(ParentDir);
4329194a91dSDouglas Gregor           }
4339194a91dSDouglas Gregor 
4349194a91dSDouglas Gregor           if (inferred == InferredDirectories.end())
4359194a91dSDouglas Gregor             inferred = InferredDirectories.insert(
4369194a91dSDouglas Gregor                          std::make_pair(ParentDir, InferredDirectory())).first;
4379194a91dSDouglas Gregor         }
4389194a91dSDouglas Gregor 
4399194a91dSDouglas Gregor         if (inferred->second.InferModules) {
4409194a91dSDouglas Gregor           // We're allowed to infer for this directory, but make sure it's okay
4419194a91dSDouglas Gregor           // to infer this particular module.
4424ddf2221SDouglas Gregor           StringRef Name = llvm::sys::path::stem(FrameworkDirName);
4439194a91dSDouglas Gregor           canInfer = std::find(inferred->second.ExcludedModules.begin(),
4449194a91dSDouglas Gregor                                inferred->second.ExcludedModules.end(),
4459194a91dSDouglas Gregor                                Name) == inferred->second.ExcludedModules.end();
4469194a91dSDouglas Gregor 
4479194a91dSDouglas Gregor           if (inferred->second.InferSystemModules)
4489194a91dSDouglas Gregor             IsSystem = true;
4499194a91dSDouglas Gregor         }
4509194a91dSDouglas Gregor       }
4519194a91dSDouglas Gregor     }
4529194a91dSDouglas Gregor 
4539194a91dSDouglas Gregor     // If we're not allowed to infer a framework module, don't.
4549194a91dSDouglas Gregor     if (!canInfer)
4559194a91dSDouglas Gregor       return 0;
4569194a91dSDouglas Gregor   }
4579194a91dSDouglas Gregor 
4589194a91dSDouglas Gregor 
45956c64013SDouglas Gregor   // Look for an umbrella header.
4602c1dd271SDylan Noblesmith   SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
46156c64013SDouglas Gregor   llvm::sys::path::append(UmbrellaName, "Headers");
46256c64013SDouglas Gregor   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
463e89dbc1dSDouglas Gregor   const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
46456c64013SDouglas Gregor 
46556c64013SDouglas Gregor   // FIXME: If there's no umbrella header, we could probably scan the
46656c64013SDouglas Gregor   // framework to load *everything*. But, it's not clear that this is a good
46756c64013SDouglas Gregor   // idea.
46856c64013SDouglas Gregor   if (!UmbrellaHeader)
46956c64013SDouglas Gregor     return 0;
47056c64013SDouglas Gregor 
471e89dbc1dSDouglas Gregor   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
472e89dbc1dSDouglas Gregor                               /*IsFramework=*/true, /*IsExplicit=*/false);
473a686e1b0SDouglas Gregor   if (IsSystem)
474a686e1b0SDouglas Gregor     Result->IsSystem = IsSystem;
475a686e1b0SDouglas Gregor 
476eb90e830SDouglas Gregor   if (!Parent)
477e89dbc1dSDouglas Gregor     Modules[ModuleName] = Result;
478e89dbc1dSDouglas Gregor 
479322f633cSDouglas Gregor   // umbrella header "umbrella-header-name"
48073141fa9SDouglas Gregor   Result->Umbrella = UmbrellaHeader;
48159527666SDouglas Gregor   Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
4824dc71835SDouglas Gregor   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
483d8bd7537SDouglas Gregor 
484d8bd7537SDouglas Gregor   // export *
485d8bd7537SDouglas Gregor   Result->Exports.push_back(Module::ExportDecl(0, true));
486d8bd7537SDouglas Gregor 
487a89c5ac4SDouglas Gregor   // module * { export * }
488a89c5ac4SDouglas Gregor   Result->InferSubmodules = true;
489a89c5ac4SDouglas Gregor   Result->InferExportWildcard = true;
490a89c5ac4SDouglas Gregor 
491e89dbc1dSDouglas Gregor   // Look for subframeworks.
492e89dbc1dSDouglas Gregor   llvm::error_code EC;
4932c1dd271SDylan Noblesmith   SmallString<128> SubframeworksDirName
494ddaa69cbSDouglas Gregor     = StringRef(FrameworkDir->getName());
495e89dbc1dSDouglas Gregor   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
4962c1dd271SDylan Noblesmith   SmallString<128> SubframeworksDirNameNative;
497ddaa69cbSDouglas Gregor   llvm::sys::path::native(SubframeworksDirName.str(),
498ddaa69cbSDouglas Gregor                           SubframeworksDirNameNative);
499ddaa69cbSDouglas Gregor   for (llvm::sys::fs::directory_iterator
500ddaa69cbSDouglas Gregor          Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
501e89dbc1dSDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
502e89dbc1dSDouglas Gregor     if (!StringRef(Dir->path()).endswith(".framework"))
503e89dbc1dSDouglas Gregor       continue;
504f2161a70SDouglas Gregor 
505e89dbc1dSDouglas Gregor     if (const DirectoryEntry *SubframeworkDir
506e89dbc1dSDouglas Gregor           = FileMgr.getDirectory(Dir->path())) {
50707c22b78SDouglas Gregor       // Note: as an egregious but useful hack, we use the real path here and
50807c22b78SDouglas Gregor       // check whether it is actually a subdirectory of the parent directory.
50907c22b78SDouglas Gregor       // This will not be the case if the 'subframework' is actually a symlink
51007c22b78SDouglas Gregor       // out to a top-level framework.
511e00c8b20SDouglas Gregor       StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
51207c22b78SDouglas Gregor       bool FoundParent = false;
51307c22b78SDouglas Gregor       do {
51407c22b78SDouglas Gregor         // Get the parent directory name.
51507c22b78SDouglas Gregor         SubframeworkDirName
51607c22b78SDouglas Gregor           = llvm::sys::path::parent_path(SubframeworkDirName);
51707c22b78SDouglas Gregor         if (SubframeworkDirName.empty())
51807c22b78SDouglas Gregor           break;
51907c22b78SDouglas Gregor 
52007c22b78SDouglas Gregor         if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
52107c22b78SDouglas Gregor           FoundParent = true;
52207c22b78SDouglas Gregor           break;
52307c22b78SDouglas Gregor         }
52407c22b78SDouglas Gregor       } while (true);
52507c22b78SDouglas Gregor 
52607c22b78SDouglas Gregor       if (!FoundParent)
52707c22b78SDouglas Gregor         continue;
52807c22b78SDouglas Gregor 
529e89dbc1dSDouglas Gregor       // FIXME: Do we want to warn about subframeworks without umbrella headers?
530056396aeSDouglas Gregor       SmallString<32> NameBuf;
531056396aeSDouglas Gregor       inferFrameworkModule(sanitizeFilenameAsIdentifier(
532056396aeSDouglas Gregor                              llvm::sys::path::stem(Dir->path()), NameBuf),
533056396aeSDouglas Gregor                            SubframeworkDir, IsSystem, Result);
534e89dbc1dSDouglas Gregor     }
535e89dbc1dSDouglas Gregor   }
536e89dbc1dSDouglas Gregor 
53711dfe6feSDouglas Gregor   // If the module is a top-level framework, automatically link against the
53811dfe6feSDouglas Gregor   // framework.
53911dfe6feSDouglas Gregor   if (!Result->isSubFramework()) {
54011dfe6feSDouglas Gregor     inferFrameworkLink(Result, FrameworkDir, FileMgr);
54111dfe6feSDouglas Gregor   }
54211dfe6feSDouglas Gregor 
54356c64013SDouglas Gregor   return Result;
54456c64013SDouglas Gregor }
54556c64013SDouglas Gregor 
546a89c5ac4SDouglas Gregor void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
54759527666SDouglas Gregor   Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
54873141fa9SDouglas Gregor   Mod->Umbrella = UmbrellaHeader;
5497033127bSDouglas Gregor   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
550a89c5ac4SDouglas Gregor }
551a89c5ac4SDouglas Gregor 
552524e33e1SDouglas Gregor void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
553524e33e1SDouglas Gregor   Mod->Umbrella = UmbrellaDir;
554524e33e1SDouglas Gregor   UmbrellaDirs[UmbrellaDir] = Mod;
555524e33e1SDouglas Gregor }
556524e33e1SDouglas Gregor 
55759527666SDouglas Gregor void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
55859527666SDouglas Gregor                           bool Excluded) {
559b146baabSArgyrios Kyrtzidis   if (Excluded) {
56059527666SDouglas Gregor     Mod->ExcludedHeaders.push_back(Header);
561b146baabSArgyrios Kyrtzidis   } else {
562a89c5ac4SDouglas Gregor     Mod->Headers.push_back(Header);
563b146baabSArgyrios Kyrtzidis     HeaderInfo.MarkFileModuleHeader(Header);
564b146baabSArgyrios Kyrtzidis   }
56559527666SDouglas Gregor   Headers[Header] = KnownHeader(Mod, Excluded);
566a89c5ac4SDouglas Gregor }
567a89c5ac4SDouglas Gregor 
568514b636aSDouglas Gregor const FileEntry *
569e4412640SArgyrios Kyrtzidis ModuleMap::getContainingModuleMapFile(Module *Module) const {
570514b636aSDouglas Gregor   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
571514b636aSDouglas Gregor     return 0;
572514b636aSDouglas Gregor 
573514b636aSDouglas Gregor   return SourceMgr->getFileEntryForID(
574514b636aSDouglas Gregor            SourceMgr->getFileID(Module->DefinitionLoc));
575514b636aSDouglas Gregor }
576514b636aSDouglas Gregor 
577718292f2SDouglas Gregor void ModuleMap::dump() {
578718292f2SDouglas Gregor   llvm::errs() << "Modules:";
579718292f2SDouglas Gregor   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
580718292f2SDouglas Gregor                                         MEnd = Modules.end();
581718292f2SDouglas Gregor        M != MEnd; ++M)
582d28d1b8dSDouglas Gregor     M->getValue()->print(llvm::errs(), 2);
583718292f2SDouglas Gregor 
584718292f2SDouglas Gregor   llvm::errs() << "Headers:";
58559527666SDouglas Gregor   for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
586718292f2SDouglas Gregor        H != HEnd; ++H) {
587718292f2SDouglas Gregor     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
58859527666SDouglas Gregor                  << H->second.getModule()->getFullModuleName() << "\n";
589718292f2SDouglas Gregor   }
590718292f2SDouglas Gregor }
591718292f2SDouglas Gregor 
5922b82c2a5SDouglas Gregor bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
5932b82c2a5SDouglas Gregor   bool HadError = false;
5942b82c2a5SDouglas Gregor   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
5952b82c2a5SDouglas Gregor     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
5962b82c2a5SDouglas Gregor                                               Complain);
597f5eedd05SDouglas Gregor     if (Export.getPointer() || Export.getInt())
5982b82c2a5SDouglas Gregor       Mod->Exports.push_back(Export);
5992b82c2a5SDouglas Gregor     else
6002b82c2a5SDouglas Gregor       HadError = true;
6012b82c2a5SDouglas Gregor   }
6022b82c2a5SDouglas Gregor   Mod->UnresolvedExports.clear();
6032b82c2a5SDouglas Gregor   return HadError;
6042b82c2a5SDouglas Gregor }
6052b82c2a5SDouglas Gregor 
6060093b3c7SDouglas Gregor Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
6070093b3c7SDouglas Gregor   if (Loc.isInvalid())
6080093b3c7SDouglas Gregor     return 0;
6090093b3c7SDouglas Gregor 
6100093b3c7SDouglas Gregor   // Use the expansion location to determine which module we're in.
6110093b3c7SDouglas Gregor   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
6120093b3c7SDouglas Gregor   if (!ExpansionLoc.isFileID())
6130093b3c7SDouglas Gregor     return 0;
6140093b3c7SDouglas Gregor 
6150093b3c7SDouglas Gregor 
6160093b3c7SDouglas Gregor   const SourceManager &SrcMgr = Loc.getManager();
6170093b3c7SDouglas Gregor   FileID ExpansionFileID = ExpansionLoc.getFileID();
618224d8a74SDouglas Gregor 
619224d8a74SDouglas Gregor   while (const FileEntry *ExpansionFile
620224d8a74SDouglas Gregor            = SrcMgr.getFileEntryForID(ExpansionFileID)) {
621224d8a74SDouglas Gregor     // Find the module that owns this header (if any).
622224d8a74SDouglas Gregor     if (Module *Mod = findModuleForHeader(ExpansionFile))
623224d8a74SDouglas Gregor       return Mod;
624224d8a74SDouglas Gregor 
625224d8a74SDouglas Gregor     // No module owns this header, so look up the inclusion chain to see if
626224d8a74SDouglas Gregor     // any included header has an associated module.
627224d8a74SDouglas Gregor     SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
628224d8a74SDouglas Gregor     if (IncludeLoc.isInvalid())
6290093b3c7SDouglas Gregor       return 0;
6300093b3c7SDouglas Gregor 
631224d8a74SDouglas Gregor     ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
632224d8a74SDouglas Gregor   }
633224d8a74SDouglas Gregor 
634224d8a74SDouglas Gregor   return 0;
6350093b3c7SDouglas Gregor }
6360093b3c7SDouglas Gregor 
637718292f2SDouglas Gregor //----------------------------------------------------------------------------//
638718292f2SDouglas Gregor // Module map file parser
639718292f2SDouglas Gregor //----------------------------------------------------------------------------//
640718292f2SDouglas Gregor 
641718292f2SDouglas Gregor namespace clang {
642718292f2SDouglas Gregor   /// \brief A token in a module map file.
643718292f2SDouglas Gregor   struct MMToken {
644718292f2SDouglas Gregor     enum TokenKind {
6451fb5c3a6SDouglas Gregor       Comma,
646*35b13eceSDouglas Gregor       ConfigMacros,
647718292f2SDouglas Gregor       EndOfFile,
648718292f2SDouglas Gregor       HeaderKeyword,
649718292f2SDouglas Gregor       Identifier,
65059527666SDouglas Gregor       ExcludeKeyword,
651718292f2SDouglas Gregor       ExplicitKeyword,
6522b82c2a5SDouglas Gregor       ExportKeyword,
653755b2055SDouglas Gregor       FrameworkKeyword,
6546ddfca91SDouglas Gregor       LinkKeyword,
655718292f2SDouglas Gregor       ModuleKeyword,
6562b82c2a5SDouglas Gregor       Period,
657718292f2SDouglas Gregor       UmbrellaKeyword,
6581fb5c3a6SDouglas Gregor       RequiresKeyword,
6592b82c2a5SDouglas Gregor       Star,
660718292f2SDouglas Gregor       StringLiteral,
661718292f2SDouglas Gregor       LBrace,
662a686e1b0SDouglas Gregor       RBrace,
663a686e1b0SDouglas Gregor       LSquare,
664a686e1b0SDouglas Gregor       RSquare
665718292f2SDouglas Gregor     } Kind;
666718292f2SDouglas Gregor 
667718292f2SDouglas Gregor     unsigned Location;
668718292f2SDouglas Gregor     unsigned StringLength;
669718292f2SDouglas Gregor     const char *StringData;
670718292f2SDouglas Gregor 
671718292f2SDouglas Gregor     void clear() {
672718292f2SDouglas Gregor       Kind = EndOfFile;
673718292f2SDouglas Gregor       Location = 0;
674718292f2SDouglas Gregor       StringLength = 0;
675718292f2SDouglas Gregor       StringData = 0;
676718292f2SDouglas Gregor     }
677718292f2SDouglas Gregor 
678718292f2SDouglas Gregor     bool is(TokenKind K) const { return Kind == K; }
679718292f2SDouglas Gregor 
680718292f2SDouglas Gregor     SourceLocation getLocation() const {
681718292f2SDouglas Gregor       return SourceLocation::getFromRawEncoding(Location);
682718292f2SDouglas Gregor     }
683718292f2SDouglas Gregor 
684718292f2SDouglas Gregor     StringRef getString() const {
685718292f2SDouglas Gregor       return StringRef(StringData, StringLength);
686718292f2SDouglas Gregor     }
687718292f2SDouglas Gregor   };
688718292f2SDouglas Gregor 
6899194a91dSDouglas Gregor   /// \brief The set of attributes that can be attached to a module.
6904442605fSBill Wendling   struct Attributes {
691*35b13eceSDouglas Gregor     Attributes() : IsSystem(), IsExhaustive() { }
6929194a91dSDouglas Gregor 
6939194a91dSDouglas Gregor     /// \brief Whether this is a system module.
6949194a91dSDouglas Gregor     unsigned IsSystem : 1;
695*35b13eceSDouglas Gregor 
696*35b13eceSDouglas Gregor     /// \brief Whether this is an exhaustive set of configuration macros.
697*35b13eceSDouglas Gregor     unsigned IsExhaustive : 1;
6989194a91dSDouglas Gregor   };
6999194a91dSDouglas Gregor 
7009194a91dSDouglas Gregor 
701718292f2SDouglas Gregor   class ModuleMapParser {
702718292f2SDouglas Gregor     Lexer &L;
703718292f2SDouglas Gregor     SourceManager &SourceMgr;
704bc10b9fbSDouglas Gregor 
705bc10b9fbSDouglas Gregor     /// \brief Default target information, used only for string literal
706bc10b9fbSDouglas Gregor     /// parsing.
707bc10b9fbSDouglas Gregor     const TargetInfo *Target;
708bc10b9fbSDouglas Gregor 
709718292f2SDouglas Gregor     DiagnosticsEngine &Diags;
710718292f2SDouglas Gregor     ModuleMap &Map;
711718292f2SDouglas Gregor 
7125257fc63SDouglas Gregor     /// \brief The directory that this module map resides in.
7135257fc63SDouglas Gregor     const DirectoryEntry *Directory;
7145257fc63SDouglas Gregor 
7153ec6663bSDouglas Gregor     /// \brief The directory containing Clang-supplied headers.
7163ec6663bSDouglas Gregor     const DirectoryEntry *BuiltinIncludeDir;
7173ec6663bSDouglas Gregor 
718718292f2SDouglas Gregor     /// \brief Whether an error occurred.
719718292f2SDouglas Gregor     bool HadError;
720718292f2SDouglas Gregor 
721718292f2SDouglas Gregor     /// \brief Stores string data for the various string literals referenced
722718292f2SDouglas Gregor     /// during parsing.
723718292f2SDouglas Gregor     llvm::BumpPtrAllocator StringData;
724718292f2SDouglas Gregor 
725718292f2SDouglas Gregor     /// \brief The current token.
726718292f2SDouglas Gregor     MMToken Tok;
727718292f2SDouglas Gregor 
728718292f2SDouglas Gregor     /// \brief The active module.
729de3ef502SDouglas Gregor     Module *ActiveModule;
730718292f2SDouglas Gregor 
731718292f2SDouglas Gregor     /// \brief Consume the current token and return its location.
732718292f2SDouglas Gregor     SourceLocation consumeToken();
733718292f2SDouglas Gregor 
734718292f2SDouglas Gregor     /// \brief Skip tokens until we reach the a token with the given kind
735718292f2SDouglas Gregor     /// (or the end of the file).
736718292f2SDouglas Gregor     void skipUntil(MMToken::TokenKind K);
737718292f2SDouglas Gregor 
738f857950dSDmitri Gribenko     typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
739e7ab3669SDouglas Gregor     bool parseModuleId(ModuleId &Id);
740718292f2SDouglas Gregor     void parseModuleDecl();
7411fb5c3a6SDouglas Gregor     void parseRequiresDecl();
74259527666SDouglas Gregor     void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
743524e33e1SDouglas Gregor     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
7442b82c2a5SDouglas Gregor     void parseExportDecl();
7456ddfca91SDouglas Gregor     void parseLinkDecl();
746*35b13eceSDouglas Gregor     void parseConfigMacros();
7479194a91dSDouglas Gregor     void parseInferredModuleDecl(bool Framework, bool Explicit);
7484442605fSBill Wendling     bool parseOptionalAttributes(Attributes &Attrs);
749718292f2SDouglas Gregor 
7507033127bSDouglas Gregor     const DirectoryEntry *getOverriddenHeaderSearchDir();
7517033127bSDouglas Gregor 
752718292f2SDouglas Gregor   public:
753718292f2SDouglas Gregor     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
754bc10b9fbSDouglas Gregor                              const TargetInfo *Target,
755718292f2SDouglas Gregor                              DiagnosticsEngine &Diags,
7565257fc63SDouglas Gregor                              ModuleMap &Map,
7573ec6663bSDouglas Gregor                              const DirectoryEntry *Directory,
7583ec6663bSDouglas Gregor                              const DirectoryEntry *BuiltinIncludeDir)
759bc10b9fbSDouglas Gregor       : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
7603ec6663bSDouglas Gregor         Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
7613ec6663bSDouglas Gregor         HadError(false), ActiveModule(0)
762718292f2SDouglas Gregor     {
763718292f2SDouglas Gregor       Tok.clear();
764718292f2SDouglas Gregor       consumeToken();
765718292f2SDouglas Gregor     }
766718292f2SDouglas Gregor 
767718292f2SDouglas Gregor     bool parseModuleMapFile();
768718292f2SDouglas Gregor   };
769718292f2SDouglas Gregor }
770718292f2SDouglas Gregor 
771718292f2SDouglas Gregor SourceLocation ModuleMapParser::consumeToken() {
772718292f2SDouglas Gregor retry:
773718292f2SDouglas Gregor   SourceLocation Result = Tok.getLocation();
774718292f2SDouglas Gregor   Tok.clear();
775718292f2SDouglas Gregor 
776718292f2SDouglas Gregor   Token LToken;
777718292f2SDouglas Gregor   L.LexFromRawLexer(LToken);
778718292f2SDouglas Gregor   Tok.Location = LToken.getLocation().getRawEncoding();
779718292f2SDouglas Gregor   switch (LToken.getKind()) {
780718292f2SDouglas Gregor   case tok::raw_identifier:
781718292f2SDouglas Gregor     Tok.StringData = LToken.getRawIdentifierData();
782718292f2SDouglas Gregor     Tok.StringLength = LToken.getLength();
783718292f2SDouglas Gregor     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
784*35b13eceSDouglas Gregor                  .Case("config_macros", MMToken::ConfigMacros)
78559527666SDouglas Gregor                  .Case("exclude", MMToken::ExcludeKeyword)
786718292f2SDouglas Gregor                  .Case("explicit", MMToken::ExplicitKeyword)
7872b82c2a5SDouglas Gregor                  .Case("export", MMToken::ExportKeyword)
788755b2055SDouglas Gregor                  .Case("framework", MMToken::FrameworkKeyword)
789*35b13eceSDouglas Gregor                  .Case("header", MMToken::HeaderKeyword)
7906ddfca91SDouglas Gregor                  .Case("link", MMToken::LinkKeyword)
791718292f2SDouglas Gregor                  .Case("module", MMToken::ModuleKeyword)
7921fb5c3a6SDouglas Gregor                  .Case("requires", MMToken::RequiresKeyword)
793718292f2SDouglas Gregor                  .Case("umbrella", MMToken::UmbrellaKeyword)
794718292f2SDouglas Gregor                  .Default(MMToken::Identifier);
795718292f2SDouglas Gregor     break;
796718292f2SDouglas Gregor 
7971fb5c3a6SDouglas Gregor   case tok::comma:
7981fb5c3a6SDouglas Gregor     Tok.Kind = MMToken::Comma;
7991fb5c3a6SDouglas Gregor     break;
8001fb5c3a6SDouglas Gregor 
801718292f2SDouglas Gregor   case tok::eof:
802718292f2SDouglas Gregor     Tok.Kind = MMToken::EndOfFile;
803718292f2SDouglas Gregor     break;
804718292f2SDouglas Gregor 
805718292f2SDouglas Gregor   case tok::l_brace:
806718292f2SDouglas Gregor     Tok.Kind = MMToken::LBrace;
807718292f2SDouglas Gregor     break;
808718292f2SDouglas Gregor 
809a686e1b0SDouglas Gregor   case tok::l_square:
810a686e1b0SDouglas Gregor     Tok.Kind = MMToken::LSquare;
811a686e1b0SDouglas Gregor     break;
812a686e1b0SDouglas Gregor 
8132b82c2a5SDouglas Gregor   case tok::period:
8142b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Period;
8152b82c2a5SDouglas Gregor     break;
8162b82c2a5SDouglas Gregor 
817718292f2SDouglas Gregor   case tok::r_brace:
818718292f2SDouglas Gregor     Tok.Kind = MMToken::RBrace;
819718292f2SDouglas Gregor     break;
820718292f2SDouglas Gregor 
821a686e1b0SDouglas Gregor   case tok::r_square:
822a686e1b0SDouglas Gregor     Tok.Kind = MMToken::RSquare;
823a686e1b0SDouglas Gregor     break;
824a686e1b0SDouglas Gregor 
8252b82c2a5SDouglas Gregor   case tok::star:
8262b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Star;
8272b82c2a5SDouglas Gregor     break;
8282b82c2a5SDouglas Gregor 
829718292f2SDouglas Gregor   case tok::string_literal: {
830d67aea28SRichard Smith     if (LToken.hasUDSuffix()) {
831d67aea28SRichard Smith       Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
832d67aea28SRichard Smith       HadError = true;
833d67aea28SRichard Smith       goto retry;
834d67aea28SRichard Smith     }
835d67aea28SRichard Smith 
836718292f2SDouglas Gregor     // Parse the string literal.
837718292f2SDouglas Gregor     LangOptions LangOpts;
838718292f2SDouglas Gregor     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
839718292f2SDouglas Gregor     if (StringLiteral.hadError)
840718292f2SDouglas Gregor       goto retry;
841718292f2SDouglas Gregor 
842718292f2SDouglas Gregor     // Copy the string literal into our string data allocator.
843718292f2SDouglas Gregor     unsigned Length = StringLiteral.GetStringLength();
844718292f2SDouglas Gregor     char *Saved = StringData.Allocate<char>(Length + 1);
845718292f2SDouglas Gregor     memcpy(Saved, StringLiteral.GetString().data(), Length);
846718292f2SDouglas Gregor     Saved[Length] = 0;
847718292f2SDouglas Gregor 
848718292f2SDouglas Gregor     // Form the token.
849718292f2SDouglas Gregor     Tok.Kind = MMToken::StringLiteral;
850718292f2SDouglas Gregor     Tok.StringData = Saved;
851718292f2SDouglas Gregor     Tok.StringLength = Length;
852718292f2SDouglas Gregor     break;
853718292f2SDouglas Gregor   }
854718292f2SDouglas Gregor 
855718292f2SDouglas Gregor   case tok::comment:
856718292f2SDouglas Gregor     goto retry;
857718292f2SDouglas Gregor 
858718292f2SDouglas Gregor   default:
859718292f2SDouglas Gregor     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
860718292f2SDouglas Gregor     HadError = true;
861718292f2SDouglas Gregor     goto retry;
862718292f2SDouglas Gregor   }
863718292f2SDouglas Gregor 
864718292f2SDouglas Gregor   return Result;
865718292f2SDouglas Gregor }
866718292f2SDouglas Gregor 
867718292f2SDouglas Gregor void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
868718292f2SDouglas Gregor   unsigned braceDepth = 0;
869a686e1b0SDouglas Gregor   unsigned squareDepth = 0;
870718292f2SDouglas Gregor   do {
871718292f2SDouglas Gregor     switch (Tok.Kind) {
872718292f2SDouglas Gregor     case MMToken::EndOfFile:
873718292f2SDouglas Gregor       return;
874718292f2SDouglas Gregor 
875718292f2SDouglas Gregor     case MMToken::LBrace:
876a686e1b0SDouglas Gregor       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
877718292f2SDouglas Gregor         return;
878718292f2SDouglas Gregor 
879718292f2SDouglas Gregor       ++braceDepth;
880718292f2SDouglas Gregor       break;
881718292f2SDouglas Gregor 
882a686e1b0SDouglas Gregor     case MMToken::LSquare:
883a686e1b0SDouglas Gregor       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
884a686e1b0SDouglas Gregor         return;
885a686e1b0SDouglas Gregor 
886a686e1b0SDouglas Gregor       ++squareDepth;
887a686e1b0SDouglas Gregor       break;
888a686e1b0SDouglas Gregor 
889718292f2SDouglas Gregor     case MMToken::RBrace:
890718292f2SDouglas Gregor       if (braceDepth > 0)
891718292f2SDouglas Gregor         --braceDepth;
892718292f2SDouglas Gregor       else if (Tok.is(K))
893718292f2SDouglas Gregor         return;
894718292f2SDouglas Gregor       break;
895718292f2SDouglas Gregor 
896a686e1b0SDouglas Gregor     case MMToken::RSquare:
897a686e1b0SDouglas Gregor       if (squareDepth > 0)
898a686e1b0SDouglas Gregor         --squareDepth;
899a686e1b0SDouglas Gregor       else if (Tok.is(K))
900a686e1b0SDouglas Gregor         return;
901a686e1b0SDouglas Gregor       break;
902a686e1b0SDouglas Gregor 
903718292f2SDouglas Gregor     default:
904a686e1b0SDouglas Gregor       if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
905718292f2SDouglas Gregor         return;
906718292f2SDouglas Gregor       break;
907718292f2SDouglas Gregor     }
908718292f2SDouglas Gregor 
909718292f2SDouglas Gregor    consumeToken();
910718292f2SDouglas Gregor   } while (true);
911718292f2SDouglas Gregor }
912718292f2SDouglas Gregor 
913e7ab3669SDouglas Gregor /// \brief Parse a module-id.
914e7ab3669SDouglas Gregor ///
915e7ab3669SDouglas Gregor ///   module-id:
916e7ab3669SDouglas Gregor ///     identifier
917e7ab3669SDouglas Gregor ///     identifier '.' module-id
918e7ab3669SDouglas Gregor ///
919e7ab3669SDouglas Gregor /// \returns true if an error occurred, false otherwise.
920e7ab3669SDouglas Gregor bool ModuleMapParser::parseModuleId(ModuleId &Id) {
921e7ab3669SDouglas Gregor   Id.clear();
922e7ab3669SDouglas Gregor   do {
923e7ab3669SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
924e7ab3669SDouglas Gregor       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
925e7ab3669SDouglas Gregor       consumeToken();
926e7ab3669SDouglas Gregor     } else {
927e7ab3669SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
928e7ab3669SDouglas Gregor       return true;
929e7ab3669SDouglas Gregor     }
930e7ab3669SDouglas Gregor 
931e7ab3669SDouglas Gregor     if (!Tok.is(MMToken::Period))
932e7ab3669SDouglas Gregor       break;
933e7ab3669SDouglas Gregor 
934e7ab3669SDouglas Gregor     consumeToken();
935e7ab3669SDouglas Gregor   } while (true);
936e7ab3669SDouglas Gregor 
937e7ab3669SDouglas Gregor   return false;
938e7ab3669SDouglas Gregor }
939e7ab3669SDouglas Gregor 
940a686e1b0SDouglas Gregor namespace {
941a686e1b0SDouglas Gregor   /// \brief Enumerates the known attributes.
942a686e1b0SDouglas Gregor   enum AttributeKind {
943a686e1b0SDouglas Gregor     /// \brief An unknown attribute.
944a686e1b0SDouglas Gregor     AT_unknown,
945a686e1b0SDouglas Gregor     /// \brief The 'system' attribute.
946*35b13eceSDouglas Gregor     AT_system,
947*35b13eceSDouglas Gregor     /// \brief The 'exhaustive' attribute.
948*35b13eceSDouglas Gregor     AT_exhaustive
949a686e1b0SDouglas Gregor   };
950a686e1b0SDouglas Gregor }
951a686e1b0SDouglas Gregor 
952718292f2SDouglas Gregor /// \brief Parse a module declaration.
953718292f2SDouglas Gregor ///
954718292f2SDouglas Gregor ///   module-declaration:
955a686e1b0SDouglas Gregor ///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
956a686e1b0SDouglas Gregor ///       { module-member* }
957a686e1b0SDouglas Gregor ///
958718292f2SDouglas Gregor ///   module-member:
9591fb5c3a6SDouglas Gregor ///     requires-declaration
960718292f2SDouglas Gregor ///     header-declaration
961e7ab3669SDouglas Gregor ///     submodule-declaration
9622b82c2a5SDouglas Gregor ///     export-declaration
9636ddfca91SDouglas Gregor ///     link-declaration
96473441091SDouglas Gregor ///
96573441091SDouglas Gregor ///   submodule-declaration:
96673441091SDouglas Gregor ///     module-declaration
96773441091SDouglas Gregor ///     inferred-submodule-declaration
968718292f2SDouglas Gregor void ModuleMapParser::parseModuleDecl() {
969755b2055SDouglas Gregor   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
970755b2055SDouglas Gregor          Tok.is(MMToken::FrameworkKeyword));
971f2161a70SDouglas Gregor   // Parse 'explicit' or 'framework' keyword, if present.
972e7ab3669SDouglas Gregor   SourceLocation ExplicitLoc;
973718292f2SDouglas Gregor   bool Explicit = false;
974f2161a70SDouglas Gregor   bool Framework = false;
975755b2055SDouglas Gregor 
976f2161a70SDouglas Gregor   // Parse 'explicit' keyword, if present.
977f2161a70SDouglas Gregor   if (Tok.is(MMToken::ExplicitKeyword)) {
978e7ab3669SDouglas Gregor     ExplicitLoc = consumeToken();
979f2161a70SDouglas Gregor     Explicit = true;
980f2161a70SDouglas Gregor   }
981f2161a70SDouglas Gregor 
982f2161a70SDouglas Gregor   // Parse 'framework' keyword, if present.
983755b2055SDouglas Gregor   if (Tok.is(MMToken::FrameworkKeyword)) {
984755b2055SDouglas Gregor     consumeToken();
985755b2055SDouglas Gregor     Framework = true;
986755b2055SDouglas Gregor   }
987718292f2SDouglas Gregor 
988718292f2SDouglas Gregor   // Parse 'module' keyword.
989718292f2SDouglas Gregor   if (!Tok.is(MMToken::ModuleKeyword)) {
990d6343c99SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
991718292f2SDouglas Gregor     consumeToken();
992718292f2SDouglas Gregor     HadError = true;
993718292f2SDouglas Gregor     return;
994718292f2SDouglas Gregor   }
995718292f2SDouglas Gregor   consumeToken(); // 'module' keyword
996718292f2SDouglas Gregor 
99773441091SDouglas Gregor   // If we have a wildcard for the module name, this is an inferred submodule.
99873441091SDouglas Gregor   // Parse it.
99973441091SDouglas Gregor   if (Tok.is(MMToken::Star))
10009194a91dSDouglas Gregor     return parseInferredModuleDecl(Framework, Explicit);
100173441091SDouglas Gregor 
1002718292f2SDouglas Gregor   // Parse the module name.
1003e7ab3669SDouglas Gregor   ModuleId Id;
1004e7ab3669SDouglas Gregor   if (parseModuleId(Id)) {
1005718292f2SDouglas Gregor     HadError = true;
1006718292f2SDouglas Gregor     return;
1007718292f2SDouglas Gregor   }
1008e7ab3669SDouglas Gregor 
1009e7ab3669SDouglas Gregor   if (ActiveModule) {
1010e7ab3669SDouglas Gregor     if (Id.size() > 1) {
1011e7ab3669SDouglas Gregor       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1012e7ab3669SDouglas Gregor         << SourceRange(Id.front().second, Id.back().second);
1013e7ab3669SDouglas Gregor 
1014e7ab3669SDouglas Gregor       HadError = true;
1015e7ab3669SDouglas Gregor       return;
1016e7ab3669SDouglas Gregor     }
1017e7ab3669SDouglas Gregor   } else if (Id.size() == 1 && Explicit) {
1018e7ab3669SDouglas Gregor     // Top-level modules can't be explicit.
1019e7ab3669SDouglas Gregor     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1020e7ab3669SDouglas Gregor     Explicit = false;
1021e7ab3669SDouglas Gregor     ExplicitLoc = SourceLocation();
1022e7ab3669SDouglas Gregor     HadError = true;
1023e7ab3669SDouglas Gregor   }
1024e7ab3669SDouglas Gregor 
1025e7ab3669SDouglas Gregor   Module *PreviousActiveModule = ActiveModule;
1026e7ab3669SDouglas Gregor   if (Id.size() > 1) {
1027e7ab3669SDouglas Gregor     // This module map defines a submodule. Go find the module of which it
1028e7ab3669SDouglas Gregor     // is a submodule.
1029e7ab3669SDouglas Gregor     ActiveModule = 0;
1030e7ab3669SDouglas Gregor     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1031e7ab3669SDouglas Gregor       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1032e7ab3669SDouglas Gregor         ActiveModule = Next;
1033e7ab3669SDouglas Gregor         continue;
1034e7ab3669SDouglas Gregor       }
1035e7ab3669SDouglas Gregor 
1036e7ab3669SDouglas Gregor       if (ActiveModule) {
1037e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1038e7ab3669SDouglas Gregor           << Id[I].first << ActiveModule->getTopLevelModule();
1039e7ab3669SDouglas Gregor       } else {
1040e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1041e7ab3669SDouglas Gregor       }
1042e7ab3669SDouglas Gregor       HadError = true;
1043e7ab3669SDouglas Gregor       return;
1044e7ab3669SDouglas Gregor     }
1045e7ab3669SDouglas Gregor   }
1046e7ab3669SDouglas Gregor 
1047e7ab3669SDouglas Gregor   StringRef ModuleName = Id.back().first;
1048e7ab3669SDouglas Gregor   SourceLocation ModuleNameLoc = Id.back().second;
1049718292f2SDouglas Gregor 
1050a686e1b0SDouglas Gregor   // Parse the optional attribute list.
10514442605fSBill Wendling   Attributes Attrs;
10529194a91dSDouglas Gregor   parseOptionalAttributes(Attrs);
1053a686e1b0SDouglas Gregor 
1054718292f2SDouglas Gregor   // Parse the opening brace.
1055718292f2SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
1056718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1057718292f2SDouglas Gregor       << ModuleName;
1058718292f2SDouglas Gregor     HadError = true;
1059718292f2SDouglas Gregor     return;
1060718292f2SDouglas Gregor   }
1061718292f2SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
1062718292f2SDouglas Gregor 
1063718292f2SDouglas Gregor   // Determine whether this (sub)module has already been defined.
1064eb90e830SDouglas Gregor   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1065fcc54a3bSDouglas Gregor     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1066fcc54a3bSDouglas Gregor       // Skip the module definition.
1067fcc54a3bSDouglas Gregor       skipUntil(MMToken::RBrace);
1068fcc54a3bSDouglas Gregor       if (Tok.is(MMToken::RBrace))
1069fcc54a3bSDouglas Gregor         consumeToken();
1070fcc54a3bSDouglas Gregor       else {
1071fcc54a3bSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1072fcc54a3bSDouglas Gregor         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1073fcc54a3bSDouglas Gregor         HadError = true;
1074fcc54a3bSDouglas Gregor       }
1075fcc54a3bSDouglas Gregor       return;
1076fcc54a3bSDouglas Gregor     }
1077fcc54a3bSDouglas Gregor 
1078718292f2SDouglas Gregor     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1079718292f2SDouglas Gregor       << ModuleName;
1080eb90e830SDouglas Gregor     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1081718292f2SDouglas Gregor 
1082718292f2SDouglas Gregor     // Skip the module definition.
1083718292f2SDouglas Gregor     skipUntil(MMToken::RBrace);
1084718292f2SDouglas Gregor     if (Tok.is(MMToken::RBrace))
1085718292f2SDouglas Gregor       consumeToken();
1086718292f2SDouglas Gregor 
1087718292f2SDouglas Gregor     HadError = true;
1088718292f2SDouglas Gregor     return;
1089718292f2SDouglas Gregor   }
1090718292f2SDouglas Gregor 
1091718292f2SDouglas Gregor   // Start defining this module.
1092eb90e830SDouglas Gregor   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1093eb90e830SDouglas Gregor                                         Explicit).first;
1094eb90e830SDouglas Gregor   ActiveModule->DefinitionLoc = ModuleNameLoc;
10959194a91dSDouglas Gregor   if (Attrs.IsSystem)
1096a686e1b0SDouglas Gregor     ActiveModule->IsSystem = true;
1097718292f2SDouglas Gregor 
1098718292f2SDouglas Gregor   bool Done = false;
1099718292f2SDouglas Gregor   do {
1100718292f2SDouglas Gregor     switch (Tok.Kind) {
1101718292f2SDouglas Gregor     case MMToken::EndOfFile:
1102718292f2SDouglas Gregor     case MMToken::RBrace:
1103718292f2SDouglas Gregor       Done = true;
1104718292f2SDouglas Gregor       break;
1105718292f2SDouglas Gregor 
1106*35b13eceSDouglas Gregor     case MMToken::ConfigMacros:
1107*35b13eceSDouglas Gregor       parseConfigMacros();
1108*35b13eceSDouglas Gregor       break;
1109*35b13eceSDouglas Gregor 
1110718292f2SDouglas Gregor     case MMToken::ExplicitKeyword:
1111f2161a70SDouglas Gregor     case MMToken::FrameworkKeyword:
1112718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
1113718292f2SDouglas Gregor       parseModuleDecl();
1114718292f2SDouglas Gregor       break;
1115718292f2SDouglas Gregor 
11162b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
11172b82c2a5SDouglas Gregor       parseExportDecl();
11182b82c2a5SDouglas Gregor       break;
11192b82c2a5SDouglas Gregor 
11201fb5c3a6SDouglas Gregor     case MMToken::RequiresKeyword:
11211fb5c3a6SDouglas Gregor       parseRequiresDecl();
11221fb5c3a6SDouglas Gregor       break;
11231fb5c3a6SDouglas Gregor 
1124524e33e1SDouglas Gregor     case MMToken::UmbrellaKeyword: {
1125524e33e1SDouglas Gregor       SourceLocation UmbrellaLoc = consumeToken();
1126524e33e1SDouglas Gregor       if (Tok.is(MMToken::HeaderKeyword))
112759527666SDouglas Gregor         parseHeaderDecl(UmbrellaLoc, SourceLocation());
1128524e33e1SDouglas Gregor       else
1129524e33e1SDouglas Gregor         parseUmbrellaDirDecl(UmbrellaLoc);
1130718292f2SDouglas Gregor       break;
1131524e33e1SDouglas Gregor     }
1132718292f2SDouglas Gregor 
113359527666SDouglas Gregor     case MMToken::ExcludeKeyword: {
113459527666SDouglas Gregor       SourceLocation ExcludeLoc = consumeToken();
113559527666SDouglas Gregor       if (Tok.is(MMToken::HeaderKeyword)) {
113659527666SDouglas Gregor         parseHeaderDecl(SourceLocation(), ExcludeLoc);
113759527666SDouglas Gregor       } else {
113859527666SDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
113959527666SDouglas Gregor           << "exclude";
114059527666SDouglas Gregor       }
114159527666SDouglas Gregor       break;
114259527666SDouglas Gregor     }
114359527666SDouglas Gregor 
1144322f633cSDouglas Gregor     case MMToken::HeaderKeyword:
114559527666SDouglas Gregor       parseHeaderDecl(SourceLocation(), SourceLocation());
1146718292f2SDouglas Gregor       break;
1147718292f2SDouglas Gregor 
11486ddfca91SDouglas Gregor     case MMToken::LinkKeyword:
11496ddfca91SDouglas Gregor       parseLinkDecl();
11506ddfca91SDouglas Gregor       break;
11516ddfca91SDouglas Gregor 
1152718292f2SDouglas Gregor     default:
1153718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1154718292f2SDouglas Gregor       consumeToken();
1155718292f2SDouglas Gregor       break;
1156718292f2SDouglas Gregor     }
1157718292f2SDouglas Gregor   } while (!Done);
1158718292f2SDouglas Gregor 
1159718292f2SDouglas Gregor   if (Tok.is(MMToken::RBrace))
1160718292f2SDouglas Gregor     consumeToken();
1161718292f2SDouglas Gregor   else {
1162718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1163718292f2SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1164718292f2SDouglas Gregor     HadError = true;
1165718292f2SDouglas Gregor   }
1166718292f2SDouglas Gregor 
116711dfe6feSDouglas Gregor   // If the active module is a top-level framework, and there are no link
116811dfe6feSDouglas Gregor   // libraries, automatically link against the framework.
116911dfe6feSDouglas Gregor   if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
117011dfe6feSDouglas Gregor       ActiveModule->LinkLibraries.empty()) {
117111dfe6feSDouglas Gregor     inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
117211dfe6feSDouglas Gregor   }
117311dfe6feSDouglas Gregor 
1174e7ab3669SDouglas Gregor   // We're done parsing this module. Pop back to the previous module.
1175e7ab3669SDouglas Gregor   ActiveModule = PreviousActiveModule;
1176718292f2SDouglas Gregor }
1177718292f2SDouglas Gregor 
11781fb5c3a6SDouglas Gregor /// \brief Parse a requires declaration.
11791fb5c3a6SDouglas Gregor ///
11801fb5c3a6SDouglas Gregor ///   requires-declaration:
11811fb5c3a6SDouglas Gregor ///     'requires' feature-list
11821fb5c3a6SDouglas Gregor ///
11831fb5c3a6SDouglas Gregor ///   feature-list:
11841fb5c3a6SDouglas Gregor ///     identifier ',' feature-list
11851fb5c3a6SDouglas Gregor ///     identifier
11861fb5c3a6SDouglas Gregor void ModuleMapParser::parseRequiresDecl() {
11871fb5c3a6SDouglas Gregor   assert(Tok.is(MMToken::RequiresKeyword));
11881fb5c3a6SDouglas Gregor 
11891fb5c3a6SDouglas Gregor   // Parse 'requires' keyword.
11901fb5c3a6SDouglas Gregor   consumeToken();
11911fb5c3a6SDouglas Gregor 
11921fb5c3a6SDouglas Gregor   // Parse the feature-list.
11931fb5c3a6SDouglas Gregor   do {
11941fb5c3a6SDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
11951fb5c3a6SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
11961fb5c3a6SDouglas Gregor       HadError = true;
11971fb5c3a6SDouglas Gregor       return;
11981fb5c3a6SDouglas Gregor     }
11991fb5c3a6SDouglas Gregor 
12001fb5c3a6SDouglas Gregor     // Consume the feature name.
12011fb5c3a6SDouglas Gregor     std::string Feature = Tok.getString();
12021fb5c3a6SDouglas Gregor     consumeToken();
12031fb5c3a6SDouglas Gregor 
12041fb5c3a6SDouglas Gregor     // Add this feature.
120589929282SDouglas Gregor     ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
12061fb5c3a6SDouglas Gregor 
12071fb5c3a6SDouglas Gregor     if (!Tok.is(MMToken::Comma))
12081fb5c3a6SDouglas Gregor       break;
12091fb5c3a6SDouglas Gregor 
12101fb5c3a6SDouglas Gregor     // Consume the comma.
12111fb5c3a6SDouglas Gregor     consumeToken();
12121fb5c3a6SDouglas Gregor   } while (true);
12131fb5c3a6SDouglas Gregor }
12141fb5c3a6SDouglas Gregor 
1215f2161a70SDouglas Gregor /// \brief Append to \p Paths the set of paths needed to get to the
1216f2161a70SDouglas Gregor /// subframework in which the given module lives.
1217bf8da9d7SBenjamin Kramer static void appendSubframeworkPaths(Module *Mod,
1218f857950dSDmitri Gribenko                                     SmallVectorImpl<char> &Path) {
1219f2161a70SDouglas Gregor   // Collect the framework names from the given module to the top-level module.
1220f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Paths;
1221f2161a70SDouglas Gregor   for (; Mod; Mod = Mod->Parent) {
1222f2161a70SDouglas Gregor     if (Mod->IsFramework)
1223f2161a70SDouglas Gregor       Paths.push_back(Mod->Name);
1224f2161a70SDouglas Gregor   }
1225f2161a70SDouglas Gregor 
1226f2161a70SDouglas Gregor   if (Paths.empty())
1227f2161a70SDouglas Gregor     return;
1228f2161a70SDouglas Gregor 
1229f2161a70SDouglas Gregor   // Add Frameworks/Name.framework for each subframework.
1230f2161a70SDouglas Gregor   for (unsigned I = Paths.size() - 1; I != 0; --I) {
1231f2161a70SDouglas Gregor     llvm::sys::path::append(Path, "Frameworks");
1232f2161a70SDouglas Gregor     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1233f2161a70SDouglas Gregor   }
1234f2161a70SDouglas Gregor }
1235f2161a70SDouglas Gregor 
12363ec6663bSDouglas Gregor /// \brief Determine whether the given file name is the name of a builtin
12373ec6663bSDouglas Gregor /// header, supplied by Clang to replace, override, or augment existing system
12383ec6663bSDouglas Gregor /// headers.
12393ec6663bSDouglas Gregor static bool isBuiltinHeader(StringRef FileName) {
12403ec6663bSDouglas Gregor   return llvm::StringSwitch<bool>(FileName)
12413ec6663bSDouglas Gregor       .Case("float.h", true)
12423ec6663bSDouglas Gregor       .Case("iso646.h", true)
12433ec6663bSDouglas Gregor       .Case("limits.h", true)
12443ec6663bSDouglas Gregor       .Case("stdalign.h", true)
12453ec6663bSDouglas Gregor       .Case("stdarg.h", true)
12463ec6663bSDouglas Gregor       .Case("stdbool.h", true)
12473ec6663bSDouglas Gregor       .Case("stddef.h", true)
12483ec6663bSDouglas Gregor       .Case("stdint.h", true)
12493ec6663bSDouglas Gregor       .Case("tgmath.h", true)
12503ec6663bSDouglas Gregor       .Case("unwind.h", true)
12513ec6663bSDouglas Gregor       .Default(false);
12523ec6663bSDouglas Gregor }
12533ec6663bSDouglas Gregor 
1254718292f2SDouglas Gregor /// \brief Parse a header declaration.
1255718292f2SDouglas Gregor ///
1256718292f2SDouglas Gregor ///   header-declaration:
1257322f633cSDouglas Gregor ///     'umbrella'[opt] 'header' string-literal
125859527666SDouglas Gregor ///     'exclude'[opt] 'header' string-literal
125959527666SDouglas Gregor void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
126059527666SDouglas Gregor                                       SourceLocation ExcludeLoc) {
1261718292f2SDouglas Gregor   assert(Tok.is(MMToken::HeaderKeyword));
12621871ed3dSBenjamin Kramer   consumeToken();
1263718292f2SDouglas Gregor 
1264322f633cSDouglas Gregor   bool Umbrella = UmbrellaLoc.isValid();
126559527666SDouglas Gregor   bool Exclude = ExcludeLoc.isValid();
126659527666SDouglas Gregor   assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
1267718292f2SDouglas Gregor   // Parse the header name.
1268718292f2SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
1269718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1270718292f2SDouglas Gregor       << "header";
1271718292f2SDouglas Gregor     HadError = true;
1272718292f2SDouglas Gregor     return;
1273718292f2SDouglas Gregor   }
1274e7ab3669SDouglas Gregor   std::string FileName = Tok.getString();
1275718292f2SDouglas Gregor   SourceLocation FileNameLoc = consumeToken();
1276718292f2SDouglas Gregor 
1277524e33e1SDouglas Gregor   // Check whether we already have an umbrella.
1278524e33e1SDouglas Gregor   if (Umbrella && ActiveModule->Umbrella) {
1279524e33e1SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1280524e33e1SDouglas Gregor       << ActiveModule->getFullModuleName();
1281322f633cSDouglas Gregor     HadError = true;
1282322f633cSDouglas Gregor     return;
1283322f633cSDouglas Gregor   }
1284322f633cSDouglas Gregor 
12855257fc63SDouglas Gregor   // Look for this file.
1286e7ab3669SDouglas Gregor   const FileEntry *File = 0;
12873ec6663bSDouglas Gregor   const FileEntry *BuiltinFile = 0;
12882c1dd271SDylan Noblesmith   SmallString<128> PathName;
1289e7ab3669SDouglas Gregor   if (llvm::sys::path::is_absolute(FileName)) {
1290e7ab3669SDouglas Gregor     PathName = FileName;
1291e7ab3669SDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
12927033127bSDouglas Gregor   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
12937033127bSDouglas Gregor     PathName = Dir->getName();
12947033127bSDouglas Gregor     llvm::sys::path::append(PathName, FileName);
12957033127bSDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
1296e7ab3669SDouglas Gregor   } else {
1297e7ab3669SDouglas Gregor     // Search for the header file within the search directory.
12987033127bSDouglas Gregor     PathName = Directory->getName();
1299e7ab3669SDouglas Gregor     unsigned PathLength = PathName.size();
1300755b2055SDouglas Gregor 
1301f2161a70SDouglas Gregor     if (ActiveModule->isPartOfFramework()) {
1302f2161a70SDouglas Gregor       appendSubframeworkPaths(ActiveModule, PathName);
1303755b2055SDouglas Gregor 
1304e7ab3669SDouglas Gregor       // Check whether this file is in the public headers.
1305e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, "Headers");
13065257fc63SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
1307e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
1308e7ab3669SDouglas Gregor 
1309e7ab3669SDouglas Gregor       if (!File) {
1310e7ab3669SDouglas Gregor         // Check whether this file is in the private headers.
1311e7ab3669SDouglas Gregor         PathName.resize(PathLength);
1312e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, "PrivateHeaders");
1313e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, FileName);
1314e7ab3669SDouglas Gregor         File = SourceMgr.getFileManager().getFile(PathName);
1315e7ab3669SDouglas Gregor       }
1316e7ab3669SDouglas Gregor     } else {
1317e7ab3669SDouglas Gregor       // Lookup for normal headers.
1318e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
1319e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
13203ec6663bSDouglas Gregor 
13213ec6663bSDouglas Gregor       // If this is a system module with a top-level header, this header
13223ec6663bSDouglas Gregor       // may have a counterpart (or replacement) in the set of headers
13233ec6663bSDouglas Gregor       // supplied by Clang. Find that builtin header.
13243ec6663bSDouglas Gregor       if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
13253ec6663bSDouglas Gregor           BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
13262c1dd271SDylan Noblesmith         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
13273ec6663bSDouglas Gregor         llvm::sys::path::append(BuiltinPathName, FileName);
13283ec6663bSDouglas Gregor         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
13293ec6663bSDouglas Gregor 
13303ec6663bSDouglas Gregor         // If Clang supplies this header but the underlying system does not,
13313ec6663bSDouglas Gregor         // just silently swap in our builtin version. Otherwise, we'll end
13323ec6663bSDouglas Gregor         // up adding both (later).
13333ec6663bSDouglas Gregor         if (!File && BuiltinFile) {
13343ec6663bSDouglas Gregor           File = BuiltinFile;
13353ec6663bSDouglas Gregor           BuiltinFile = 0;
13363ec6663bSDouglas Gregor         }
13373ec6663bSDouglas Gregor       }
1338e7ab3669SDouglas Gregor     }
1339e7ab3669SDouglas Gregor   }
13405257fc63SDouglas Gregor 
13415257fc63SDouglas Gregor   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
13425257fc63SDouglas Gregor   // Come up with a lazy way to do this.
1343e7ab3669SDouglas Gregor   if (File) {
134459527666SDouglas Gregor     if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
13455257fc63SDouglas Gregor       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
134659527666SDouglas Gregor         << FileName << OwningModule.getModule()->getFullModuleName();
13475257fc63SDouglas Gregor       HadError = true;
1348322f633cSDouglas Gregor     } else if (Umbrella) {
1349322f633cSDouglas Gregor       const DirectoryEntry *UmbrellaDir = File->getDir();
135059527666SDouglas Gregor       if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1351322f633cSDouglas Gregor         Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
135259527666SDouglas Gregor           << UmbrellaModule->getFullModuleName();
1353322f633cSDouglas Gregor         HadError = true;
13545257fc63SDouglas Gregor       } else {
1355322f633cSDouglas Gregor         // Record this umbrella header.
1356322f633cSDouglas Gregor         Map.setUmbrellaHeader(ActiveModule, File);
1357322f633cSDouglas Gregor       }
1358322f633cSDouglas Gregor     } else {
1359322f633cSDouglas Gregor       // Record this header.
136059527666SDouglas Gregor       Map.addHeader(ActiveModule, File, Exclude);
13613ec6663bSDouglas Gregor 
13623ec6663bSDouglas Gregor       // If there is a builtin counterpart to this file, add it now.
13633ec6663bSDouglas Gregor       if (BuiltinFile)
136459527666SDouglas Gregor         Map.addHeader(ActiveModule, BuiltinFile, Exclude);
13655257fc63SDouglas Gregor     }
13664b27a64bSDouglas Gregor   } else if (!Exclude) {
13674b27a64bSDouglas Gregor     // Ignore excluded header files. They're optional anyway.
13684b27a64bSDouglas Gregor 
13695257fc63SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1370524e33e1SDouglas Gregor       << Umbrella << FileName;
13715257fc63SDouglas Gregor     HadError = true;
13725257fc63SDouglas Gregor   }
1373718292f2SDouglas Gregor }
1374718292f2SDouglas Gregor 
1375524e33e1SDouglas Gregor /// \brief Parse an umbrella directory declaration.
1376524e33e1SDouglas Gregor ///
1377524e33e1SDouglas Gregor ///   umbrella-dir-declaration:
1378524e33e1SDouglas Gregor ///     umbrella string-literal
1379524e33e1SDouglas Gregor void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1380524e33e1SDouglas Gregor   // Parse the directory name.
1381524e33e1SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
1382524e33e1SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1383524e33e1SDouglas Gregor       << "umbrella";
1384524e33e1SDouglas Gregor     HadError = true;
1385524e33e1SDouglas Gregor     return;
1386524e33e1SDouglas Gregor   }
1387524e33e1SDouglas Gregor 
1388524e33e1SDouglas Gregor   std::string DirName = Tok.getString();
1389524e33e1SDouglas Gregor   SourceLocation DirNameLoc = consumeToken();
1390524e33e1SDouglas Gregor 
1391524e33e1SDouglas Gregor   // Check whether we already have an umbrella.
1392524e33e1SDouglas Gregor   if (ActiveModule->Umbrella) {
1393524e33e1SDouglas Gregor     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1394524e33e1SDouglas Gregor       << ActiveModule->getFullModuleName();
1395524e33e1SDouglas Gregor     HadError = true;
1396524e33e1SDouglas Gregor     return;
1397524e33e1SDouglas Gregor   }
1398524e33e1SDouglas Gregor 
1399524e33e1SDouglas Gregor   // Look for this file.
1400524e33e1SDouglas Gregor   const DirectoryEntry *Dir = 0;
1401524e33e1SDouglas Gregor   if (llvm::sys::path::is_absolute(DirName))
1402524e33e1SDouglas Gregor     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1403524e33e1SDouglas Gregor   else {
14042c1dd271SDylan Noblesmith     SmallString<128> PathName;
1405524e33e1SDouglas Gregor     PathName = Directory->getName();
1406524e33e1SDouglas Gregor     llvm::sys::path::append(PathName, DirName);
1407524e33e1SDouglas Gregor     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1408524e33e1SDouglas Gregor   }
1409524e33e1SDouglas Gregor 
1410524e33e1SDouglas Gregor   if (!Dir) {
1411524e33e1SDouglas Gregor     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1412524e33e1SDouglas Gregor       << DirName;
1413524e33e1SDouglas Gregor     HadError = true;
1414524e33e1SDouglas Gregor     return;
1415524e33e1SDouglas Gregor   }
1416524e33e1SDouglas Gregor 
1417524e33e1SDouglas Gregor   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1418524e33e1SDouglas Gregor     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1419524e33e1SDouglas Gregor       << OwningModule->getFullModuleName();
1420524e33e1SDouglas Gregor     HadError = true;
1421524e33e1SDouglas Gregor     return;
1422524e33e1SDouglas Gregor   }
1423524e33e1SDouglas Gregor 
1424524e33e1SDouglas Gregor   // Record this umbrella directory.
1425524e33e1SDouglas Gregor   Map.setUmbrellaDir(ActiveModule, Dir);
1426524e33e1SDouglas Gregor }
1427524e33e1SDouglas Gregor 
14282b82c2a5SDouglas Gregor /// \brief Parse a module export declaration.
14292b82c2a5SDouglas Gregor ///
14302b82c2a5SDouglas Gregor ///   export-declaration:
14312b82c2a5SDouglas Gregor ///     'export' wildcard-module-id
14322b82c2a5SDouglas Gregor ///
14332b82c2a5SDouglas Gregor ///   wildcard-module-id:
14342b82c2a5SDouglas Gregor ///     identifier
14352b82c2a5SDouglas Gregor ///     '*'
14362b82c2a5SDouglas Gregor ///     identifier '.' wildcard-module-id
14372b82c2a5SDouglas Gregor void ModuleMapParser::parseExportDecl() {
14382b82c2a5SDouglas Gregor   assert(Tok.is(MMToken::ExportKeyword));
14392b82c2a5SDouglas Gregor   SourceLocation ExportLoc = consumeToken();
14402b82c2a5SDouglas Gregor 
14412b82c2a5SDouglas Gregor   // Parse the module-id with an optional wildcard at the end.
14422b82c2a5SDouglas Gregor   ModuleId ParsedModuleId;
14432b82c2a5SDouglas Gregor   bool Wildcard = false;
14442b82c2a5SDouglas Gregor   do {
14452b82c2a5SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
14462b82c2a5SDouglas Gregor       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
14472b82c2a5SDouglas Gregor                                               Tok.getLocation()));
14482b82c2a5SDouglas Gregor       consumeToken();
14492b82c2a5SDouglas Gregor 
14502b82c2a5SDouglas Gregor       if (Tok.is(MMToken::Period)) {
14512b82c2a5SDouglas Gregor         consumeToken();
14522b82c2a5SDouglas Gregor         continue;
14532b82c2a5SDouglas Gregor       }
14542b82c2a5SDouglas Gregor 
14552b82c2a5SDouglas Gregor       break;
14562b82c2a5SDouglas Gregor     }
14572b82c2a5SDouglas Gregor 
14582b82c2a5SDouglas Gregor     if(Tok.is(MMToken::Star)) {
14592b82c2a5SDouglas Gregor       Wildcard = true;
1460f5eedd05SDouglas Gregor       consumeToken();
14612b82c2a5SDouglas Gregor       break;
14622b82c2a5SDouglas Gregor     }
14632b82c2a5SDouglas Gregor 
14642b82c2a5SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
14652b82c2a5SDouglas Gregor     HadError = true;
14662b82c2a5SDouglas Gregor     return;
14672b82c2a5SDouglas Gregor   } while (true);
14682b82c2a5SDouglas Gregor 
14692b82c2a5SDouglas Gregor   Module::UnresolvedExportDecl Unresolved = {
14702b82c2a5SDouglas Gregor     ExportLoc, ParsedModuleId, Wildcard
14712b82c2a5SDouglas Gregor   };
14722b82c2a5SDouglas Gregor   ActiveModule->UnresolvedExports.push_back(Unresolved);
14732b82c2a5SDouglas Gregor }
14742b82c2a5SDouglas Gregor 
14756ddfca91SDouglas Gregor /// \brief Parse a link declaration.
14766ddfca91SDouglas Gregor ///
14776ddfca91SDouglas Gregor ///   module-declaration:
14786ddfca91SDouglas Gregor ///     'link' 'framework'[opt] string-literal
14796ddfca91SDouglas Gregor void ModuleMapParser::parseLinkDecl() {
14806ddfca91SDouglas Gregor   assert(Tok.is(MMToken::LinkKeyword));
14816ddfca91SDouglas Gregor   SourceLocation LinkLoc = consumeToken();
14826ddfca91SDouglas Gregor 
14836ddfca91SDouglas Gregor   // Parse the optional 'framework' keyword.
14846ddfca91SDouglas Gregor   bool IsFramework = false;
14856ddfca91SDouglas Gregor   if (Tok.is(MMToken::FrameworkKeyword)) {
14866ddfca91SDouglas Gregor     consumeToken();
14876ddfca91SDouglas Gregor     IsFramework = true;
14886ddfca91SDouglas Gregor   }
14896ddfca91SDouglas Gregor 
14906ddfca91SDouglas Gregor   // Parse the library name
14916ddfca91SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
14926ddfca91SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
14936ddfca91SDouglas Gregor       << IsFramework << SourceRange(LinkLoc);
14946ddfca91SDouglas Gregor     HadError = true;
14956ddfca91SDouglas Gregor     return;
14966ddfca91SDouglas Gregor   }
14976ddfca91SDouglas Gregor 
14986ddfca91SDouglas Gregor   std::string LibraryName = Tok.getString();
14996ddfca91SDouglas Gregor   consumeToken();
15006ddfca91SDouglas Gregor   ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
15016ddfca91SDouglas Gregor                                                             IsFramework));
15026ddfca91SDouglas Gregor }
15036ddfca91SDouglas Gregor 
1504*35b13eceSDouglas Gregor /// \brief Parse a configuration macro declaration.
1505*35b13eceSDouglas Gregor ///
1506*35b13eceSDouglas Gregor ///   module-declaration:
1507*35b13eceSDouglas Gregor ///     'config_macros' attributes[opt] config-macro-list?
1508*35b13eceSDouglas Gregor ///
1509*35b13eceSDouglas Gregor ///   config-macro-list:
1510*35b13eceSDouglas Gregor ///     identifier (',' identifier)?
1511*35b13eceSDouglas Gregor void ModuleMapParser::parseConfigMacros() {
1512*35b13eceSDouglas Gregor   assert(Tok.is(MMToken::ConfigMacros));
1513*35b13eceSDouglas Gregor   SourceLocation ConfigMacrosLoc = consumeToken();
1514*35b13eceSDouglas Gregor 
1515*35b13eceSDouglas Gregor   // Only top-level modules can have configuration macros.
1516*35b13eceSDouglas Gregor   if (ActiveModule->Parent) {
1517*35b13eceSDouglas Gregor     Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1518*35b13eceSDouglas Gregor   }
1519*35b13eceSDouglas Gregor 
1520*35b13eceSDouglas Gregor   // Parse the optional attributes.
1521*35b13eceSDouglas Gregor   Attributes Attrs;
1522*35b13eceSDouglas Gregor   parseOptionalAttributes(Attrs);
1523*35b13eceSDouglas Gregor   if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1524*35b13eceSDouglas Gregor     ActiveModule->ConfigMacrosExhaustive = true;
1525*35b13eceSDouglas Gregor   }
1526*35b13eceSDouglas Gregor 
1527*35b13eceSDouglas Gregor   // If we don't have an identifier, we're done.
1528*35b13eceSDouglas Gregor   if (!Tok.is(MMToken::Identifier))
1529*35b13eceSDouglas Gregor     return;
1530*35b13eceSDouglas Gregor 
1531*35b13eceSDouglas Gregor   // Consume the first identifier.
1532*35b13eceSDouglas Gregor   if (!ActiveModule->Parent) {
1533*35b13eceSDouglas Gregor     ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1534*35b13eceSDouglas Gregor   }
1535*35b13eceSDouglas Gregor   consumeToken();
1536*35b13eceSDouglas Gregor 
1537*35b13eceSDouglas Gregor   do {
1538*35b13eceSDouglas Gregor     // If there's a comma, consume it.
1539*35b13eceSDouglas Gregor     if (!Tok.is(MMToken::Comma))
1540*35b13eceSDouglas Gregor       break;
1541*35b13eceSDouglas Gregor     consumeToken();
1542*35b13eceSDouglas Gregor 
1543*35b13eceSDouglas Gregor     // We expect to see a macro name here.
1544*35b13eceSDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
1545*35b13eceSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1546*35b13eceSDouglas Gregor       break;
1547*35b13eceSDouglas Gregor     }
1548*35b13eceSDouglas Gregor 
1549*35b13eceSDouglas Gregor     // Consume the macro name.
1550*35b13eceSDouglas Gregor     if (!ActiveModule->Parent) {
1551*35b13eceSDouglas Gregor       ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1552*35b13eceSDouglas Gregor     }
1553*35b13eceSDouglas Gregor     consumeToken();
1554*35b13eceSDouglas Gregor   } while (true);
1555*35b13eceSDouglas Gregor }
1556*35b13eceSDouglas Gregor 
15576ddfca91SDouglas Gregor /// \brief Parse an inferred module declaration (wildcard modules).
15589194a91dSDouglas Gregor ///
15599194a91dSDouglas Gregor ///   module-declaration:
15609194a91dSDouglas Gregor ///     'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
15619194a91dSDouglas Gregor ///       { inferred-module-member* }
15629194a91dSDouglas Gregor ///
15639194a91dSDouglas Gregor ///   inferred-module-member:
15649194a91dSDouglas Gregor ///     'export' '*'
15659194a91dSDouglas Gregor ///     'exclude' identifier
15669194a91dSDouglas Gregor void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
156773441091SDouglas Gregor   assert(Tok.is(MMToken::Star));
156873441091SDouglas Gregor   SourceLocation StarLoc = consumeToken();
156973441091SDouglas Gregor   bool Failed = false;
157073441091SDouglas Gregor 
157173441091SDouglas Gregor   // Inferred modules must be submodules.
15729194a91dSDouglas Gregor   if (!ActiveModule && !Framework) {
157373441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
157473441091SDouglas Gregor     Failed = true;
157573441091SDouglas Gregor   }
157673441091SDouglas Gregor 
15779194a91dSDouglas Gregor   if (ActiveModule) {
1578524e33e1SDouglas Gregor     // Inferred modules must have umbrella directories.
1579524e33e1SDouglas Gregor     if (!Failed && !ActiveModule->getUmbrellaDir()) {
158073441091SDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
158173441091SDouglas Gregor       Failed = true;
158273441091SDouglas Gregor     }
158373441091SDouglas Gregor 
158473441091SDouglas Gregor     // Check for redefinition of an inferred module.
1585dd005f69SDouglas Gregor     if (!Failed && ActiveModule->InferSubmodules) {
158673441091SDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1587dd005f69SDouglas Gregor       if (ActiveModule->InferredSubmoduleLoc.isValid())
1588dd005f69SDouglas Gregor         Diags.Report(ActiveModule->InferredSubmoduleLoc,
158973441091SDouglas Gregor                      diag::note_mmap_prev_definition);
159073441091SDouglas Gregor       Failed = true;
159173441091SDouglas Gregor     }
159273441091SDouglas Gregor 
15939194a91dSDouglas Gregor     // Check for the 'framework' keyword, which is not permitted here.
15949194a91dSDouglas Gregor     if (Framework) {
15959194a91dSDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
15969194a91dSDouglas Gregor       Framework = false;
15979194a91dSDouglas Gregor     }
15989194a91dSDouglas Gregor   } else if (Explicit) {
15999194a91dSDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
16009194a91dSDouglas Gregor     Explicit = false;
16019194a91dSDouglas Gregor   }
16029194a91dSDouglas Gregor 
160373441091SDouglas Gregor   // If there were any problems with this inferred submodule, skip its body.
160473441091SDouglas Gregor   if (Failed) {
160573441091SDouglas Gregor     if (Tok.is(MMToken::LBrace)) {
160673441091SDouglas Gregor       consumeToken();
160773441091SDouglas Gregor       skipUntil(MMToken::RBrace);
160873441091SDouglas Gregor       if (Tok.is(MMToken::RBrace))
160973441091SDouglas Gregor         consumeToken();
161073441091SDouglas Gregor     }
161173441091SDouglas Gregor     HadError = true;
161273441091SDouglas Gregor     return;
161373441091SDouglas Gregor   }
161473441091SDouglas Gregor 
16159194a91dSDouglas Gregor   // Parse optional attributes.
16164442605fSBill Wendling   Attributes Attrs;
16179194a91dSDouglas Gregor   parseOptionalAttributes(Attrs);
16189194a91dSDouglas Gregor 
16199194a91dSDouglas Gregor   if (ActiveModule) {
162073441091SDouglas Gregor     // Note that we have an inferred submodule.
1621dd005f69SDouglas Gregor     ActiveModule->InferSubmodules = true;
1622dd005f69SDouglas Gregor     ActiveModule->InferredSubmoduleLoc = StarLoc;
1623dd005f69SDouglas Gregor     ActiveModule->InferExplicitSubmodules = Explicit;
16249194a91dSDouglas Gregor   } else {
16259194a91dSDouglas Gregor     // We'll be inferring framework modules for this directory.
16269194a91dSDouglas Gregor     Map.InferredDirectories[Directory].InferModules = true;
16279194a91dSDouglas Gregor     Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
16289194a91dSDouglas Gregor   }
162973441091SDouglas Gregor 
163073441091SDouglas Gregor   // Parse the opening brace.
163173441091SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
163273441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
163373441091SDouglas Gregor     HadError = true;
163473441091SDouglas Gregor     return;
163573441091SDouglas Gregor   }
163673441091SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
163773441091SDouglas Gregor 
163873441091SDouglas Gregor   // Parse the body of the inferred submodule.
163973441091SDouglas Gregor   bool Done = false;
164073441091SDouglas Gregor   do {
164173441091SDouglas Gregor     switch (Tok.Kind) {
164273441091SDouglas Gregor     case MMToken::EndOfFile:
164373441091SDouglas Gregor     case MMToken::RBrace:
164473441091SDouglas Gregor       Done = true;
164573441091SDouglas Gregor       break;
164673441091SDouglas Gregor 
16479194a91dSDouglas Gregor     case MMToken::ExcludeKeyword: {
16489194a91dSDouglas Gregor       if (ActiveModule) {
16499194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1650162405daSDouglas Gregor           << (ActiveModule != 0);
16519194a91dSDouglas Gregor         consumeToken();
16529194a91dSDouglas Gregor         break;
16539194a91dSDouglas Gregor       }
16549194a91dSDouglas Gregor 
16559194a91dSDouglas Gregor       consumeToken();
16569194a91dSDouglas Gregor       if (!Tok.is(MMToken::Identifier)) {
16579194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
16589194a91dSDouglas Gregor         break;
16599194a91dSDouglas Gregor       }
16609194a91dSDouglas Gregor 
16619194a91dSDouglas Gregor       Map.InferredDirectories[Directory].ExcludedModules
16629194a91dSDouglas Gregor         .push_back(Tok.getString());
16639194a91dSDouglas Gregor       consumeToken();
16649194a91dSDouglas Gregor       break;
16659194a91dSDouglas Gregor     }
16669194a91dSDouglas Gregor 
16679194a91dSDouglas Gregor     case MMToken::ExportKeyword:
16689194a91dSDouglas Gregor       if (!ActiveModule) {
16699194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1670162405daSDouglas Gregor           << (ActiveModule != 0);
16719194a91dSDouglas Gregor         consumeToken();
16729194a91dSDouglas Gregor         break;
16739194a91dSDouglas Gregor       }
16749194a91dSDouglas Gregor 
167573441091SDouglas Gregor       consumeToken();
167673441091SDouglas Gregor       if (Tok.is(MMToken::Star))
1677dd005f69SDouglas Gregor         ActiveModule->InferExportWildcard = true;
167873441091SDouglas Gregor       else
167973441091SDouglas Gregor         Diags.Report(Tok.getLocation(),
168073441091SDouglas Gregor                      diag::err_mmap_expected_export_wildcard);
168173441091SDouglas Gregor       consumeToken();
168273441091SDouglas Gregor       break;
168373441091SDouglas Gregor 
168473441091SDouglas Gregor     case MMToken::ExplicitKeyword:
168573441091SDouglas Gregor     case MMToken::ModuleKeyword:
168673441091SDouglas Gregor     case MMToken::HeaderKeyword:
168773441091SDouglas Gregor     case MMToken::UmbrellaKeyword:
168873441091SDouglas Gregor     default:
16899194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1690162405daSDouglas Gregor           << (ActiveModule != 0);
169173441091SDouglas Gregor       consumeToken();
169273441091SDouglas Gregor       break;
169373441091SDouglas Gregor     }
169473441091SDouglas Gregor   } while (!Done);
169573441091SDouglas Gregor 
169673441091SDouglas Gregor   if (Tok.is(MMToken::RBrace))
169773441091SDouglas Gregor     consumeToken();
169873441091SDouglas Gregor   else {
169973441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
170073441091SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
170173441091SDouglas Gregor     HadError = true;
170273441091SDouglas Gregor   }
170373441091SDouglas Gregor }
170473441091SDouglas Gregor 
17059194a91dSDouglas Gregor /// \brief Parse optional attributes.
17069194a91dSDouglas Gregor ///
17079194a91dSDouglas Gregor ///   attributes:
17089194a91dSDouglas Gregor ///     attribute attributes
17099194a91dSDouglas Gregor ///     attribute
17109194a91dSDouglas Gregor ///
17119194a91dSDouglas Gregor ///   attribute:
17129194a91dSDouglas Gregor ///     [ identifier ]
17139194a91dSDouglas Gregor ///
17149194a91dSDouglas Gregor /// \param Attrs Will be filled in with the parsed attributes.
17159194a91dSDouglas Gregor ///
17169194a91dSDouglas Gregor /// \returns true if an error occurred, false otherwise.
17174442605fSBill Wendling bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
17189194a91dSDouglas Gregor   bool HadError = false;
17199194a91dSDouglas Gregor 
17209194a91dSDouglas Gregor   while (Tok.is(MMToken::LSquare)) {
17219194a91dSDouglas Gregor     // Consume the '['.
17229194a91dSDouglas Gregor     SourceLocation LSquareLoc = consumeToken();
17239194a91dSDouglas Gregor 
17249194a91dSDouglas Gregor     // Check whether we have an attribute name here.
17259194a91dSDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
17269194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
17279194a91dSDouglas Gregor       skipUntil(MMToken::RSquare);
17289194a91dSDouglas Gregor       if (Tok.is(MMToken::RSquare))
17299194a91dSDouglas Gregor         consumeToken();
17309194a91dSDouglas Gregor       HadError = true;
17319194a91dSDouglas Gregor     }
17329194a91dSDouglas Gregor 
17339194a91dSDouglas Gregor     // Decode the attribute name.
17349194a91dSDouglas Gregor     AttributeKind Attribute
17359194a91dSDouglas Gregor       = llvm::StringSwitch<AttributeKind>(Tok.getString())
1736*35b13eceSDouglas Gregor           .Case("exhaustive", AT_exhaustive)
17379194a91dSDouglas Gregor           .Case("system", AT_system)
17389194a91dSDouglas Gregor           .Default(AT_unknown);
17399194a91dSDouglas Gregor     switch (Attribute) {
17409194a91dSDouglas Gregor     case AT_unknown:
17419194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
17429194a91dSDouglas Gregor         << Tok.getString();
17439194a91dSDouglas Gregor       break;
17449194a91dSDouglas Gregor 
17459194a91dSDouglas Gregor     case AT_system:
17469194a91dSDouglas Gregor       Attrs.IsSystem = true;
17479194a91dSDouglas Gregor       break;
1748*35b13eceSDouglas Gregor 
1749*35b13eceSDouglas Gregor     case AT_exhaustive:
1750*35b13eceSDouglas Gregor       Attrs.IsExhaustive = true;
1751*35b13eceSDouglas Gregor       break;
17529194a91dSDouglas Gregor     }
17539194a91dSDouglas Gregor     consumeToken();
17549194a91dSDouglas Gregor 
17559194a91dSDouglas Gregor     // Consume the ']'.
17569194a91dSDouglas Gregor     if (!Tok.is(MMToken::RSquare)) {
17579194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
17589194a91dSDouglas Gregor       Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
17599194a91dSDouglas Gregor       skipUntil(MMToken::RSquare);
17609194a91dSDouglas Gregor       HadError = true;
17619194a91dSDouglas Gregor     }
17629194a91dSDouglas Gregor 
17639194a91dSDouglas Gregor     if (Tok.is(MMToken::RSquare))
17649194a91dSDouglas Gregor       consumeToken();
17659194a91dSDouglas Gregor   }
17669194a91dSDouglas Gregor 
17679194a91dSDouglas Gregor   return HadError;
17689194a91dSDouglas Gregor }
17699194a91dSDouglas Gregor 
17707033127bSDouglas Gregor /// \brief If there is a specific header search directory due the presence
17717033127bSDouglas Gregor /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
17727033127bSDouglas Gregor const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
17737033127bSDouglas Gregor   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
17747033127bSDouglas Gregor     // If we have an umbrella directory, use that.
17757033127bSDouglas Gregor     if (Mod->hasUmbrellaDir())
17767033127bSDouglas Gregor       return Mod->getUmbrellaDir();
17777033127bSDouglas Gregor 
17787033127bSDouglas Gregor     // If we have a framework directory, stop looking.
17797033127bSDouglas Gregor     if (Mod->IsFramework)
17807033127bSDouglas Gregor       return 0;
17817033127bSDouglas Gregor   }
17827033127bSDouglas Gregor 
17837033127bSDouglas Gregor   return 0;
17847033127bSDouglas Gregor }
17857033127bSDouglas Gregor 
1786718292f2SDouglas Gregor /// \brief Parse a module map file.
1787718292f2SDouglas Gregor ///
1788718292f2SDouglas Gregor ///   module-map-file:
1789718292f2SDouglas Gregor ///     module-declaration*
1790718292f2SDouglas Gregor bool ModuleMapParser::parseModuleMapFile() {
1791718292f2SDouglas Gregor   do {
1792718292f2SDouglas Gregor     switch (Tok.Kind) {
1793718292f2SDouglas Gregor     case MMToken::EndOfFile:
1794718292f2SDouglas Gregor       return HadError;
1795718292f2SDouglas Gregor 
1796e7ab3669SDouglas Gregor     case MMToken::ExplicitKeyword:
1797718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
1798755b2055SDouglas Gregor     case MMToken::FrameworkKeyword:
1799718292f2SDouglas Gregor       parseModuleDecl();
1800718292f2SDouglas Gregor       break;
1801718292f2SDouglas Gregor 
18021fb5c3a6SDouglas Gregor     case MMToken::Comma:
1803*35b13eceSDouglas Gregor     case MMToken::ConfigMacros:
180459527666SDouglas Gregor     case MMToken::ExcludeKeyword:
18052b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
1806718292f2SDouglas Gregor     case MMToken::HeaderKeyword:
1807718292f2SDouglas Gregor     case MMToken::Identifier:
1808718292f2SDouglas Gregor     case MMToken::LBrace:
18096ddfca91SDouglas Gregor     case MMToken::LinkKeyword:
1810a686e1b0SDouglas Gregor     case MMToken::LSquare:
18112b82c2a5SDouglas Gregor     case MMToken::Period:
1812718292f2SDouglas Gregor     case MMToken::RBrace:
1813a686e1b0SDouglas Gregor     case MMToken::RSquare:
18141fb5c3a6SDouglas Gregor     case MMToken::RequiresKeyword:
18152b82c2a5SDouglas Gregor     case MMToken::Star:
1816718292f2SDouglas Gregor     case MMToken::StringLiteral:
1817718292f2SDouglas Gregor     case MMToken::UmbrellaKeyword:
1818718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1819718292f2SDouglas Gregor       HadError = true;
1820718292f2SDouglas Gregor       consumeToken();
1821718292f2SDouglas Gregor       break;
1822718292f2SDouglas Gregor     }
1823718292f2SDouglas Gregor   } while (true);
1824718292f2SDouglas Gregor }
1825718292f2SDouglas Gregor 
1826718292f2SDouglas Gregor bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
18274ddf2221SDouglas Gregor   llvm::DenseMap<const FileEntry *, bool>::iterator Known
18284ddf2221SDouglas Gregor     = ParsedModuleMap.find(File);
18294ddf2221SDouglas Gregor   if (Known != ParsedModuleMap.end())
18304ddf2221SDouglas Gregor     return Known->second;
18314ddf2221SDouglas Gregor 
183289929282SDouglas Gregor   assert(Target != 0 && "Missing target information");
1833718292f2SDouglas Gregor   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1834718292f2SDouglas Gregor   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1835718292f2SDouglas Gregor   if (!Buffer)
18364ddf2221SDouglas Gregor     return ParsedModuleMap[File] = true;
1837718292f2SDouglas Gregor 
1838718292f2SDouglas Gregor   // Parse this module map file.
18391fb5c3a6SDouglas Gregor   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
18401fb5c3a6SDouglas Gregor   Diags->getClient()->BeginSourceFile(MMapLangOpts);
1841bc10b9fbSDouglas Gregor   ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
18423ec6663bSDouglas Gregor                          BuiltinIncludeDir);
1843718292f2SDouglas Gregor   bool Result = Parser.parseModuleMapFile();
1844718292f2SDouglas Gregor   Diags->getClient()->EndSourceFile();
18454ddf2221SDouglas Gregor   ParsedModuleMap[File] = Result;
1846718292f2SDouglas Gregor   return Result;
1847718292f2SDouglas Gregor }
1848