xref: /minix3/external/bsd/llvm/dist/clang/lib/Lex/ModuleMap.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc //===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
2*f4a2713aSLionel Sambuc //
3*f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4*f4a2713aSLionel Sambuc //
5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7*f4a2713aSLionel Sambuc //
8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9*f4a2713aSLionel Sambuc //
10*f4a2713aSLionel Sambuc // This file defines the ModuleMap implementation, which describes the layout
11*f4a2713aSLionel Sambuc // of a module as it relates to headers.
12*f4a2713aSLionel Sambuc //
13*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14*f4a2713aSLionel Sambuc #include "clang/Lex/ModuleMap.h"
15*f4a2713aSLionel Sambuc #include "clang/Basic/CharInfo.h"
16*f4a2713aSLionel Sambuc #include "clang/Basic/Diagnostic.h"
17*f4a2713aSLionel Sambuc #include "clang/Basic/DiagnosticOptions.h"
18*f4a2713aSLionel Sambuc #include "clang/Basic/FileManager.h"
19*f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h"
20*f4a2713aSLionel Sambuc #include "clang/Basic/TargetOptions.h"
21*f4a2713aSLionel Sambuc #include "clang/Lex/HeaderSearch.h"
22*f4a2713aSLionel Sambuc #include "clang/Lex/LexDiagnostic.h"
23*f4a2713aSLionel Sambuc #include "clang/Lex/Lexer.h"
24*f4a2713aSLionel Sambuc #include "clang/Lex/LiteralSupport.h"
25*f4a2713aSLionel Sambuc #include "llvm/ADT/StringRef.h"
26*f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h"
27*f4a2713aSLionel Sambuc #include "llvm/Support/Allocator.h"
28*f4a2713aSLionel Sambuc #include "llvm/Support/FileSystem.h"
29*f4a2713aSLionel Sambuc #include "llvm/Support/Host.h"
30*f4a2713aSLionel Sambuc #include "llvm/Support/Path.h"
31*f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
32*f4a2713aSLionel Sambuc #include <stdlib.h>
33*f4a2713aSLionel Sambuc #if defined(LLVM_ON_UNIX)
34*f4a2713aSLionel Sambuc #include <limits.h>
35*f4a2713aSLionel Sambuc #endif
36*f4a2713aSLionel Sambuc using namespace clang;
37*f4a2713aSLionel Sambuc 
38*f4a2713aSLionel Sambuc Module::ExportDecl
39*f4a2713aSLionel Sambuc ModuleMap::resolveExport(Module *Mod,
40*f4a2713aSLionel Sambuc                          const Module::UnresolvedExportDecl &Unresolved,
41*f4a2713aSLionel Sambuc                          bool Complain) const {
42*f4a2713aSLionel Sambuc   // We may have just a wildcard.
43*f4a2713aSLionel Sambuc   if (Unresolved.Id.empty()) {
44*f4a2713aSLionel Sambuc     assert(Unresolved.Wildcard && "Invalid unresolved export");
45*f4a2713aSLionel Sambuc     return Module::ExportDecl(0, true);
46*f4a2713aSLionel Sambuc   }
47*f4a2713aSLionel Sambuc 
48*f4a2713aSLionel Sambuc   // Resolve the module-id.
49*f4a2713aSLionel Sambuc   Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
50*f4a2713aSLionel Sambuc   if (!Context)
51*f4a2713aSLionel Sambuc     return Module::ExportDecl();
52*f4a2713aSLionel Sambuc 
53*f4a2713aSLionel Sambuc   return Module::ExportDecl(Context, Unresolved.Wildcard);
54*f4a2713aSLionel Sambuc }
55*f4a2713aSLionel Sambuc 
56*f4a2713aSLionel Sambuc Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
57*f4a2713aSLionel Sambuc                                    bool Complain) const {
58*f4a2713aSLionel Sambuc   // Find the starting module.
59*f4a2713aSLionel Sambuc   Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
60*f4a2713aSLionel Sambuc   if (!Context) {
61*f4a2713aSLionel Sambuc     if (Complain)
62*f4a2713aSLionel Sambuc       Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
63*f4a2713aSLionel Sambuc       << Id[0].first << Mod->getFullModuleName();
64*f4a2713aSLionel Sambuc 
65*f4a2713aSLionel Sambuc     return 0;
66*f4a2713aSLionel Sambuc   }
67*f4a2713aSLionel Sambuc 
68*f4a2713aSLionel Sambuc   // Dig into the module path.
69*f4a2713aSLionel Sambuc   for (unsigned I = 1, N = Id.size(); I != N; ++I) {
70*f4a2713aSLionel Sambuc     Module *Sub = lookupModuleQualified(Id[I].first, Context);
71*f4a2713aSLionel Sambuc     if (!Sub) {
72*f4a2713aSLionel Sambuc       if (Complain)
73*f4a2713aSLionel Sambuc         Diags->Report(Id[I].second, diag::err_mmap_missing_module_qualified)
74*f4a2713aSLionel Sambuc         << Id[I].first << Context->getFullModuleName()
75*f4a2713aSLionel Sambuc         << SourceRange(Id[0].second, Id[I-1].second);
76*f4a2713aSLionel Sambuc 
77*f4a2713aSLionel Sambuc       return 0;
78*f4a2713aSLionel Sambuc     }
79*f4a2713aSLionel Sambuc 
80*f4a2713aSLionel Sambuc     Context = Sub;
81*f4a2713aSLionel Sambuc   }
82*f4a2713aSLionel Sambuc 
83*f4a2713aSLionel Sambuc   return Context;
84*f4a2713aSLionel Sambuc }
85*f4a2713aSLionel Sambuc 
86*f4a2713aSLionel Sambuc ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticConsumer &DC,
87*f4a2713aSLionel Sambuc                      const LangOptions &LangOpts, const TargetInfo *Target,
88*f4a2713aSLionel Sambuc                      HeaderSearch &HeaderInfo)
89*f4a2713aSLionel Sambuc     : SourceMgr(SourceMgr), LangOpts(LangOpts), Target(Target),
90*f4a2713aSLionel Sambuc       HeaderInfo(HeaderInfo), BuiltinIncludeDir(0), CompilingModule(0),
91*f4a2713aSLionel Sambuc       SourceModule(0) {
92*f4a2713aSLionel Sambuc   IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
93*f4a2713aSLionel Sambuc   Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
94*f4a2713aSLionel Sambuc             new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
95*f4a2713aSLionel Sambuc   Diags->setClient(new ForwardingDiagnosticConsumer(DC),
96*f4a2713aSLionel Sambuc                    /*ShouldOwnClient=*/true);
97*f4a2713aSLionel Sambuc   Diags->setSourceManager(&SourceMgr);
98*f4a2713aSLionel Sambuc }
99*f4a2713aSLionel Sambuc 
100*f4a2713aSLionel Sambuc ModuleMap::~ModuleMap() {
101*f4a2713aSLionel Sambuc   for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
102*f4a2713aSLionel Sambuc                                         IEnd = Modules.end();
103*f4a2713aSLionel Sambuc        I != IEnd; ++I) {
104*f4a2713aSLionel Sambuc     delete I->getValue();
105*f4a2713aSLionel Sambuc   }
106*f4a2713aSLionel Sambuc }
107*f4a2713aSLionel Sambuc 
108*f4a2713aSLionel Sambuc void ModuleMap::setTarget(const TargetInfo &Target) {
109*f4a2713aSLionel Sambuc   assert((!this->Target || this->Target == &Target) &&
110*f4a2713aSLionel Sambuc          "Improper target override");
111*f4a2713aSLionel Sambuc   this->Target = &Target;
112*f4a2713aSLionel Sambuc }
113*f4a2713aSLionel Sambuc 
114*f4a2713aSLionel Sambuc /// \brief "Sanitize" a filename so that it can be used as an identifier.
115*f4a2713aSLionel Sambuc static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
116*f4a2713aSLionel Sambuc                                               SmallVectorImpl<char> &Buffer) {
117*f4a2713aSLionel Sambuc   if (Name.empty())
118*f4a2713aSLionel Sambuc     return Name;
119*f4a2713aSLionel Sambuc 
120*f4a2713aSLionel Sambuc   if (!isValidIdentifier(Name)) {
121*f4a2713aSLionel Sambuc     // If we don't already have something with the form of an identifier,
122*f4a2713aSLionel Sambuc     // create a buffer with the sanitized name.
123*f4a2713aSLionel Sambuc     Buffer.clear();
124*f4a2713aSLionel Sambuc     if (isDigit(Name[0]))
125*f4a2713aSLionel Sambuc       Buffer.push_back('_');
126*f4a2713aSLionel Sambuc     Buffer.reserve(Buffer.size() + Name.size());
127*f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Name.size(); I != N; ++I) {
128*f4a2713aSLionel Sambuc       if (isIdentifierBody(Name[I]))
129*f4a2713aSLionel Sambuc         Buffer.push_back(Name[I]);
130*f4a2713aSLionel Sambuc       else
131*f4a2713aSLionel Sambuc         Buffer.push_back('_');
132*f4a2713aSLionel Sambuc     }
133*f4a2713aSLionel Sambuc 
134*f4a2713aSLionel Sambuc     Name = StringRef(Buffer.data(), Buffer.size());
135*f4a2713aSLionel Sambuc   }
136*f4a2713aSLionel Sambuc 
137*f4a2713aSLionel Sambuc   while (llvm::StringSwitch<bool>(Name)
138*f4a2713aSLionel Sambuc #define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
139*f4a2713aSLionel Sambuc #define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
140*f4a2713aSLionel Sambuc #include "clang/Basic/TokenKinds.def"
141*f4a2713aSLionel Sambuc            .Default(false)) {
142*f4a2713aSLionel Sambuc     if (Name.data() != Buffer.data())
143*f4a2713aSLionel Sambuc       Buffer.append(Name.begin(), Name.end());
144*f4a2713aSLionel Sambuc     Buffer.push_back('_');
145*f4a2713aSLionel Sambuc     Name = StringRef(Buffer.data(), Buffer.size());
146*f4a2713aSLionel Sambuc   }
147*f4a2713aSLionel Sambuc 
148*f4a2713aSLionel Sambuc   return Name;
149*f4a2713aSLionel Sambuc }
150*f4a2713aSLionel Sambuc 
151*f4a2713aSLionel Sambuc /// \brief Determine whether the given file name is the name of a builtin
152*f4a2713aSLionel Sambuc /// header, supplied by Clang to replace, override, or augment existing system
153*f4a2713aSLionel Sambuc /// headers.
154*f4a2713aSLionel Sambuc static bool isBuiltinHeader(StringRef FileName) {
155*f4a2713aSLionel Sambuc   return llvm::StringSwitch<bool>(FileName)
156*f4a2713aSLionel Sambuc            .Case("float.h", true)
157*f4a2713aSLionel Sambuc            .Case("iso646.h", true)
158*f4a2713aSLionel Sambuc            .Case("limits.h", true)
159*f4a2713aSLionel Sambuc            .Case("stdalign.h", true)
160*f4a2713aSLionel Sambuc            .Case("stdarg.h", true)
161*f4a2713aSLionel Sambuc            .Case("stdbool.h", true)
162*f4a2713aSLionel Sambuc            .Case("stddef.h", true)
163*f4a2713aSLionel Sambuc            .Case("stdint.h", true)
164*f4a2713aSLionel Sambuc            .Case("tgmath.h", true)
165*f4a2713aSLionel Sambuc            .Case("unwind.h", true)
166*f4a2713aSLionel Sambuc            .Default(false);
167*f4a2713aSLionel Sambuc }
168*f4a2713aSLionel Sambuc 
169*f4a2713aSLionel Sambuc ModuleMap::KnownHeader
170*f4a2713aSLionel Sambuc ModuleMap::findModuleForHeader(const FileEntry *File,
171*f4a2713aSLionel Sambuc                                Module *RequestingModule) {
172*f4a2713aSLionel Sambuc   HeadersMap::iterator Known = Headers.find(File);
173*f4a2713aSLionel Sambuc   if (Known != Headers.end()) {
174*f4a2713aSLionel Sambuc     ModuleMap::KnownHeader Result = KnownHeader();
175*f4a2713aSLionel Sambuc 
176*f4a2713aSLionel Sambuc     // Iterate over all modules that 'File' is part of to find the best fit.
177*f4a2713aSLionel Sambuc     for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
178*f4a2713aSLionel Sambuc                                                 E = Known->second.end();
179*f4a2713aSLionel Sambuc          I != E; ++I) {
180*f4a2713aSLionel Sambuc       // Cannot use a module if the header is excluded or unavailable in it.
181*f4a2713aSLionel Sambuc       if (I->getRole() == ModuleMap::ExcludedHeader ||
182*f4a2713aSLionel Sambuc           !I->getModule()->isAvailable())
183*f4a2713aSLionel Sambuc         continue;
184*f4a2713aSLionel Sambuc 
185*f4a2713aSLionel Sambuc       // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
186*f4a2713aSLionel Sambuc       // module we are looking for.
187*f4a2713aSLionel Sambuc       if (I->getModule() == RequestingModule)
188*f4a2713aSLionel Sambuc         return *I;
189*f4a2713aSLionel Sambuc 
190*f4a2713aSLionel Sambuc       // If uses need to be specified explicitly, we are only allowed to return
191*f4a2713aSLionel Sambuc       // modules that are explicitly used by the requesting module.
192*f4a2713aSLionel Sambuc       if (RequestingModule && LangOpts.ModulesDeclUse &&
193*f4a2713aSLionel Sambuc           std::find(RequestingModule->DirectUses.begin(),
194*f4a2713aSLionel Sambuc                     RequestingModule->DirectUses.end(),
195*f4a2713aSLionel Sambuc                     I->getModule()) == RequestingModule->DirectUses.end())
196*f4a2713aSLionel Sambuc         continue;
197*f4a2713aSLionel Sambuc       Result = *I;
198*f4a2713aSLionel Sambuc       // If 'File' is a public header of this module, this is as good as we
199*f4a2713aSLionel Sambuc       // are going to get.
200*f4a2713aSLionel Sambuc       if (I->getRole() == ModuleMap::NormalHeader)
201*f4a2713aSLionel Sambuc         break;
202*f4a2713aSLionel Sambuc     }
203*f4a2713aSLionel Sambuc     return Result;
204*f4a2713aSLionel Sambuc   }
205*f4a2713aSLionel Sambuc 
206*f4a2713aSLionel Sambuc   // If we've found a builtin header within Clang's builtin include directory,
207*f4a2713aSLionel Sambuc   // load all of the module maps to see if it will get associated with a
208*f4a2713aSLionel Sambuc   // specific module (e.g., in /usr/include).
209*f4a2713aSLionel Sambuc   if (File->getDir() == BuiltinIncludeDir &&
210*f4a2713aSLionel Sambuc       isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
211*f4a2713aSLionel Sambuc     HeaderInfo.loadTopLevelSystemModules();
212*f4a2713aSLionel Sambuc 
213*f4a2713aSLionel Sambuc     // Check again.
214*f4a2713aSLionel Sambuc     if (Headers.find(File) != Headers.end())
215*f4a2713aSLionel Sambuc       return findModuleForHeader(File, RequestingModule);
216*f4a2713aSLionel Sambuc   }
217*f4a2713aSLionel Sambuc 
218*f4a2713aSLionel Sambuc   const DirectoryEntry *Dir = File->getDir();
219*f4a2713aSLionel Sambuc   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
220*f4a2713aSLionel Sambuc 
221*f4a2713aSLionel Sambuc   // Note: as an egregious but useful hack we use the real path here, because
222*f4a2713aSLionel Sambuc   // frameworks moving from top-level frameworks to embedded frameworks tend
223*f4a2713aSLionel Sambuc   // to be symlinked from the top-level location to the embedded location,
224*f4a2713aSLionel Sambuc   // and we need to resolve lookups as if we had found the embedded location.
225*f4a2713aSLionel Sambuc   StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
226*f4a2713aSLionel Sambuc 
227*f4a2713aSLionel Sambuc   // Keep walking up the directory hierarchy, looking for a directory with
228*f4a2713aSLionel Sambuc   // an umbrella header.
229*f4a2713aSLionel Sambuc   do {
230*f4a2713aSLionel Sambuc     llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
231*f4a2713aSLionel Sambuc       = UmbrellaDirs.find(Dir);
232*f4a2713aSLionel Sambuc     if (KnownDir != UmbrellaDirs.end()) {
233*f4a2713aSLionel Sambuc       Module *Result = KnownDir->second;
234*f4a2713aSLionel Sambuc 
235*f4a2713aSLionel Sambuc       // Search up the module stack until we find a module with an umbrella
236*f4a2713aSLionel Sambuc       // directory.
237*f4a2713aSLionel Sambuc       Module *UmbrellaModule = Result;
238*f4a2713aSLionel Sambuc       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
239*f4a2713aSLionel Sambuc         UmbrellaModule = UmbrellaModule->Parent;
240*f4a2713aSLionel Sambuc 
241*f4a2713aSLionel Sambuc       if (UmbrellaModule->InferSubmodules) {
242*f4a2713aSLionel Sambuc         // Infer submodules for each of the directories we found between
243*f4a2713aSLionel Sambuc         // the directory of the umbrella header and the directory where
244*f4a2713aSLionel Sambuc         // the actual header is located.
245*f4a2713aSLionel Sambuc         bool Explicit = UmbrellaModule->InferExplicitSubmodules;
246*f4a2713aSLionel Sambuc 
247*f4a2713aSLionel Sambuc         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
248*f4a2713aSLionel Sambuc           // Find or create the module that corresponds to this directory name.
249*f4a2713aSLionel Sambuc           SmallString<32> NameBuf;
250*f4a2713aSLionel Sambuc           StringRef Name = sanitizeFilenameAsIdentifier(
251*f4a2713aSLionel Sambuc                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
252*f4a2713aSLionel Sambuc                              NameBuf);
253*f4a2713aSLionel Sambuc           Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
254*f4a2713aSLionel Sambuc                                       Explicit).first;
255*f4a2713aSLionel Sambuc 
256*f4a2713aSLionel Sambuc           // Associate the module and the directory.
257*f4a2713aSLionel Sambuc           UmbrellaDirs[SkippedDirs[I-1]] = Result;
258*f4a2713aSLionel Sambuc 
259*f4a2713aSLionel Sambuc           // If inferred submodules export everything they import, add a
260*f4a2713aSLionel Sambuc           // wildcard to the set of exports.
261*f4a2713aSLionel Sambuc           if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
262*f4a2713aSLionel Sambuc             Result->Exports.push_back(Module::ExportDecl(0, true));
263*f4a2713aSLionel Sambuc         }
264*f4a2713aSLionel Sambuc 
265*f4a2713aSLionel Sambuc         // Infer a submodule with the same name as this header file.
266*f4a2713aSLionel Sambuc         SmallString<32> NameBuf;
267*f4a2713aSLionel Sambuc         StringRef Name = sanitizeFilenameAsIdentifier(
268*f4a2713aSLionel Sambuc                            llvm::sys::path::stem(File->getName()), NameBuf);
269*f4a2713aSLionel Sambuc         Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
270*f4a2713aSLionel Sambuc                                     Explicit).first;
271*f4a2713aSLionel Sambuc         Result->addTopHeader(File);
272*f4a2713aSLionel Sambuc 
273*f4a2713aSLionel Sambuc         // If inferred submodules export everything they import, add a
274*f4a2713aSLionel Sambuc         // wildcard to the set of exports.
275*f4a2713aSLionel Sambuc         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
276*f4a2713aSLionel Sambuc           Result->Exports.push_back(Module::ExportDecl(0, true));
277*f4a2713aSLionel Sambuc       } else {
278*f4a2713aSLionel Sambuc         // Record each of the directories we stepped through as being part of
279*f4a2713aSLionel Sambuc         // the module we found, since the umbrella header covers them all.
280*f4a2713aSLionel Sambuc         for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
281*f4a2713aSLionel Sambuc           UmbrellaDirs[SkippedDirs[I]] = Result;
282*f4a2713aSLionel Sambuc       }
283*f4a2713aSLionel Sambuc 
284*f4a2713aSLionel Sambuc       Headers[File].push_back(KnownHeader(Result, NormalHeader));
285*f4a2713aSLionel Sambuc 
286*f4a2713aSLionel Sambuc       // If a header corresponds to an unavailable module, don't report
287*f4a2713aSLionel Sambuc       // that it maps to anything.
288*f4a2713aSLionel Sambuc       if (!Result->isAvailable())
289*f4a2713aSLionel Sambuc         return KnownHeader();
290*f4a2713aSLionel Sambuc 
291*f4a2713aSLionel Sambuc       return Headers[File].back();
292*f4a2713aSLionel Sambuc     }
293*f4a2713aSLionel Sambuc 
294*f4a2713aSLionel Sambuc     SkippedDirs.push_back(Dir);
295*f4a2713aSLionel Sambuc 
296*f4a2713aSLionel Sambuc     // Retrieve our parent path.
297*f4a2713aSLionel Sambuc     DirName = llvm::sys::path::parent_path(DirName);
298*f4a2713aSLionel Sambuc     if (DirName.empty())
299*f4a2713aSLionel Sambuc       break;
300*f4a2713aSLionel Sambuc 
301*f4a2713aSLionel Sambuc     // Resolve the parent path to a directory entry.
302*f4a2713aSLionel Sambuc     Dir = SourceMgr.getFileManager().getDirectory(DirName);
303*f4a2713aSLionel Sambuc   } while (Dir);
304*f4a2713aSLionel Sambuc 
305*f4a2713aSLionel Sambuc   return KnownHeader();
306*f4a2713aSLionel Sambuc }
307*f4a2713aSLionel Sambuc 
308*f4a2713aSLionel Sambuc bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
309*f4a2713aSLionel Sambuc   HeadersMap::const_iterator Known = Headers.find(Header);
310*f4a2713aSLionel Sambuc   if (Known != Headers.end()) {
311*f4a2713aSLionel Sambuc     for (SmallVectorImpl<KnownHeader>::const_iterator
312*f4a2713aSLionel Sambuc              I = Known->second.begin(),
313*f4a2713aSLionel Sambuc              E = Known->second.end();
314*f4a2713aSLionel Sambuc          I != E; ++I) {
315*f4a2713aSLionel Sambuc       if (I->isAvailable())
316*f4a2713aSLionel Sambuc         return false;
317*f4a2713aSLionel Sambuc     }
318*f4a2713aSLionel Sambuc     return true;
319*f4a2713aSLionel Sambuc   }
320*f4a2713aSLionel Sambuc 
321*f4a2713aSLionel Sambuc   const DirectoryEntry *Dir = Header->getDir();
322*f4a2713aSLionel Sambuc   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
323*f4a2713aSLionel Sambuc   StringRef DirName = Dir->getName();
324*f4a2713aSLionel Sambuc 
325*f4a2713aSLionel Sambuc   // Keep walking up the directory hierarchy, looking for a directory with
326*f4a2713aSLionel Sambuc   // an umbrella header.
327*f4a2713aSLionel Sambuc   do {
328*f4a2713aSLionel Sambuc     llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
329*f4a2713aSLionel Sambuc       = UmbrellaDirs.find(Dir);
330*f4a2713aSLionel Sambuc     if (KnownDir != UmbrellaDirs.end()) {
331*f4a2713aSLionel Sambuc       Module *Found = KnownDir->second;
332*f4a2713aSLionel Sambuc       if (!Found->isAvailable())
333*f4a2713aSLionel Sambuc         return true;
334*f4a2713aSLionel Sambuc 
335*f4a2713aSLionel Sambuc       // Search up the module stack until we find a module with an umbrella
336*f4a2713aSLionel Sambuc       // directory.
337*f4a2713aSLionel Sambuc       Module *UmbrellaModule = Found;
338*f4a2713aSLionel Sambuc       while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
339*f4a2713aSLionel Sambuc         UmbrellaModule = UmbrellaModule->Parent;
340*f4a2713aSLionel Sambuc 
341*f4a2713aSLionel Sambuc       if (UmbrellaModule->InferSubmodules) {
342*f4a2713aSLionel Sambuc         for (unsigned I = SkippedDirs.size(); I != 0; --I) {
343*f4a2713aSLionel Sambuc           // Find or create the module that corresponds to this directory name.
344*f4a2713aSLionel Sambuc           SmallString<32> NameBuf;
345*f4a2713aSLionel Sambuc           StringRef Name = sanitizeFilenameAsIdentifier(
346*f4a2713aSLionel Sambuc                              llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
347*f4a2713aSLionel Sambuc                              NameBuf);
348*f4a2713aSLionel Sambuc           Found = lookupModuleQualified(Name, Found);
349*f4a2713aSLionel Sambuc           if (!Found)
350*f4a2713aSLionel Sambuc             return false;
351*f4a2713aSLionel Sambuc           if (!Found->isAvailable())
352*f4a2713aSLionel Sambuc             return true;
353*f4a2713aSLionel Sambuc         }
354*f4a2713aSLionel Sambuc 
355*f4a2713aSLionel Sambuc         // Infer a submodule with the same name as this header file.
356*f4a2713aSLionel Sambuc         SmallString<32> NameBuf;
357*f4a2713aSLionel Sambuc         StringRef Name = sanitizeFilenameAsIdentifier(
358*f4a2713aSLionel Sambuc                            llvm::sys::path::stem(Header->getName()),
359*f4a2713aSLionel Sambuc                            NameBuf);
360*f4a2713aSLionel Sambuc         Found = lookupModuleQualified(Name, Found);
361*f4a2713aSLionel Sambuc         if (!Found)
362*f4a2713aSLionel Sambuc           return false;
363*f4a2713aSLionel Sambuc       }
364*f4a2713aSLionel Sambuc 
365*f4a2713aSLionel Sambuc       return !Found->isAvailable();
366*f4a2713aSLionel Sambuc     }
367*f4a2713aSLionel Sambuc 
368*f4a2713aSLionel Sambuc     SkippedDirs.push_back(Dir);
369*f4a2713aSLionel Sambuc 
370*f4a2713aSLionel Sambuc     // Retrieve our parent path.
371*f4a2713aSLionel Sambuc     DirName = llvm::sys::path::parent_path(DirName);
372*f4a2713aSLionel Sambuc     if (DirName.empty())
373*f4a2713aSLionel Sambuc       break;
374*f4a2713aSLionel Sambuc 
375*f4a2713aSLionel Sambuc     // Resolve the parent path to a directory entry.
376*f4a2713aSLionel Sambuc     Dir = SourceMgr.getFileManager().getDirectory(DirName);
377*f4a2713aSLionel Sambuc   } while (Dir);
378*f4a2713aSLionel Sambuc 
379*f4a2713aSLionel Sambuc   return false;
380*f4a2713aSLionel Sambuc }
381*f4a2713aSLionel Sambuc 
382*f4a2713aSLionel Sambuc Module *ModuleMap::findModule(StringRef Name) const {
383*f4a2713aSLionel Sambuc   llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
384*f4a2713aSLionel Sambuc   if (Known != Modules.end())
385*f4a2713aSLionel Sambuc     return Known->getValue();
386*f4a2713aSLionel Sambuc 
387*f4a2713aSLionel Sambuc   return 0;
388*f4a2713aSLionel Sambuc }
389*f4a2713aSLionel Sambuc 
390*f4a2713aSLionel Sambuc Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
391*f4a2713aSLionel Sambuc                                            Module *Context) const {
392*f4a2713aSLionel Sambuc   for(; Context; Context = Context->Parent) {
393*f4a2713aSLionel Sambuc     if (Module *Sub = lookupModuleQualified(Name, Context))
394*f4a2713aSLionel Sambuc       return Sub;
395*f4a2713aSLionel Sambuc   }
396*f4a2713aSLionel Sambuc 
397*f4a2713aSLionel Sambuc   return findModule(Name);
398*f4a2713aSLionel Sambuc }
399*f4a2713aSLionel Sambuc 
400*f4a2713aSLionel Sambuc Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
401*f4a2713aSLionel Sambuc   if (!Context)
402*f4a2713aSLionel Sambuc     return findModule(Name);
403*f4a2713aSLionel Sambuc 
404*f4a2713aSLionel Sambuc   return Context->findSubmodule(Name);
405*f4a2713aSLionel Sambuc }
406*f4a2713aSLionel Sambuc 
407*f4a2713aSLionel Sambuc std::pair<Module *, bool>
408*f4a2713aSLionel Sambuc ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
409*f4a2713aSLionel Sambuc                               bool IsExplicit) {
410*f4a2713aSLionel Sambuc   // Try to find an existing module with this name.
411*f4a2713aSLionel Sambuc   if (Module *Sub = lookupModuleQualified(Name, Parent))
412*f4a2713aSLionel Sambuc     return std::make_pair(Sub, false);
413*f4a2713aSLionel Sambuc 
414*f4a2713aSLionel Sambuc   // Create a new module with this name.
415*f4a2713aSLionel Sambuc   Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
416*f4a2713aSLionel Sambuc                               IsExplicit);
417*f4a2713aSLionel Sambuc   if (LangOpts.CurrentModule == Name) {
418*f4a2713aSLionel Sambuc     SourceModule = Result;
419*f4a2713aSLionel Sambuc     SourceModuleName = Name;
420*f4a2713aSLionel Sambuc   }
421*f4a2713aSLionel Sambuc   if (!Parent) {
422*f4a2713aSLionel Sambuc     Modules[Name] = Result;
423*f4a2713aSLionel Sambuc     if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
424*f4a2713aSLionel Sambuc         Name == LangOpts.CurrentModule) {
425*f4a2713aSLionel Sambuc       CompilingModule = Result;
426*f4a2713aSLionel Sambuc     }
427*f4a2713aSLionel Sambuc   }
428*f4a2713aSLionel Sambuc   return std::make_pair(Result, true);
429*f4a2713aSLionel Sambuc }
430*f4a2713aSLionel Sambuc 
431*f4a2713aSLionel Sambuc bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
432*f4a2713aSLionel Sambuc                                         StringRef Name, bool &IsSystem) const {
433*f4a2713aSLionel Sambuc   // Check whether we have already looked into the parent directory
434*f4a2713aSLionel Sambuc   // for a module map.
435*f4a2713aSLionel Sambuc   llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
436*f4a2713aSLionel Sambuc     inferred = InferredDirectories.find(ParentDir);
437*f4a2713aSLionel Sambuc   if (inferred == InferredDirectories.end())
438*f4a2713aSLionel Sambuc     return false;
439*f4a2713aSLionel Sambuc 
440*f4a2713aSLionel Sambuc   if (!inferred->second.InferModules)
441*f4a2713aSLionel Sambuc     return false;
442*f4a2713aSLionel Sambuc 
443*f4a2713aSLionel Sambuc   // We're allowed to infer for this directory, but make sure it's okay
444*f4a2713aSLionel Sambuc   // to infer this particular module.
445*f4a2713aSLionel Sambuc   bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
446*f4a2713aSLionel Sambuc                             inferred->second.ExcludedModules.end(),
447*f4a2713aSLionel Sambuc                             Name) == inferred->second.ExcludedModules.end();
448*f4a2713aSLionel Sambuc 
449*f4a2713aSLionel Sambuc   if (canInfer && inferred->second.InferSystemModules)
450*f4a2713aSLionel Sambuc     IsSystem = true;
451*f4a2713aSLionel Sambuc 
452*f4a2713aSLionel Sambuc   return canInfer;
453*f4a2713aSLionel Sambuc }
454*f4a2713aSLionel Sambuc 
455*f4a2713aSLionel Sambuc /// \brief For a framework module, infer the framework against which we
456*f4a2713aSLionel Sambuc /// should link.
457*f4a2713aSLionel Sambuc static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
458*f4a2713aSLionel Sambuc                                FileManager &FileMgr) {
459*f4a2713aSLionel Sambuc   assert(Mod->IsFramework && "Can only infer linking for framework modules");
460*f4a2713aSLionel Sambuc   assert(!Mod->isSubFramework() &&
461*f4a2713aSLionel Sambuc          "Can only infer linking for top-level frameworks");
462*f4a2713aSLionel Sambuc 
463*f4a2713aSLionel Sambuc   SmallString<128> LibName;
464*f4a2713aSLionel Sambuc   LibName += FrameworkDir->getName();
465*f4a2713aSLionel Sambuc   llvm::sys::path::append(LibName, Mod->Name);
466*f4a2713aSLionel Sambuc   if (FileMgr.getFile(LibName)) {
467*f4a2713aSLionel Sambuc     Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
468*f4a2713aSLionel Sambuc                                                      /*IsFramework=*/true));
469*f4a2713aSLionel Sambuc   }
470*f4a2713aSLionel Sambuc }
471*f4a2713aSLionel Sambuc 
472*f4a2713aSLionel Sambuc Module *
473*f4a2713aSLionel Sambuc ModuleMap::inferFrameworkModule(StringRef ModuleName,
474*f4a2713aSLionel Sambuc                                 const DirectoryEntry *FrameworkDir,
475*f4a2713aSLionel Sambuc                                 bool IsSystem,
476*f4a2713aSLionel Sambuc                                 Module *Parent) {
477*f4a2713aSLionel Sambuc   // Check whether we've already found this module.
478*f4a2713aSLionel Sambuc   if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
479*f4a2713aSLionel Sambuc     return Mod;
480*f4a2713aSLionel Sambuc 
481*f4a2713aSLionel Sambuc   FileManager &FileMgr = SourceMgr.getFileManager();
482*f4a2713aSLionel Sambuc 
483*f4a2713aSLionel Sambuc   // If the framework has a parent path from which we're allowed to infer
484*f4a2713aSLionel Sambuc   // a framework module, do so.
485*f4a2713aSLionel Sambuc   if (!Parent) {
486*f4a2713aSLionel Sambuc     // Determine whether we're allowed to infer a module map.
487*f4a2713aSLionel Sambuc 
488*f4a2713aSLionel Sambuc     // Note: as an egregious but useful hack we use the real path here, because
489*f4a2713aSLionel Sambuc     // we might be looking at an embedded framework that symlinks out to a
490*f4a2713aSLionel Sambuc     // top-level framework, and we need to infer as if we were naming the
491*f4a2713aSLionel Sambuc     // top-level framework.
492*f4a2713aSLionel Sambuc     StringRef FrameworkDirName
493*f4a2713aSLionel Sambuc       = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
494*f4a2713aSLionel Sambuc 
495*f4a2713aSLionel Sambuc     bool canInfer = false;
496*f4a2713aSLionel Sambuc     if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
497*f4a2713aSLionel Sambuc       // Figure out the parent path.
498*f4a2713aSLionel Sambuc       StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
499*f4a2713aSLionel Sambuc       if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
500*f4a2713aSLionel Sambuc         // Check whether we have already looked into the parent directory
501*f4a2713aSLionel Sambuc         // for a module map.
502*f4a2713aSLionel Sambuc         llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
503*f4a2713aSLionel Sambuc           inferred = InferredDirectories.find(ParentDir);
504*f4a2713aSLionel Sambuc         if (inferred == InferredDirectories.end()) {
505*f4a2713aSLionel Sambuc           // We haven't looked here before. Load a module map, if there is
506*f4a2713aSLionel Sambuc           // one.
507*f4a2713aSLionel Sambuc           SmallString<128> ModMapPath = Parent;
508*f4a2713aSLionel Sambuc           llvm::sys::path::append(ModMapPath, "module.map");
509*f4a2713aSLionel Sambuc           if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
510*f4a2713aSLionel Sambuc             parseModuleMapFile(ModMapFile, IsSystem);
511*f4a2713aSLionel Sambuc             inferred = InferredDirectories.find(ParentDir);
512*f4a2713aSLionel Sambuc           }
513*f4a2713aSLionel Sambuc 
514*f4a2713aSLionel Sambuc           if (inferred == InferredDirectories.end())
515*f4a2713aSLionel Sambuc             inferred = InferredDirectories.insert(
516*f4a2713aSLionel Sambuc                          std::make_pair(ParentDir, InferredDirectory())).first;
517*f4a2713aSLionel Sambuc         }
518*f4a2713aSLionel Sambuc 
519*f4a2713aSLionel Sambuc         if (inferred->second.InferModules) {
520*f4a2713aSLionel Sambuc           // We're allowed to infer for this directory, but make sure it's okay
521*f4a2713aSLionel Sambuc           // to infer this particular module.
522*f4a2713aSLionel Sambuc           StringRef Name = llvm::sys::path::stem(FrameworkDirName);
523*f4a2713aSLionel Sambuc           canInfer = std::find(inferred->second.ExcludedModules.begin(),
524*f4a2713aSLionel Sambuc                                inferred->second.ExcludedModules.end(),
525*f4a2713aSLionel Sambuc                                Name) == inferred->second.ExcludedModules.end();
526*f4a2713aSLionel Sambuc 
527*f4a2713aSLionel Sambuc           if (inferred->second.InferSystemModules)
528*f4a2713aSLionel Sambuc             IsSystem = true;
529*f4a2713aSLionel Sambuc         }
530*f4a2713aSLionel Sambuc       }
531*f4a2713aSLionel Sambuc     }
532*f4a2713aSLionel Sambuc 
533*f4a2713aSLionel Sambuc     // If we're not allowed to infer a framework module, don't.
534*f4a2713aSLionel Sambuc     if (!canInfer)
535*f4a2713aSLionel Sambuc       return 0;
536*f4a2713aSLionel Sambuc   }
537*f4a2713aSLionel Sambuc 
538*f4a2713aSLionel Sambuc 
539*f4a2713aSLionel Sambuc   // Look for an umbrella header.
540*f4a2713aSLionel Sambuc   SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
541*f4a2713aSLionel Sambuc   llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
542*f4a2713aSLionel Sambuc   const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
543*f4a2713aSLionel Sambuc 
544*f4a2713aSLionel Sambuc   // FIXME: If there's no umbrella header, we could probably scan the
545*f4a2713aSLionel Sambuc   // framework to load *everything*. But, it's not clear that this is a good
546*f4a2713aSLionel Sambuc   // idea.
547*f4a2713aSLionel Sambuc   if (!UmbrellaHeader)
548*f4a2713aSLionel Sambuc     return 0;
549*f4a2713aSLionel Sambuc 
550*f4a2713aSLionel Sambuc   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
551*f4a2713aSLionel Sambuc                               /*IsFramework=*/true, /*IsExplicit=*/false);
552*f4a2713aSLionel Sambuc   if (LangOpts.CurrentModule == ModuleName) {
553*f4a2713aSLionel Sambuc     SourceModule = Result;
554*f4a2713aSLionel Sambuc     SourceModuleName = ModuleName;
555*f4a2713aSLionel Sambuc   }
556*f4a2713aSLionel Sambuc   if (IsSystem)
557*f4a2713aSLionel Sambuc     Result->IsSystem = IsSystem;
558*f4a2713aSLionel Sambuc 
559*f4a2713aSLionel Sambuc   if (!Parent)
560*f4a2713aSLionel Sambuc     Modules[ModuleName] = Result;
561*f4a2713aSLionel Sambuc 
562*f4a2713aSLionel Sambuc   // umbrella header "umbrella-header-name"
563*f4a2713aSLionel Sambuc   Result->Umbrella = UmbrellaHeader;
564*f4a2713aSLionel Sambuc   Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
565*f4a2713aSLionel Sambuc   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
566*f4a2713aSLionel Sambuc 
567*f4a2713aSLionel Sambuc   // export *
568*f4a2713aSLionel Sambuc   Result->Exports.push_back(Module::ExportDecl(0, true));
569*f4a2713aSLionel Sambuc 
570*f4a2713aSLionel Sambuc   // module * { export * }
571*f4a2713aSLionel Sambuc   Result->InferSubmodules = true;
572*f4a2713aSLionel Sambuc   Result->InferExportWildcard = true;
573*f4a2713aSLionel Sambuc 
574*f4a2713aSLionel Sambuc   // Look for subframeworks.
575*f4a2713aSLionel Sambuc   llvm::error_code EC;
576*f4a2713aSLionel Sambuc   SmallString<128> SubframeworksDirName
577*f4a2713aSLionel Sambuc     = StringRef(FrameworkDir->getName());
578*f4a2713aSLionel Sambuc   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
579*f4a2713aSLionel Sambuc   llvm::sys::path::native(SubframeworksDirName);
580*f4a2713aSLionel Sambuc   for (llvm::sys::fs::directory_iterator
581*f4a2713aSLionel Sambuc          Dir(SubframeworksDirName.str(), EC), DirEnd;
582*f4a2713aSLionel Sambuc        Dir != DirEnd && !EC; Dir.increment(EC)) {
583*f4a2713aSLionel Sambuc     if (!StringRef(Dir->path()).endswith(".framework"))
584*f4a2713aSLionel Sambuc       continue;
585*f4a2713aSLionel Sambuc 
586*f4a2713aSLionel Sambuc     if (const DirectoryEntry *SubframeworkDir
587*f4a2713aSLionel Sambuc           = FileMgr.getDirectory(Dir->path())) {
588*f4a2713aSLionel Sambuc       // Note: as an egregious but useful hack, we use the real path here and
589*f4a2713aSLionel Sambuc       // check whether it is actually a subdirectory of the parent directory.
590*f4a2713aSLionel Sambuc       // This will not be the case if the 'subframework' is actually a symlink
591*f4a2713aSLionel Sambuc       // out to a top-level framework.
592*f4a2713aSLionel Sambuc       StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
593*f4a2713aSLionel Sambuc       bool FoundParent = false;
594*f4a2713aSLionel Sambuc       do {
595*f4a2713aSLionel Sambuc         // Get the parent directory name.
596*f4a2713aSLionel Sambuc         SubframeworkDirName
597*f4a2713aSLionel Sambuc           = llvm::sys::path::parent_path(SubframeworkDirName);
598*f4a2713aSLionel Sambuc         if (SubframeworkDirName.empty())
599*f4a2713aSLionel Sambuc           break;
600*f4a2713aSLionel Sambuc 
601*f4a2713aSLionel Sambuc         if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
602*f4a2713aSLionel Sambuc           FoundParent = true;
603*f4a2713aSLionel Sambuc           break;
604*f4a2713aSLionel Sambuc         }
605*f4a2713aSLionel Sambuc       } while (true);
606*f4a2713aSLionel Sambuc 
607*f4a2713aSLionel Sambuc       if (!FoundParent)
608*f4a2713aSLionel Sambuc         continue;
609*f4a2713aSLionel Sambuc 
610*f4a2713aSLionel Sambuc       // FIXME: Do we want to warn about subframeworks without umbrella headers?
611*f4a2713aSLionel Sambuc       SmallString<32> NameBuf;
612*f4a2713aSLionel Sambuc       inferFrameworkModule(sanitizeFilenameAsIdentifier(
613*f4a2713aSLionel Sambuc                              llvm::sys::path::stem(Dir->path()), NameBuf),
614*f4a2713aSLionel Sambuc                            SubframeworkDir, IsSystem, Result);
615*f4a2713aSLionel Sambuc     }
616*f4a2713aSLionel Sambuc   }
617*f4a2713aSLionel Sambuc 
618*f4a2713aSLionel Sambuc   // If the module is a top-level framework, automatically link against the
619*f4a2713aSLionel Sambuc   // framework.
620*f4a2713aSLionel Sambuc   if (!Result->isSubFramework()) {
621*f4a2713aSLionel Sambuc     inferFrameworkLink(Result, FrameworkDir, FileMgr);
622*f4a2713aSLionel Sambuc   }
623*f4a2713aSLionel Sambuc 
624*f4a2713aSLionel Sambuc   return Result;
625*f4a2713aSLionel Sambuc }
626*f4a2713aSLionel Sambuc 
627*f4a2713aSLionel Sambuc void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
628*f4a2713aSLionel Sambuc   Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
629*f4a2713aSLionel Sambuc   Mod->Umbrella = UmbrellaHeader;
630*f4a2713aSLionel Sambuc   UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
631*f4a2713aSLionel Sambuc }
632*f4a2713aSLionel Sambuc 
633*f4a2713aSLionel Sambuc void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
634*f4a2713aSLionel Sambuc   Mod->Umbrella = UmbrellaDir;
635*f4a2713aSLionel Sambuc   UmbrellaDirs[UmbrellaDir] = Mod;
636*f4a2713aSLionel Sambuc }
637*f4a2713aSLionel Sambuc 
638*f4a2713aSLionel Sambuc void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
639*f4a2713aSLionel Sambuc                           ModuleHeaderRole Role) {
640*f4a2713aSLionel Sambuc   if (Role == ExcludedHeader) {
641*f4a2713aSLionel Sambuc     Mod->ExcludedHeaders.push_back(Header);
642*f4a2713aSLionel Sambuc   } else {
643*f4a2713aSLionel Sambuc     if (Role == PrivateHeader)
644*f4a2713aSLionel Sambuc       Mod->PrivateHeaders.push_back(Header);
645*f4a2713aSLionel Sambuc     else
646*f4a2713aSLionel Sambuc       Mod->NormalHeaders.push_back(Header);
647*f4a2713aSLionel Sambuc     bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
648*f4a2713aSLionel Sambuc     HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
649*f4a2713aSLionel Sambuc   }
650*f4a2713aSLionel Sambuc   Headers[Header].push_back(KnownHeader(Mod, Role));
651*f4a2713aSLionel Sambuc }
652*f4a2713aSLionel Sambuc 
653*f4a2713aSLionel Sambuc const FileEntry *
654*f4a2713aSLionel Sambuc ModuleMap::getContainingModuleMapFile(Module *Module) const {
655*f4a2713aSLionel Sambuc   if (Module->DefinitionLoc.isInvalid())
656*f4a2713aSLionel Sambuc     return 0;
657*f4a2713aSLionel Sambuc 
658*f4a2713aSLionel Sambuc   return SourceMgr.getFileEntryForID(
659*f4a2713aSLionel Sambuc            SourceMgr.getFileID(Module->DefinitionLoc));
660*f4a2713aSLionel Sambuc }
661*f4a2713aSLionel Sambuc 
662*f4a2713aSLionel Sambuc void ModuleMap::dump() {
663*f4a2713aSLionel Sambuc   llvm::errs() << "Modules:";
664*f4a2713aSLionel Sambuc   for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
665*f4a2713aSLionel Sambuc                                         MEnd = Modules.end();
666*f4a2713aSLionel Sambuc        M != MEnd; ++M)
667*f4a2713aSLionel Sambuc     M->getValue()->print(llvm::errs(), 2);
668*f4a2713aSLionel Sambuc 
669*f4a2713aSLionel Sambuc   llvm::errs() << "Headers:";
670*f4a2713aSLionel Sambuc   for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
671*f4a2713aSLionel Sambuc        H != HEnd; ++H) {
672*f4a2713aSLionel Sambuc     llvm::errs() << "  \"" << H->first->getName() << "\" -> ";
673*f4a2713aSLionel Sambuc     for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
674*f4a2713aSLionel Sambuc                                                       E = H->second.end();
675*f4a2713aSLionel Sambuc          I != E; ++I) {
676*f4a2713aSLionel Sambuc       if (I != H->second.begin())
677*f4a2713aSLionel Sambuc         llvm::errs() << ",";
678*f4a2713aSLionel Sambuc       llvm::errs() << I->getModule()->getFullModuleName();
679*f4a2713aSLionel Sambuc     }
680*f4a2713aSLionel Sambuc     llvm::errs() << "\n";
681*f4a2713aSLionel Sambuc   }
682*f4a2713aSLionel Sambuc }
683*f4a2713aSLionel Sambuc 
684*f4a2713aSLionel Sambuc bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
685*f4a2713aSLionel Sambuc   bool HadError = false;
686*f4a2713aSLionel Sambuc   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
687*f4a2713aSLionel Sambuc     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
688*f4a2713aSLionel Sambuc                                               Complain);
689*f4a2713aSLionel Sambuc     if (Export.getPointer() || Export.getInt())
690*f4a2713aSLionel Sambuc       Mod->Exports.push_back(Export);
691*f4a2713aSLionel Sambuc     else
692*f4a2713aSLionel Sambuc       HadError = true;
693*f4a2713aSLionel Sambuc   }
694*f4a2713aSLionel Sambuc   Mod->UnresolvedExports.clear();
695*f4a2713aSLionel Sambuc   return HadError;
696*f4a2713aSLionel Sambuc }
697*f4a2713aSLionel Sambuc 
698*f4a2713aSLionel Sambuc bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
699*f4a2713aSLionel Sambuc   bool HadError = false;
700*f4a2713aSLionel Sambuc   for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
701*f4a2713aSLionel Sambuc     Module *DirectUse =
702*f4a2713aSLionel Sambuc         resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
703*f4a2713aSLionel Sambuc     if (DirectUse)
704*f4a2713aSLionel Sambuc       Mod->DirectUses.push_back(DirectUse);
705*f4a2713aSLionel Sambuc     else
706*f4a2713aSLionel Sambuc       HadError = true;
707*f4a2713aSLionel Sambuc   }
708*f4a2713aSLionel Sambuc   Mod->UnresolvedDirectUses.clear();
709*f4a2713aSLionel Sambuc   return HadError;
710*f4a2713aSLionel Sambuc }
711*f4a2713aSLionel Sambuc 
712*f4a2713aSLionel Sambuc bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
713*f4a2713aSLionel Sambuc   bool HadError = false;
714*f4a2713aSLionel Sambuc   for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
715*f4a2713aSLionel Sambuc     Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
716*f4a2713aSLionel Sambuc                                        Mod, Complain);
717*f4a2713aSLionel Sambuc     if (!OtherMod) {
718*f4a2713aSLionel Sambuc       HadError = true;
719*f4a2713aSLionel Sambuc       continue;
720*f4a2713aSLionel Sambuc     }
721*f4a2713aSLionel Sambuc 
722*f4a2713aSLionel Sambuc     Module::Conflict Conflict;
723*f4a2713aSLionel Sambuc     Conflict.Other = OtherMod;
724*f4a2713aSLionel Sambuc     Conflict.Message = Mod->UnresolvedConflicts[I].Message;
725*f4a2713aSLionel Sambuc     Mod->Conflicts.push_back(Conflict);
726*f4a2713aSLionel Sambuc   }
727*f4a2713aSLionel Sambuc   Mod->UnresolvedConflicts.clear();
728*f4a2713aSLionel Sambuc   return HadError;
729*f4a2713aSLionel Sambuc }
730*f4a2713aSLionel Sambuc 
731*f4a2713aSLionel Sambuc Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
732*f4a2713aSLionel Sambuc   if (Loc.isInvalid())
733*f4a2713aSLionel Sambuc     return 0;
734*f4a2713aSLionel Sambuc 
735*f4a2713aSLionel Sambuc   // Use the expansion location to determine which module we're in.
736*f4a2713aSLionel Sambuc   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
737*f4a2713aSLionel Sambuc   if (!ExpansionLoc.isFileID())
738*f4a2713aSLionel Sambuc     return 0;
739*f4a2713aSLionel Sambuc 
740*f4a2713aSLionel Sambuc 
741*f4a2713aSLionel Sambuc   const SourceManager &SrcMgr = Loc.getManager();
742*f4a2713aSLionel Sambuc   FileID ExpansionFileID = ExpansionLoc.getFileID();
743*f4a2713aSLionel Sambuc 
744*f4a2713aSLionel Sambuc   while (const FileEntry *ExpansionFile
745*f4a2713aSLionel Sambuc            = SrcMgr.getFileEntryForID(ExpansionFileID)) {
746*f4a2713aSLionel Sambuc     // Find the module that owns this header (if any).
747*f4a2713aSLionel Sambuc     if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
748*f4a2713aSLionel Sambuc       return Mod;
749*f4a2713aSLionel Sambuc 
750*f4a2713aSLionel Sambuc     // No module owns this header, so look up the inclusion chain to see if
751*f4a2713aSLionel Sambuc     // any included header has an associated module.
752*f4a2713aSLionel Sambuc     SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
753*f4a2713aSLionel Sambuc     if (IncludeLoc.isInvalid())
754*f4a2713aSLionel Sambuc       return 0;
755*f4a2713aSLionel Sambuc 
756*f4a2713aSLionel Sambuc     ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
757*f4a2713aSLionel Sambuc   }
758*f4a2713aSLionel Sambuc 
759*f4a2713aSLionel Sambuc   return 0;
760*f4a2713aSLionel Sambuc }
761*f4a2713aSLionel Sambuc 
762*f4a2713aSLionel Sambuc //----------------------------------------------------------------------------//
763*f4a2713aSLionel Sambuc // Module map file parser
764*f4a2713aSLionel Sambuc //----------------------------------------------------------------------------//
765*f4a2713aSLionel Sambuc 
766*f4a2713aSLionel Sambuc namespace clang {
767*f4a2713aSLionel Sambuc   /// \brief A token in a module map file.
768*f4a2713aSLionel Sambuc   struct MMToken {
769*f4a2713aSLionel Sambuc     enum TokenKind {
770*f4a2713aSLionel Sambuc       Comma,
771*f4a2713aSLionel Sambuc       ConfigMacros,
772*f4a2713aSLionel Sambuc       Conflict,
773*f4a2713aSLionel Sambuc       EndOfFile,
774*f4a2713aSLionel Sambuc       HeaderKeyword,
775*f4a2713aSLionel Sambuc       Identifier,
776*f4a2713aSLionel Sambuc       Exclaim,
777*f4a2713aSLionel Sambuc       ExcludeKeyword,
778*f4a2713aSLionel Sambuc       ExplicitKeyword,
779*f4a2713aSLionel Sambuc       ExportKeyword,
780*f4a2713aSLionel Sambuc       ExternKeyword,
781*f4a2713aSLionel Sambuc       FrameworkKeyword,
782*f4a2713aSLionel Sambuc       LinkKeyword,
783*f4a2713aSLionel Sambuc       ModuleKeyword,
784*f4a2713aSLionel Sambuc       Period,
785*f4a2713aSLionel Sambuc       PrivateKeyword,
786*f4a2713aSLionel Sambuc       UmbrellaKeyword,
787*f4a2713aSLionel Sambuc       UseKeyword,
788*f4a2713aSLionel Sambuc       RequiresKeyword,
789*f4a2713aSLionel Sambuc       Star,
790*f4a2713aSLionel Sambuc       StringLiteral,
791*f4a2713aSLionel Sambuc       LBrace,
792*f4a2713aSLionel Sambuc       RBrace,
793*f4a2713aSLionel Sambuc       LSquare,
794*f4a2713aSLionel Sambuc       RSquare
795*f4a2713aSLionel Sambuc     } Kind;
796*f4a2713aSLionel Sambuc 
797*f4a2713aSLionel Sambuc     unsigned Location;
798*f4a2713aSLionel Sambuc     unsigned StringLength;
799*f4a2713aSLionel Sambuc     const char *StringData;
800*f4a2713aSLionel Sambuc 
801*f4a2713aSLionel Sambuc     void clear() {
802*f4a2713aSLionel Sambuc       Kind = EndOfFile;
803*f4a2713aSLionel Sambuc       Location = 0;
804*f4a2713aSLionel Sambuc       StringLength = 0;
805*f4a2713aSLionel Sambuc       StringData = 0;
806*f4a2713aSLionel Sambuc     }
807*f4a2713aSLionel Sambuc 
808*f4a2713aSLionel Sambuc     bool is(TokenKind K) const { return Kind == K; }
809*f4a2713aSLionel Sambuc 
810*f4a2713aSLionel Sambuc     SourceLocation getLocation() const {
811*f4a2713aSLionel Sambuc       return SourceLocation::getFromRawEncoding(Location);
812*f4a2713aSLionel Sambuc     }
813*f4a2713aSLionel Sambuc 
814*f4a2713aSLionel Sambuc     StringRef getString() const {
815*f4a2713aSLionel Sambuc       return StringRef(StringData, StringLength);
816*f4a2713aSLionel Sambuc     }
817*f4a2713aSLionel Sambuc   };
818*f4a2713aSLionel Sambuc 
819*f4a2713aSLionel Sambuc   /// \brief The set of attributes that can be attached to a module.
820*f4a2713aSLionel Sambuc   struct Attributes {
821*f4a2713aSLionel Sambuc     Attributes() : IsSystem(), IsExhaustive() { }
822*f4a2713aSLionel Sambuc 
823*f4a2713aSLionel Sambuc     /// \brief Whether this is a system module.
824*f4a2713aSLionel Sambuc     unsigned IsSystem : 1;
825*f4a2713aSLionel Sambuc 
826*f4a2713aSLionel Sambuc     /// \brief Whether this is an exhaustive set of configuration macros.
827*f4a2713aSLionel Sambuc     unsigned IsExhaustive : 1;
828*f4a2713aSLionel Sambuc   };
829*f4a2713aSLionel Sambuc 
830*f4a2713aSLionel Sambuc 
831*f4a2713aSLionel Sambuc   class ModuleMapParser {
832*f4a2713aSLionel Sambuc     Lexer &L;
833*f4a2713aSLionel Sambuc     SourceManager &SourceMgr;
834*f4a2713aSLionel Sambuc 
835*f4a2713aSLionel Sambuc     /// \brief Default target information, used only for string literal
836*f4a2713aSLionel Sambuc     /// parsing.
837*f4a2713aSLionel Sambuc     const TargetInfo *Target;
838*f4a2713aSLionel Sambuc 
839*f4a2713aSLionel Sambuc     DiagnosticsEngine &Diags;
840*f4a2713aSLionel Sambuc     ModuleMap &Map;
841*f4a2713aSLionel Sambuc 
842*f4a2713aSLionel Sambuc     /// \brief The directory that this module map resides in.
843*f4a2713aSLionel Sambuc     const DirectoryEntry *Directory;
844*f4a2713aSLionel Sambuc 
845*f4a2713aSLionel Sambuc     /// \brief The directory containing Clang-supplied headers.
846*f4a2713aSLionel Sambuc     const DirectoryEntry *BuiltinIncludeDir;
847*f4a2713aSLionel Sambuc 
848*f4a2713aSLionel Sambuc     /// \brief Whether this module map is in a system header directory.
849*f4a2713aSLionel Sambuc     bool IsSystem;
850*f4a2713aSLionel Sambuc 
851*f4a2713aSLionel Sambuc     /// \brief Whether an error occurred.
852*f4a2713aSLionel Sambuc     bool HadError;
853*f4a2713aSLionel Sambuc 
854*f4a2713aSLionel Sambuc     /// \brief Stores string data for the various string literals referenced
855*f4a2713aSLionel Sambuc     /// during parsing.
856*f4a2713aSLionel Sambuc     llvm::BumpPtrAllocator StringData;
857*f4a2713aSLionel Sambuc 
858*f4a2713aSLionel Sambuc     /// \brief The current token.
859*f4a2713aSLionel Sambuc     MMToken Tok;
860*f4a2713aSLionel Sambuc 
861*f4a2713aSLionel Sambuc     /// \brief The active module.
862*f4a2713aSLionel Sambuc     Module *ActiveModule;
863*f4a2713aSLionel Sambuc 
864*f4a2713aSLionel Sambuc     /// \brief Consume the current token and return its location.
865*f4a2713aSLionel Sambuc     SourceLocation consumeToken();
866*f4a2713aSLionel Sambuc 
867*f4a2713aSLionel Sambuc     /// \brief Skip tokens until we reach the a token with the given kind
868*f4a2713aSLionel Sambuc     /// (or the end of the file).
869*f4a2713aSLionel Sambuc     void skipUntil(MMToken::TokenKind K);
870*f4a2713aSLionel Sambuc 
871*f4a2713aSLionel Sambuc     typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
872*f4a2713aSLionel Sambuc     bool parseModuleId(ModuleId &Id);
873*f4a2713aSLionel Sambuc     void parseModuleDecl();
874*f4a2713aSLionel Sambuc     void parseExternModuleDecl();
875*f4a2713aSLionel Sambuc     void parseRequiresDecl();
876*f4a2713aSLionel Sambuc     void parseHeaderDecl(clang::MMToken::TokenKind,
877*f4a2713aSLionel Sambuc                          SourceLocation LeadingLoc);
878*f4a2713aSLionel Sambuc     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
879*f4a2713aSLionel Sambuc     void parseExportDecl();
880*f4a2713aSLionel Sambuc     void parseUseDecl();
881*f4a2713aSLionel Sambuc     void parseLinkDecl();
882*f4a2713aSLionel Sambuc     void parseConfigMacros();
883*f4a2713aSLionel Sambuc     void parseConflict();
884*f4a2713aSLionel Sambuc     void parseInferredModuleDecl(bool Framework, bool Explicit);
885*f4a2713aSLionel Sambuc     bool parseOptionalAttributes(Attributes &Attrs);
886*f4a2713aSLionel Sambuc 
887*f4a2713aSLionel Sambuc     const DirectoryEntry *getOverriddenHeaderSearchDir();
888*f4a2713aSLionel Sambuc 
889*f4a2713aSLionel Sambuc   public:
890*f4a2713aSLionel Sambuc     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
891*f4a2713aSLionel Sambuc                              const TargetInfo *Target,
892*f4a2713aSLionel Sambuc                              DiagnosticsEngine &Diags,
893*f4a2713aSLionel Sambuc                              ModuleMap &Map,
894*f4a2713aSLionel Sambuc                              const DirectoryEntry *Directory,
895*f4a2713aSLionel Sambuc                              const DirectoryEntry *BuiltinIncludeDir,
896*f4a2713aSLionel Sambuc                              bool IsSystem)
897*f4a2713aSLionel Sambuc       : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
898*f4a2713aSLionel Sambuc         Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
899*f4a2713aSLionel Sambuc         IsSystem(IsSystem), HadError(false), ActiveModule(0)
900*f4a2713aSLionel Sambuc     {
901*f4a2713aSLionel Sambuc       Tok.clear();
902*f4a2713aSLionel Sambuc       consumeToken();
903*f4a2713aSLionel Sambuc     }
904*f4a2713aSLionel Sambuc 
905*f4a2713aSLionel Sambuc     bool parseModuleMapFile();
906*f4a2713aSLionel Sambuc   };
907*f4a2713aSLionel Sambuc }
908*f4a2713aSLionel Sambuc 
909*f4a2713aSLionel Sambuc SourceLocation ModuleMapParser::consumeToken() {
910*f4a2713aSLionel Sambuc retry:
911*f4a2713aSLionel Sambuc   SourceLocation Result = Tok.getLocation();
912*f4a2713aSLionel Sambuc   Tok.clear();
913*f4a2713aSLionel Sambuc 
914*f4a2713aSLionel Sambuc   Token LToken;
915*f4a2713aSLionel Sambuc   L.LexFromRawLexer(LToken);
916*f4a2713aSLionel Sambuc   Tok.Location = LToken.getLocation().getRawEncoding();
917*f4a2713aSLionel Sambuc   switch (LToken.getKind()) {
918*f4a2713aSLionel Sambuc   case tok::raw_identifier:
919*f4a2713aSLionel Sambuc     Tok.StringData = LToken.getRawIdentifierData();
920*f4a2713aSLionel Sambuc     Tok.StringLength = LToken.getLength();
921*f4a2713aSLionel Sambuc     Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
922*f4a2713aSLionel Sambuc                  .Case("config_macros", MMToken::ConfigMacros)
923*f4a2713aSLionel Sambuc                  .Case("conflict", MMToken::Conflict)
924*f4a2713aSLionel Sambuc                  .Case("exclude", MMToken::ExcludeKeyword)
925*f4a2713aSLionel Sambuc                  .Case("explicit", MMToken::ExplicitKeyword)
926*f4a2713aSLionel Sambuc                  .Case("export", MMToken::ExportKeyword)
927*f4a2713aSLionel Sambuc                  .Case("extern", MMToken::ExternKeyword)
928*f4a2713aSLionel Sambuc                  .Case("framework", MMToken::FrameworkKeyword)
929*f4a2713aSLionel Sambuc                  .Case("header", MMToken::HeaderKeyword)
930*f4a2713aSLionel Sambuc                  .Case("link", MMToken::LinkKeyword)
931*f4a2713aSLionel Sambuc                  .Case("module", MMToken::ModuleKeyword)
932*f4a2713aSLionel Sambuc                  .Case("private", MMToken::PrivateKeyword)
933*f4a2713aSLionel Sambuc                  .Case("requires", MMToken::RequiresKeyword)
934*f4a2713aSLionel Sambuc                  .Case("umbrella", MMToken::UmbrellaKeyword)
935*f4a2713aSLionel Sambuc                  .Case("use", MMToken::UseKeyword)
936*f4a2713aSLionel Sambuc                  .Default(MMToken::Identifier);
937*f4a2713aSLionel Sambuc     break;
938*f4a2713aSLionel Sambuc 
939*f4a2713aSLionel Sambuc   case tok::comma:
940*f4a2713aSLionel Sambuc     Tok.Kind = MMToken::Comma;
941*f4a2713aSLionel Sambuc     break;
942*f4a2713aSLionel Sambuc 
943*f4a2713aSLionel Sambuc   case tok::eof:
944*f4a2713aSLionel Sambuc     Tok.Kind = MMToken::EndOfFile;
945*f4a2713aSLionel Sambuc     break;
946*f4a2713aSLionel Sambuc 
947*f4a2713aSLionel Sambuc   case tok::l_brace:
948*f4a2713aSLionel Sambuc     Tok.Kind = MMToken::LBrace;
949*f4a2713aSLionel Sambuc     break;
950*f4a2713aSLionel Sambuc 
951*f4a2713aSLionel Sambuc   case tok::l_square:
952*f4a2713aSLionel Sambuc     Tok.Kind = MMToken::LSquare;
953*f4a2713aSLionel Sambuc     break;
954*f4a2713aSLionel Sambuc 
955*f4a2713aSLionel Sambuc   case tok::period:
956*f4a2713aSLionel Sambuc     Tok.Kind = MMToken::Period;
957*f4a2713aSLionel Sambuc     break;
958*f4a2713aSLionel Sambuc 
959*f4a2713aSLionel Sambuc   case tok::r_brace:
960*f4a2713aSLionel Sambuc     Tok.Kind = MMToken::RBrace;
961*f4a2713aSLionel Sambuc     break;
962*f4a2713aSLionel Sambuc 
963*f4a2713aSLionel Sambuc   case tok::r_square:
964*f4a2713aSLionel Sambuc     Tok.Kind = MMToken::RSquare;
965*f4a2713aSLionel Sambuc     break;
966*f4a2713aSLionel Sambuc 
967*f4a2713aSLionel Sambuc   case tok::star:
968*f4a2713aSLionel Sambuc     Tok.Kind = MMToken::Star;
969*f4a2713aSLionel Sambuc     break;
970*f4a2713aSLionel Sambuc 
971*f4a2713aSLionel Sambuc   case tok::exclaim:
972*f4a2713aSLionel Sambuc     Tok.Kind = MMToken::Exclaim;
973*f4a2713aSLionel Sambuc     break;
974*f4a2713aSLionel Sambuc 
975*f4a2713aSLionel Sambuc   case tok::string_literal: {
976*f4a2713aSLionel Sambuc     if (LToken.hasUDSuffix()) {
977*f4a2713aSLionel Sambuc       Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
978*f4a2713aSLionel Sambuc       HadError = true;
979*f4a2713aSLionel Sambuc       goto retry;
980*f4a2713aSLionel Sambuc     }
981*f4a2713aSLionel Sambuc 
982*f4a2713aSLionel Sambuc     // Parse the string literal.
983*f4a2713aSLionel Sambuc     LangOptions LangOpts;
984*f4a2713aSLionel Sambuc     StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
985*f4a2713aSLionel Sambuc     if (StringLiteral.hadError)
986*f4a2713aSLionel Sambuc       goto retry;
987*f4a2713aSLionel Sambuc 
988*f4a2713aSLionel Sambuc     // Copy the string literal into our string data allocator.
989*f4a2713aSLionel Sambuc     unsigned Length = StringLiteral.GetStringLength();
990*f4a2713aSLionel Sambuc     char *Saved = StringData.Allocate<char>(Length + 1);
991*f4a2713aSLionel Sambuc     memcpy(Saved, StringLiteral.GetString().data(), Length);
992*f4a2713aSLionel Sambuc     Saved[Length] = 0;
993*f4a2713aSLionel Sambuc 
994*f4a2713aSLionel Sambuc     // Form the token.
995*f4a2713aSLionel Sambuc     Tok.Kind = MMToken::StringLiteral;
996*f4a2713aSLionel Sambuc     Tok.StringData = Saved;
997*f4a2713aSLionel Sambuc     Tok.StringLength = Length;
998*f4a2713aSLionel Sambuc     break;
999*f4a2713aSLionel Sambuc   }
1000*f4a2713aSLionel Sambuc 
1001*f4a2713aSLionel Sambuc   case tok::comment:
1002*f4a2713aSLionel Sambuc     goto retry;
1003*f4a2713aSLionel Sambuc 
1004*f4a2713aSLionel Sambuc   default:
1005*f4a2713aSLionel Sambuc     Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1006*f4a2713aSLionel Sambuc     HadError = true;
1007*f4a2713aSLionel Sambuc     goto retry;
1008*f4a2713aSLionel Sambuc   }
1009*f4a2713aSLionel Sambuc 
1010*f4a2713aSLionel Sambuc   return Result;
1011*f4a2713aSLionel Sambuc }
1012*f4a2713aSLionel Sambuc 
1013*f4a2713aSLionel Sambuc void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1014*f4a2713aSLionel Sambuc   unsigned braceDepth = 0;
1015*f4a2713aSLionel Sambuc   unsigned squareDepth = 0;
1016*f4a2713aSLionel Sambuc   do {
1017*f4a2713aSLionel Sambuc     switch (Tok.Kind) {
1018*f4a2713aSLionel Sambuc     case MMToken::EndOfFile:
1019*f4a2713aSLionel Sambuc       return;
1020*f4a2713aSLionel Sambuc 
1021*f4a2713aSLionel Sambuc     case MMToken::LBrace:
1022*f4a2713aSLionel Sambuc       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1023*f4a2713aSLionel Sambuc         return;
1024*f4a2713aSLionel Sambuc 
1025*f4a2713aSLionel Sambuc       ++braceDepth;
1026*f4a2713aSLionel Sambuc       break;
1027*f4a2713aSLionel Sambuc 
1028*f4a2713aSLionel Sambuc     case MMToken::LSquare:
1029*f4a2713aSLionel Sambuc       if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1030*f4a2713aSLionel Sambuc         return;
1031*f4a2713aSLionel Sambuc 
1032*f4a2713aSLionel Sambuc       ++squareDepth;
1033*f4a2713aSLionel Sambuc       break;
1034*f4a2713aSLionel Sambuc 
1035*f4a2713aSLionel Sambuc     case MMToken::RBrace:
1036*f4a2713aSLionel Sambuc       if (braceDepth > 0)
1037*f4a2713aSLionel Sambuc         --braceDepth;
1038*f4a2713aSLionel Sambuc       else if (Tok.is(K))
1039*f4a2713aSLionel Sambuc         return;
1040*f4a2713aSLionel Sambuc       break;
1041*f4a2713aSLionel Sambuc 
1042*f4a2713aSLionel Sambuc     case MMToken::RSquare:
1043*f4a2713aSLionel Sambuc       if (squareDepth > 0)
1044*f4a2713aSLionel Sambuc         --squareDepth;
1045*f4a2713aSLionel Sambuc       else if (Tok.is(K))
1046*f4a2713aSLionel Sambuc         return;
1047*f4a2713aSLionel Sambuc       break;
1048*f4a2713aSLionel Sambuc 
1049*f4a2713aSLionel Sambuc     default:
1050*f4a2713aSLionel Sambuc       if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1051*f4a2713aSLionel Sambuc         return;
1052*f4a2713aSLionel Sambuc       break;
1053*f4a2713aSLionel Sambuc     }
1054*f4a2713aSLionel Sambuc 
1055*f4a2713aSLionel Sambuc    consumeToken();
1056*f4a2713aSLionel Sambuc   } while (true);
1057*f4a2713aSLionel Sambuc }
1058*f4a2713aSLionel Sambuc 
1059*f4a2713aSLionel Sambuc /// \brief Parse a module-id.
1060*f4a2713aSLionel Sambuc ///
1061*f4a2713aSLionel Sambuc ///   module-id:
1062*f4a2713aSLionel Sambuc ///     identifier
1063*f4a2713aSLionel Sambuc ///     identifier '.' module-id
1064*f4a2713aSLionel Sambuc ///
1065*f4a2713aSLionel Sambuc /// \returns true if an error occurred, false otherwise.
1066*f4a2713aSLionel Sambuc bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1067*f4a2713aSLionel Sambuc   Id.clear();
1068*f4a2713aSLionel Sambuc   do {
1069*f4a2713aSLionel Sambuc     if (Tok.is(MMToken::Identifier)) {
1070*f4a2713aSLionel Sambuc       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1071*f4a2713aSLionel Sambuc       consumeToken();
1072*f4a2713aSLionel Sambuc     } else {
1073*f4a2713aSLionel Sambuc       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1074*f4a2713aSLionel Sambuc       return true;
1075*f4a2713aSLionel Sambuc     }
1076*f4a2713aSLionel Sambuc 
1077*f4a2713aSLionel Sambuc     if (!Tok.is(MMToken::Period))
1078*f4a2713aSLionel Sambuc       break;
1079*f4a2713aSLionel Sambuc 
1080*f4a2713aSLionel Sambuc     consumeToken();
1081*f4a2713aSLionel Sambuc   } while (true);
1082*f4a2713aSLionel Sambuc 
1083*f4a2713aSLionel Sambuc   return false;
1084*f4a2713aSLionel Sambuc }
1085*f4a2713aSLionel Sambuc 
1086*f4a2713aSLionel Sambuc namespace {
1087*f4a2713aSLionel Sambuc   /// \brief Enumerates the known attributes.
1088*f4a2713aSLionel Sambuc   enum AttributeKind {
1089*f4a2713aSLionel Sambuc     /// \brief An unknown attribute.
1090*f4a2713aSLionel Sambuc     AT_unknown,
1091*f4a2713aSLionel Sambuc     /// \brief The 'system' attribute.
1092*f4a2713aSLionel Sambuc     AT_system,
1093*f4a2713aSLionel Sambuc     /// \brief The 'exhaustive' attribute.
1094*f4a2713aSLionel Sambuc     AT_exhaustive
1095*f4a2713aSLionel Sambuc   };
1096*f4a2713aSLionel Sambuc }
1097*f4a2713aSLionel Sambuc 
1098*f4a2713aSLionel Sambuc /// \brief Parse a module declaration.
1099*f4a2713aSLionel Sambuc ///
1100*f4a2713aSLionel Sambuc ///   module-declaration:
1101*f4a2713aSLionel Sambuc ///     'extern' 'module' module-id string-literal
1102*f4a2713aSLionel Sambuc ///     'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1103*f4a2713aSLionel Sambuc ///       { module-member* }
1104*f4a2713aSLionel Sambuc ///
1105*f4a2713aSLionel Sambuc ///   module-member:
1106*f4a2713aSLionel Sambuc ///     requires-declaration
1107*f4a2713aSLionel Sambuc ///     header-declaration
1108*f4a2713aSLionel Sambuc ///     submodule-declaration
1109*f4a2713aSLionel Sambuc ///     export-declaration
1110*f4a2713aSLionel Sambuc ///     link-declaration
1111*f4a2713aSLionel Sambuc ///
1112*f4a2713aSLionel Sambuc ///   submodule-declaration:
1113*f4a2713aSLionel Sambuc ///     module-declaration
1114*f4a2713aSLionel Sambuc ///     inferred-submodule-declaration
1115*f4a2713aSLionel Sambuc void ModuleMapParser::parseModuleDecl() {
1116*f4a2713aSLionel Sambuc   assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1117*f4a2713aSLionel Sambuc          Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1118*f4a2713aSLionel Sambuc   if (Tok.is(MMToken::ExternKeyword)) {
1119*f4a2713aSLionel Sambuc     parseExternModuleDecl();
1120*f4a2713aSLionel Sambuc     return;
1121*f4a2713aSLionel Sambuc   }
1122*f4a2713aSLionel Sambuc 
1123*f4a2713aSLionel Sambuc   // Parse 'explicit' or 'framework' keyword, if present.
1124*f4a2713aSLionel Sambuc   SourceLocation ExplicitLoc;
1125*f4a2713aSLionel Sambuc   bool Explicit = false;
1126*f4a2713aSLionel Sambuc   bool Framework = false;
1127*f4a2713aSLionel Sambuc 
1128*f4a2713aSLionel Sambuc   // Parse 'explicit' keyword, if present.
1129*f4a2713aSLionel Sambuc   if (Tok.is(MMToken::ExplicitKeyword)) {
1130*f4a2713aSLionel Sambuc     ExplicitLoc = consumeToken();
1131*f4a2713aSLionel Sambuc     Explicit = true;
1132*f4a2713aSLionel Sambuc   }
1133*f4a2713aSLionel Sambuc 
1134*f4a2713aSLionel Sambuc   // Parse 'framework' keyword, if present.
1135*f4a2713aSLionel Sambuc   if (Tok.is(MMToken::FrameworkKeyword)) {
1136*f4a2713aSLionel Sambuc     consumeToken();
1137*f4a2713aSLionel Sambuc     Framework = true;
1138*f4a2713aSLionel Sambuc   }
1139*f4a2713aSLionel Sambuc 
1140*f4a2713aSLionel Sambuc   // Parse 'module' keyword.
1141*f4a2713aSLionel Sambuc   if (!Tok.is(MMToken::ModuleKeyword)) {
1142*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1143*f4a2713aSLionel Sambuc     consumeToken();
1144*f4a2713aSLionel Sambuc     HadError = true;
1145*f4a2713aSLionel Sambuc     return;
1146*f4a2713aSLionel Sambuc   }
1147*f4a2713aSLionel Sambuc   consumeToken(); // 'module' keyword
1148*f4a2713aSLionel Sambuc 
1149*f4a2713aSLionel Sambuc   // If we have a wildcard for the module name, this is an inferred submodule.
1150*f4a2713aSLionel Sambuc   // Parse it.
1151*f4a2713aSLionel Sambuc   if (Tok.is(MMToken::Star))
1152*f4a2713aSLionel Sambuc     return parseInferredModuleDecl(Framework, Explicit);
1153*f4a2713aSLionel Sambuc 
1154*f4a2713aSLionel Sambuc   // Parse the module name.
1155*f4a2713aSLionel Sambuc   ModuleId Id;
1156*f4a2713aSLionel Sambuc   if (parseModuleId(Id)) {
1157*f4a2713aSLionel Sambuc     HadError = true;
1158*f4a2713aSLionel Sambuc     return;
1159*f4a2713aSLionel Sambuc   }
1160*f4a2713aSLionel Sambuc 
1161*f4a2713aSLionel Sambuc   if (ActiveModule) {
1162*f4a2713aSLionel Sambuc     if (Id.size() > 1) {
1163*f4a2713aSLionel Sambuc       Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1164*f4a2713aSLionel Sambuc         << SourceRange(Id.front().second, Id.back().second);
1165*f4a2713aSLionel Sambuc 
1166*f4a2713aSLionel Sambuc       HadError = true;
1167*f4a2713aSLionel Sambuc       return;
1168*f4a2713aSLionel Sambuc     }
1169*f4a2713aSLionel Sambuc   } else if (Id.size() == 1 && Explicit) {
1170*f4a2713aSLionel Sambuc     // Top-level modules can't be explicit.
1171*f4a2713aSLionel Sambuc     Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1172*f4a2713aSLionel Sambuc     Explicit = false;
1173*f4a2713aSLionel Sambuc     ExplicitLoc = SourceLocation();
1174*f4a2713aSLionel Sambuc     HadError = true;
1175*f4a2713aSLionel Sambuc   }
1176*f4a2713aSLionel Sambuc 
1177*f4a2713aSLionel Sambuc   Module *PreviousActiveModule = ActiveModule;
1178*f4a2713aSLionel Sambuc   if (Id.size() > 1) {
1179*f4a2713aSLionel Sambuc     // This module map defines a submodule. Go find the module of which it
1180*f4a2713aSLionel Sambuc     // is a submodule.
1181*f4a2713aSLionel Sambuc     ActiveModule = 0;
1182*f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1183*f4a2713aSLionel Sambuc       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1184*f4a2713aSLionel Sambuc         ActiveModule = Next;
1185*f4a2713aSLionel Sambuc         continue;
1186*f4a2713aSLionel Sambuc       }
1187*f4a2713aSLionel Sambuc 
1188*f4a2713aSLionel Sambuc       if (ActiveModule) {
1189*f4a2713aSLionel Sambuc         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1190*f4a2713aSLionel Sambuc           << Id[I].first << ActiveModule->getTopLevelModule();
1191*f4a2713aSLionel Sambuc       } else {
1192*f4a2713aSLionel Sambuc         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1193*f4a2713aSLionel Sambuc       }
1194*f4a2713aSLionel Sambuc       HadError = true;
1195*f4a2713aSLionel Sambuc       return;
1196*f4a2713aSLionel Sambuc     }
1197*f4a2713aSLionel Sambuc   }
1198*f4a2713aSLionel Sambuc 
1199*f4a2713aSLionel Sambuc   StringRef ModuleName = Id.back().first;
1200*f4a2713aSLionel Sambuc   SourceLocation ModuleNameLoc = Id.back().second;
1201*f4a2713aSLionel Sambuc 
1202*f4a2713aSLionel Sambuc   // Parse the optional attribute list.
1203*f4a2713aSLionel Sambuc   Attributes Attrs;
1204*f4a2713aSLionel Sambuc   parseOptionalAttributes(Attrs);
1205*f4a2713aSLionel Sambuc 
1206*f4a2713aSLionel Sambuc   // Parse the opening brace.
1207*f4a2713aSLionel Sambuc   if (!Tok.is(MMToken::LBrace)) {
1208*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1209*f4a2713aSLionel Sambuc       << ModuleName;
1210*f4a2713aSLionel Sambuc     HadError = true;
1211*f4a2713aSLionel Sambuc     return;
1212*f4a2713aSLionel Sambuc   }
1213*f4a2713aSLionel Sambuc   SourceLocation LBraceLoc = consumeToken();
1214*f4a2713aSLionel Sambuc 
1215*f4a2713aSLionel Sambuc   // Determine whether this (sub)module has already been defined.
1216*f4a2713aSLionel Sambuc   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
1217*f4a2713aSLionel Sambuc     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1218*f4a2713aSLionel Sambuc       // Skip the module definition.
1219*f4a2713aSLionel Sambuc       skipUntil(MMToken::RBrace);
1220*f4a2713aSLionel Sambuc       if (Tok.is(MMToken::RBrace))
1221*f4a2713aSLionel Sambuc         consumeToken();
1222*f4a2713aSLionel Sambuc       else {
1223*f4a2713aSLionel Sambuc         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1224*f4a2713aSLionel Sambuc         Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1225*f4a2713aSLionel Sambuc         HadError = true;
1226*f4a2713aSLionel Sambuc       }
1227*f4a2713aSLionel Sambuc       return;
1228*f4a2713aSLionel Sambuc     }
1229*f4a2713aSLionel Sambuc 
1230*f4a2713aSLionel Sambuc     Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1231*f4a2713aSLionel Sambuc       << ModuleName;
1232*f4a2713aSLionel Sambuc     Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
1233*f4a2713aSLionel Sambuc 
1234*f4a2713aSLionel Sambuc     // Skip the module definition.
1235*f4a2713aSLionel Sambuc     skipUntil(MMToken::RBrace);
1236*f4a2713aSLionel Sambuc     if (Tok.is(MMToken::RBrace))
1237*f4a2713aSLionel Sambuc       consumeToken();
1238*f4a2713aSLionel Sambuc 
1239*f4a2713aSLionel Sambuc     HadError = true;
1240*f4a2713aSLionel Sambuc     return;
1241*f4a2713aSLionel Sambuc   }
1242*f4a2713aSLionel Sambuc 
1243*f4a2713aSLionel Sambuc   // Start defining this module.
1244*f4a2713aSLionel Sambuc   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1245*f4a2713aSLionel Sambuc                                         Explicit).first;
1246*f4a2713aSLionel Sambuc   ActiveModule->DefinitionLoc = ModuleNameLoc;
1247*f4a2713aSLionel Sambuc   if (Attrs.IsSystem || IsSystem)
1248*f4a2713aSLionel Sambuc     ActiveModule->IsSystem = true;
1249*f4a2713aSLionel Sambuc 
1250*f4a2713aSLionel Sambuc   bool Done = false;
1251*f4a2713aSLionel Sambuc   do {
1252*f4a2713aSLionel Sambuc     switch (Tok.Kind) {
1253*f4a2713aSLionel Sambuc     case MMToken::EndOfFile:
1254*f4a2713aSLionel Sambuc     case MMToken::RBrace:
1255*f4a2713aSLionel Sambuc       Done = true;
1256*f4a2713aSLionel Sambuc       break;
1257*f4a2713aSLionel Sambuc 
1258*f4a2713aSLionel Sambuc     case MMToken::ConfigMacros:
1259*f4a2713aSLionel Sambuc       parseConfigMacros();
1260*f4a2713aSLionel Sambuc       break;
1261*f4a2713aSLionel Sambuc 
1262*f4a2713aSLionel Sambuc     case MMToken::Conflict:
1263*f4a2713aSLionel Sambuc       parseConflict();
1264*f4a2713aSLionel Sambuc       break;
1265*f4a2713aSLionel Sambuc 
1266*f4a2713aSLionel Sambuc     case MMToken::ExplicitKeyword:
1267*f4a2713aSLionel Sambuc     case MMToken::ExternKeyword:
1268*f4a2713aSLionel Sambuc     case MMToken::FrameworkKeyword:
1269*f4a2713aSLionel Sambuc     case MMToken::ModuleKeyword:
1270*f4a2713aSLionel Sambuc       parseModuleDecl();
1271*f4a2713aSLionel Sambuc       break;
1272*f4a2713aSLionel Sambuc 
1273*f4a2713aSLionel Sambuc     case MMToken::ExportKeyword:
1274*f4a2713aSLionel Sambuc       parseExportDecl();
1275*f4a2713aSLionel Sambuc       break;
1276*f4a2713aSLionel Sambuc 
1277*f4a2713aSLionel Sambuc     case MMToken::UseKeyword:
1278*f4a2713aSLionel Sambuc       parseUseDecl();
1279*f4a2713aSLionel Sambuc       break;
1280*f4a2713aSLionel Sambuc 
1281*f4a2713aSLionel Sambuc     case MMToken::RequiresKeyword:
1282*f4a2713aSLionel Sambuc       parseRequiresDecl();
1283*f4a2713aSLionel Sambuc       break;
1284*f4a2713aSLionel Sambuc 
1285*f4a2713aSLionel Sambuc     case MMToken::UmbrellaKeyword: {
1286*f4a2713aSLionel Sambuc       SourceLocation UmbrellaLoc = consumeToken();
1287*f4a2713aSLionel Sambuc       if (Tok.is(MMToken::HeaderKeyword))
1288*f4a2713aSLionel Sambuc         parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
1289*f4a2713aSLionel Sambuc       else
1290*f4a2713aSLionel Sambuc         parseUmbrellaDirDecl(UmbrellaLoc);
1291*f4a2713aSLionel Sambuc       break;
1292*f4a2713aSLionel Sambuc     }
1293*f4a2713aSLionel Sambuc 
1294*f4a2713aSLionel Sambuc     case MMToken::ExcludeKeyword: {
1295*f4a2713aSLionel Sambuc       SourceLocation ExcludeLoc = consumeToken();
1296*f4a2713aSLionel Sambuc       if (Tok.is(MMToken::HeaderKeyword)) {
1297*f4a2713aSLionel Sambuc         parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
1298*f4a2713aSLionel Sambuc       } else {
1299*f4a2713aSLionel Sambuc         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1300*f4a2713aSLionel Sambuc           << "exclude";
1301*f4a2713aSLionel Sambuc       }
1302*f4a2713aSLionel Sambuc       break;
1303*f4a2713aSLionel Sambuc     }
1304*f4a2713aSLionel Sambuc 
1305*f4a2713aSLionel Sambuc     case MMToken::PrivateKeyword: {
1306*f4a2713aSLionel Sambuc       SourceLocation PrivateLoc = consumeToken();
1307*f4a2713aSLionel Sambuc       if (Tok.is(MMToken::HeaderKeyword)) {
1308*f4a2713aSLionel Sambuc         parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1309*f4a2713aSLionel Sambuc       } else {
1310*f4a2713aSLionel Sambuc         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1311*f4a2713aSLionel Sambuc           << "private";
1312*f4a2713aSLionel Sambuc       }
1313*f4a2713aSLionel Sambuc       break;
1314*f4a2713aSLionel Sambuc     }
1315*f4a2713aSLionel Sambuc 
1316*f4a2713aSLionel Sambuc     case MMToken::HeaderKeyword:
1317*f4a2713aSLionel Sambuc       parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
1318*f4a2713aSLionel Sambuc       break;
1319*f4a2713aSLionel Sambuc 
1320*f4a2713aSLionel Sambuc     case MMToken::LinkKeyword:
1321*f4a2713aSLionel Sambuc       parseLinkDecl();
1322*f4a2713aSLionel Sambuc       break;
1323*f4a2713aSLionel Sambuc 
1324*f4a2713aSLionel Sambuc     default:
1325*f4a2713aSLionel Sambuc       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1326*f4a2713aSLionel Sambuc       consumeToken();
1327*f4a2713aSLionel Sambuc       break;
1328*f4a2713aSLionel Sambuc     }
1329*f4a2713aSLionel Sambuc   } while (!Done);
1330*f4a2713aSLionel Sambuc 
1331*f4a2713aSLionel Sambuc   if (Tok.is(MMToken::RBrace))
1332*f4a2713aSLionel Sambuc     consumeToken();
1333*f4a2713aSLionel Sambuc   else {
1334*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1335*f4a2713aSLionel Sambuc     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1336*f4a2713aSLionel Sambuc     HadError = true;
1337*f4a2713aSLionel Sambuc   }
1338*f4a2713aSLionel Sambuc 
1339*f4a2713aSLionel Sambuc   // If the active module is a top-level framework, and there are no link
1340*f4a2713aSLionel Sambuc   // libraries, automatically link against the framework.
1341*f4a2713aSLionel Sambuc   if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1342*f4a2713aSLionel Sambuc       ActiveModule->LinkLibraries.empty()) {
1343*f4a2713aSLionel Sambuc     inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1344*f4a2713aSLionel Sambuc   }
1345*f4a2713aSLionel Sambuc 
1346*f4a2713aSLionel Sambuc   // We're done parsing this module. Pop back to the previous module.
1347*f4a2713aSLionel Sambuc   ActiveModule = PreviousActiveModule;
1348*f4a2713aSLionel Sambuc }
1349*f4a2713aSLionel Sambuc 
1350*f4a2713aSLionel Sambuc /// \brief Parse an extern module declaration.
1351*f4a2713aSLionel Sambuc ///
1352*f4a2713aSLionel Sambuc ///   extern module-declaration:
1353*f4a2713aSLionel Sambuc ///     'extern' 'module' module-id string-literal
1354*f4a2713aSLionel Sambuc void ModuleMapParser::parseExternModuleDecl() {
1355*f4a2713aSLionel Sambuc   assert(Tok.is(MMToken::ExternKeyword));
1356*f4a2713aSLionel Sambuc   consumeToken(); // 'extern' keyword
1357*f4a2713aSLionel Sambuc 
1358*f4a2713aSLionel Sambuc   // Parse 'module' keyword.
1359*f4a2713aSLionel Sambuc   if (!Tok.is(MMToken::ModuleKeyword)) {
1360*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1361*f4a2713aSLionel Sambuc     consumeToken();
1362*f4a2713aSLionel Sambuc     HadError = true;
1363*f4a2713aSLionel Sambuc     return;
1364*f4a2713aSLionel Sambuc   }
1365*f4a2713aSLionel Sambuc   consumeToken(); // 'module' keyword
1366*f4a2713aSLionel Sambuc 
1367*f4a2713aSLionel Sambuc   // Parse the module name.
1368*f4a2713aSLionel Sambuc   ModuleId Id;
1369*f4a2713aSLionel Sambuc   if (parseModuleId(Id)) {
1370*f4a2713aSLionel Sambuc     HadError = true;
1371*f4a2713aSLionel Sambuc     return;
1372*f4a2713aSLionel Sambuc   }
1373*f4a2713aSLionel Sambuc 
1374*f4a2713aSLionel Sambuc   // Parse the referenced module map file name.
1375*f4a2713aSLionel Sambuc   if (!Tok.is(MMToken::StringLiteral)) {
1376*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1377*f4a2713aSLionel Sambuc     HadError = true;
1378*f4a2713aSLionel Sambuc     return;
1379*f4a2713aSLionel Sambuc   }
1380*f4a2713aSLionel Sambuc   std::string FileName = Tok.getString();
1381*f4a2713aSLionel Sambuc   consumeToken(); // filename
1382*f4a2713aSLionel Sambuc 
1383*f4a2713aSLionel Sambuc   StringRef FileNameRef = FileName;
1384*f4a2713aSLionel Sambuc   SmallString<128> ModuleMapFileName;
1385*f4a2713aSLionel Sambuc   if (llvm::sys::path::is_relative(FileNameRef)) {
1386*f4a2713aSLionel Sambuc     ModuleMapFileName += Directory->getName();
1387*f4a2713aSLionel Sambuc     llvm::sys::path::append(ModuleMapFileName, FileName);
1388*f4a2713aSLionel Sambuc     FileNameRef = ModuleMapFileName.str();
1389*f4a2713aSLionel Sambuc   }
1390*f4a2713aSLionel Sambuc   if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1391*f4a2713aSLionel Sambuc     Map.parseModuleMapFile(File, /*IsSystem=*/false);
1392*f4a2713aSLionel Sambuc }
1393*f4a2713aSLionel Sambuc 
1394*f4a2713aSLionel Sambuc /// \brief Parse a requires declaration.
1395*f4a2713aSLionel Sambuc ///
1396*f4a2713aSLionel Sambuc ///   requires-declaration:
1397*f4a2713aSLionel Sambuc ///     'requires' feature-list
1398*f4a2713aSLionel Sambuc ///
1399*f4a2713aSLionel Sambuc ///   feature-list:
1400*f4a2713aSLionel Sambuc ///     feature ',' feature-list
1401*f4a2713aSLionel Sambuc ///     feature
1402*f4a2713aSLionel Sambuc ///
1403*f4a2713aSLionel Sambuc ///   feature:
1404*f4a2713aSLionel Sambuc ///     '!'[opt] identifier
1405*f4a2713aSLionel Sambuc void ModuleMapParser::parseRequiresDecl() {
1406*f4a2713aSLionel Sambuc   assert(Tok.is(MMToken::RequiresKeyword));
1407*f4a2713aSLionel Sambuc 
1408*f4a2713aSLionel Sambuc   // Parse 'requires' keyword.
1409*f4a2713aSLionel Sambuc   consumeToken();
1410*f4a2713aSLionel Sambuc 
1411*f4a2713aSLionel Sambuc   // Parse the feature-list.
1412*f4a2713aSLionel Sambuc   do {
1413*f4a2713aSLionel Sambuc     bool RequiredState = true;
1414*f4a2713aSLionel Sambuc     if (Tok.is(MMToken::Exclaim)) {
1415*f4a2713aSLionel Sambuc       RequiredState = false;
1416*f4a2713aSLionel Sambuc       consumeToken();
1417*f4a2713aSLionel Sambuc     }
1418*f4a2713aSLionel Sambuc 
1419*f4a2713aSLionel Sambuc     if (!Tok.is(MMToken::Identifier)) {
1420*f4a2713aSLionel Sambuc       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1421*f4a2713aSLionel Sambuc       HadError = true;
1422*f4a2713aSLionel Sambuc       return;
1423*f4a2713aSLionel Sambuc     }
1424*f4a2713aSLionel Sambuc 
1425*f4a2713aSLionel Sambuc     // Consume the feature name.
1426*f4a2713aSLionel Sambuc     std::string Feature = Tok.getString();
1427*f4a2713aSLionel Sambuc     consumeToken();
1428*f4a2713aSLionel Sambuc 
1429*f4a2713aSLionel Sambuc     // Add this feature.
1430*f4a2713aSLionel Sambuc     ActiveModule->addRequirement(Feature, RequiredState,
1431*f4a2713aSLionel Sambuc                                  Map.LangOpts, *Map.Target);
1432*f4a2713aSLionel Sambuc 
1433*f4a2713aSLionel Sambuc     if (!Tok.is(MMToken::Comma))
1434*f4a2713aSLionel Sambuc       break;
1435*f4a2713aSLionel Sambuc 
1436*f4a2713aSLionel Sambuc     // Consume the comma.
1437*f4a2713aSLionel Sambuc     consumeToken();
1438*f4a2713aSLionel Sambuc   } while (true);
1439*f4a2713aSLionel Sambuc }
1440*f4a2713aSLionel Sambuc 
1441*f4a2713aSLionel Sambuc /// \brief Append to \p Paths the set of paths needed to get to the
1442*f4a2713aSLionel Sambuc /// subframework in which the given module lives.
1443*f4a2713aSLionel Sambuc static void appendSubframeworkPaths(Module *Mod,
1444*f4a2713aSLionel Sambuc                                     SmallVectorImpl<char> &Path) {
1445*f4a2713aSLionel Sambuc   // Collect the framework names from the given module to the top-level module.
1446*f4a2713aSLionel Sambuc   SmallVector<StringRef, 2> Paths;
1447*f4a2713aSLionel Sambuc   for (; Mod; Mod = Mod->Parent) {
1448*f4a2713aSLionel Sambuc     if (Mod->IsFramework)
1449*f4a2713aSLionel Sambuc       Paths.push_back(Mod->Name);
1450*f4a2713aSLionel Sambuc   }
1451*f4a2713aSLionel Sambuc 
1452*f4a2713aSLionel Sambuc   if (Paths.empty())
1453*f4a2713aSLionel Sambuc     return;
1454*f4a2713aSLionel Sambuc 
1455*f4a2713aSLionel Sambuc   // Add Frameworks/Name.framework for each subframework.
1456*f4a2713aSLionel Sambuc   for (unsigned I = Paths.size() - 1; I != 0; --I)
1457*f4a2713aSLionel Sambuc     llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
1458*f4a2713aSLionel Sambuc }
1459*f4a2713aSLionel Sambuc 
1460*f4a2713aSLionel Sambuc /// \brief Parse a header declaration.
1461*f4a2713aSLionel Sambuc ///
1462*f4a2713aSLionel Sambuc ///   header-declaration:
1463*f4a2713aSLionel Sambuc ///     'umbrella'[opt] 'header' string-literal
1464*f4a2713aSLionel Sambuc ///     'exclude'[opt] 'header' string-literal
1465*f4a2713aSLionel Sambuc void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1466*f4a2713aSLionel Sambuc                                       SourceLocation LeadingLoc) {
1467*f4a2713aSLionel Sambuc   assert(Tok.is(MMToken::HeaderKeyword));
1468*f4a2713aSLionel Sambuc   consumeToken();
1469*f4a2713aSLionel Sambuc 
1470*f4a2713aSLionel Sambuc   // Parse the header name.
1471*f4a2713aSLionel Sambuc   if (!Tok.is(MMToken::StringLiteral)) {
1472*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1473*f4a2713aSLionel Sambuc       << "header";
1474*f4a2713aSLionel Sambuc     HadError = true;
1475*f4a2713aSLionel Sambuc     return;
1476*f4a2713aSLionel Sambuc   }
1477*f4a2713aSLionel Sambuc   std::string FileName = Tok.getString();
1478*f4a2713aSLionel Sambuc   SourceLocation FileNameLoc = consumeToken();
1479*f4a2713aSLionel Sambuc 
1480*f4a2713aSLionel Sambuc   // Check whether we already have an umbrella.
1481*f4a2713aSLionel Sambuc   if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
1482*f4a2713aSLionel Sambuc     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1483*f4a2713aSLionel Sambuc       << ActiveModule->getFullModuleName();
1484*f4a2713aSLionel Sambuc     HadError = true;
1485*f4a2713aSLionel Sambuc     return;
1486*f4a2713aSLionel Sambuc   }
1487*f4a2713aSLionel Sambuc 
1488*f4a2713aSLionel Sambuc   // Look for this file.
1489*f4a2713aSLionel Sambuc   const FileEntry *File = 0;
1490*f4a2713aSLionel Sambuc   const FileEntry *BuiltinFile = 0;
1491*f4a2713aSLionel Sambuc   SmallString<128> PathName;
1492*f4a2713aSLionel Sambuc   if (llvm::sys::path::is_absolute(FileName)) {
1493*f4a2713aSLionel Sambuc     PathName = FileName;
1494*f4a2713aSLionel Sambuc     File = SourceMgr.getFileManager().getFile(PathName);
1495*f4a2713aSLionel Sambuc   } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1496*f4a2713aSLionel Sambuc     PathName = Dir->getName();
1497*f4a2713aSLionel Sambuc     llvm::sys::path::append(PathName, FileName);
1498*f4a2713aSLionel Sambuc     File = SourceMgr.getFileManager().getFile(PathName);
1499*f4a2713aSLionel Sambuc   } else {
1500*f4a2713aSLionel Sambuc     // Search for the header file within the search directory.
1501*f4a2713aSLionel Sambuc     PathName = Directory->getName();
1502*f4a2713aSLionel Sambuc     unsigned PathLength = PathName.size();
1503*f4a2713aSLionel Sambuc 
1504*f4a2713aSLionel Sambuc     if (ActiveModule->isPartOfFramework()) {
1505*f4a2713aSLionel Sambuc       appendSubframeworkPaths(ActiveModule, PathName);
1506*f4a2713aSLionel Sambuc 
1507*f4a2713aSLionel Sambuc       // Check whether this file is in the public headers.
1508*f4a2713aSLionel Sambuc       llvm::sys::path::append(PathName, "Headers", FileName);
1509*f4a2713aSLionel Sambuc       File = SourceMgr.getFileManager().getFile(PathName);
1510*f4a2713aSLionel Sambuc 
1511*f4a2713aSLionel Sambuc       if (!File) {
1512*f4a2713aSLionel Sambuc         // Check whether this file is in the private headers.
1513*f4a2713aSLionel Sambuc         PathName.resize(PathLength);
1514*f4a2713aSLionel Sambuc         llvm::sys::path::append(PathName, "PrivateHeaders", FileName);
1515*f4a2713aSLionel Sambuc         File = SourceMgr.getFileManager().getFile(PathName);
1516*f4a2713aSLionel Sambuc       }
1517*f4a2713aSLionel Sambuc     } else {
1518*f4a2713aSLionel Sambuc       // Lookup for normal headers.
1519*f4a2713aSLionel Sambuc       llvm::sys::path::append(PathName, FileName);
1520*f4a2713aSLionel Sambuc       File = SourceMgr.getFileManager().getFile(PathName);
1521*f4a2713aSLionel Sambuc 
1522*f4a2713aSLionel Sambuc       // If this is a system module with a top-level header, this header
1523*f4a2713aSLionel Sambuc       // may have a counterpart (or replacement) in the set of headers
1524*f4a2713aSLionel Sambuc       // supplied by Clang. Find that builtin header.
1525*f4a2713aSLionel Sambuc       if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1526*f4a2713aSLionel Sambuc           BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1527*f4a2713aSLionel Sambuc           isBuiltinHeader(FileName)) {
1528*f4a2713aSLionel Sambuc         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
1529*f4a2713aSLionel Sambuc         llvm::sys::path::append(BuiltinPathName, FileName);
1530*f4a2713aSLionel Sambuc         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1531*f4a2713aSLionel Sambuc 
1532*f4a2713aSLionel Sambuc         // If Clang supplies this header but the underlying system does not,
1533*f4a2713aSLionel Sambuc         // just silently swap in our builtin version. Otherwise, we'll end
1534*f4a2713aSLionel Sambuc         // up adding both (later).
1535*f4a2713aSLionel Sambuc         if (!File && BuiltinFile) {
1536*f4a2713aSLionel Sambuc           File = BuiltinFile;
1537*f4a2713aSLionel Sambuc           BuiltinFile = 0;
1538*f4a2713aSLionel Sambuc         }
1539*f4a2713aSLionel Sambuc       }
1540*f4a2713aSLionel Sambuc     }
1541*f4a2713aSLionel Sambuc   }
1542*f4a2713aSLionel Sambuc 
1543*f4a2713aSLionel Sambuc   // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1544*f4a2713aSLionel Sambuc   // Come up with a lazy way to do this.
1545*f4a2713aSLionel Sambuc   if (File) {
1546*f4a2713aSLionel Sambuc     if (LeadingToken == MMToken::UmbrellaKeyword) {
1547*f4a2713aSLionel Sambuc       const DirectoryEntry *UmbrellaDir = File->getDir();
1548*f4a2713aSLionel Sambuc       if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
1549*f4a2713aSLionel Sambuc         Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
1550*f4a2713aSLionel Sambuc           << UmbrellaModule->getFullModuleName();
1551*f4a2713aSLionel Sambuc         HadError = true;
1552*f4a2713aSLionel Sambuc       } else {
1553*f4a2713aSLionel Sambuc         // Record this umbrella header.
1554*f4a2713aSLionel Sambuc         Map.setUmbrellaHeader(ActiveModule, File);
1555*f4a2713aSLionel Sambuc       }
1556*f4a2713aSLionel Sambuc     } else {
1557*f4a2713aSLionel Sambuc       // Record this header.
1558*f4a2713aSLionel Sambuc       ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1559*f4a2713aSLionel Sambuc       if (LeadingToken == MMToken::ExcludeKeyword)
1560*f4a2713aSLionel Sambuc         Role = ModuleMap::ExcludedHeader;
1561*f4a2713aSLionel Sambuc       else if (LeadingToken == MMToken::PrivateKeyword)
1562*f4a2713aSLionel Sambuc         Role = ModuleMap::PrivateHeader;
1563*f4a2713aSLionel Sambuc       else
1564*f4a2713aSLionel Sambuc         assert(LeadingToken == MMToken::HeaderKeyword);
1565*f4a2713aSLionel Sambuc 
1566*f4a2713aSLionel Sambuc       Map.addHeader(ActiveModule, File, Role);
1567*f4a2713aSLionel Sambuc 
1568*f4a2713aSLionel Sambuc       // If there is a builtin counterpart to this file, add it now.
1569*f4a2713aSLionel Sambuc       if (BuiltinFile)
1570*f4a2713aSLionel Sambuc         Map.addHeader(ActiveModule, BuiltinFile, Role);
1571*f4a2713aSLionel Sambuc     }
1572*f4a2713aSLionel Sambuc   } else if (LeadingToken != MMToken::ExcludeKeyword) {
1573*f4a2713aSLionel Sambuc     // Ignore excluded header files. They're optional anyway.
1574*f4a2713aSLionel Sambuc 
1575*f4a2713aSLionel Sambuc     Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
1576*f4a2713aSLionel Sambuc       << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
1577*f4a2713aSLionel Sambuc     HadError = true;
1578*f4a2713aSLionel Sambuc   }
1579*f4a2713aSLionel Sambuc }
1580*f4a2713aSLionel Sambuc 
1581*f4a2713aSLionel Sambuc /// \brief Parse an umbrella directory declaration.
1582*f4a2713aSLionel Sambuc ///
1583*f4a2713aSLionel Sambuc ///   umbrella-dir-declaration:
1584*f4a2713aSLionel Sambuc ///     umbrella string-literal
1585*f4a2713aSLionel Sambuc void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1586*f4a2713aSLionel Sambuc   // Parse the directory name.
1587*f4a2713aSLionel Sambuc   if (!Tok.is(MMToken::StringLiteral)) {
1588*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1589*f4a2713aSLionel Sambuc       << "umbrella";
1590*f4a2713aSLionel Sambuc     HadError = true;
1591*f4a2713aSLionel Sambuc     return;
1592*f4a2713aSLionel Sambuc   }
1593*f4a2713aSLionel Sambuc 
1594*f4a2713aSLionel Sambuc   std::string DirName = Tok.getString();
1595*f4a2713aSLionel Sambuc   SourceLocation DirNameLoc = consumeToken();
1596*f4a2713aSLionel Sambuc 
1597*f4a2713aSLionel Sambuc   // Check whether we already have an umbrella.
1598*f4a2713aSLionel Sambuc   if (ActiveModule->Umbrella) {
1599*f4a2713aSLionel Sambuc     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1600*f4a2713aSLionel Sambuc       << ActiveModule->getFullModuleName();
1601*f4a2713aSLionel Sambuc     HadError = true;
1602*f4a2713aSLionel Sambuc     return;
1603*f4a2713aSLionel Sambuc   }
1604*f4a2713aSLionel Sambuc 
1605*f4a2713aSLionel Sambuc   // Look for this file.
1606*f4a2713aSLionel Sambuc   const DirectoryEntry *Dir = 0;
1607*f4a2713aSLionel Sambuc   if (llvm::sys::path::is_absolute(DirName))
1608*f4a2713aSLionel Sambuc     Dir = SourceMgr.getFileManager().getDirectory(DirName);
1609*f4a2713aSLionel Sambuc   else {
1610*f4a2713aSLionel Sambuc     SmallString<128> PathName;
1611*f4a2713aSLionel Sambuc     PathName = Directory->getName();
1612*f4a2713aSLionel Sambuc     llvm::sys::path::append(PathName, DirName);
1613*f4a2713aSLionel Sambuc     Dir = SourceMgr.getFileManager().getDirectory(PathName);
1614*f4a2713aSLionel Sambuc   }
1615*f4a2713aSLionel Sambuc 
1616*f4a2713aSLionel Sambuc   if (!Dir) {
1617*f4a2713aSLionel Sambuc     Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1618*f4a2713aSLionel Sambuc       << DirName;
1619*f4a2713aSLionel Sambuc     HadError = true;
1620*f4a2713aSLionel Sambuc     return;
1621*f4a2713aSLionel Sambuc   }
1622*f4a2713aSLionel Sambuc 
1623*f4a2713aSLionel Sambuc   if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1624*f4a2713aSLionel Sambuc     Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1625*f4a2713aSLionel Sambuc       << OwningModule->getFullModuleName();
1626*f4a2713aSLionel Sambuc     HadError = true;
1627*f4a2713aSLionel Sambuc     return;
1628*f4a2713aSLionel Sambuc   }
1629*f4a2713aSLionel Sambuc 
1630*f4a2713aSLionel Sambuc   // Record this umbrella directory.
1631*f4a2713aSLionel Sambuc   Map.setUmbrellaDir(ActiveModule, Dir);
1632*f4a2713aSLionel Sambuc }
1633*f4a2713aSLionel Sambuc 
1634*f4a2713aSLionel Sambuc /// \brief Parse a module export declaration.
1635*f4a2713aSLionel Sambuc ///
1636*f4a2713aSLionel Sambuc ///   export-declaration:
1637*f4a2713aSLionel Sambuc ///     'export' wildcard-module-id
1638*f4a2713aSLionel Sambuc ///
1639*f4a2713aSLionel Sambuc ///   wildcard-module-id:
1640*f4a2713aSLionel Sambuc ///     identifier
1641*f4a2713aSLionel Sambuc ///     '*'
1642*f4a2713aSLionel Sambuc ///     identifier '.' wildcard-module-id
1643*f4a2713aSLionel Sambuc void ModuleMapParser::parseExportDecl() {
1644*f4a2713aSLionel Sambuc   assert(Tok.is(MMToken::ExportKeyword));
1645*f4a2713aSLionel Sambuc   SourceLocation ExportLoc = consumeToken();
1646*f4a2713aSLionel Sambuc 
1647*f4a2713aSLionel Sambuc   // Parse the module-id with an optional wildcard at the end.
1648*f4a2713aSLionel Sambuc   ModuleId ParsedModuleId;
1649*f4a2713aSLionel Sambuc   bool Wildcard = false;
1650*f4a2713aSLionel Sambuc   do {
1651*f4a2713aSLionel Sambuc     if (Tok.is(MMToken::Identifier)) {
1652*f4a2713aSLionel Sambuc       ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1653*f4a2713aSLionel Sambuc                                               Tok.getLocation()));
1654*f4a2713aSLionel Sambuc       consumeToken();
1655*f4a2713aSLionel Sambuc 
1656*f4a2713aSLionel Sambuc       if (Tok.is(MMToken::Period)) {
1657*f4a2713aSLionel Sambuc         consumeToken();
1658*f4a2713aSLionel Sambuc         continue;
1659*f4a2713aSLionel Sambuc       }
1660*f4a2713aSLionel Sambuc 
1661*f4a2713aSLionel Sambuc       break;
1662*f4a2713aSLionel Sambuc     }
1663*f4a2713aSLionel Sambuc 
1664*f4a2713aSLionel Sambuc     if(Tok.is(MMToken::Star)) {
1665*f4a2713aSLionel Sambuc       Wildcard = true;
1666*f4a2713aSLionel Sambuc       consumeToken();
1667*f4a2713aSLionel Sambuc       break;
1668*f4a2713aSLionel Sambuc     }
1669*f4a2713aSLionel Sambuc 
1670*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
1671*f4a2713aSLionel Sambuc     HadError = true;
1672*f4a2713aSLionel Sambuc     return;
1673*f4a2713aSLionel Sambuc   } while (true);
1674*f4a2713aSLionel Sambuc 
1675*f4a2713aSLionel Sambuc   Module::UnresolvedExportDecl Unresolved = {
1676*f4a2713aSLionel Sambuc     ExportLoc, ParsedModuleId, Wildcard
1677*f4a2713aSLionel Sambuc   };
1678*f4a2713aSLionel Sambuc   ActiveModule->UnresolvedExports.push_back(Unresolved);
1679*f4a2713aSLionel Sambuc }
1680*f4a2713aSLionel Sambuc 
1681*f4a2713aSLionel Sambuc /// \brief Parse a module uses declaration.
1682*f4a2713aSLionel Sambuc ///
1683*f4a2713aSLionel Sambuc ///   uses-declaration:
1684*f4a2713aSLionel Sambuc ///     'uses' wildcard-module-id
1685*f4a2713aSLionel Sambuc void ModuleMapParser::parseUseDecl() {
1686*f4a2713aSLionel Sambuc   assert(Tok.is(MMToken::UseKeyword));
1687*f4a2713aSLionel Sambuc   consumeToken();
1688*f4a2713aSLionel Sambuc   // Parse the module-id.
1689*f4a2713aSLionel Sambuc   ModuleId ParsedModuleId;
1690*f4a2713aSLionel Sambuc 
1691*f4a2713aSLionel Sambuc   do {
1692*f4a2713aSLionel Sambuc     if (Tok.is(MMToken::Identifier)) {
1693*f4a2713aSLionel Sambuc       ParsedModuleId.push_back(
1694*f4a2713aSLionel Sambuc           std::make_pair(Tok.getString(), Tok.getLocation()));
1695*f4a2713aSLionel Sambuc       consumeToken();
1696*f4a2713aSLionel Sambuc 
1697*f4a2713aSLionel Sambuc       if (Tok.is(MMToken::Period)) {
1698*f4a2713aSLionel Sambuc         consumeToken();
1699*f4a2713aSLionel Sambuc         continue;
1700*f4a2713aSLionel Sambuc       }
1701*f4a2713aSLionel Sambuc 
1702*f4a2713aSLionel Sambuc       break;
1703*f4a2713aSLionel Sambuc     }
1704*f4a2713aSLionel Sambuc 
1705*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
1706*f4a2713aSLionel Sambuc     HadError = true;
1707*f4a2713aSLionel Sambuc     return;
1708*f4a2713aSLionel Sambuc   } while (true);
1709*f4a2713aSLionel Sambuc 
1710*f4a2713aSLionel Sambuc   ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1711*f4a2713aSLionel Sambuc }
1712*f4a2713aSLionel Sambuc 
1713*f4a2713aSLionel Sambuc /// \brief Parse a link declaration.
1714*f4a2713aSLionel Sambuc ///
1715*f4a2713aSLionel Sambuc ///   module-declaration:
1716*f4a2713aSLionel Sambuc ///     'link' 'framework'[opt] string-literal
1717*f4a2713aSLionel Sambuc void ModuleMapParser::parseLinkDecl() {
1718*f4a2713aSLionel Sambuc   assert(Tok.is(MMToken::LinkKeyword));
1719*f4a2713aSLionel Sambuc   SourceLocation LinkLoc = consumeToken();
1720*f4a2713aSLionel Sambuc 
1721*f4a2713aSLionel Sambuc   // Parse the optional 'framework' keyword.
1722*f4a2713aSLionel Sambuc   bool IsFramework = false;
1723*f4a2713aSLionel Sambuc   if (Tok.is(MMToken::FrameworkKeyword)) {
1724*f4a2713aSLionel Sambuc     consumeToken();
1725*f4a2713aSLionel Sambuc     IsFramework = true;
1726*f4a2713aSLionel Sambuc   }
1727*f4a2713aSLionel Sambuc 
1728*f4a2713aSLionel Sambuc   // Parse the library name
1729*f4a2713aSLionel Sambuc   if (!Tok.is(MMToken::StringLiteral)) {
1730*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1731*f4a2713aSLionel Sambuc       << IsFramework << SourceRange(LinkLoc);
1732*f4a2713aSLionel Sambuc     HadError = true;
1733*f4a2713aSLionel Sambuc     return;
1734*f4a2713aSLionel Sambuc   }
1735*f4a2713aSLionel Sambuc 
1736*f4a2713aSLionel Sambuc   std::string LibraryName = Tok.getString();
1737*f4a2713aSLionel Sambuc   consumeToken();
1738*f4a2713aSLionel Sambuc   ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1739*f4a2713aSLionel Sambuc                                                             IsFramework));
1740*f4a2713aSLionel Sambuc }
1741*f4a2713aSLionel Sambuc 
1742*f4a2713aSLionel Sambuc /// \brief Parse a configuration macro declaration.
1743*f4a2713aSLionel Sambuc ///
1744*f4a2713aSLionel Sambuc ///   module-declaration:
1745*f4a2713aSLionel Sambuc ///     'config_macros' attributes[opt] config-macro-list?
1746*f4a2713aSLionel Sambuc ///
1747*f4a2713aSLionel Sambuc ///   config-macro-list:
1748*f4a2713aSLionel Sambuc ///     identifier (',' identifier)?
1749*f4a2713aSLionel Sambuc void ModuleMapParser::parseConfigMacros() {
1750*f4a2713aSLionel Sambuc   assert(Tok.is(MMToken::ConfigMacros));
1751*f4a2713aSLionel Sambuc   SourceLocation ConfigMacrosLoc = consumeToken();
1752*f4a2713aSLionel Sambuc 
1753*f4a2713aSLionel Sambuc   // Only top-level modules can have configuration macros.
1754*f4a2713aSLionel Sambuc   if (ActiveModule->Parent) {
1755*f4a2713aSLionel Sambuc     Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1756*f4a2713aSLionel Sambuc   }
1757*f4a2713aSLionel Sambuc 
1758*f4a2713aSLionel Sambuc   // Parse the optional attributes.
1759*f4a2713aSLionel Sambuc   Attributes Attrs;
1760*f4a2713aSLionel Sambuc   parseOptionalAttributes(Attrs);
1761*f4a2713aSLionel Sambuc   if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1762*f4a2713aSLionel Sambuc     ActiveModule->ConfigMacrosExhaustive = true;
1763*f4a2713aSLionel Sambuc   }
1764*f4a2713aSLionel Sambuc 
1765*f4a2713aSLionel Sambuc   // If we don't have an identifier, we're done.
1766*f4a2713aSLionel Sambuc   if (!Tok.is(MMToken::Identifier))
1767*f4a2713aSLionel Sambuc     return;
1768*f4a2713aSLionel Sambuc 
1769*f4a2713aSLionel Sambuc   // Consume the first identifier.
1770*f4a2713aSLionel Sambuc   if (!ActiveModule->Parent) {
1771*f4a2713aSLionel Sambuc     ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1772*f4a2713aSLionel Sambuc   }
1773*f4a2713aSLionel Sambuc   consumeToken();
1774*f4a2713aSLionel Sambuc 
1775*f4a2713aSLionel Sambuc   do {
1776*f4a2713aSLionel Sambuc     // If there's a comma, consume it.
1777*f4a2713aSLionel Sambuc     if (!Tok.is(MMToken::Comma))
1778*f4a2713aSLionel Sambuc       break;
1779*f4a2713aSLionel Sambuc     consumeToken();
1780*f4a2713aSLionel Sambuc 
1781*f4a2713aSLionel Sambuc     // We expect to see a macro name here.
1782*f4a2713aSLionel Sambuc     if (!Tok.is(MMToken::Identifier)) {
1783*f4a2713aSLionel Sambuc       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1784*f4a2713aSLionel Sambuc       break;
1785*f4a2713aSLionel Sambuc     }
1786*f4a2713aSLionel Sambuc 
1787*f4a2713aSLionel Sambuc     // Consume the macro name.
1788*f4a2713aSLionel Sambuc     if (!ActiveModule->Parent) {
1789*f4a2713aSLionel Sambuc       ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1790*f4a2713aSLionel Sambuc     }
1791*f4a2713aSLionel Sambuc     consumeToken();
1792*f4a2713aSLionel Sambuc   } while (true);
1793*f4a2713aSLionel Sambuc }
1794*f4a2713aSLionel Sambuc 
1795*f4a2713aSLionel Sambuc /// \brief Format a module-id into a string.
1796*f4a2713aSLionel Sambuc static std::string formatModuleId(const ModuleId &Id) {
1797*f4a2713aSLionel Sambuc   std::string result;
1798*f4a2713aSLionel Sambuc   {
1799*f4a2713aSLionel Sambuc     llvm::raw_string_ostream OS(result);
1800*f4a2713aSLionel Sambuc 
1801*f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1802*f4a2713aSLionel Sambuc       if (I)
1803*f4a2713aSLionel Sambuc         OS << ".";
1804*f4a2713aSLionel Sambuc       OS << Id[I].first;
1805*f4a2713aSLionel Sambuc     }
1806*f4a2713aSLionel Sambuc   }
1807*f4a2713aSLionel Sambuc 
1808*f4a2713aSLionel Sambuc   return result;
1809*f4a2713aSLionel Sambuc }
1810*f4a2713aSLionel Sambuc 
1811*f4a2713aSLionel Sambuc /// \brief Parse a conflict declaration.
1812*f4a2713aSLionel Sambuc ///
1813*f4a2713aSLionel Sambuc ///   module-declaration:
1814*f4a2713aSLionel Sambuc ///     'conflict' module-id ',' string-literal
1815*f4a2713aSLionel Sambuc void ModuleMapParser::parseConflict() {
1816*f4a2713aSLionel Sambuc   assert(Tok.is(MMToken::Conflict));
1817*f4a2713aSLionel Sambuc   SourceLocation ConflictLoc = consumeToken();
1818*f4a2713aSLionel Sambuc   Module::UnresolvedConflict Conflict;
1819*f4a2713aSLionel Sambuc 
1820*f4a2713aSLionel Sambuc   // Parse the module-id.
1821*f4a2713aSLionel Sambuc   if (parseModuleId(Conflict.Id))
1822*f4a2713aSLionel Sambuc     return;
1823*f4a2713aSLionel Sambuc 
1824*f4a2713aSLionel Sambuc   // Parse the ','.
1825*f4a2713aSLionel Sambuc   if (!Tok.is(MMToken::Comma)) {
1826*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1827*f4a2713aSLionel Sambuc       << SourceRange(ConflictLoc);
1828*f4a2713aSLionel Sambuc     return;
1829*f4a2713aSLionel Sambuc   }
1830*f4a2713aSLionel Sambuc   consumeToken();
1831*f4a2713aSLionel Sambuc 
1832*f4a2713aSLionel Sambuc   // Parse the message.
1833*f4a2713aSLionel Sambuc   if (!Tok.is(MMToken::StringLiteral)) {
1834*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1835*f4a2713aSLionel Sambuc       << formatModuleId(Conflict.Id);
1836*f4a2713aSLionel Sambuc     return;
1837*f4a2713aSLionel Sambuc   }
1838*f4a2713aSLionel Sambuc   Conflict.Message = Tok.getString().str();
1839*f4a2713aSLionel Sambuc   consumeToken();
1840*f4a2713aSLionel Sambuc 
1841*f4a2713aSLionel Sambuc   // Add this unresolved conflict.
1842*f4a2713aSLionel Sambuc   ActiveModule->UnresolvedConflicts.push_back(Conflict);
1843*f4a2713aSLionel Sambuc }
1844*f4a2713aSLionel Sambuc 
1845*f4a2713aSLionel Sambuc /// \brief Parse an inferred module declaration (wildcard modules).
1846*f4a2713aSLionel Sambuc ///
1847*f4a2713aSLionel Sambuc ///   module-declaration:
1848*f4a2713aSLionel Sambuc ///     'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1849*f4a2713aSLionel Sambuc ///       { inferred-module-member* }
1850*f4a2713aSLionel Sambuc ///
1851*f4a2713aSLionel Sambuc ///   inferred-module-member:
1852*f4a2713aSLionel Sambuc ///     'export' '*'
1853*f4a2713aSLionel Sambuc ///     'exclude' identifier
1854*f4a2713aSLionel Sambuc void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
1855*f4a2713aSLionel Sambuc   assert(Tok.is(MMToken::Star));
1856*f4a2713aSLionel Sambuc   SourceLocation StarLoc = consumeToken();
1857*f4a2713aSLionel Sambuc   bool Failed = false;
1858*f4a2713aSLionel Sambuc 
1859*f4a2713aSLionel Sambuc   // Inferred modules must be submodules.
1860*f4a2713aSLionel Sambuc   if (!ActiveModule && !Framework) {
1861*f4a2713aSLionel Sambuc     Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1862*f4a2713aSLionel Sambuc     Failed = true;
1863*f4a2713aSLionel Sambuc   }
1864*f4a2713aSLionel Sambuc 
1865*f4a2713aSLionel Sambuc   if (ActiveModule) {
1866*f4a2713aSLionel Sambuc     // Inferred modules must have umbrella directories.
1867*f4a2713aSLionel Sambuc     if (!Failed && !ActiveModule->getUmbrellaDir()) {
1868*f4a2713aSLionel Sambuc       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1869*f4a2713aSLionel Sambuc       Failed = true;
1870*f4a2713aSLionel Sambuc     }
1871*f4a2713aSLionel Sambuc 
1872*f4a2713aSLionel Sambuc     // Check for redefinition of an inferred module.
1873*f4a2713aSLionel Sambuc     if (!Failed && ActiveModule->InferSubmodules) {
1874*f4a2713aSLionel Sambuc       Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1875*f4a2713aSLionel Sambuc       if (ActiveModule->InferredSubmoduleLoc.isValid())
1876*f4a2713aSLionel Sambuc         Diags.Report(ActiveModule->InferredSubmoduleLoc,
1877*f4a2713aSLionel Sambuc                      diag::note_mmap_prev_definition);
1878*f4a2713aSLionel Sambuc       Failed = true;
1879*f4a2713aSLionel Sambuc     }
1880*f4a2713aSLionel Sambuc 
1881*f4a2713aSLionel Sambuc     // Check for the 'framework' keyword, which is not permitted here.
1882*f4a2713aSLionel Sambuc     if (Framework) {
1883*f4a2713aSLionel Sambuc       Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1884*f4a2713aSLionel Sambuc       Framework = false;
1885*f4a2713aSLionel Sambuc     }
1886*f4a2713aSLionel Sambuc   } else if (Explicit) {
1887*f4a2713aSLionel Sambuc     Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1888*f4a2713aSLionel Sambuc     Explicit = false;
1889*f4a2713aSLionel Sambuc   }
1890*f4a2713aSLionel Sambuc 
1891*f4a2713aSLionel Sambuc   // If there were any problems with this inferred submodule, skip its body.
1892*f4a2713aSLionel Sambuc   if (Failed) {
1893*f4a2713aSLionel Sambuc     if (Tok.is(MMToken::LBrace)) {
1894*f4a2713aSLionel Sambuc       consumeToken();
1895*f4a2713aSLionel Sambuc       skipUntil(MMToken::RBrace);
1896*f4a2713aSLionel Sambuc       if (Tok.is(MMToken::RBrace))
1897*f4a2713aSLionel Sambuc         consumeToken();
1898*f4a2713aSLionel Sambuc     }
1899*f4a2713aSLionel Sambuc     HadError = true;
1900*f4a2713aSLionel Sambuc     return;
1901*f4a2713aSLionel Sambuc   }
1902*f4a2713aSLionel Sambuc 
1903*f4a2713aSLionel Sambuc   // Parse optional attributes.
1904*f4a2713aSLionel Sambuc   Attributes Attrs;
1905*f4a2713aSLionel Sambuc   parseOptionalAttributes(Attrs);
1906*f4a2713aSLionel Sambuc 
1907*f4a2713aSLionel Sambuc   if (ActiveModule) {
1908*f4a2713aSLionel Sambuc     // Note that we have an inferred submodule.
1909*f4a2713aSLionel Sambuc     ActiveModule->InferSubmodules = true;
1910*f4a2713aSLionel Sambuc     ActiveModule->InferredSubmoduleLoc = StarLoc;
1911*f4a2713aSLionel Sambuc     ActiveModule->InferExplicitSubmodules = Explicit;
1912*f4a2713aSLionel Sambuc   } else {
1913*f4a2713aSLionel Sambuc     // We'll be inferring framework modules for this directory.
1914*f4a2713aSLionel Sambuc     Map.InferredDirectories[Directory].InferModules = true;
1915*f4a2713aSLionel Sambuc     Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1916*f4a2713aSLionel Sambuc   }
1917*f4a2713aSLionel Sambuc 
1918*f4a2713aSLionel Sambuc   // Parse the opening brace.
1919*f4a2713aSLionel Sambuc   if (!Tok.is(MMToken::LBrace)) {
1920*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1921*f4a2713aSLionel Sambuc     HadError = true;
1922*f4a2713aSLionel Sambuc     return;
1923*f4a2713aSLionel Sambuc   }
1924*f4a2713aSLionel Sambuc   SourceLocation LBraceLoc = consumeToken();
1925*f4a2713aSLionel Sambuc 
1926*f4a2713aSLionel Sambuc   // Parse the body of the inferred submodule.
1927*f4a2713aSLionel Sambuc   bool Done = false;
1928*f4a2713aSLionel Sambuc   do {
1929*f4a2713aSLionel Sambuc     switch (Tok.Kind) {
1930*f4a2713aSLionel Sambuc     case MMToken::EndOfFile:
1931*f4a2713aSLionel Sambuc     case MMToken::RBrace:
1932*f4a2713aSLionel Sambuc       Done = true;
1933*f4a2713aSLionel Sambuc       break;
1934*f4a2713aSLionel Sambuc 
1935*f4a2713aSLionel Sambuc     case MMToken::ExcludeKeyword: {
1936*f4a2713aSLionel Sambuc       if (ActiveModule) {
1937*f4a2713aSLionel Sambuc         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1938*f4a2713aSLionel Sambuc           << (ActiveModule != 0);
1939*f4a2713aSLionel Sambuc         consumeToken();
1940*f4a2713aSLionel Sambuc         break;
1941*f4a2713aSLionel Sambuc       }
1942*f4a2713aSLionel Sambuc 
1943*f4a2713aSLionel Sambuc       consumeToken();
1944*f4a2713aSLionel Sambuc       if (!Tok.is(MMToken::Identifier)) {
1945*f4a2713aSLionel Sambuc         Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1946*f4a2713aSLionel Sambuc         break;
1947*f4a2713aSLionel Sambuc       }
1948*f4a2713aSLionel Sambuc 
1949*f4a2713aSLionel Sambuc       Map.InferredDirectories[Directory].ExcludedModules
1950*f4a2713aSLionel Sambuc         .push_back(Tok.getString());
1951*f4a2713aSLionel Sambuc       consumeToken();
1952*f4a2713aSLionel Sambuc       break;
1953*f4a2713aSLionel Sambuc     }
1954*f4a2713aSLionel Sambuc 
1955*f4a2713aSLionel Sambuc     case MMToken::ExportKeyword:
1956*f4a2713aSLionel Sambuc       if (!ActiveModule) {
1957*f4a2713aSLionel Sambuc         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1958*f4a2713aSLionel Sambuc           << (ActiveModule != 0);
1959*f4a2713aSLionel Sambuc         consumeToken();
1960*f4a2713aSLionel Sambuc         break;
1961*f4a2713aSLionel Sambuc       }
1962*f4a2713aSLionel Sambuc 
1963*f4a2713aSLionel Sambuc       consumeToken();
1964*f4a2713aSLionel Sambuc       if (Tok.is(MMToken::Star))
1965*f4a2713aSLionel Sambuc         ActiveModule->InferExportWildcard = true;
1966*f4a2713aSLionel Sambuc       else
1967*f4a2713aSLionel Sambuc         Diags.Report(Tok.getLocation(),
1968*f4a2713aSLionel Sambuc                      diag::err_mmap_expected_export_wildcard);
1969*f4a2713aSLionel Sambuc       consumeToken();
1970*f4a2713aSLionel Sambuc       break;
1971*f4a2713aSLionel Sambuc 
1972*f4a2713aSLionel Sambuc     case MMToken::ExplicitKeyword:
1973*f4a2713aSLionel Sambuc     case MMToken::ModuleKeyword:
1974*f4a2713aSLionel Sambuc     case MMToken::HeaderKeyword:
1975*f4a2713aSLionel Sambuc     case MMToken::PrivateKeyword:
1976*f4a2713aSLionel Sambuc     case MMToken::UmbrellaKeyword:
1977*f4a2713aSLionel Sambuc     default:
1978*f4a2713aSLionel Sambuc       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
1979*f4a2713aSLionel Sambuc           << (ActiveModule != 0);
1980*f4a2713aSLionel Sambuc       consumeToken();
1981*f4a2713aSLionel Sambuc       break;
1982*f4a2713aSLionel Sambuc     }
1983*f4a2713aSLionel Sambuc   } while (!Done);
1984*f4a2713aSLionel Sambuc 
1985*f4a2713aSLionel Sambuc   if (Tok.is(MMToken::RBrace))
1986*f4a2713aSLionel Sambuc     consumeToken();
1987*f4a2713aSLionel Sambuc   else {
1988*f4a2713aSLionel Sambuc     Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1989*f4a2713aSLionel Sambuc     Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1990*f4a2713aSLionel Sambuc     HadError = true;
1991*f4a2713aSLionel Sambuc   }
1992*f4a2713aSLionel Sambuc }
1993*f4a2713aSLionel Sambuc 
1994*f4a2713aSLionel Sambuc /// \brief Parse optional attributes.
1995*f4a2713aSLionel Sambuc ///
1996*f4a2713aSLionel Sambuc ///   attributes:
1997*f4a2713aSLionel Sambuc ///     attribute attributes
1998*f4a2713aSLionel Sambuc ///     attribute
1999*f4a2713aSLionel Sambuc ///
2000*f4a2713aSLionel Sambuc ///   attribute:
2001*f4a2713aSLionel Sambuc ///     [ identifier ]
2002*f4a2713aSLionel Sambuc ///
2003*f4a2713aSLionel Sambuc /// \param Attrs Will be filled in with the parsed attributes.
2004*f4a2713aSLionel Sambuc ///
2005*f4a2713aSLionel Sambuc /// \returns true if an error occurred, false otherwise.
2006*f4a2713aSLionel Sambuc bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
2007*f4a2713aSLionel Sambuc   bool HadError = false;
2008*f4a2713aSLionel Sambuc 
2009*f4a2713aSLionel Sambuc   while (Tok.is(MMToken::LSquare)) {
2010*f4a2713aSLionel Sambuc     // Consume the '['.
2011*f4a2713aSLionel Sambuc     SourceLocation LSquareLoc = consumeToken();
2012*f4a2713aSLionel Sambuc 
2013*f4a2713aSLionel Sambuc     // Check whether we have an attribute name here.
2014*f4a2713aSLionel Sambuc     if (!Tok.is(MMToken::Identifier)) {
2015*f4a2713aSLionel Sambuc       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2016*f4a2713aSLionel Sambuc       skipUntil(MMToken::RSquare);
2017*f4a2713aSLionel Sambuc       if (Tok.is(MMToken::RSquare))
2018*f4a2713aSLionel Sambuc         consumeToken();
2019*f4a2713aSLionel Sambuc       HadError = true;
2020*f4a2713aSLionel Sambuc     }
2021*f4a2713aSLionel Sambuc 
2022*f4a2713aSLionel Sambuc     // Decode the attribute name.
2023*f4a2713aSLionel Sambuc     AttributeKind Attribute
2024*f4a2713aSLionel Sambuc       = llvm::StringSwitch<AttributeKind>(Tok.getString())
2025*f4a2713aSLionel Sambuc           .Case("exhaustive", AT_exhaustive)
2026*f4a2713aSLionel Sambuc           .Case("system", AT_system)
2027*f4a2713aSLionel Sambuc           .Default(AT_unknown);
2028*f4a2713aSLionel Sambuc     switch (Attribute) {
2029*f4a2713aSLionel Sambuc     case AT_unknown:
2030*f4a2713aSLionel Sambuc       Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2031*f4a2713aSLionel Sambuc         << Tok.getString();
2032*f4a2713aSLionel Sambuc       break;
2033*f4a2713aSLionel Sambuc 
2034*f4a2713aSLionel Sambuc     case AT_system:
2035*f4a2713aSLionel Sambuc       Attrs.IsSystem = true;
2036*f4a2713aSLionel Sambuc       break;
2037*f4a2713aSLionel Sambuc 
2038*f4a2713aSLionel Sambuc     case AT_exhaustive:
2039*f4a2713aSLionel Sambuc       Attrs.IsExhaustive = true;
2040*f4a2713aSLionel Sambuc       break;
2041*f4a2713aSLionel Sambuc     }
2042*f4a2713aSLionel Sambuc     consumeToken();
2043*f4a2713aSLionel Sambuc 
2044*f4a2713aSLionel Sambuc     // Consume the ']'.
2045*f4a2713aSLionel Sambuc     if (!Tok.is(MMToken::RSquare)) {
2046*f4a2713aSLionel Sambuc       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2047*f4a2713aSLionel Sambuc       Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2048*f4a2713aSLionel Sambuc       skipUntil(MMToken::RSquare);
2049*f4a2713aSLionel Sambuc       HadError = true;
2050*f4a2713aSLionel Sambuc     }
2051*f4a2713aSLionel Sambuc 
2052*f4a2713aSLionel Sambuc     if (Tok.is(MMToken::RSquare))
2053*f4a2713aSLionel Sambuc       consumeToken();
2054*f4a2713aSLionel Sambuc   }
2055*f4a2713aSLionel Sambuc 
2056*f4a2713aSLionel Sambuc   return HadError;
2057*f4a2713aSLionel Sambuc }
2058*f4a2713aSLionel Sambuc 
2059*f4a2713aSLionel Sambuc /// \brief If there is a specific header search directory due the presence
2060*f4a2713aSLionel Sambuc /// of an umbrella directory, retrieve that directory. Otherwise, returns null.
2061*f4a2713aSLionel Sambuc const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
2062*f4a2713aSLionel Sambuc   for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
2063*f4a2713aSLionel Sambuc     // If we have an umbrella directory, use that.
2064*f4a2713aSLionel Sambuc     if (Mod->hasUmbrellaDir())
2065*f4a2713aSLionel Sambuc       return Mod->getUmbrellaDir();
2066*f4a2713aSLionel Sambuc 
2067*f4a2713aSLionel Sambuc     // If we have a framework directory, stop looking.
2068*f4a2713aSLionel Sambuc     if (Mod->IsFramework)
2069*f4a2713aSLionel Sambuc       return 0;
2070*f4a2713aSLionel Sambuc   }
2071*f4a2713aSLionel Sambuc 
2072*f4a2713aSLionel Sambuc   return 0;
2073*f4a2713aSLionel Sambuc }
2074*f4a2713aSLionel Sambuc 
2075*f4a2713aSLionel Sambuc /// \brief Parse a module map file.
2076*f4a2713aSLionel Sambuc ///
2077*f4a2713aSLionel Sambuc ///   module-map-file:
2078*f4a2713aSLionel Sambuc ///     module-declaration*
2079*f4a2713aSLionel Sambuc bool ModuleMapParser::parseModuleMapFile() {
2080*f4a2713aSLionel Sambuc   do {
2081*f4a2713aSLionel Sambuc     switch (Tok.Kind) {
2082*f4a2713aSLionel Sambuc     case MMToken::EndOfFile:
2083*f4a2713aSLionel Sambuc       return HadError;
2084*f4a2713aSLionel Sambuc 
2085*f4a2713aSLionel Sambuc     case MMToken::ExplicitKeyword:
2086*f4a2713aSLionel Sambuc     case MMToken::ExternKeyword:
2087*f4a2713aSLionel Sambuc     case MMToken::ModuleKeyword:
2088*f4a2713aSLionel Sambuc     case MMToken::FrameworkKeyword:
2089*f4a2713aSLionel Sambuc       parseModuleDecl();
2090*f4a2713aSLionel Sambuc       break;
2091*f4a2713aSLionel Sambuc 
2092*f4a2713aSLionel Sambuc     case MMToken::Comma:
2093*f4a2713aSLionel Sambuc     case MMToken::ConfigMacros:
2094*f4a2713aSLionel Sambuc     case MMToken::Conflict:
2095*f4a2713aSLionel Sambuc     case MMToken::Exclaim:
2096*f4a2713aSLionel Sambuc     case MMToken::ExcludeKeyword:
2097*f4a2713aSLionel Sambuc     case MMToken::ExportKeyword:
2098*f4a2713aSLionel Sambuc     case MMToken::HeaderKeyword:
2099*f4a2713aSLionel Sambuc     case MMToken::Identifier:
2100*f4a2713aSLionel Sambuc     case MMToken::LBrace:
2101*f4a2713aSLionel Sambuc     case MMToken::LinkKeyword:
2102*f4a2713aSLionel Sambuc     case MMToken::LSquare:
2103*f4a2713aSLionel Sambuc     case MMToken::Period:
2104*f4a2713aSLionel Sambuc     case MMToken::PrivateKeyword:
2105*f4a2713aSLionel Sambuc     case MMToken::RBrace:
2106*f4a2713aSLionel Sambuc     case MMToken::RSquare:
2107*f4a2713aSLionel Sambuc     case MMToken::RequiresKeyword:
2108*f4a2713aSLionel Sambuc     case MMToken::Star:
2109*f4a2713aSLionel Sambuc     case MMToken::StringLiteral:
2110*f4a2713aSLionel Sambuc     case MMToken::UmbrellaKeyword:
2111*f4a2713aSLionel Sambuc     case MMToken::UseKeyword:
2112*f4a2713aSLionel Sambuc       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2113*f4a2713aSLionel Sambuc       HadError = true;
2114*f4a2713aSLionel Sambuc       consumeToken();
2115*f4a2713aSLionel Sambuc       break;
2116*f4a2713aSLionel Sambuc     }
2117*f4a2713aSLionel Sambuc   } while (true);
2118*f4a2713aSLionel Sambuc }
2119*f4a2713aSLionel Sambuc 
2120*f4a2713aSLionel Sambuc bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
2121*f4a2713aSLionel Sambuc   llvm::DenseMap<const FileEntry *, bool>::iterator Known
2122*f4a2713aSLionel Sambuc     = ParsedModuleMap.find(File);
2123*f4a2713aSLionel Sambuc   if (Known != ParsedModuleMap.end())
2124*f4a2713aSLionel Sambuc     return Known->second;
2125*f4a2713aSLionel Sambuc 
2126*f4a2713aSLionel Sambuc   assert(Target != 0 && "Missing target information");
2127*f4a2713aSLionel Sambuc   FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
2128*f4a2713aSLionel Sambuc   const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
2129*f4a2713aSLionel Sambuc   if (!Buffer)
2130*f4a2713aSLionel Sambuc     return ParsedModuleMap[File] = true;
2131*f4a2713aSLionel Sambuc 
2132*f4a2713aSLionel Sambuc   // Parse this module map file.
2133*f4a2713aSLionel Sambuc   Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
2134*f4a2713aSLionel Sambuc   Diags->getClient()->BeginSourceFile(MMapLangOpts);
2135*f4a2713aSLionel Sambuc   ModuleMapParser Parser(L, SourceMgr, Target, *Diags, *this, File->getDir(),
2136*f4a2713aSLionel Sambuc                          BuiltinIncludeDir, IsSystem);
2137*f4a2713aSLionel Sambuc   bool Result = Parser.parseModuleMapFile();
2138*f4a2713aSLionel Sambuc   Diags->getClient()->EndSourceFile();
2139*f4a2713aSLionel Sambuc   ParsedModuleMap[File] = Result;
2140*f4a2713aSLionel Sambuc   return Result;
2141*f4a2713aSLionel Sambuc }
2142