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 
48*fb912657SDouglas Gregor   // Resolve the module-id.
49*fb912657SDouglas Gregor   Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
50*fb912657SDouglas Gregor   if (!Context)
51*fb912657SDouglas Gregor     return Module::ExportDecl();
52*fb912657SDouglas Gregor 
53*fb912657SDouglas Gregor   return Module::ExportDecl(Context, Unresolved.Wildcard);
54*fb912657SDouglas Gregor }
55*fb912657SDouglas Gregor 
56*fb912657SDouglas Gregor Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
57*fb912657SDouglas Gregor                                    bool Complain) const {
582b82c2a5SDouglas Gregor   // Find the starting module.
59*fb912657SDouglas Gregor   Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
602b82c2a5SDouglas Gregor   if (!Context) {
612b82c2a5SDouglas Gregor     if (Complain)
62*fb912657SDouglas Gregor       Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
63*fb912657SDouglas Gregor       << Id[0].first << Mod->getFullModuleName();
642b82c2a5SDouglas Gregor 
65*fb912657SDouglas Gregor     return 0;
662b82c2a5SDouglas Gregor   }
672b82c2a5SDouglas Gregor 
682b82c2a5SDouglas Gregor   // Dig into the module path.
69*fb912657SDouglas Gregor   for (unsigned I = 1, N = Id.size(); I != N; ++I) {
70*fb912657SDouglas Gregor     Module *Sub = lookupModuleQualified(Id[I].first, Context);
712b82c2a5SDouglas Gregor     if (!Sub) {
722b82c2a5SDouglas Gregor       if (Complain)
73*fb912657SDouglas Gregor         Diags->Report(Id[I].second, diag::err_mmap_missing_module_qualified)
74*fb912657SDouglas Gregor         << Id[I].first << Context->getFullModuleName()
75*fb912657SDouglas Gregor         << SourceRange(Id[0].second, Id[I-1].second);
762b82c2a5SDouglas Gregor 
77*fb912657SDouglas Gregor       return 0;
782b82c2a5SDouglas Gregor     }
792b82c2a5SDouglas Gregor 
802b82c2a5SDouglas Gregor     Context = Sub;
812b82c2a5SDouglas Gregor   }
822b82c2a5SDouglas Gregor 
83*fb912657SDouglas Gregor   return Context;
842b82c2a5SDouglas Gregor }
852b82c2a5SDouglas Gregor 
861fb5c3a6SDouglas Gregor ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
87b146baabSArgyrios Kyrtzidis                      const LangOptions &LangOpts, const TargetInfo *Target,
88b146baabSArgyrios Kyrtzidis                      HeaderSearch &HeaderInfo)
89b146baabSArgyrios Kyrtzidis   : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
90b146baabSArgyrios Kyrtzidis     BuiltinIncludeDir(0)
911fb5c3a6SDouglas Gregor {
92c95d8192SDylan Noblesmith   IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
93c95d8192SDylan Noblesmith   Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
94811db4eaSDouglas Gregor             new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
95718292f2SDouglas Gregor   Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
96718292f2SDouglas Gregor   SourceMgr = new SourceManager(*Diags, FileMgr);
97718292f2SDouglas Gregor }
98718292f2SDouglas Gregor 
99718292f2SDouglas Gregor ModuleMap::~ModuleMap() {
1005acdf59eSDouglas Gregor   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
1015acdf59eSDouglas Gregor                                         IEnd = Modules.end();
1025acdf59eSDouglas Gregor        I != IEnd; ++I) {
1035acdf59eSDouglas Gregor     delete I->getValue();
1045acdf59eSDouglas Gregor   }
1055acdf59eSDouglas Gregor 
106718292f2SDouglas Gregor   delete SourceMgr;
107718292f2SDouglas Gregor }
108718292f2SDouglas Gregor 
10989929282SDouglas Gregor void ModuleMap::setTarget(const TargetInfo &Target) {
11089929282SDouglas Gregor   assert((!this->Target || this->Target == &Target) &&
11189929282SDouglas Gregor          "Improper target override");
11289929282SDouglas Gregor   this->Target = &Target;
11389929282SDouglas Gregor }
11489929282SDouglas Gregor 
115056396aeSDouglas Gregor /// \brief "Sanitize" a filename so that it can be used as an identifier.
116056396aeSDouglas Gregor static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
117056396aeSDouglas Gregor                                               SmallVectorImpl<char> &Buffer) {
118056396aeSDouglas Gregor   if (Name.empty())
119056396aeSDouglas Gregor     return Name;
120056396aeSDouglas Gregor 
121a7d03840SJordan Rose   if (!isValidIdentifier(Name)) {
122056396aeSDouglas Gregor     // If we don't already have something with the form of an identifier,
123056396aeSDouglas Gregor     // create a buffer with the sanitized name.
124056396aeSDouglas Gregor     Buffer.clear();
125a7d03840SJordan Rose     if (isDigit(Name[0]))
126056396aeSDouglas Gregor       Buffer.push_back('_');
127056396aeSDouglas Gregor     Buffer.reserve(Buffer.size() + Name.size());
128056396aeSDouglas Gregor     for (unsigned I = 0, N = Name.size(); I != N; ++I) {
129a7d03840SJordan Rose       if (isIdentifierBody(Name[I]))
130056396aeSDouglas Gregor         Buffer.push_back(Name[I]);
131056396aeSDouglas Gregor       else
132056396aeSDouglas Gregor         Buffer.push_back('_');
133056396aeSDouglas Gregor     }
134056396aeSDouglas Gregor 
135056396aeSDouglas Gregor     Name = StringRef(Buffer.data(), Buffer.size());
136056396aeSDouglas Gregor   }
137056396aeSDouglas Gregor 
138056396aeSDouglas Gregor   while (llvm::StringSwitch<bool>(Name)
139056396aeSDouglas Gregor #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
140056396aeSDouglas Gregor #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
141056396aeSDouglas Gregor #include "clang/Basic/TokenKinds.def"
142056396aeSDouglas Gregor            .Default(false)) {
143056396aeSDouglas Gregor     if (Name.data() != Buffer.data())
144056396aeSDouglas Gregor       Buffer.append(Name.begin(), Name.end());
145056396aeSDouglas Gregor     Buffer.push_back('_');
146056396aeSDouglas Gregor     Name = StringRef(Buffer.data(), Buffer.size());
147056396aeSDouglas Gregor   }
148056396aeSDouglas Gregor 
149056396aeSDouglas Gregor   return Name;
150056396aeSDouglas Gregor }
151056396aeSDouglas Gregor 
152de3ef502SDouglas Gregor Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
15359527666SDouglas Gregor   HeadersMap::iterator Known = Headers.find(File);
1541fb5c3a6SDouglas Gregor   if (Known != Headers.end()) {
15559527666SDouglas Gregor     // If a header is not available, don't report that it maps to anything.
15659527666SDouglas Gregor     if (!Known->second.isAvailable())
1571fb5c3a6SDouglas Gregor       return 0;
1581fb5c3a6SDouglas Gregor 
15959527666SDouglas Gregor     return Known->second.getModule();
1601fb5c3a6SDouglas Gregor   }
161ab0c8a84SDouglas Gregor 
162b65dbfffSDouglas Gregor   const DirectoryEntry *Dir = File->getDir();
163f857950dSDmitri Gribenko   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
164e00c8b20SDouglas Gregor 
16574260502SDouglas Gregor   // Note: as an egregious but useful hack we use the real path here, because
16674260502SDouglas Gregor   // frameworks moving from top-level frameworks to embedded frameworks tend
16774260502SDouglas Gregor   // to be symlinked from the top-level location to the embedded location,
16874260502SDouglas Gregor   // and we need to resolve lookups as if we had found the embedded location.
169e00c8b20SDouglas Gregor   StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
170a89c5ac4SDouglas Gregor 
171a89c5ac4SDouglas Gregor   // Keep walking up the directory hierarchy, looking for a directory with
172a89c5ac4SDouglas Gregor   // an umbrella header.
173b65dbfffSDouglas Gregor   do {
174a89c5ac4SDouglas Gregor     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
175a89c5ac4SDouglas Gregor       = UmbrellaDirs.find(Dir);
176a89c5ac4SDouglas Gregor     if (KnownDir != UmbrellaDirs.end()) {
177a89c5ac4SDouglas Gregor       Module *Result = KnownDir->second;
178930a85ccSDouglas Gregor 
179930a85ccSDouglas Gregor       // Search up the module stack until we find a module with an umbrella
18073141fa9SDouglas Gregor       // directory.
181930a85ccSDouglas Gregor       Module *UmbrellaModule = Result;
18273141fa9SDouglas Gregor       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
183930a85ccSDouglas Gregor         UmbrellaModule = UmbrellaModule->Parent;
184930a85ccSDouglas Gregor 
185930a85ccSDouglas Gregor       if (UmbrellaModule->InferSubmodules) {
186a89c5ac4SDouglas Gregor         // Infer submodules for each of the directories we found between
187a89c5ac4SDouglas Gregor         // the directory of the umbrella header and the directory where
188a89c5ac4SDouglas Gregor         // the actual header is located.
1899458f82dSDouglas Gregor         bool Explicit = UmbrellaModule->InferExplicitSubmodules;
1909458f82dSDouglas Gregor 
1917033127bSDouglas Gregor         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
192a89c5ac4SDouglas Gregor           // Find or create the module that corresponds to this directory name.
193056396aeSDouglas Gregor           SmallString<32> NameBuf;
194056396aeSDouglas Gregor           StringRef Name = sanitizeFilenameAsIdentifier(
195056396aeSDouglas Gregor                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
196056396aeSDouglas Gregor                              NameBuf);
197a89c5ac4SDouglas Gregor           Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
1989458f82dSDouglas Gregor                                       Explicit).first;
199a89c5ac4SDouglas Gregor 
200a89c5ac4SDouglas Gregor           // Associate the module and the directory.
201a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I-1]] = Result;
202a89c5ac4SDouglas Gregor 
203a89c5ac4SDouglas Gregor           // If inferred submodules export everything they import, add a
204a89c5ac4SDouglas Gregor           // wildcard to the set of exports.
205930a85ccSDouglas Gregor           if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
206a89c5ac4SDouglas Gregor             Result->Exports.push_back(Module::ExportDecl(0, true));
207a89c5ac4SDouglas Gregor         }
208a89c5ac4SDouglas Gregor 
209a89c5ac4SDouglas Gregor         // Infer a submodule with the same name as this header file.
210056396aeSDouglas Gregor         SmallString<32> NameBuf;
211056396aeSDouglas Gregor         StringRef Name = sanitizeFilenameAsIdentifier(
212056396aeSDouglas Gregor                            llvm::sys::path::stem(File->getName()), NameBuf);
213a89c5ac4SDouglas Gregor         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
2149458f82dSDouglas Gregor                                     Explicit).first;
2153c5305c1SArgyrios Kyrtzidis         Result->addTopHeader(File);
216a89c5ac4SDouglas Gregor 
217a89c5ac4SDouglas Gregor         // If inferred submodules export everything they import, add a
218a89c5ac4SDouglas Gregor         // wildcard to the set of exports.
219930a85ccSDouglas Gregor         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
220a89c5ac4SDouglas Gregor           Result->Exports.push_back(Module::ExportDecl(0, true));
221a89c5ac4SDouglas Gregor       } else {
222a89c5ac4SDouglas Gregor         // Record each of the directories we stepped through as being part of
223a89c5ac4SDouglas Gregor         // the module we found, since the umbrella header covers them all.
224a89c5ac4SDouglas Gregor         for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
225a89c5ac4SDouglas Gregor           UmbrellaDirs[SkippedDirs[I]] = Result;
226a89c5ac4SDouglas Gregor       }
227a89c5ac4SDouglas Gregor 
22859527666SDouglas Gregor       Headers[File] = KnownHeader(Result, /*Excluded=*/false);
2291fb5c3a6SDouglas Gregor 
2301fb5c3a6SDouglas Gregor       // If a header corresponds to an unavailable module, don't report
2311fb5c3a6SDouglas Gregor       // that it maps to anything.
2321fb5c3a6SDouglas Gregor       if (!Result->isAvailable())
2331fb5c3a6SDouglas Gregor         return 0;
2341fb5c3a6SDouglas Gregor 
235a89c5ac4SDouglas Gregor       return Result;
236a89c5ac4SDouglas Gregor     }
237a89c5ac4SDouglas Gregor 
238a89c5ac4SDouglas Gregor     SkippedDirs.push_back(Dir);
239a89c5ac4SDouglas Gregor 
240b65dbfffSDouglas Gregor     // Retrieve our parent path.
241b65dbfffSDouglas Gregor     DirName = llvm::sys::path::parent_path(DirName);
242b65dbfffSDouglas Gregor     if (DirName.empty())
243b65dbfffSDouglas Gregor       break;
244b65dbfffSDouglas Gregor 
245b65dbfffSDouglas Gregor     // Resolve the parent path to a directory entry.
246b65dbfffSDouglas Gregor     Dir = SourceMgr->getFileManager().getDirectory(DirName);
247a89c5ac4SDouglas Gregor   } while (Dir);
248b65dbfffSDouglas Gregor 
249ab0c8a84SDouglas Gregor   return 0;
250ab0c8a84SDouglas Gregor }
251ab0c8a84SDouglas Gregor 
252e4412640SArgyrios Kyrtzidis bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
253e4412640SArgyrios Kyrtzidis   HeadersMap::const_iterator Known = Headers.find(Header);
2541fb5c3a6SDouglas Gregor   if (Known != Headers.end())
25559527666SDouglas Gregor     return !Known->second.isAvailable();
2561fb5c3a6SDouglas Gregor 
2571fb5c3a6SDouglas Gregor   const DirectoryEntry *Dir = Header->getDir();
258f857950dSDmitri Gribenko   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
2591fb5c3a6SDouglas Gregor   StringRef DirName = Dir->getName();
2601fb5c3a6SDouglas Gregor 
2611fb5c3a6SDouglas Gregor   // Keep walking up the directory hierarchy, looking for a directory with
2621fb5c3a6SDouglas Gregor   // an umbrella header.
2631fb5c3a6SDouglas Gregor   do {
264e4412640SArgyrios Kyrtzidis     llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
2651fb5c3a6SDouglas Gregor       = UmbrellaDirs.find(Dir);
2661fb5c3a6SDouglas Gregor     if (KnownDir != UmbrellaDirs.end()) {
2671fb5c3a6SDouglas Gregor       Module *Found = KnownDir->second;
2681fb5c3a6SDouglas Gregor       if (!Found->isAvailable())
2691fb5c3a6SDouglas Gregor         return true;
2701fb5c3a6SDouglas Gregor 
2711fb5c3a6SDouglas Gregor       // Search up the module stack until we find a module with an umbrella
2721fb5c3a6SDouglas Gregor       // directory.
2731fb5c3a6SDouglas Gregor       Module *UmbrellaModule = Found;
2741fb5c3a6SDouglas Gregor       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
2751fb5c3a6SDouglas Gregor         UmbrellaModule = UmbrellaModule->Parent;
2761fb5c3a6SDouglas Gregor 
2771fb5c3a6SDouglas Gregor       if (UmbrellaModule->InferSubmodules) {
2781fb5c3a6SDouglas Gregor         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
2791fb5c3a6SDouglas Gregor           // Find or create the module that corresponds to this directory name.
280056396aeSDouglas Gregor           SmallString<32> NameBuf;
281056396aeSDouglas Gregor           StringRef Name = sanitizeFilenameAsIdentifier(
282056396aeSDouglas Gregor                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
283056396aeSDouglas Gregor                              NameBuf);
2841fb5c3a6SDouglas Gregor           Found = lookupModuleQualified(Name, Found);
2851fb5c3a6SDouglas Gregor           if (!Found)
2861fb5c3a6SDouglas Gregor             return false;
2871fb5c3a6SDouglas Gregor           if (!Found->isAvailable())
2881fb5c3a6SDouglas Gregor             return true;
2891fb5c3a6SDouglas Gregor         }
2901fb5c3a6SDouglas Gregor 
2911fb5c3a6SDouglas Gregor         // Infer a submodule with the same name as this header file.
292056396aeSDouglas Gregor         SmallString<32> NameBuf;
293056396aeSDouglas Gregor         StringRef Name = sanitizeFilenameAsIdentifier(
294056396aeSDouglas Gregor                            llvm::sys::path::stem(Header->getName()),
295056396aeSDouglas Gregor                            NameBuf);
2961fb5c3a6SDouglas Gregor         Found = lookupModuleQualified(Name, Found);
2971fb5c3a6SDouglas Gregor         if (!Found)
2981fb5c3a6SDouglas Gregor           return false;
2991fb5c3a6SDouglas Gregor       }
3001fb5c3a6SDouglas Gregor 
3011fb5c3a6SDouglas Gregor       return !Found->isAvailable();
3021fb5c3a6SDouglas Gregor     }
3031fb5c3a6SDouglas Gregor 
3041fb5c3a6SDouglas Gregor     SkippedDirs.push_back(Dir);
3051fb5c3a6SDouglas Gregor 
3061fb5c3a6SDouglas Gregor     // Retrieve our parent path.
3071fb5c3a6SDouglas Gregor     DirName = llvm::sys::path::parent_path(DirName);
3081fb5c3a6SDouglas Gregor     if (DirName.empty())
3091fb5c3a6SDouglas Gregor       break;
3101fb5c3a6SDouglas Gregor 
3111fb5c3a6SDouglas Gregor     // Resolve the parent path to a directory entry.
3121fb5c3a6SDouglas Gregor     Dir = SourceMgr->getFileManager().getDirectory(DirName);
3131fb5c3a6SDouglas Gregor   } while (Dir);
3141fb5c3a6SDouglas Gregor 
3151fb5c3a6SDouglas Gregor   return false;
3161fb5c3a6SDouglas Gregor }
3171fb5c3a6SDouglas Gregor 
318e4412640SArgyrios Kyrtzidis Module *ModuleMap::findModule(StringRef Name) const {
319e4412640SArgyrios Kyrtzidis   llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
32088bdfb0eSDouglas Gregor   if (Known != Modules.end())
32188bdfb0eSDouglas Gregor     return Known->getValue();
32288bdfb0eSDouglas Gregor 
32388bdfb0eSDouglas Gregor   return 0;
32488bdfb0eSDouglas Gregor }
32588bdfb0eSDouglas Gregor 
326e4412640SArgyrios Kyrtzidis Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
327e4412640SArgyrios Kyrtzidis                                            Module *Context) const {
3282b82c2a5SDouglas Gregor   for(; Context; Context = Context->Parent) {
3292b82c2a5SDouglas Gregor     if (Module *Sub = lookupModuleQualified(Name, Context))
3302b82c2a5SDouglas Gregor       return Sub;
3312b82c2a5SDouglas Gregor   }
3322b82c2a5SDouglas Gregor 
3332b82c2a5SDouglas Gregor   return findModule(Name);
3342b82c2a5SDouglas Gregor }
3352b82c2a5SDouglas Gregor 
336e4412640SArgyrios Kyrtzidis Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
3372b82c2a5SDouglas Gregor   if (!Context)
3382b82c2a5SDouglas Gregor     return findModule(Name);
3392b82c2a5SDouglas Gregor 
340eb90e830SDouglas Gregor   return Context->findSubmodule(Name);
3412b82c2a5SDouglas Gregor }
3422b82c2a5SDouglas Gregor 
343de3ef502SDouglas Gregor std::pair<Module *, bool>
34469021974SDouglas Gregor ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
34569021974SDouglas Gregor                               bool IsExplicit) {
34669021974SDouglas Gregor   // Try to find an existing module with this name.
347eb90e830SDouglas Gregor   if (Module *Sub = lookupModuleQualified(Name, Parent))
348eb90e830SDouglas Gregor     return std::make_pair(Sub, false);
34969021974SDouglas Gregor 
35069021974SDouglas Gregor   // Create a new module with this name.
35169021974SDouglas Gregor   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
35269021974SDouglas Gregor                               IsExplicit);
353eb90e830SDouglas Gregor   if (!Parent)
35469021974SDouglas Gregor     Modules[Name] = Result;
35569021974SDouglas Gregor   return std::make_pair(Result, true);
35669021974SDouglas Gregor }
35769021974SDouglas Gregor 
3589194a91dSDouglas Gregor bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
359e4412640SArgyrios Kyrtzidis                                         StringRef Name, bool &IsSystem) const {
3609194a91dSDouglas Gregor   // Check whether we have already looked into the parent directory
3619194a91dSDouglas Gregor   // for a module map.
362e4412640SArgyrios Kyrtzidis   llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
3639194a91dSDouglas Gregor     inferred = InferredDirectories.find(ParentDir);
3649194a91dSDouglas Gregor   if (inferred == InferredDirectories.end())
3659194a91dSDouglas Gregor     return false;
3669194a91dSDouglas Gregor 
3679194a91dSDouglas Gregor   if (!inferred->second.InferModules)
3689194a91dSDouglas Gregor     return false;
3699194a91dSDouglas Gregor 
3709194a91dSDouglas Gregor   // We're allowed to infer for this directory, but make sure it's okay
3719194a91dSDouglas Gregor   // to infer this particular module.
3729194a91dSDouglas Gregor   bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
3739194a91dSDouglas Gregor                             inferred->second.ExcludedModules.end(),
3749194a91dSDouglas Gregor                             Name) == inferred->second.ExcludedModules.end();
3759194a91dSDouglas Gregor 
3769194a91dSDouglas Gregor   if (canInfer && inferred->second.InferSystemModules)
3779194a91dSDouglas Gregor     IsSystem = true;
3789194a91dSDouglas Gregor 
3799194a91dSDouglas Gregor   return canInfer;
3809194a91dSDouglas Gregor }
3819194a91dSDouglas Gregor 
38211dfe6feSDouglas Gregor /// \brief For a framework module, infer the framework against which we
38311dfe6feSDouglas Gregor /// should link.
38411dfe6feSDouglas Gregor static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
38511dfe6feSDouglas Gregor                                FileManager &FileMgr) {
38611dfe6feSDouglas Gregor   assert(Mod->IsFramework && "Can only infer linking for framework modules");
38711dfe6feSDouglas Gregor   assert(!Mod->isSubFramework() &&
38811dfe6feSDouglas Gregor          "Can only infer linking for top-level frameworks");
38911dfe6feSDouglas Gregor 
39011dfe6feSDouglas Gregor   SmallString<128> LibName;
39111dfe6feSDouglas Gregor   LibName += FrameworkDir->getName();
39211dfe6feSDouglas Gregor   llvm::sys::path::append(LibName, Mod->Name);
39311dfe6feSDouglas Gregor   if (FileMgr.getFile(LibName)) {
39411dfe6feSDouglas Gregor     Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
39511dfe6feSDouglas Gregor                                                      /*IsFramework=*/true));
39611dfe6feSDouglas Gregor   }
39711dfe6feSDouglas Gregor }
39811dfe6feSDouglas Gregor 
399de3ef502SDouglas Gregor Module *
40056c64013SDouglas Gregor ModuleMap::inferFrameworkModule(StringRef ModuleName,
401e89dbc1dSDouglas Gregor                                 const DirectoryEntry *FrameworkDir,
402a686e1b0SDouglas Gregor                                 bool IsSystem,
403e89dbc1dSDouglas Gregor                                 Module *Parent) {
40456c64013SDouglas Gregor   // Check whether we've already found this module.
405e89dbc1dSDouglas Gregor   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
406e89dbc1dSDouglas Gregor     return Mod;
407e89dbc1dSDouglas Gregor 
408e89dbc1dSDouglas Gregor   FileManager &FileMgr = SourceMgr->getFileManager();
40956c64013SDouglas Gregor 
4109194a91dSDouglas Gregor   // If the framework has a parent path from which we're allowed to infer
4119194a91dSDouglas Gregor   // a framework module, do so.
4129194a91dSDouglas Gregor   if (!Parent) {
4134ddf2221SDouglas Gregor     // Determine whether we're allowed to infer a module map.
414e00c8b20SDouglas Gregor 
4154ddf2221SDouglas Gregor     // Note: as an egregious but useful hack we use the real path here, because
4164ddf2221SDouglas Gregor     // we might be looking at an embedded framework that symlinks out to a
4174ddf2221SDouglas Gregor     // top-level framework, and we need to infer as if we were naming the
4184ddf2221SDouglas Gregor     // top-level framework.
419e00c8b20SDouglas Gregor     StringRef FrameworkDirName
420e00c8b20SDouglas Gregor       = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
4214ddf2221SDouglas Gregor 
4229194a91dSDouglas Gregor     bool canInfer = false;
4234ddf2221SDouglas Gregor     if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
4249194a91dSDouglas Gregor       // Figure out the parent path.
4254ddf2221SDouglas Gregor       StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
4269194a91dSDouglas Gregor       if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
4279194a91dSDouglas Gregor         // Check whether we have already looked into the parent directory
4289194a91dSDouglas Gregor         // for a module map.
429e4412640SArgyrios Kyrtzidis         llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
4309194a91dSDouglas Gregor           inferred = InferredDirectories.find(ParentDir);
4319194a91dSDouglas Gregor         if (inferred == InferredDirectories.end()) {
4329194a91dSDouglas Gregor           // We haven't looked here before. Load a module map, if there is
4339194a91dSDouglas Gregor           // one.
4349194a91dSDouglas Gregor           SmallString<128> ModMapPath = Parent;
4359194a91dSDouglas Gregor           llvm::sys::path::append(ModMapPath, "module.map");
4369194a91dSDouglas Gregor           if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
4379194a91dSDouglas Gregor             parseModuleMapFile(ModMapFile);
4389194a91dSDouglas Gregor             inferred = InferredDirectories.find(ParentDir);
4399194a91dSDouglas Gregor           }
4409194a91dSDouglas Gregor 
4419194a91dSDouglas Gregor           if (inferred == InferredDirectories.end())
4429194a91dSDouglas Gregor             inferred = InferredDirectories.insert(
4439194a91dSDouglas Gregor                          std::make_pair(ParentDir, InferredDirectory())).first;
4449194a91dSDouglas Gregor         }
4459194a91dSDouglas Gregor 
4469194a91dSDouglas Gregor         if (inferred->second.InferModules) {
4479194a91dSDouglas Gregor           // We're allowed to infer for this directory, but make sure it's okay
4489194a91dSDouglas Gregor           // to infer this particular module.
4494ddf2221SDouglas Gregor           StringRef Name = llvm::sys::path::stem(FrameworkDirName);
4509194a91dSDouglas Gregor           canInfer = std::find(inferred->second.ExcludedModules.begin(),
4519194a91dSDouglas Gregor                                inferred->second.ExcludedModules.end(),
4529194a91dSDouglas Gregor                                Name) == inferred->second.ExcludedModules.end();
4539194a91dSDouglas Gregor 
4549194a91dSDouglas Gregor           if (inferred->second.InferSystemModules)
4559194a91dSDouglas Gregor             IsSystem = true;
4569194a91dSDouglas Gregor         }
4579194a91dSDouglas Gregor       }
4589194a91dSDouglas Gregor     }
4599194a91dSDouglas Gregor 
4609194a91dSDouglas Gregor     // If we're not allowed to infer a framework module, don't.
4619194a91dSDouglas Gregor     if (!canInfer)
4629194a91dSDouglas Gregor       return 0;
4639194a91dSDouglas Gregor   }
4649194a91dSDouglas Gregor 
4659194a91dSDouglas Gregor 
46656c64013SDouglas Gregor   // Look for an umbrella header.
4672c1dd271SDylan Noblesmith   SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
46856c64013SDouglas Gregor   llvm::sys::path::append(UmbrellaName, "Headers");
46956c64013SDouglas Gregor   llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
470e89dbc1dSDouglas Gregor   const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
47156c64013SDouglas Gregor 
47256c64013SDouglas Gregor   // FIXME: If there's no umbrella header, we could probably scan the
47356c64013SDouglas Gregor   // framework to load *everything*. But, it's not clear that this is a good
47456c64013SDouglas Gregor   // idea.
47556c64013SDouglas Gregor   if (!UmbrellaHeader)
47656c64013SDouglas Gregor     return 0;
47756c64013SDouglas Gregor 
478e89dbc1dSDouglas Gregor   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
479e89dbc1dSDouglas Gregor                               /*IsFramework=*/true, /*IsExplicit=*/false);
480a686e1b0SDouglas Gregor   if (IsSystem)
481a686e1b0SDouglas Gregor     Result->IsSystem = IsSystem;
482a686e1b0SDouglas Gregor 
483eb90e830SDouglas Gregor   if (!Parent)
484e89dbc1dSDouglas Gregor     Modules[ModuleName] = Result;
485e89dbc1dSDouglas Gregor 
486322f633cSDouglas Gregor   // umbrella header "umbrella-header-name"
48773141fa9SDouglas Gregor   Result->Umbrella = UmbrellaHeader;
48859527666SDouglas Gregor   Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
4894dc71835SDouglas Gregor   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
490d8bd7537SDouglas Gregor 
491d8bd7537SDouglas Gregor   // export *
492d8bd7537SDouglas Gregor   Result->Exports.push_back(Module::ExportDecl(0, true));
493d8bd7537SDouglas Gregor 
494a89c5ac4SDouglas Gregor   // module * { export * }
495a89c5ac4SDouglas Gregor   Result->InferSubmodules = true;
496a89c5ac4SDouglas Gregor   Result->InferExportWildcard = true;
497a89c5ac4SDouglas Gregor 
498e89dbc1dSDouglas Gregor   // Look for subframeworks.
499e89dbc1dSDouglas Gregor   llvm::error_code EC;
5002c1dd271SDylan Noblesmith   SmallString<128> SubframeworksDirName
501ddaa69cbSDouglas Gregor     = StringRef(FrameworkDir->getName());
502e89dbc1dSDouglas Gregor   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
5032c1dd271SDylan Noblesmith   SmallString<128> SubframeworksDirNameNative;
504ddaa69cbSDouglas Gregor   llvm::sys::path::native(SubframeworksDirName.str(),
505ddaa69cbSDouglas Gregor                           SubframeworksDirNameNative);
506ddaa69cbSDouglas Gregor   for (llvm::sys::fs::directory_iterator
507ddaa69cbSDouglas Gregor          Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
508e89dbc1dSDouglas Gregor        Dir != DirEnd && !EC; Dir.increment(EC)) {
509e89dbc1dSDouglas Gregor     if (!StringRef(Dir->path()).endswith(".framework"))
510e89dbc1dSDouglas Gregor       continue;
511f2161a70SDouglas Gregor 
512e89dbc1dSDouglas Gregor     if (const DirectoryEntry *SubframeworkDir
513e89dbc1dSDouglas Gregor           = FileMgr.getDirectory(Dir->path())) {
51407c22b78SDouglas Gregor       // Note: as an egregious but useful hack, we use the real path here and
51507c22b78SDouglas Gregor       // check whether it is actually a subdirectory of the parent directory.
51607c22b78SDouglas Gregor       // This will not be the case if the 'subframework' is actually a symlink
51707c22b78SDouglas Gregor       // out to a top-level framework.
518e00c8b20SDouglas Gregor       StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
51907c22b78SDouglas Gregor       bool FoundParent = false;
52007c22b78SDouglas Gregor       do {
52107c22b78SDouglas Gregor         // Get the parent directory name.
52207c22b78SDouglas Gregor         SubframeworkDirName
52307c22b78SDouglas Gregor           = llvm::sys::path::parent_path(SubframeworkDirName);
52407c22b78SDouglas Gregor         if (SubframeworkDirName.empty())
52507c22b78SDouglas Gregor           break;
52607c22b78SDouglas Gregor 
52707c22b78SDouglas Gregor         if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
52807c22b78SDouglas Gregor           FoundParent = true;
52907c22b78SDouglas Gregor           break;
53007c22b78SDouglas Gregor         }
53107c22b78SDouglas Gregor       } while (true);
53207c22b78SDouglas Gregor 
53307c22b78SDouglas Gregor       if (!FoundParent)
53407c22b78SDouglas Gregor         continue;
53507c22b78SDouglas Gregor 
536e89dbc1dSDouglas Gregor       // FIXME: Do we want to warn about subframeworks without umbrella headers?
537056396aeSDouglas Gregor       SmallString<32> NameBuf;
538056396aeSDouglas Gregor       inferFrameworkModule(sanitizeFilenameAsIdentifier(
539056396aeSDouglas Gregor                              llvm::sys::path::stem(Dir->path()), NameBuf),
540056396aeSDouglas Gregor                            SubframeworkDir, IsSystem, Result);
541e89dbc1dSDouglas Gregor     }
542e89dbc1dSDouglas Gregor   }
543e89dbc1dSDouglas Gregor 
54411dfe6feSDouglas Gregor   // If the module is a top-level framework, automatically link against the
54511dfe6feSDouglas Gregor   // framework.
54611dfe6feSDouglas Gregor   if (!Result->isSubFramework()) {
54711dfe6feSDouglas Gregor     inferFrameworkLink(Result, FrameworkDir, FileMgr);
54811dfe6feSDouglas Gregor   }
54911dfe6feSDouglas Gregor 
55056c64013SDouglas Gregor   return Result;
55156c64013SDouglas Gregor }
55256c64013SDouglas Gregor 
553a89c5ac4SDouglas Gregor void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
55459527666SDouglas Gregor   Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
55573141fa9SDouglas Gregor   Mod->Umbrella = UmbrellaHeader;
5567033127bSDouglas Gregor   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
557a89c5ac4SDouglas Gregor }
558a89c5ac4SDouglas Gregor 
559524e33e1SDouglas Gregor void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
560524e33e1SDouglas Gregor   Mod->Umbrella = UmbrellaDir;
561524e33e1SDouglas Gregor   UmbrellaDirs[UmbrellaDir] = Mod;
562524e33e1SDouglas Gregor }
563524e33e1SDouglas Gregor 
56459527666SDouglas Gregor void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
56559527666SDouglas Gregor                           bool Excluded) {
566b146baabSArgyrios Kyrtzidis   if (Excluded) {
56759527666SDouglas Gregor     Mod->ExcludedHeaders.push_back(Header);
568b146baabSArgyrios Kyrtzidis   } else {
569a89c5ac4SDouglas Gregor     Mod->Headers.push_back(Header);
570b146baabSArgyrios Kyrtzidis     HeaderInfo.MarkFileModuleHeader(Header);
571b146baabSArgyrios Kyrtzidis   }
57259527666SDouglas Gregor   Headers[Header] = KnownHeader(Mod, Excluded);
573a89c5ac4SDouglas Gregor }
574a89c5ac4SDouglas Gregor 
575514b636aSDouglas Gregor const FileEntry *
576e4412640SArgyrios Kyrtzidis ModuleMap::getContainingModuleMapFile(Module *Module) const {
577514b636aSDouglas Gregor   if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
578514b636aSDouglas Gregor     return 0;
579514b636aSDouglas Gregor 
580514b636aSDouglas Gregor   return SourceMgr->getFileEntryForID(
581514b636aSDouglas Gregor            SourceMgr->getFileID(Module->DefinitionLoc));
582514b636aSDouglas Gregor }
583514b636aSDouglas Gregor 
584718292f2SDouglas Gregor void ModuleMap::dump() {
585718292f2SDouglas Gregor   llvm::errs() << "Modules:";
586718292f2SDouglas Gregor   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
587718292f2SDouglas Gregor                                         MEnd = Modules.end();
588718292f2SDouglas Gregor        M != MEnd; ++M)
589d28d1b8dSDouglas Gregor     M->getValue()->print(llvm::errs(), 2);
590718292f2SDouglas Gregor 
591718292f2SDouglas Gregor   llvm::errs() << "Headers:";
59259527666SDouglas Gregor   for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
593718292f2SDouglas Gregor        H != HEnd; ++H) {
594718292f2SDouglas Gregor     llvm::errs() << "  \"" << H->first->getName() << "\" -> "
59559527666SDouglas Gregor                  << H->second.getModule()->getFullModuleName() << "\n";
596718292f2SDouglas Gregor   }
597718292f2SDouglas Gregor }
598718292f2SDouglas Gregor 
5992b82c2a5SDouglas Gregor bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
6002b82c2a5SDouglas Gregor   bool HadError = false;
6012b82c2a5SDouglas Gregor   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
6022b82c2a5SDouglas Gregor     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
6032b82c2a5SDouglas Gregor                                               Complain);
604f5eedd05SDouglas Gregor     if (Export.getPointer() || Export.getInt())
6052b82c2a5SDouglas Gregor       Mod->Exports.push_back(Export);
6062b82c2a5SDouglas Gregor     else
6072b82c2a5SDouglas Gregor       HadError = true;
6082b82c2a5SDouglas Gregor   }
6092b82c2a5SDouglas Gregor   Mod->UnresolvedExports.clear();
6102b82c2a5SDouglas Gregor   return HadError;
6112b82c2a5SDouglas Gregor }
6122b82c2a5SDouglas Gregor 
613*fb912657SDouglas Gregor bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
614*fb912657SDouglas Gregor   bool HadError = false;
615*fb912657SDouglas Gregor   for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
616*fb912657SDouglas Gregor     Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
617*fb912657SDouglas Gregor                                        Mod, Complain);
618*fb912657SDouglas Gregor     if (!OtherMod) {
619*fb912657SDouglas Gregor       HadError = true;
620*fb912657SDouglas Gregor       continue;
621*fb912657SDouglas Gregor     }
622*fb912657SDouglas Gregor 
623*fb912657SDouglas Gregor     Module::Conflict Conflict;
624*fb912657SDouglas Gregor     Conflict.Other = OtherMod;
625*fb912657SDouglas Gregor     Conflict.Message = Mod->UnresolvedConflicts[I].Message;
626*fb912657SDouglas Gregor     Mod->Conflicts.push_back(Conflict);
627*fb912657SDouglas Gregor   }
628*fb912657SDouglas Gregor   Mod->UnresolvedConflicts.clear();
629*fb912657SDouglas Gregor   return HadError;
630*fb912657SDouglas Gregor }
631*fb912657SDouglas Gregor 
6320093b3c7SDouglas Gregor Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
6330093b3c7SDouglas Gregor   if (Loc.isInvalid())
6340093b3c7SDouglas Gregor     return 0;
6350093b3c7SDouglas Gregor 
6360093b3c7SDouglas Gregor   // Use the expansion location to determine which module we're in.
6370093b3c7SDouglas Gregor   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
6380093b3c7SDouglas Gregor   if (!ExpansionLoc.isFileID())
6390093b3c7SDouglas Gregor     return 0;
6400093b3c7SDouglas Gregor 
6410093b3c7SDouglas Gregor 
6420093b3c7SDouglas Gregor   const SourceManager &SrcMgr = Loc.getManager();
6430093b3c7SDouglas Gregor   FileID ExpansionFileID = ExpansionLoc.getFileID();
644224d8a74SDouglas Gregor 
645224d8a74SDouglas Gregor   while (const FileEntry *ExpansionFile
646224d8a74SDouglas Gregor            = SrcMgr.getFileEntryForID(ExpansionFileID)) {
647224d8a74SDouglas Gregor     // Find the module that owns this header (if any).
648224d8a74SDouglas Gregor     if (Module *Mod = findModuleForHeader(ExpansionFile))
649224d8a74SDouglas Gregor       return Mod;
650224d8a74SDouglas Gregor 
651224d8a74SDouglas Gregor     // No module owns this header, so look up the inclusion chain to see if
652224d8a74SDouglas Gregor     // any included header has an associated module.
653224d8a74SDouglas Gregor     SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
654224d8a74SDouglas Gregor     if (IncludeLoc.isInvalid())
6550093b3c7SDouglas Gregor       return 0;
6560093b3c7SDouglas Gregor 
657224d8a74SDouglas Gregor     ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
658224d8a74SDouglas Gregor   }
659224d8a74SDouglas Gregor 
660224d8a74SDouglas Gregor   return 0;
6610093b3c7SDouglas Gregor }
6620093b3c7SDouglas Gregor 
663718292f2SDouglas Gregor //----------------------------------------------------------------------------//
664718292f2SDouglas Gregor // Module map file parser
665718292f2SDouglas Gregor //----------------------------------------------------------------------------//
666718292f2SDouglas Gregor 
667718292f2SDouglas Gregor namespace clang {
668718292f2SDouglas Gregor   /// \brief A token in a module map file.
669718292f2SDouglas Gregor   struct MMToken {
670718292f2SDouglas Gregor     enum TokenKind {
6711fb5c3a6SDouglas Gregor       Comma,
67235b13eceSDouglas Gregor       ConfigMacros,
673*fb912657SDouglas Gregor       Conflict,
674718292f2SDouglas Gregor       EndOfFile,
675718292f2SDouglas Gregor       HeaderKeyword,
676718292f2SDouglas Gregor       Identifier,
67759527666SDouglas Gregor       ExcludeKeyword,
678718292f2SDouglas Gregor       ExplicitKeyword,
6792b82c2a5SDouglas Gregor       ExportKeyword,
680755b2055SDouglas Gregor       FrameworkKeyword,
6816ddfca91SDouglas Gregor       LinkKeyword,
682718292f2SDouglas Gregor       ModuleKeyword,
6832b82c2a5SDouglas Gregor       Period,
684718292f2SDouglas Gregor       UmbrellaKeyword,
6851fb5c3a6SDouglas Gregor       RequiresKeyword,
6862b82c2a5SDouglas Gregor       Star,
687718292f2SDouglas Gregor       StringLiteral,
688718292f2SDouglas Gregor       LBrace,
689a686e1b0SDouglas Gregor       RBrace,
690a686e1b0SDouglas Gregor       LSquare,
691a686e1b0SDouglas Gregor       RSquare
692718292f2SDouglas Gregor     } Kind;
693718292f2SDouglas Gregor 
694718292f2SDouglas Gregor     unsigned Location;
695718292f2SDouglas Gregor     unsigned StringLength;
696718292f2SDouglas Gregor     const char *StringData;
697718292f2SDouglas Gregor 
698718292f2SDouglas Gregor     void clear() {
699718292f2SDouglas Gregor       Kind = EndOfFile;
700718292f2SDouglas Gregor       Location = 0;
701718292f2SDouglas Gregor       StringLength = 0;
702718292f2SDouglas Gregor       StringData = 0;
703718292f2SDouglas Gregor     }
704718292f2SDouglas Gregor 
705718292f2SDouglas Gregor     bool is(TokenKind K) const { return Kind == K; }
706718292f2SDouglas Gregor 
707718292f2SDouglas Gregor     SourceLocation getLocation() const {
708718292f2SDouglas Gregor       return SourceLocation::getFromRawEncoding(Location);
709718292f2SDouglas Gregor     }
710718292f2SDouglas Gregor 
711718292f2SDouglas Gregor     StringRef getString() const {
712718292f2SDouglas Gregor       return StringRef(StringData, StringLength);
713718292f2SDouglas Gregor     }
714718292f2SDouglas Gregor   };
715718292f2SDouglas Gregor 
7169194a91dSDouglas Gregor   /// \brief The set of attributes that can be attached to a module.
7174442605fSBill Wendling   struct Attributes {
71835b13eceSDouglas Gregor     Attributes() : IsSystem(), IsExhaustive() { }
7199194a91dSDouglas Gregor 
7209194a91dSDouglas Gregor     /// \brief Whether this is a system module.
7219194a91dSDouglas Gregor     unsigned IsSystem : 1;
72235b13eceSDouglas Gregor 
72335b13eceSDouglas Gregor     /// \brief Whether this is an exhaustive set of configuration macros.
72435b13eceSDouglas Gregor     unsigned IsExhaustive : 1;
7259194a91dSDouglas Gregor   };
7269194a91dSDouglas Gregor 
7279194a91dSDouglas Gregor 
728718292f2SDouglas Gregor   class ModuleMapParser {
729718292f2SDouglas Gregor     Lexer &L;
730718292f2SDouglas Gregor     SourceManager &SourceMgr;
731bc10b9fbSDouglas Gregor 
732bc10b9fbSDouglas Gregor     /// \brief Default target information, used only for string literal
733bc10b9fbSDouglas Gregor     /// parsing.
734bc10b9fbSDouglas Gregor     const TargetInfo *Target;
735bc10b9fbSDouglas Gregor 
736718292f2SDouglas Gregor     DiagnosticsEngine &Diags;
737718292f2SDouglas Gregor     ModuleMap &Map;
738718292f2SDouglas Gregor 
7395257fc63SDouglas Gregor     /// \brief The directory that this module map resides in.
7405257fc63SDouglas Gregor     const DirectoryEntry *Directory;
7415257fc63SDouglas Gregor 
7423ec6663bSDouglas Gregor     /// \brief The directory containing Clang-supplied headers.
7433ec6663bSDouglas Gregor     const DirectoryEntry *BuiltinIncludeDir;
7443ec6663bSDouglas Gregor 
745718292f2SDouglas Gregor     /// \brief Whether an error occurred.
746718292f2SDouglas Gregor     bool HadError;
747718292f2SDouglas Gregor 
748718292f2SDouglas Gregor     /// \brief Stores string data for the various string literals referenced
749718292f2SDouglas Gregor     /// during parsing.
750718292f2SDouglas Gregor     llvm::BumpPtrAllocator StringData;
751718292f2SDouglas Gregor 
752718292f2SDouglas Gregor     /// \brief The current token.
753718292f2SDouglas Gregor     MMToken Tok;
754718292f2SDouglas Gregor 
755718292f2SDouglas Gregor     /// \brief The active module.
756de3ef502SDouglas Gregor     Module *ActiveModule;
757718292f2SDouglas Gregor 
758718292f2SDouglas Gregor     /// \brief Consume the current token and return its location.
759718292f2SDouglas Gregor     SourceLocation consumeToken();
760718292f2SDouglas Gregor 
761718292f2SDouglas Gregor     /// \brief Skip tokens until we reach the a token with the given kind
762718292f2SDouglas Gregor     /// (or the end of the file).
763718292f2SDouglas Gregor     void skipUntil(MMToken::TokenKind K);
764718292f2SDouglas Gregor 
765f857950dSDmitri Gribenko     typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
766e7ab3669SDouglas Gregor     bool parseModuleId(ModuleId &Id);
767718292f2SDouglas Gregor     void parseModuleDecl();
7681fb5c3a6SDouglas Gregor     void parseRequiresDecl();
76959527666SDouglas Gregor     void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
770524e33e1SDouglas Gregor     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
7712b82c2a5SDouglas Gregor     void parseExportDecl();
7726ddfca91SDouglas Gregor     void parseLinkDecl();
77335b13eceSDouglas Gregor     void parseConfigMacros();
774*fb912657SDouglas Gregor     void parseConflict();
7759194a91dSDouglas Gregor     void parseInferredModuleDecl(bool Framework, bool Explicit);
7764442605fSBill Wendling     bool parseOptionalAttributes(Attributes &Attrs);
777718292f2SDouglas Gregor 
7787033127bSDouglas Gregor     const DirectoryEntry *getOverriddenHeaderSearchDir();
7797033127bSDouglas Gregor 
780718292f2SDouglas Gregor   public:
781718292f2SDouglas Gregor     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
782bc10b9fbSDouglas Gregor                              const TargetInfo *Target,
783718292f2SDouglas Gregor                              DiagnosticsEngine &Diags,
7845257fc63SDouglas Gregor                              ModuleMap &Map,
7853ec6663bSDouglas Gregor                              const DirectoryEntry *Directory,
7863ec6663bSDouglas Gregor                              const DirectoryEntry *BuiltinIncludeDir)
787bc10b9fbSDouglas Gregor       : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
7883ec6663bSDouglas Gregor         Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
7893ec6663bSDouglas Gregor         HadError(false), ActiveModule(0)
790718292f2SDouglas Gregor     {
791718292f2SDouglas Gregor       Tok.clear();
792718292f2SDouglas Gregor       consumeToken();
793718292f2SDouglas Gregor     }
794718292f2SDouglas Gregor 
795718292f2SDouglas Gregor     bool parseModuleMapFile();
796718292f2SDouglas Gregor   };
797718292f2SDouglas Gregor }
798718292f2SDouglas Gregor 
799718292f2SDouglas Gregor SourceLocation ModuleMapParser::consumeToken() {
800718292f2SDouglas Gregor retry:
801718292f2SDouglas Gregor   SourceLocation Result = Tok.getLocation();
802718292f2SDouglas Gregor   Tok.clear();
803718292f2SDouglas Gregor 
804718292f2SDouglas Gregor   Token LToken;
805718292f2SDouglas Gregor   L.LexFromRawLexer(LToken);
806718292f2SDouglas Gregor   Tok.Location = LToken.getLocation().getRawEncoding();
807718292f2SDouglas Gregor   switch (LToken.getKind()) {
808718292f2SDouglas Gregor   case tok::raw_identifier:
809718292f2SDouglas Gregor     Tok.StringData = LToken.getRawIdentifierData();
810718292f2SDouglas Gregor     Tok.StringLength = LToken.getLength();
811718292f2SDouglas Gregor     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
81235b13eceSDouglas Gregor                  .Case("config_macros", MMToken::ConfigMacros)
813*fb912657SDouglas Gregor                  .Case("conflict", MMToken::Conflict)
81459527666SDouglas Gregor                  .Case("exclude", MMToken::ExcludeKeyword)
815718292f2SDouglas Gregor                  .Case("explicit", MMToken::ExplicitKeyword)
8162b82c2a5SDouglas Gregor                  .Case("export", MMToken::ExportKeyword)
817755b2055SDouglas Gregor                  .Case("framework", MMToken::FrameworkKeyword)
81835b13eceSDouglas Gregor                  .Case("header", MMToken::HeaderKeyword)
8196ddfca91SDouglas Gregor                  .Case("link", MMToken::LinkKeyword)
820718292f2SDouglas Gregor                  .Case("module", MMToken::ModuleKeyword)
8211fb5c3a6SDouglas Gregor                  .Case("requires", MMToken::RequiresKeyword)
822718292f2SDouglas Gregor                  .Case("umbrella", MMToken::UmbrellaKeyword)
823718292f2SDouglas Gregor                  .Default(MMToken::Identifier);
824718292f2SDouglas Gregor     break;
825718292f2SDouglas Gregor 
8261fb5c3a6SDouglas Gregor   case tok::comma:
8271fb5c3a6SDouglas Gregor     Tok.Kind = MMToken::Comma;
8281fb5c3a6SDouglas Gregor     break;
8291fb5c3a6SDouglas Gregor 
830718292f2SDouglas Gregor   case tok::eof:
831718292f2SDouglas Gregor     Tok.Kind = MMToken::EndOfFile;
832718292f2SDouglas Gregor     break;
833718292f2SDouglas Gregor 
834718292f2SDouglas Gregor   case tok::l_brace:
835718292f2SDouglas Gregor     Tok.Kind = MMToken::LBrace;
836718292f2SDouglas Gregor     break;
837718292f2SDouglas Gregor 
838a686e1b0SDouglas Gregor   case tok::l_square:
839a686e1b0SDouglas Gregor     Tok.Kind = MMToken::LSquare;
840a686e1b0SDouglas Gregor     break;
841a686e1b0SDouglas Gregor 
8422b82c2a5SDouglas Gregor   case tok::period:
8432b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Period;
8442b82c2a5SDouglas Gregor     break;
8452b82c2a5SDouglas Gregor 
846718292f2SDouglas Gregor   case tok::r_brace:
847718292f2SDouglas Gregor     Tok.Kind = MMToken::RBrace;
848718292f2SDouglas Gregor     break;
849718292f2SDouglas Gregor 
850a686e1b0SDouglas Gregor   case tok::r_square:
851a686e1b0SDouglas Gregor     Tok.Kind = MMToken::RSquare;
852a686e1b0SDouglas Gregor     break;
853a686e1b0SDouglas Gregor 
8542b82c2a5SDouglas Gregor   case tok::star:
8552b82c2a5SDouglas Gregor     Tok.Kind = MMToken::Star;
8562b82c2a5SDouglas Gregor     break;
8572b82c2a5SDouglas Gregor 
858718292f2SDouglas Gregor   case tok::string_literal: {
859d67aea28SRichard Smith     if (LToken.hasUDSuffix()) {
860d67aea28SRichard Smith       Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
861d67aea28SRichard Smith       HadError = true;
862d67aea28SRichard Smith       goto retry;
863d67aea28SRichard Smith     }
864d67aea28SRichard Smith 
865718292f2SDouglas Gregor     // Parse the string literal.
866718292f2SDouglas Gregor     LangOptions LangOpts;
867718292f2SDouglas Gregor     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
868718292f2SDouglas Gregor     if (StringLiteral.hadError)
869718292f2SDouglas Gregor       goto retry;
870718292f2SDouglas Gregor 
871718292f2SDouglas Gregor     // Copy the string literal into our string data allocator.
872718292f2SDouglas Gregor     unsigned Length = StringLiteral.GetStringLength();
873718292f2SDouglas Gregor     char *Saved = StringData.Allocate<char>(Length + 1);
874718292f2SDouglas Gregor     memcpy(Saved, StringLiteral.GetString().data(), Length);
875718292f2SDouglas Gregor     Saved[Length] = 0;
876718292f2SDouglas Gregor 
877718292f2SDouglas Gregor     // Form the token.
878718292f2SDouglas Gregor     Tok.Kind = MMToken::StringLiteral;
879718292f2SDouglas Gregor     Tok.StringData = Saved;
880718292f2SDouglas Gregor     Tok.StringLength = Length;
881718292f2SDouglas Gregor     break;
882718292f2SDouglas Gregor   }
883718292f2SDouglas Gregor 
884718292f2SDouglas Gregor   case tok::comment:
885718292f2SDouglas Gregor     goto retry;
886718292f2SDouglas Gregor 
887718292f2SDouglas Gregor   default:
888718292f2SDouglas Gregor     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
889718292f2SDouglas Gregor     HadError = true;
890718292f2SDouglas Gregor     goto retry;
891718292f2SDouglas Gregor   }
892718292f2SDouglas Gregor 
893718292f2SDouglas Gregor   return Result;
894718292f2SDouglas Gregor }
895718292f2SDouglas Gregor 
896718292f2SDouglas Gregor void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
897718292f2SDouglas Gregor   unsigned braceDepth = 0;
898a686e1b0SDouglas Gregor   unsigned squareDepth = 0;
899718292f2SDouglas Gregor   do {
900718292f2SDouglas Gregor     switch (Tok.Kind) {
901718292f2SDouglas Gregor     case MMToken::EndOfFile:
902718292f2SDouglas Gregor       return;
903718292f2SDouglas Gregor 
904718292f2SDouglas Gregor     case MMToken::LBrace:
905a686e1b0SDouglas Gregor       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
906718292f2SDouglas Gregor         return;
907718292f2SDouglas Gregor 
908718292f2SDouglas Gregor       ++braceDepth;
909718292f2SDouglas Gregor       break;
910718292f2SDouglas Gregor 
911a686e1b0SDouglas Gregor     case MMToken::LSquare:
912a686e1b0SDouglas Gregor       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
913a686e1b0SDouglas Gregor         return;
914a686e1b0SDouglas Gregor 
915a686e1b0SDouglas Gregor       ++squareDepth;
916a686e1b0SDouglas Gregor       break;
917a686e1b0SDouglas Gregor 
918718292f2SDouglas Gregor     case MMToken::RBrace:
919718292f2SDouglas Gregor       if (braceDepth > 0)
920718292f2SDouglas Gregor         --braceDepth;
921718292f2SDouglas Gregor       else if (Tok.is(K))
922718292f2SDouglas Gregor         return;
923718292f2SDouglas Gregor       break;
924718292f2SDouglas Gregor 
925a686e1b0SDouglas Gregor     case MMToken::RSquare:
926a686e1b0SDouglas Gregor       if (squareDepth > 0)
927a686e1b0SDouglas Gregor         --squareDepth;
928a686e1b0SDouglas Gregor       else if (Tok.is(K))
929a686e1b0SDouglas Gregor         return;
930a686e1b0SDouglas Gregor       break;
931a686e1b0SDouglas Gregor 
932718292f2SDouglas Gregor     default:
933a686e1b0SDouglas Gregor       if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
934718292f2SDouglas Gregor         return;
935718292f2SDouglas Gregor       break;
936718292f2SDouglas Gregor     }
937718292f2SDouglas Gregor 
938718292f2SDouglas Gregor    consumeToken();
939718292f2SDouglas Gregor   } while (true);
940718292f2SDouglas Gregor }
941718292f2SDouglas Gregor 
942e7ab3669SDouglas Gregor /// \brief Parse a module-id.
943e7ab3669SDouglas Gregor ///
944e7ab3669SDouglas Gregor ///   module-id:
945e7ab3669SDouglas Gregor ///     identifier
946e7ab3669SDouglas Gregor ///     identifier '.' module-id
947e7ab3669SDouglas Gregor ///
948e7ab3669SDouglas Gregor /// \returns true if an error occurred, false otherwise.
949e7ab3669SDouglas Gregor bool ModuleMapParser::parseModuleId(ModuleId &Id) {
950e7ab3669SDouglas Gregor   Id.clear();
951e7ab3669SDouglas Gregor   do {
952e7ab3669SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
953e7ab3669SDouglas Gregor       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
954e7ab3669SDouglas Gregor       consumeToken();
955e7ab3669SDouglas Gregor     } else {
956e7ab3669SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
957e7ab3669SDouglas Gregor       return true;
958e7ab3669SDouglas Gregor     }
959e7ab3669SDouglas Gregor 
960e7ab3669SDouglas Gregor     if (!Tok.is(MMToken::Period))
961e7ab3669SDouglas Gregor       break;
962e7ab3669SDouglas Gregor 
963e7ab3669SDouglas Gregor     consumeToken();
964e7ab3669SDouglas Gregor   } while (true);
965e7ab3669SDouglas Gregor 
966e7ab3669SDouglas Gregor   return false;
967e7ab3669SDouglas Gregor }
968e7ab3669SDouglas Gregor 
969a686e1b0SDouglas Gregor namespace {
970a686e1b0SDouglas Gregor   /// \brief Enumerates the known attributes.
971a686e1b0SDouglas Gregor   enum AttributeKind {
972a686e1b0SDouglas Gregor     /// \brief An unknown attribute.
973a686e1b0SDouglas Gregor     AT_unknown,
974a686e1b0SDouglas Gregor     /// \brief The 'system' attribute.
97535b13eceSDouglas Gregor     AT_system,
97635b13eceSDouglas Gregor     /// \brief The 'exhaustive' attribute.
97735b13eceSDouglas Gregor     AT_exhaustive
978a686e1b0SDouglas Gregor   };
979a686e1b0SDouglas Gregor }
980a686e1b0SDouglas Gregor 
981718292f2SDouglas Gregor /// \brief Parse a module declaration.
982718292f2SDouglas Gregor ///
983718292f2SDouglas Gregor ///   module-declaration:
984a686e1b0SDouglas Gregor ///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
985a686e1b0SDouglas Gregor ///       { module-member* }
986a686e1b0SDouglas Gregor ///
987718292f2SDouglas Gregor ///   module-member:
9881fb5c3a6SDouglas Gregor ///     requires-declaration
989718292f2SDouglas Gregor ///     header-declaration
990e7ab3669SDouglas Gregor ///     submodule-declaration
9912b82c2a5SDouglas Gregor ///     export-declaration
9926ddfca91SDouglas Gregor ///     link-declaration
99373441091SDouglas Gregor ///
99473441091SDouglas Gregor ///   submodule-declaration:
99573441091SDouglas Gregor ///     module-declaration
99673441091SDouglas Gregor ///     inferred-submodule-declaration
997718292f2SDouglas Gregor void ModuleMapParser::parseModuleDecl() {
998755b2055SDouglas Gregor   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
999755b2055SDouglas Gregor          Tok.is(MMToken::FrameworkKeyword));
1000f2161a70SDouglas Gregor   // Parse 'explicit' or 'framework' keyword, if present.
1001e7ab3669SDouglas Gregor   SourceLocation ExplicitLoc;
1002718292f2SDouglas Gregor   bool Explicit = false;
1003f2161a70SDouglas Gregor   bool Framework = false;
1004755b2055SDouglas Gregor 
1005f2161a70SDouglas Gregor   // Parse 'explicit' keyword, if present.
1006f2161a70SDouglas Gregor   if (Tok.is(MMToken::ExplicitKeyword)) {
1007e7ab3669SDouglas Gregor     ExplicitLoc = consumeToken();
1008f2161a70SDouglas Gregor     Explicit = true;
1009f2161a70SDouglas Gregor   }
1010f2161a70SDouglas Gregor 
1011f2161a70SDouglas Gregor   // Parse 'framework' keyword, if present.
1012755b2055SDouglas Gregor   if (Tok.is(MMToken::FrameworkKeyword)) {
1013755b2055SDouglas Gregor     consumeToken();
1014755b2055SDouglas Gregor     Framework = true;
1015755b2055SDouglas Gregor   }
1016718292f2SDouglas Gregor 
1017718292f2SDouglas Gregor   // Parse 'module' keyword.
1018718292f2SDouglas Gregor   if (!Tok.is(MMToken::ModuleKeyword)) {
1019d6343c99SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1020718292f2SDouglas Gregor     consumeToken();
1021718292f2SDouglas Gregor     HadError = true;
1022718292f2SDouglas Gregor     return;
1023718292f2SDouglas Gregor   }
1024718292f2SDouglas Gregor   consumeToken(); // 'module' keyword
1025718292f2SDouglas Gregor 
102673441091SDouglas Gregor   // If we have a wildcard for the module name, this is an inferred submodule.
102773441091SDouglas Gregor   // Parse it.
102873441091SDouglas Gregor   if (Tok.is(MMToken::Star))
10299194a91dSDouglas Gregor     return parseInferredModuleDecl(Framework, Explicit);
103073441091SDouglas Gregor 
1031718292f2SDouglas Gregor   // Parse the module name.
1032e7ab3669SDouglas Gregor   ModuleId Id;
1033e7ab3669SDouglas Gregor   if (parseModuleId(Id)) {
1034718292f2SDouglas Gregor     HadError = true;
1035718292f2SDouglas Gregor     return;
1036718292f2SDouglas Gregor   }
1037e7ab3669SDouglas Gregor 
1038e7ab3669SDouglas Gregor   if (ActiveModule) {
1039e7ab3669SDouglas Gregor     if (Id.size() > 1) {
1040e7ab3669SDouglas Gregor       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1041e7ab3669SDouglas Gregor         << SourceRange(Id.front().second, Id.back().second);
1042e7ab3669SDouglas Gregor 
1043e7ab3669SDouglas Gregor       HadError = true;
1044e7ab3669SDouglas Gregor       return;
1045e7ab3669SDouglas Gregor     }
1046e7ab3669SDouglas Gregor   } else if (Id.size() == 1 && Explicit) {
1047e7ab3669SDouglas Gregor     // Top-level modules can't be explicit.
1048e7ab3669SDouglas Gregor     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1049e7ab3669SDouglas Gregor     Explicit = false;
1050e7ab3669SDouglas Gregor     ExplicitLoc = SourceLocation();
1051e7ab3669SDouglas Gregor     HadError = true;
1052e7ab3669SDouglas Gregor   }
1053e7ab3669SDouglas Gregor 
1054e7ab3669SDouglas Gregor   Module *PreviousActiveModule = ActiveModule;
1055e7ab3669SDouglas Gregor   if (Id.size() > 1) {
1056e7ab3669SDouglas Gregor     // This module map defines a submodule. Go find the module of which it
1057e7ab3669SDouglas Gregor     // is a submodule.
1058e7ab3669SDouglas Gregor     ActiveModule = 0;
1059e7ab3669SDouglas Gregor     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1060e7ab3669SDouglas Gregor       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1061e7ab3669SDouglas Gregor         ActiveModule = Next;
1062e7ab3669SDouglas Gregor         continue;
1063e7ab3669SDouglas Gregor       }
1064e7ab3669SDouglas Gregor 
1065e7ab3669SDouglas Gregor       if (ActiveModule) {
1066e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1067e7ab3669SDouglas Gregor           << Id[I].first << ActiveModule->getTopLevelModule();
1068e7ab3669SDouglas Gregor       } else {
1069e7ab3669SDouglas Gregor         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1070e7ab3669SDouglas Gregor       }
1071e7ab3669SDouglas Gregor       HadError = true;
1072e7ab3669SDouglas Gregor       return;
1073e7ab3669SDouglas Gregor     }
1074e7ab3669SDouglas Gregor   }
1075e7ab3669SDouglas Gregor 
1076e7ab3669SDouglas Gregor   StringRef ModuleName = Id.back().first;
1077e7ab3669SDouglas Gregor   SourceLocation ModuleNameLoc = Id.back().second;
1078718292f2SDouglas Gregor 
1079a686e1b0SDouglas Gregor   // Parse the optional attribute list.
10804442605fSBill Wendling   Attributes Attrs;
10819194a91dSDouglas Gregor   parseOptionalAttributes(Attrs);
1082a686e1b0SDouglas Gregor 
1083718292f2SDouglas Gregor   // Parse the opening brace.
1084718292f2SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
1085718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1086718292f2SDouglas Gregor       << ModuleName;
1087718292f2SDouglas Gregor     HadError = true;
1088718292f2SDouglas Gregor     return;
1089718292f2SDouglas Gregor   }
1090718292f2SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
1091718292f2SDouglas Gregor 
1092718292f2SDouglas Gregor   // Determine whether this (sub)module has already been defined.
1093eb90e830SDouglas Gregor   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1094fcc54a3bSDouglas Gregor     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1095fcc54a3bSDouglas Gregor       // Skip the module definition.
1096fcc54a3bSDouglas Gregor       skipUntil(MMToken::RBrace);
1097fcc54a3bSDouglas Gregor       if (Tok.is(MMToken::RBrace))
1098fcc54a3bSDouglas Gregor         consumeToken();
1099fcc54a3bSDouglas Gregor       else {
1100fcc54a3bSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1101fcc54a3bSDouglas Gregor         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1102fcc54a3bSDouglas Gregor         HadError = true;
1103fcc54a3bSDouglas Gregor       }
1104fcc54a3bSDouglas Gregor       return;
1105fcc54a3bSDouglas Gregor     }
1106fcc54a3bSDouglas Gregor 
1107718292f2SDouglas Gregor     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1108718292f2SDouglas Gregor       << ModuleName;
1109eb90e830SDouglas Gregor     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1110718292f2SDouglas Gregor 
1111718292f2SDouglas Gregor     // Skip the module definition.
1112718292f2SDouglas Gregor     skipUntil(MMToken::RBrace);
1113718292f2SDouglas Gregor     if (Tok.is(MMToken::RBrace))
1114718292f2SDouglas Gregor       consumeToken();
1115718292f2SDouglas Gregor 
1116718292f2SDouglas Gregor     HadError = true;
1117718292f2SDouglas Gregor     return;
1118718292f2SDouglas Gregor   }
1119718292f2SDouglas Gregor 
1120718292f2SDouglas Gregor   // Start defining this module.
1121eb90e830SDouglas Gregor   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1122eb90e830SDouglas Gregor                                         Explicit).first;
1123eb90e830SDouglas Gregor   ActiveModule->DefinitionLoc = ModuleNameLoc;
11249194a91dSDouglas Gregor   if (Attrs.IsSystem)
1125a686e1b0SDouglas Gregor     ActiveModule->IsSystem = true;
1126718292f2SDouglas Gregor 
1127718292f2SDouglas Gregor   bool Done = false;
1128718292f2SDouglas Gregor   do {
1129718292f2SDouglas Gregor     switch (Tok.Kind) {
1130718292f2SDouglas Gregor     case MMToken::EndOfFile:
1131718292f2SDouglas Gregor     case MMToken::RBrace:
1132718292f2SDouglas Gregor       Done = true;
1133718292f2SDouglas Gregor       break;
1134718292f2SDouglas Gregor 
113535b13eceSDouglas Gregor     case MMToken::ConfigMacros:
113635b13eceSDouglas Gregor       parseConfigMacros();
113735b13eceSDouglas Gregor       break;
113835b13eceSDouglas Gregor 
1139*fb912657SDouglas Gregor     case MMToken::Conflict:
1140*fb912657SDouglas Gregor       parseConflict();
1141*fb912657SDouglas Gregor       break;
1142*fb912657SDouglas Gregor 
1143718292f2SDouglas Gregor     case MMToken::ExplicitKeyword:
1144f2161a70SDouglas Gregor     case MMToken::FrameworkKeyword:
1145718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
1146718292f2SDouglas Gregor       parseModuleDecl();
1147718292f2SDouglas Gregor       break;
1148718292f2SDouglas Gregor 
11492b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
11502b82c2a5SDouglas Gregor       parseExportDecl();
11512b82c2a5SDouglas Gregor       break;
11522b82c2a5SDouglas Gregor 
11531fb5c3a6SDouglas Gregor     case MMToken::RequiresKeyword:
11541fb5c3a6SDouglas Gregor       parseRequiresDecl();
11551fb5c3a6SDouglas Gregor       break;
11561fb5c3a6SDouglas Gregor 
1157524e33e1SDouglas Gregor     case MMToken::UmbrellaKeyword: {
1158524e33e1SDouglas Gregor       SourceLocation UmbrellaLoc = consumeToken();
1159524e33e1SDouglas Gregor       if (Tok.is(MMToken::HeaderKeyword))
116059527666SDouglas Gregor         parseHeaderDecl(UmbrellaLoc, SourceLocation());
1161524e33e1SDouglas Gregor       else
1162524e33e1SDouglas Gregor         parseUmbrellaDirDecl(UmbrellaLoc);
1163718292f2SDouglas Gregor       break;
1164524e33e1SDouglas Gregor     }
1165718292f2SDouglas Gregor 
116659527666SDouglas Gregor     case MMToken::ExcludeKeyword: {
116759527666SDouglas Gregor       SourceLocation ExcludeLoc = consumeToken();
116859527666SDouglas Gregor       if (Tok.is(MMToken::HeaderKeyword)) {
116959527666SDouglas Gregor         parseHeaderDecl(SourceLocation(), ExcludeLoc);
117059527666SDouglas Gregor       } else {
117159527666SDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
117259527666SDouglas Gregor           << "exclude";
117359527666SDouglas Gregor       }
117459527666SDouglas Gregor       break;
117559527666SDouglas Gregor     }
117659527666SDouglas Gregor 
1177322f633cSDouglas Gregor     case MMToken::HeaderKeyword:
117859527666SDouglas Gregor       parseHeaderDecl(SourceLocation(), SourceLocation());
1179718292f2SDouglas Gregor       break;
1180718292f2SDouglas Gregor 
11816ddfca91SDouglas Gregor     case MMToken::LinkKeyword:
11826ddfca91SDouglas Gregor       parseLinkDecl();
11836ddfca91SDouglas Gregor       break;
11846ddfca91SDouglas Gregor 
1185718292f2SDouglas Gregor     default:
1186718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1187718292f2SDouglas Gregor       consumeToken();
1188718292f2SDouglas Gregor       break;
1189718292f2SDouglas Gregor     }
1190718292f2SDouglas Gregor   } while (!Done);
1191718292f2SDouglas Gregor 
1192718292f2SDouglas Gregor   if (Tok.is(MMToken::RBrace))
1193718292f2SDouglas Gregor     consumeToken();
1194718292f2SDouglas Gregor   else {
1195718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1196718292f2SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1197718292f2SDouglas Gregor     HadError = true;
1198718292f2SDouglas Gregor   }
1199718292f2SDouglas Gregor 
120011dfe6feSDouglas Gregor   // If the active module is a top-level framework, and there are no link
120111dfe6feSDouglas Gregor   // libraries, automatically link against the framework.
120211dfe6feSDouglas Gregor   if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
120311dfe6feSDouglas Gregor       ActiveModule->LinkLibraries.empty()) {
120411dfe6feSDouglas Gregor     inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
120511dfe6feSDouglas Gregor   }
120611dfe6feSDouglas Gregor 
1207e7ab3669SDouglas Gregor   // We're done parsing this module. Pop back to the previous module.
1208e7ab3669SDouglas Gregor   ActiveModule = PreviousActiveModule;
1209718292f2SDouglas Gregor }
1210718292f2SDouglas Gregor 
12111fb5c3a6SDouglas Gregor /// \brief Parse a requires declaration.
12121fb5c3a6SDouglas Gregor ///
12131fb5c3a6SDouglas Gregor ///   requires-declaration:
12141fb5c3a6SDouglas Gregor ///     'requires' feature-list
12151fb5c3a6SDouglas Gregor ///
12161fb5c3a6SDouglas Gregor ///   feature-list:
12171fb5c3a6SDouglas Gregor ///     identifier ',' feature-list
12181fb5c3a6SDouglas Gregor ///     identifier
12191fb5c3a6SDouglas Gregor void ModuleMapParser::parseRequiresDecl() {
12201fb5c3a6SDouglas Gregor   assert(Tok.is(MMToken::RequiresKeyword));
12211fb5c3a6SDouglas Gregor 
12221fb5c3a6SDouglas Gregor   // Parse 'requires' keyword.
12231fb5c3a6SDouglas Gregor   consumeToken();
12241fb5c3a6SDouglas Gregor 
12251fb5c3a6SDouglas Gregor   // Parse the feature-list.
12261fb5c3a6SDouglas Gregor   do {
12271fb5c3a6SDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
12281fb5c3a6SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
12291fb5c3a6SDouglas Gregor       HadError = true;
12301fb5c3a6SDouglas Gregor       return;
12311fb5c3a6SDouglas Gregor     }
12321fb5c3a6SDouglas Gregor 
12331fb5c3a6SDouglas Gregor     // Consume the feature name.
12341fb5c3a6SDouglas Gregor     std::string Feature = Tok.getString();
12351fb5c3a6SDouglas Gregor     consumeToken();
12361fb5c3a6SDouglas Gregor 
12371fb5c3a6SDouglas Gregor     // Add this feature.
123889929282SDouglas Gregor     ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
12391fb5c3a6SDouglas Gregor 
12401fb5c3a6SDouglas Gregor     if (!Tok.is(MMToken::Comma))
12411fb5c3a6SDouglas Gregor       break;
12421fb5c3a6SDouglas Gregor 
12431fb5c3a6SDouglas Gregor     // Consume the comma.
12441fb5c3a6SDouglas Gregor     consumeToken();
12451fb5c3a6SDouglas Gregor   } while (true);
12461fb5c3a6SDouglas Gregor }
12471fb5c3a6SDouglas Gregor 
1248f2161a70SDouglas Gregor /// \brief Append to \p Paths the set of paths needed to get to the
1249f2161a70SDouglas Gregor /// subframework in which the given module lives.
1250bf8da9d7SBenjamin Kramer static void appendSubframeworkPaths(Module *Mod,
1251f857950dSDmitri Gribenko                                     SmallVectorImpl<char> &Path) {
1252f2161a70SDouglas Gregor   // Collect the framework names from the given module to the top-level module.
1253f857950dSDmitri Gribenko   SmallVector<StringRef, 2> Paths;
1254f2161a70SDouglas Gregor   for (; Mod; Mod = Mod->Parent) {
1255f2161a70SDouglas Gregor     if (Mod->IsFramework)
1256f2161a70SDouglas Gregor       Paths.push_back(Mod->Name);
1257f2161a70SDouglas Gregor   }
1258f2161a70SDouglas Gregor 
1259f2161a70SDouglas Gregor   if (Paths.empty())
1260f2161a70SDouglas Gregor     return;
1261f2161a70SDouglas Gregor 
1262f2161a70SDouglas Gregor   // Add Frameworks/Name.framework for each subframework.
1263f2161a70SDouglas Gregor   for (unsigned I = Paths.size() - 1; I != 0; --I) {
1264f2161a70SDouglas Gregor     llvm::sys::path::append(Path, "Frameworks");
1265f2161a70SDouglas Gregor     llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1266f2161a70SDouglas Gregor   }
1267f2161a70SDouglas Gregor }
1268f2161a70SDouglas Gregor 
12693ec6663bSDouglas Gregor /// \brief Determine whether the given file name is the name of a builtin
12703ec6663bSDouglas Gregor /// header, supplied by Clang to replace, override, or augment existing system
12713ec6663bSDouglas Gregor /// headers.
12723ec6663bSDouglas Gregor static bool isBuiltinHeader(StringRef FileName) {
12733ec6663bSDouglas Gregor   return llvm::StringSwitch<bool>(FileName)
12743ec6663bSDouglas Gregor       .Case("float.h", true)
12753ec6663bSDouglas Gregor       .Case("iso646.h", true)
12763ec6663bSDouglas Gregor       .Case("limits.h", true)
12773ec6663bSDouglas Gregor       .Case("stdalign.h", true)
12783ec6663bSDouglas Gregor       .Case("stdarg.h", true)
12793ec6663bSDouglas Gregor       .Case("stdbool.h", true)
12803ec6663bSDouglas Gregor       .Case("stddef.h", true)
12813ec6663bSDouglas Gregor       .Case("stdint.h", true)
12823ec6663bSDouglas Gregor       .Case("tgmath.h", true)
12833ec6663bSDouglas Gregor       .Case("unwind.h", true)
12843ec6663bSDouglas Gregor       .Default(false);
12853ec6663bSDouglas Gregor }
12863ec6663bSDouglas Gregor 
1287718292f2SDouglas Gregor /// \brief Parse a header declaration.
1288718292f2SDouglas Gregor ///
1289718292f2SDouglas Gregor ///   header-declaration:
1290322f633cSDouglas Gregor ///     'umbrella'[opt] 'header' string-literal
129159527666SDouglas Gregor ///     'exclude'[opt] 'header' string-literal
129259527666SDouglas Gregor void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
129359527666SDouglas Gregor                                       SourceLocation ExcludeLoc) {
1294718292f2SDouglas Gregor   assert(Tok.is(MMToken::HeaderKeyword));
12951871ed3dSBenjamin Kramer   consumeToken();
1296718292f2SDouglas Gregor 
1297322f633cSDouglas Gregor   bool Umbrella = UmbrellaLoc.isValid();
129859527666SDouglas Gregor   bool Exclude = ExcludeLoc.isValid();
129959527666SDouglas Gregor   assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
1300718292f2SDouglas Gregor   // Parse the header name.
1301718292f2SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
1302718292f2SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1303718292f2SDouglas Gregor       << "header";
1304718292f2SDouglas Gregor     HadError = true;
1305718292f2SDouglas Gregor     return;
1306718292f2SDouglas Gregor   }
1307e7ab3669SDouglas Gregor   std::string FileName = Tok.getString();
1308718292f2SDouglas Gregor   SourceLocation FileNameLoc = consumeToken();
1309718292f2SDouglas Gregor 
1310524e33e1SDouglas Gregor   // Check whether we already have an umbrella.
1311524e33e1SDouglas Gregor   if (Umbrella && ActiveModule->Umbrella) {
1312524e33e1SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1313524e33e1SDouglas Gregor       << ActiveModule->getFullModuleName();
1314322f633cSDouglas Gregor     HadError = true;
1315322f633cSDouglas Gregor     return;
1316322f633cSDouglas Gregor   }
1317322f633cSDouglas Gregor 
13185257fc63SDouglas Gregor   // Look for this file.
1319e7ab3669SDouglas Gregor   const FileEntry *File = 0;
13203ec6663bSDouglas Gregor   const FileEntry *BuiltinFile = 0;
13212c1dd271SDylan Noblesmith   SmallString<128> PathName;
1322e7ab3669SDouglas Gregor   if (llvm::sys::path::is_absolute(FileName)) {
1323e7ab3669SDouglas Gregor     PathName = FileName;
1324e7ab3669SDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
13257033127bSDouglas Gregor   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
13267033127bSDouglas Gregor     PathName = Dir->getName();
13277033127bSDouglas Gregor     llvm::sys::path::append(PathName, FileName);
13287033127bSDouglas Gregor     File = SourceMgr.getFileManager().getFile(PathName);
1329e7ab3669SDouglas Gregor   } else {
1330e7ab3669SDouglas Gregor     // Search for the header file within the search directory.
13317033127bSDouglas Gregor     PathName = Directory->getName();
1332e7ab3669SDouglas Gregor     unsigned PathLength = PathName.size();
1333755b2055SDouglas Gregor 
1334f2161a70SDouglas Gregor     if (ActiveModule->isPartOfFramework()) {
1335f2161a70SDouglas Gregor       appendSubframeworkPaths(ActiveModule, PathName);
1336755b2055SDouglas Gregor 
1337e7ab3669SDouglas Gregor       // Check whether this file is in the public headers.
1338e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, "Headers");
13395257fc63SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
1340e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
1341e7ab3669SDouglas Gregor 
1342e7ab3669SDouglas Gregor       if (!File) {
1343e7ab3669SDouglas Gregor         // Check whether this file is in the private headers.
1344e7ab3669SDouglas Gregor         PathName.resize(PathLength);
1345e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, "PrivateHeaders");
1346e7ab3669SDouglas Gregor         llvm::sys::path::append(PathName, FileName);
1347e7ab3669SDouglas Gregor         File = SourceMgr.getFileManager().getFile(PathName);
1348e7ab3669SDouglas Gregor       }
1349e7ab3669SDouglas Gregor     } else {
1350e7ab3669SDouglas Gregor       // Lookup for normal headers.
1351e7ab3669SDouglas Gregor       llvm::sys::path::append(PathName, FileName);
1352e7ab3669SDouglas Gregor       File = SourceMgr.getFileManager().getFile(PathName);
13533ec6663bSDouglas Gregor 
13543ec6663bSDouglas Gregor       // If this is a system module with a top-level header, this header
13553ec6663bSDouglas Gregor       // may have a counterpart (or replacement) in the set of headers
13563ec6663bSDouglas Gregor       // supplied by Clang. Find that builtin header.
13573ec6663bSDouglas Gregor       if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
13583ec6663bSDouglas Gregor           BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
13592c1dd271SDylan Noblesmith         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
13603ec6663bSDouglas Gregor         llvm::sys::path::append(BuiltinPathName, FileName);
13613ec6663bSDouglas Gregor         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
13623ec6663bSDouglas Gregor 
13633ec6663bSDouglas Gregor         // If Clang supplies this header but the underlying system does not,
13643ec6663bSDouglas Gregor         // just silently swap in our builtin version. Otherwise, we'll end
13653ec6663bSDouglas Gregor         // up adding both (later).
13663ec6663bSDouglas Gregor         if (!File && BuiltinFile) {
13673ec6663bSDouglas Gregor           File = BuiltinFile;
13683ec6663bSDouglas Gregor           BuiltinFile = 0;
13693ec6663bSDouglas Gregor         }
13703ec6663bSDouglas Gregor       }
1371e7ab3669SDouglas Gregor     }
1372e7ab3669SDouglas Gregor   }
13735257fc63SDouglas Gregor 
13745257fc63SDouglas Gregor   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
13755257fc63SDouglas Gregor   // Come up with a lazy way to do this.
1376e7ab3669SDouglas Gregor   if (File) {
137759527666SDouglas Gregor     if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
13785257fc63SDouglas Gregor       Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
137959527666SDouglas Gregor         << FileName << OwningModule.getModule()->getFullModuleName();
13805257fc63SDouglas Gregor       HadError = true;
1381322f633cSDouglas Gregor     } else if (Umbrella) {
1382322f633cSDouglas Gregor       const DirectoryEntry *UmbrellaDir = File->getDir();
138359527666SDouglas Gregor       if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1384322f633cSDouglas Gregor         Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
138559527666SDouglas Gregor           << UmbrellaModule->getFullModuleName();
1386322f633cSDouglas Gregor         HadError = true;
13875257fc63SDouglas Gregor       } else {
1388322f633cSDouglas Gregor         // Record this umbrella header.
1389322f633cSDouglas Gregor         Map.setUmbrellaHeader(ActiveModule, File);
1390322f633cSDouglas Gregor       }
1391322f633cSDouglas Gregor     } else {
1392322f633cSDouglas Gregor       // Record this header.
139359527666SDouglas Gregor       Map.addHeader(ActiveModule, File, Exclude);
13943ec6663bSDouglas Gregor 
13953ec6663bSDouglas Gregor       // If there is a builtin counterpart to this file, add it now.
13963ec6663bSDouglas Gregor       if (BuiltinFile)
139759527666SDouglas Gregor         Map.addHeader(ActiveModule, BuiltinFile, Exclude);
13985257fc63SDouglas Gregor     }
13994b27a64bSDouglas Gregor   } else if (!Exclude) {
14004b27a64bSDouglas Gregor     // Ignore excluded header files. They're optional anyway.
14014b27a64bSDouglas Gregor 
14025257fc63SDouglas Gregor     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1403524e33e1SDouglas Gregor       << Umbrella << FileName;
14045257fc63SDouglas Gregor     HadError = true;
14055257fc63SDouglas Gregor   }
1406718292f2SDouglas Gregor }
1407718292f2SDouglas Gregor 
1408524e33e1SDouglas Gregor /// \brief Parse an umbrella directory declaration.
1409524e33e1SDouglas Gregor ///
1410524e33e1SDouglas Gregor ///   umbrella-dir-declaration:
1411524e33e1SDouglas Gregor ///     umbrella string-literal
1412524e33e1SDouglas Gregor void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1413524e33e1SDouglas Gregor   // Parse the directory name.
1414524e33e1SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
1415524e33e1SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1416524e33e1SDouglas Gregor       << "umbrella";
1417524e33e1SDouglas Gregor     HadError = true;
1418524e33e1SDouglas Gregor     return;
1419524e33e1SDouglas Gregor   }
1420524e33e1SDouglas Gregor 
1421524e33e1SDouglas Gregor   std::string DirName = Tok.getString();
1422524e33e1SDouglas Gregor   SourceLocation DirNameLoc = consumeToken();
1423524e33e1SDouglas Gregor 
1424524e33e1SDouglas Gregor   // Check whether we already have an umbrella.
1425524e33e1SDouglas Gregor   if (ActiveModule->Umbrella) {
1426524e33e1SDouglas Gregor     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1427524e33e1SDouglas Gregor       << ActiveModule->getFullModuleName();
1428524e33e1SDouglas Gregor     HadError = true;
1429524e33e1SDouglas Gregor     return;
1430524e33e1SDouglas Gregor   }
1431524e33e1SDouglas Gregor 
1432524e33e1SDouglas Gregor   // Look for this file.
1433524e33e1SDouglas Gregor   const DirectoryEntry *Dir = 0;
1434524e33e1SDouglas Gregor   if (llvm::sys::path::is_absolute(DirName))
1435524e33e1SDouglas Gregor     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1436524e33e1SDouglas Gregor   else {
14372c1dd271SDylan Noblesmith     SmallString<128> PathName;
1438524e33e1SDouglas Gregor     PathName = Directory->getName();
1439524e33e1SDouglas Gregor     llvm::sys::path::append(PathName, DirName);
1440524e33e1SDouglas Gregor     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1441524e33e1SDouglas Gregor   }
1442524e33e1SDouglas Gregor 
1443524e33e1SDouglas Gregor   if (!Dir) {
1444524e33e1SDouglas Gregor     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1445524e33e1SDouglas Gregor       << DirName;
1446524e33e1SDouglas Gregor     HadError = true;
1447524e33e1SDouglas Gregor     return;
1448524e33e1SDouglas Gregor   }
1449524e33e1SDouglas Gregor 
1450524e33e1SDouglas Gregor   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1451524e33e1SDouglas Gregor     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1452524e33e1SDouglas Gregor       << OwningModule->getFullModuleName();
1453524e33e1SDouglas Gregor     HadError = true;
1454524e33e1SDouglas Gregor     return;
1455524e33e1SDouglas Gregor   }
1456524e33e1SDouglas Gregor 
1457524e33e1SDouglas Gregor   // Record this umbrella directory.
1458524e33e1SDouglas Gregor   Map.setUmbrellaDir(ActiveModule, Dir);
1459524e33e1SDouglas Gregor }
1460524e33e1SDouglas Gregor 
14612b82c2a5SDouglas Gregor /// \brief Parse a module export declaration.
14622b82c2a5SDouglas Gregor ///
14632b82c2a5SDouglas Gregor ///   export-declaration:
14642b82c2a5SDouglas Gregor ///     'export' wildcard-module-id
14652b82c2a5SDouglas Gregor ///
14662b82c2a5SDouglas Gregor ///   wildcard-module-id:
14672b82c2a5SDouglas Gregor ///     identifier
14682b82c2a5SDouglas Gregor ///     '*'
14692b82c2a5SDouglas Gregor ///     identifier '.' wildcard-module-id
14702b82c2a5SDouglas Gregor void ModuleMapParser::parseExportDecl() {
14712b82c2a5SDouglas Gregor   assert(Tok.is(MMToken::ExportKeyword));
14722b82c2a5SDouglas Gregor   SourceLocation ExportLoc = consumeToken();
14732b82c2a5SDouglas Gregor 
14742b82c2a5SDouglas Gregor   // Parse the module-id with an optional wildcard at the end.
14752b82c2a5SDouglas Gregor   ModuleId ParsedModuleId;
14762b82c2a5SDouglas Gregor   bool Wildcard = false;
14772b82c2a5SDouglas Gregor   do {
14782b82c2a5SDouglas Gregor     if (Tok.is(MMToken::Identifier)) {
14792b82c2a5SDouglas Gregor       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
14802b82c2a5SDouglas Gregor                                               Tok.getLocation()));
14812b82c2a5SDouglas Gregor       consumeToken();
14822b82c2a5SDouglas Gregor 
14832b82c2a5SDouglas Gregor       if (Tok.is(MMToken::Period)) {
14842b82c2a5SDouglas Gregor         consumeToken();
14852b82c2a5SDouglas Gregor         continue;
14862b82c2a5SDouglas Gregor       }
14872b82c2a5SDouglas Gregor 
14882b82c2a5SDouglas Gregor       break;
14892b82c2a5SDouglas Gregor     }
14902b82c2a5SDouglas Gregor 
14912b82c2a5SDouglas Gregor     if(Tok.is(MMToken::Star)) {
14922b82c2a5SDouglas Gregor       Wildcard = true;
1493f5eedd05SDouglas Gregor       consumeToken();
14942b82c2a5SDouglas Gregor       break;
14952b82c2a5SDouglas Gregor     }
14962b82c2a5SDouglas Gregor 
14972b82c2a5SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
14982b82c2a5SDouglas Gregor     HadError = true;
14992b82c2a5SDouglas Gregor     return;
15002b82c2a5SDouglas Gregor   } while (true);
15012b82c2a5SDouglas Gregor 
15022b82c2a5SDouglas Gregor   Module::UnresolvedExportDecl Unresolved = {
15032b82c2a5SDouglas Gregor     ExportLoc, ParsedModuleId, Wildcard
15042b82c2a5SDouglas Gregor   };
15052b82c2a5SDouglas Gregor   ActiveModule->UnresolvedExports.push_back(Unresolved);
15062b82c2a5SDouglas Gregor }
15072b82c2a5SDouglas Gregor 
15086ddfca91SDouglas Gregor /// \brief Parse a link declaration.
15096ddfca91SDouglas Gregor ///
15106ddfca91SDouglas Gregor ///   module-declaration:
15116ddfca91SDouglas Gregor ///     'link' 'framework'[opt] string-literal
15126ddfca91SDouglas Gregor void ModuleMapParser::parseLinkDecl() {
15136ddfca91SDouglas Gregor   assert(Tok.is(MMToken::LinkKeyword));
15146ddfca91SDouglas Gregor   SourceLocation LinkLoc = consumeToken();
15156ddfca91SDouglas Gregor 
15166ddfca91SDouglas Gregor   // Parse the optional 'framework' keyword.
15176ddfca91SDouglas Gregor   bool IsFramework = false;
15186ddfca91SDouglas Gregor   if (Tok.is(MMToken::FrameworkKeyword)) {
15196ddfca91SDouglas Gregor     consumeToken();
15206ddfca91SDouglas Gregor     IsFramework = true;
15216ddfca91SDouglas Gregor   }
15226ddfca91SDouglas Gregor 
15236ddfca91SDouglas Gregor   // Parse the library name
15246ddfca91SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
15256ddfca91SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
15266ddfca91SDouglas Gregor       << IsFramework << SourceRange(LinkLoc);
15276ddfca91SDouglas Gregor     HadError = true;
15286ddfca91SDouglas Gregor     return;
15296ddfca91SDouglas Gregor   }
15306ddfca91SDouglas Gregor 
15316ddfca91SDouglas Gregor   std::string LibraryName = Tok.getString();
15326ddfca91SDouglas Gregor   consumeToken();
15336ddfca91SDouglas Gregor   ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
15346ddfca91SDouglas Gregor                                                             IsFramework));
15356ddfca91SDouglas Gregor }
15366ddfca91SDouglas Gregor 
153735b13eceSDouglas Gregor /// \brief Parse a configuration macro declaration.
153835b13eceSDouglas Gregor ///
153935b13eceSDouglas Gregor ///   module-declaration:
154035b13eceSDouglas Gregor ///     'config_macros' attributes[opt] config-macro-list?
154135b13eceSDouglas Gregor ///
154235b13eceSDouglas Gregor ///   config-macro-list:
154335b13eceSDouglas Gregor ///     identifier (',' identifier)?
154435b13eceSDouglas Gregor void ModuleMapParser::parseConfigMacros() {
154535b13eceSDouglas Gregor   assert(Tok.is(MMToken::ConfigMacros));
154635b13eceSDouglas Gregor   SourceLocation ConfigMacrosLoc = consumeToken();
154735b13eceSDouglas Gregor 
154835b13eceSDouglas Gregor   // Only top-level modules can have configuration macros.
154935b13eceSDouglas Gregor   if (ActiveModule->Parent) {
155035b13eceSDouglas Gregor     Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
155135b13eceSDouglas Gregor   }
155235b13eceSDouglas Gregor 
155335b13eceSDouglas Gregor   // Parse the optional attributes.
155435b13eceSDouglas Gregor   Attributes Attrs;
155535b13eceSDouglas Gregor   parseOptionalAttributes(Attrs);
155635b13eceSDouglas Gregor   if (Attrs.IsExhaustive && !ActiveModule->Parent) {
155735b13eceSDouglas Gregor     ActiveModule->ConfigMacrosExhaustive = true;
155835b13eceSDouglas Gregor   }
155935b13eceSDouglas Gregor 
156035b13eceSDouglas Gregor   // If we don't have an identifier, we're done.
156135b13eceSDouglas Gregor   if (!Tok.is(MMToken::Identifier))
156235b13eceSDouglas Gregor     return;
156335b13eceSDouglas Gregor 
156435b13eceSDouglas Gregor   // Consume the first identifier.
156535b13eceSDouglas Gregor   if (!ActiveModule->Parent) {
156635b13eceSDouglas Gregor     ActiveModule->ConfigMacros.push_back(Tok.getString().str());
156735b13eceSDouglas Gregor   }
156835b13eceSDouglas Gregor   consumeToken();
156935b13eceSDouglas Gregor 
157035b13eceSDouglas Gregor   do {
157135b13eceSDouglas Gregor     // If there's a comma, consume it.
157235b13eceSDouglas Gregor     if (!Tok.is(MMToken::Comma))
157335b13eceSDouglas Gregor       break;
157435b13eceSDouglas Gregor     consumeToken();
157535b13eceSDouglas Gregor 
157635b13eceSDouglas Gregor     // We expect to see a macro name here.
157735b13eceSDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
157835b13eceSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
157935b13eceSDouglas Gregor       break;
158035b13eceSDouglas Gregor     }
158135b13eceSDouglas Gregor 
158235b13eceSDouglas Gregor     // Consume the macro name.
158335b13eceSDouglas Gregor     if (!ActiveModule->Parent) {
158435b13eceSDouglas Gregor       ActiveModule->ConfigMacros.push_back(Tok.getString().str());
158535b13eceSDouglas Gregor     }
158635b13eceSDouglas Gregor     consumeToken();
158735b13eceSDouglas Gregor   } while (true);
158835b13eceSDouglas Gregor }
158935b13eceSDouglas Gregor 
1590*fb912657SDouglas Gregor /// \brief Format a module-id into a string.
1591*fb912657SDouglas Gregor static std::string formatModuleId(const ModuleId &Id) {
1592*fb912657SDouglas Gregor   std::string result;
1593*fb912657SDouglas Gregor   {
1594*fb912657SDouglas Gregor     llvm::raw_string_ostream OS(result);
1595*fb912657SDouglas Gregor 
1596*fb912657SDouglas Gregor     for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1597*fb912657SDouglas Gregor       if (I)
1598*fb912657SDouglas Gregor         OS << ".";
1599*fb912657SDouglas Gregor       OS << Id[I].first;
1600*fb912657SDouglas Gregor     }
1601*fb912657SDouglas Gregor   }
1602*fb912657SDouglas Gregor 
1603*fb912657SDouglas Gregor   return result;
1604*fb912657SDouglas Gregor }
1605*fb912657SDouglas Gregor 
1606*fb912657SDouglas Gregor /// \brief Parse a conflict declaration.
1607*fb912657SDouglas Gregor ///
1608*fb912657SDouglas Gregor ///   module-declaration:
1609*fb912657SDouglas Gregor ///     'conflict' module-id ',' string-literal
1610*fb912657SDouglas Gregor void ModuleMapParser::parseConflict() {
1611*fb912657SDouglas Gregor   assert(Tok.is(MMToken::Conflict));
1612*fb912657SDouglas Gregor   SourceLocation ConflictLoc = consumeToken();
1613*fb912657SDouglas Gregor   Module::UnresolvedConflict Conflict;
1614*fb912657SDouglas Gregor 
1615*fb912657SDouglas Gregor   // Parse the module-id.
1616*fb912657SDouglas Gregor   if (parseModuleId(Conflict.Id))
1617*fb912657SDouglas Gregor     return;
1618*fb912657SDouglas Gregor 
1619*fb912657SDouglas Gregor   // Parse the ','.
1620*fb912657SDouglas Gregor   if (!Tok.is(MMToken::Comma)) {
1621*fb912657SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1622*fb912657SDouglas Gregor       << SourceRange(ConflictLoc);
1623*fb912657SDouglas Gregor     return;
1624*fb912657SDouglas Gregor   }
1625*fb912657SDouglas Gregor   consumeToken();
1626*fb912657SDouglas Gregor 
1627*fb912657SDouglas Gregor   // Parse the message.
1628*fb912657SDouglas Gregor   if (!Tok.is(MMToken::StringLiteral)) {
1629*fb912657SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1630*fb912657SDouglas Gregor       << formatModuleId(Conflict.Id);
1631*fb912657SDouglas Gregor     return;
1632*fb912657SDouglas Gregor   }
1633*fb912657SDouglas Gregor   Conflict.Message = Tok.getString().str();
1634*fb912657SDouglas Gregor   consumeToken();
1635*fb912657SDouglas Gregor 
1636*fb912657SDouglas Gregor   // Add this unresolved conflict.
1637*fb912657SDouglas Gregor   ActiveModule->UnresolvedConflicts.push_back(Conflict);
1638*fb912657SDouglas Gregor }
1639*fb912657SDouglas Gregor 
16406ddfca91SDouglas Gregor /// \brief Parse an inferred module declaration (wildcard modules).
16419194a91dSDouglas Gregor ///
16429194a91dSDouglas Gregor ///   module-declaration:
16439194a91dSDouglas Gregor ///     'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
16449194a91dSDouglas Gregor ///       { inferred-module-member* }
16459194a91dSDouglas Gregor ///
16469194a91dSDouglas Gregor ///   inferred-module-member:
16479194a91dSDouglas Gregor ///     'export' '*'
16489194a91dSDouglas Gregor ///     'exclude' identifier
16499194a91dSDouglas Gregor void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
165073441091SDouglas Gregor   assert(Tok.is(MMToken::Star));
165173441091SDouglas Gregor   SourceLocation StarLoc = consumeToken();
165273441091SDouglas Gregor   bool Failed = false;
165373441091SDouglas Gregor 
165473441091SDouglas Gregor   // Inferred modules must be submodules.
16559194a91dSDouglas Gregor   if (!ActiveModule && !Framework) {
165673441091SDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
165773441091SDouglas Gregor     Failed = true;
165873441091SDouglas Gregor   }
165973441091SDouglas Gregor 
16609194a91dSDouglas Gregor   if (ActiveModule) {
1661524e33e1SDouglas Gregor     // Inferred modules must have umbrella directories.
1662524e33e1SDouglas Gregor     if (!Failed && !ActiveModule->getUmbrellaDir()) {
166373441091SDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
166473441091SDouglas Gregor       Failed = true;
166573441091SDouglas Gregor     }
166673441091SDouglas Gregor 
166773441091SDouglas Gregor     // Check for redefinition of an inferred module.
1668dd005f69SDouglas Gregor     if (!Failed && ActiveModule->InferSubmodules) {
166973441091SDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1670dd005f69SDouglas Gregor       if (ActiveModule->InferredSubmoduleLoc.isValid())
1671dd005f69SDouglas Gregor         Diags.Report(ActiveModule->InferredSubmoduleLoc,
167273441091SDouglas Gregor                      diag::note_mmap_prev_definition);
167373441091SDouglas Gregor       Failed = true;
167473441091SDouglas Gregor     }
167573441091SDouglas Gregor 
16769194a91dSDouglas Gregor     // Check for the 'framework' keyword, which is not permitted here.
16779194a91dSDouglas Gregor     if (Framework) {
16789194a91dSDouglas Gregor       Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
16799194a91dSDouglas Gregor       Framework = false;
16809194a91dSDouglas Gregor     }
16819194a91dSDouglas Gregor   } else if (Explicit) {
16829194a91dSDouglas Gregor     Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
16839194a91dSDouglas Gregor     Explicit = false;
16849194a91dSDouglas Gregor   }
16859194a91dSDouglas Gregor 
168673441091SDouglas Gregor   // If there were any problems with this inferred submodule, skip its body.
168773441091SDouglas Gregor   if (Failed) {
168873441091SDouglas Gregor     if (Tok.is(MMToken::LBrace)) {
168973441091SDouglas Gregor       consumeToken();
169073441091SDouglas Gregor       skipUntil(MMToken::RBrace);
169173441091SDouglas Gregor       if (Tok.is(MMToken::RBrace))
169273441091SDouglas Gregor         consumeToken();
169373441091SDouglas Gregor     }
169473441091SDouglas Gregor     HadError = true;
169573441091SDouglas Gregor     return;
169673441091SDouglas Gregor   }
169773441091SDouglas Gregor 
16989194a91dSDouglas Gregor   // Parse optional attributes.
16994442605fSBill Wendling   Attributes Attrs;
17009194a91dSDouglas Gregor   parseOptionalAttributes(Attrs);
17019194a91dSDouglas Gregor 
17029194a91dSDouglas Gregor   if (ActiveModule) {
170373441091SDouglas Gregor     // Note that we have an inferred submodule.
1704dd005f69SDouglas Gregor     ActiveModule->InferSubmodules = true;
1705dd005f69SDouglas Gregor     ActiveModule->InferredSubmoduleLoc = StarLoc;
1706dd005f69SDouglas Gregor     ActiveModule->InferExplicitSubmodules = Explicit;
17079194a91dSDouglas Gregor   } else {
17089194a91dSDouglas Gregor     // We'll be inferring framework modules for this directory.
17099194a91dSDouglas Gregor     Map.InferredDirectories[Directory].InferModules = true;
17109194a91dSDouglas Gregor     Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
17119194a91dSDouglas Gregor   }
171273441091SDouglas Gregor 
171373441091SDouglas Gregor   // Parse the opening brace.
171473441091SDouglas Gregor   if (!Tok.is(MMToken::LBrace)) {
171573441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
171673441091SDouglas Gregor     HadError = true;
171773441091SDouglas Gregor     return;
171873441091SDouglas Gregor   }
171973441091SDouglas Gregor   SourceLocation LBraceLoc = consumeToken();
172073441091SDouglas Gregor 
172173441091SDouglas Gregor   // Parse the body of the inferred submodule.
172273441091SDouglas Gregor   bool Done = false;
172373441091SDouglas Gregor   do {
172473441091SDouglas Gregor     switch (Tok.Kind) {
172573441091SDouglas Gregor     case MMToken::EndOfFile:
172673441091SDouglas Gregor     case MMToken::RBrace:
172773441091SDouglas Gregor       Done = true;
172873441091SDouglas Gregor       break;
172973441091SDouglas Gregor 
17309194a91dSDouglas Gregor     case MMToken::ExcludeKeyword: {
17319194a91dSDouglas Gregor       if (ActiveModule) {
17329194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1733162405daSDouglas Gregor           << (ActiveModule != 0);
17349194a91dSDouglas Gregor         consumeToken();
17359194a91dSDouglas Gregor         break;
17369194a91dSDouglas Gregor       }
17379194a91dSDouglas Gregor 
17389194a91dSDouglas Gregor       consumeToken();
17399194a91dSDouglas Gregor       if (!Tok.is(MMToken::Identifier)) {
17409194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
17419194a91dSDouglas Gregor         break;
17429194a91dSDouglas Gregor       }
17439194a91dSDouglas Gregor 
17449194a91dSDouglas Gregor       Map.InferredDirectories[Directory].ExcludedModules
17459194a91dSDouglas Gregor         .push_back(Tok.getString());
17469194a91dSDouglas Gregor       consumeToken();
17479194a91dSDouglas Gregor       break;
17489194a91dSDouglas Gregor     }
17499194a91dSDouglas Gregor 
17509194a91dSDouglas Gregor     case MMToken::ExportKeyword:
17519194a91dSDouglas Gregor       if (!ActiveModule) {
17529194a91dSDouglas Gregor         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1753162405daSDouglas Gregor           << (ActiveModule != 0);
17549194a91dSDouglas Gregor         consumeToken();
17559194a91dSDouglas Gregor         break;
17569194a91dSDouglas Gregor       }
17579194a91dSDouglas Gregor 
175873441091SDouglas Gregor       consumeToken();
175973441091SDouglas Gregor       if (Tok.is(MMToken::Star))
1760dd005f69SDouglas Gregor         ActiveModule->InferExportWildcard = true;
176173441091SDouglas Gregor       else
176273441091SDouglas Gregor         Diags.Report(Tok.getLocation(),
176373441091SDouglas Gregor                      diag::err_mmap_expected_export_wildcard);
176473441091SDouglas Gregor       consumeToken();
176573441091SDouglas Gregor       break;
176673441091SDouglas Gregor 
176773441091SDouglas Gregor     case MMToken::ExplicitKeyword:
176873441091SDouglas Gregor     case MMToken::ModuleKeyword:
176973441091SDouglas Gregor     case MMToken::HeaderKeyword:
177073441091SDouglas Gregor     case MMToken::UmbrellaKeyword:
177173441091SDouglas Gregor     default:
17729194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1773162405daSDouglas Gregor           << (ActiveModule != 0);
177473441091SDouglas Gregor       consumeToken();
177573441091SDouglas Gregor       break;
177673441091SDouglas Gregor     }
177773441091SDouglas Gregor   } while (!Done);
177873441091SDouglas Gregor 
177973441091SDouglas Gregor   if (Tok.is(MMToken::RBrace))
178073441091SDouglas Gregor     consumeToken();
178173441091SDouglas Gregor   else {
178273441091SDouglas Gregor     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
178373441091SDouglas Gregor     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
178473441091SDouglas Gregor     HadError = true;
178573441091SDouglas Gregor   }
178673441091SDouglas Gregor }
178773441091SDouglas Gregor 
17889194a91dSDouglas Gregor /// \brief Parse optional attributes.
17899194a91dSDouglas Gregor ///
17909194a91dSDouglas Gregor ///   attributes:
17919194a91dSDouglas Gregor ///     attribute attributes
17929194a91dSDouglas Gregor ///     attribute
17939194a91dSDouglas Gregor ///
17949194a91dSDouglas Gregor ///   attribute:
17959194a91dSDouglas Gregor ///     [ identifier ]
17969194a91dSDouglas Gregor ///
17979194a91dSDouglas Gregor /// \param Attrs Will be filled in with the parsed attributes.
17989194a91dSDouglas Gregor ///
17999194a91dSDouglas Gregor /// \returns true if an error occurred, false otherwise.
18004442605fSBill Wendling bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
18019194a91dSDouglas Gregor   bool HadError = false;
18029194a91dSDouglas Gregor 
18039194a91dSDouglas Gregor   while (Tok.is(MMToken::LSquare)) {
18049194a91dSDouglas Gregor     // Consume the '['.
18059194a91dSDouglas Gregor     SourceLocation LSquareLoc = consumeToken();
18069194a91dSDouglas Gregor 
18079194a91dSDouglas Gregor     // Check whether we have an attribute name here.
18089194a91dSDouglas Gregor     if (!Tok.is(MMToken::Identifier)) {
18099194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
18109194a91dSDouglas Gregor       skipUntil(MMToken::RSquare);
18119194a91dSDouglas Gregor       if (Tok.is(MMToken::RSquare))
18129194a91dSDouglas Gregor         consumeToken();
18139194a91dSDouglas Gregor       HadError = true;
18149194a91dSDouglas Gregor     }
18159194a91dSDouglas Gregor 
18169194a91dSDouglas Gregor     // Decode the attribute name.
18179194a91dSDouglas Gregor     AttributeKind Attribute
18189194a91dSDouglas Gregor       = llvm::StringSwitch<AttributeKind>(Tok.getString())
181935b13eceSDouglas Gregor           .Case("exhaustive", AT_exhaustive)
18209194a91dSDouglas Gregor           .Case("system", AT_system)
18219194a91dSDouglas Gregor           .Default(AT_unknown);
18229194a91dSDouglas Gregor     switch (Attribute) {
18239194a91dSDouglas Gregor     case AT_unknown:
18249194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
18259194a91dSDouglas Gregor         << Tok.getString();
18269194a91dSDouglas Gregor       break;
18279194a91dSDouglas Gregor 
18289194a91dSDouglas Gregor     case AT_system:
18299194a91dSDouglas Gregor       Attrs.IsSystem = true;
18309194a91dSDouglas Gregor       break;
183135b13eceSDouglas Gregor 
183235b13eceSDouglas Gregor     case AT_exhaustive:
183335b13eceSDouglas Gregor       Attrs.IsExhaustive = true;
183435b13eceSDouglas Gregor       break;
18359194a91dSDouglas Gregor     }
18369194a91dSDouglas Gregor     consumeToken();
18379194a91dSDouglas Gregor 
18389194a91dSDouglas Gregor     // Consume the ']'.
18399194a91dSDouglas Gregor     if (!Tok.is(MMToken::RSquare)) {
18409194a91dSDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
18419194a91dSDouglas Gregor       Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
18429194a91dSDouglas Gregor       skipUntil(MMToken::RSquare);
18439194a91dSDouglas Gregor       HadError = true;
18449194a91dSDouglas Gregor     }
18459194a91dSDouglas Gregor 
18469194a91dSDouglas Gregor     if (Tok.is(MMToken::RSquare))
18479194a91dSDouglas Gregor       consumeToken();
18489194a91dSDouglas Gregor   }
18499194a91dSDouglas Gregor 
18509194a91dSDouglas Gregor   return HadError;
18519194a91dSDouglas Gregor }
18529194a91dSDouglas Gregor 
18537033127bSDouglas Gregor /// \brief If there is a specific header search directory due the presence
18547033127bSDouglas Gregor /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
18557033127bSDouglas Gregor const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
18567033127bSDouglas Gregor   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
18577033127bSDouglas Gregor     // If we have an umbrella directory, use that.
18587033127bSDouglas Gregor     if (Mod->hasUmbrellaDir())
18597033127bSDouglas Gregor       return Mod->getUmbrellaDir();
18607033127bSDouglas Gregor 
18617033127bSDouglas Gregor     // If we have a framework directory, stop looking.
18627033127bSDouglas Gregor     if (Mod->IsFramework)
18637033127bSDouglas Gregor       return 0;
18647033127bSDouglas Gregor   }
18657033127bSDouglas Gregor 
18667033127bSDouglas Gregor   return 0;
18677033127bSDouglas Gregor }
18687033127bSDouglas Gregor 
1869718292f2SDouglas Gregor /// \brief Parse a module map file.
1870718292f2SDouglas Gregor ///
1871718292f2SDouglas Gregor ///   module-map-file:
1872718292f2SDouglas Gregor ///     module-declaration*
1873718292f2SDouglas Gregor bool ModuleMapParser::parseModuleMapFile() {
1874718292f2SDouglas Gregor   do {
1875718292f2SDouglas Gregor     switch (Tok.Kind) {
1876718292f2SDouglas Gregor     case MMToken::EndOfFile:
1877718292f2SDouglas Gregor       return HadError;
1878718292f2SDouglas Gregor 
1879e7ab3669SDouglas Gregor     case MMToken::ExplicitKeyword:
1880718292f2SDouglas Gregor     case MMToken::ModuleKeyword:
1881755b2055SDouglas Gregor     case MMToken::FrameworkKeyword:
1882718292f2SDouglas Gregor       parseModuleDecl();
1883718292f2SDouglas Gregor       break;
1884718292f2SDouglas Gregor 
18851fb5c3a6SDouglas Gregor     case MMToken::Comma:
188635b13eceSDouglas Gregor     case MMToken::ConfigMacros:
1887*fb912657SDouglas Gregor     case MMToken::Conflict:
188859527666SDouglas Gregor     case MMToken::ExcludeKeyword:
18892b82c2a5SDouglas Gregor     case MMToken::ExportKeyword:
1890718292f2SDouglas Gregor     case MMToken::HeaderKeyword:
1891718292f2SDouglas Gregor     case MMToken::Identifier:
1892718292f2SDouglas Gregor     case MMToken::LBrace:
18936ddfca91SDouglas Gregor     case MMToken::LinkKeyword:
1894a686e1b0SDouglas Gregor     case MMToken::LSquare:
18952b82c2a5SDouglas Gregor     case MMToken::Period:
1896718292f2SDouglas Gregor     case MMToken::RBrace:
1897a686e1b0SDouglas Gregor     case MMToken::RSquare:
18981fb5c3a6SDouglas Gregor     case MMToken::RequiresKeyword:
18992b82c2a5SDouglas Gregor     case MMToken::Star:
1900718292f2SDouglas Gregor     case MMToken::StringLiteral:
1901718292f2SDouglas Gregor     case MMToken::UmbrellaKeyword:
1902718292f2SDouglas Gregor       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1903718292f2SDouglas Gregor       HadError = true;
1904718292f2SDouglas Gregor       consumeToken();
1905718292f2SDouglas Gregor       break;
1906718292f2SDouglas Gregor     }
1907718292f2SDouglas Gregor   } while (true);
1908718292f2SDouglas Gregor }
1909718292f2SDouglas Gregor 
1910718292f2SDouglas Gregor bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
19114ddf2221SDouglas Gregor   llvm::DenseMap<const FileEntry *, bool>::iterator Known
19124ddf2221SDouglas Gregor     = ParsedModuleMap.find(File);
19134ddf2221SDouglas Gregor   if (Known != ParsedModuleMap.end())
19144ddf2221SDouglas Gregor     return Known->second;
19154ddf2221SDouglas Gregor 
191689929282SDouglas Gregor   assert(Target != 0 && "Missing target information");
1917718292f2SDouglas Gregor   FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1918718292f2SDouglas Gregor   const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1919718292f2SDouglas Gregor   if (!Buffer)
19204ddf2221SDouglas Gregor     return ParsedModuleMap[File] = true;
1921718292f2SDouglas Gregor 
1922718292f2SDouglas Gregor   // Parse this module map file.
19231fb5c3a6SDouglas Gregor   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
19241fb5c3a6SDouglas Gregor   Diags->getClient()->BeginSourceFile(MMapLangOpts);
1925bc10b9fbSDouglas Gregor   ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
19263ec6663bSDouglas Gregor                          BuiltinIncludeDir);
1927718292f2SDouglas Gregor   bool Result = Parser.parseModuleMapFile();
1928718292f2SDouglas Gregor   Diags->getClient()->EndSourceFile();
19294ddf2221SDouglas Gregor   ParsedModuleMap[File] = Result;
1930718292f2SDouglas Gregor   return Result;
1931718292f2SDouglas Gregor }
1932