blob: 9cea5aace7244a8ef8b027709b5f67e9c233a4e5 [file] [log] [blame]
Douglas Gregora30cfe52011-11-11 19:10:28 +00001//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the ModuleMap implementation, which describes the layout
11// of a module as it relates to headers.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/Lex/ModuleMap.h"
Jordan Rose3f6f51e2013-02-08 22:30:41 +000015#include "clang/Basic/CharInfo.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000016#include "clang/Basic/Diagnostic.h"
Douglas Gregor02c23eb2012-10-23 22:26:28 +000017#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000018#include "clang/Basic/FileManager.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Basic/TargetOptions.h"
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000021#include "clang/Lex/HeaderSearch.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000022#include "clang/Lex/LexDiagnostic.h"
23#include "clang/Lex/Lexer.h"
24#include "clang/Lex/LiteralSupport.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/ADT/StringSwitch.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000027#include "llvm/Support/Allocator.h"
Douglas Gregorac252a32011-12-06 19:39:29 +000028#include "llvm/Support/FileSystem.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000029#include "llvm/Support/Host.h"
Douglas Gregor8b6d3de2011-11-11 21:55:48 +000030#include "llvm/Support/PathV2.h"
Douglas Gregora30cfe52011-11-11 19:10:28 +000031#include "llvm/Support/raw_ostream.h"
Douglas Gregor98cfcbf2012-09-27 14:50:15 +000032#include <stdlib.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000033#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoadeb7822013-01-26 16:29:36 +000034#include <limits.h>
Douglas Gregor3cc62772013-01-22 23:49:45 +000035#endif
Douglas Gregora30cfe52011-11-11 19:10:28 +000036using namespace clang;
37
Douglas Gregor90db2602011-12-02 01:47:07 +000038Module::ExportDecl
39ModuleMap::resolveExport(Module *Mod,
40 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +000041 bool Complain) const {
Douglas Gregor0adaa882011-12-05 17:28:06 +000042 // We may have just a wildcard.
43 if (Unresolved.Id.empty()) {
44 assert(Unresolved.Wildcard && "Invalid unresolved export");
45 return Module::ExportDecl(0, true);
46 }
47
Douglas Gregor90db2602011-12-02 01:47:07 +000048 // Find the starting module.
49 Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
50 if (!Context) {
51 if (Complain)
52 Diags->Report(Unresolved.Id[0].second,
53 diag::err_mmap_missing_module_unqualified)
54 << Unresolved.Id[0].first << Mod->getFullModuleName();
55
56 return Module::ExportDecl();
57 }
58
59 // Dig into the module path.
60 for (unsigned I = 1, N = Unresolved.Id.size(); I != N; ++I) {
61 Module *Sub = lookupModuleQualified(Unresolved.Id[I].first,
62 Context);
63 if (!Sub) {
64 if (Complain)
65 Diags->Report(Unresolved.Id[I].second,
66 diag::err_mmap_missing_module_qualified)
67 << Unresolved.Id[I].first << Context->getFullModuleName()
68 << SourceRange(Unresolved.Id[0].second, Unresolved.Id[I-1].second);
69
70 return Module::ExportDecl();
71 }
72
73 Context = Sub;
74 }
75
76 return Module::ExportDecl(Context, Unresolved.Wildcard);
77}
78
Douglas Gregor51f564f2011-12-31 04:05:44 +000079ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000080 const LangOptions &LangOpts, const TargetInfo *Target,
81 HeaderSearch &HeaderInfo)
82 : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
83 BuiltinIncludeDir(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000084{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000085 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
86 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000087 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora30cfe52011-11-11 19:10:28 +000088 Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
89 SourceMgr = new SourceManager(*Diags, FileMgr);
90}
91
92ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +000093 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
94 IEnd = Modules.end();
95 I != IEnd; ++I) {
96 delete I->getValue();
97 }
98
Douglas Gregora30cfe52011-11-11 19:10:28 +000099 delete SourceMgr;
100}
101
Douglas Gregordc58aa72012-01-30 06:01:29 +0000102void ModuleMap::setTarget(const TargetInfo &Target) {
103 assert((!this->Target || this->Target == &Target) &&
104 "Improper target override");
105 this->Target = &Target;
106}
107
Douglas Gregor8b48e082012-10-12 21:15:50 +0000108/// \brief "Sanitize" a filename so that it can be used as an identifier.
109static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
110 SmallVectorImpl<char> &Buffer) {
111 if (Name.empty())
112 return Name;
113
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000114 if (!isValidIdentifier(Name)) {
Douglas Gregor8b48e082012-10-12 21:15:50 +0000115 // If we don't already have something with the form of an identifier,
116 // create a buffer with the sanitized name.
117 Buffer.clear();
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000118 if (isDigit(Name[0]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000119 Buffer.push_back('_');
120 Buffer.reserve(Buffer.size() + Name.size());
121 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000122 if (isIdentifierBody(Name[I]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000123 Buffer.push_back(Name[I]);
124 else
125 Buffer.push_back('_');
126 }
127
128 Name = StringRef(Buffer.data(), Buffer.size());
129 }
130
131 while (llvm::StringSwitch<bool>(Name)
132#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
133#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
134#include "clang/Basic/TokenKinds.def"
135 .Default(false)) {
136 if (Name.data() != Buffer.data())
137 Buffer.append(Name.begin(), Name.end());
138 Buffer.push_back('_');
139 Name = StringRef(Buffer.data(), Buffer.size());
140 }
141
142 return Name;
143}
144
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000145Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000146 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000147 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000148 // If a header is not available, don't report that it maps to anything.
149 if (!Known->second.isAvailable())
Douglas Gregor51f564f2011-12-31 04:05:44 +0000150 return 0;
151
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000152 return Known->second.getModule();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000153 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000154
Douglas Gregoradb97992011-11-16 23:02:25 +0000155 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000156 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000157
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000158 // Note: as an egregious but useful hack we use the real path here, because
159 // frameworks moving from top-level frameworks to embedded frameworks tend
160 // to be symlinked from the top-level location to the embedded location,
161 // and we need to resolve lookups as if we had found the embedded location.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000162 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000163
164 // Keep walking up the directory hierarchy, looking for a directory with
165 // an umbrella header.
166 do {
167 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
168 = UmbrellaDirs.find(Dir);
169 if (KnownDir != UmbrellaDirs.end()) {
170 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000171
172 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000173 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000174 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000175 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000176 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000177
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000178 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000179 // Infer submodules for each of the directories we found between
180 // the directory of the umbrella header and the directory where
181 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000182 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000183
Douglas Gregor6a1db482011-12-09 02:04:43 +0000184 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000185 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000186 SmallString<32> NameBuf;
187 StringRef Name = sanitizeFilenameAsIdentifier(
188 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
189 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000190 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000191 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000192
193 // Associate the module and the directory.
194 UmbrellaDirs[SkippedDirs[I-1]] = Result;
195
196 // If inferred submodules export everything they import, add a
197 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000198 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000199 Result->Exports.push_back(Module::ExportDecl(0, true));
200 }
201
202 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000203 SmallString<32> NameBuf;
204 StringRef Name = sanitizeFilenameAsIdentifier(
205 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000206 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000207 Explicit).first;
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +0000208 Result->addTopHeader(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000209
210 // If inferred submodules export everything they import, add a
211 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000212 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000213 Result->Exports.push_back(Module::ExportDecl(0, true));
214 } else {
215 // Record each of the directories we stepped through as being part of
216 // the module we found, since the umbrella header covers them all.
217 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
218 UmbrellaDirs[SkippedDirs[I]] = Result;
219 }
220
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000221 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000222
223 // If a header corresponds to an unavailable module, don't report
224 // that it maps to anything.
225 if (!Result->isAvailable())
226 return 0;
227
Douglas Gregore209e502011-12-06 01:10:29 +0000228 return Result;
229 }
230
231 SkippedDirs.push_back(Dir);
232
Douglas Gregoradb97992011-11-16 23:02:25 +0000233 // Retrieve our parent path.
234 DirName = llvm::sys::path::parent_path(DirName);
235 if (DirName.empty())
236 break;
237
238 // Resolve the parent path to a directory entry.
239 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000240 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000241
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000242 return 0;
243}
244
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000245bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
246 HeadersMap::const_iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000247 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000248 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000249
250 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000251 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000252 StringRef DirName = Dir->getName();
253
254 // Keep walking up the directory hierarchy, looking for a directory with
255 // an umbrella header.
256 do {
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000257 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor51f564f2011-12-31 04:05:44 +0000258 = UmbrellaDirs.find(Dir);
259 if (KnownDir != UmbrellaDirs.end()) {
260 Module *Found = KnownDir->second;
261 if (!Found->isAvailable())
262 return true;
263
264 // Search up the module stack until we find a module with an umbrella
265 // directory.
266 Module *UmbrellaModule = Found;
267 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
268 UmbrellaModule = UmbrellaModule->Parent;
269
270 if (UmbrellaModule->InferSubmodules) {
271 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
272 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000273 SmallString<32> NameBuf;
274 StringRef Name = sanitizeFilenameAsIdentifier(
275 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
276 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000277 Found = lookupModuleQualified(Name, Found);
278 if (!Found)
279 return false;
280 if (!Found->isAvailable())
281 return true;
282 }
283
284 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000285 SmallString<32> NameBuf;
286 StringRef Name = sanitizeFilenameAsIdentifier(
287 llvm::sys::path::stem(Header->getName()),
288 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000289 Found = lookupModuleQualified(Name, Found);
290 if (!Found)
291 return false;
292 }
293
294 return !Found->isAvailable();
295 }
296
297 SkippedDirs.push_back(Dir);
298
299 // Retrieve our parent path.
300 DirName = llvm::sys::path::parent_path(DirName);
301 if (DirName.empty())
302 break;
303
304 // Resolve the parent path to a directory entry.
305 Dir = SourceMgr->getFileManager().getDirectory(DirName);
306 } while (Dir);
307
308 return false;
309}
310
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000311Module *ModuleMap::findModule(StringRef Name) const {
312 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor484535e2011-11-11 23:20:24 +0000313 if (Known != Modules.end())
314 return Known->getValue();
315
316 return 0;
317}
318
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000319Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
320 Module *Context) const {
Douglas Gregor90db2602011-12-02 01:47:07 +0000321 for(; Context; Context = Context->Parent) {
322 if (Module *Sub = lookupModuleQualified(Name, Context))
323 return Sub;
324 }
325
326 return findModule(Name);
327}
328
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000329Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor90db2602011-12-02 01:47:07 +0000330 if (!Context)
331 return findModule(Name);
332
Douglas Gregorb7a78192012-01-04 23:32:19 +0000333 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000334}
335
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000336std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000337ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
338 bool IsExplicit) {
339 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000340 if (Module *Sub = lookupModuleQualified(Name, Parent))
341 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000342
343 // Create a new module with this name.
344 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
345 IsExplicit);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000346 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000347 Modules[Name] = Result;
348 return std::make_pair(Result, true);
349}
350
Douglas Gregor82e52372012-11-06 19:39:40 +0000351bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000352 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000353 // Check whether we have already looked into the parent directory
354 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000355 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000356 inferred = InferredDirectories.find(ParentDir);
357 if (inferred == InferredDirectories.end())
358 return false;
359
360 if (!inferred->second.InferModules)
361 return false;
362
363 // We're allowed to infer for this directory, but make sure it's okay
364 // to infer this particular module.
365 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
366 inferred->second.ExcludedModules.end(),
367 Name) == inferred->second.ExcludedModules.end();
368
369 if (canInfer && inferred->second.InferSystemModules)
370 IsSystem = true;
371
372 return canInfer;
373}
374
Douglas Gregor8767dc22013-01-14 17:57:51 +0000375/// \brief For a framework module, infer the framework against which we
376/// should link.
377static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
378 FileManager &FileMgr) {
379 assert(Mod->IsFramework && "Can only infer linking for framework modules");
380 assert(!Mod->isSubFramework() &&
381 "Can only infer linking for top-level frameworks");
382
383 SmallString<128> LibName;
384 LibName += FrameworkDir->getName();
385 llvm::sys::path::append(LibName, Mod->Name);
386 if (FileMgr.getFile(LibName)) {
387 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
388 /*IsFramework=*/true));
389 }
390}
391
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000392Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000393ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000394 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000395 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000396 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000397 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000398 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
399 return Mod;
400
401 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000402
403 // If the framework has a parent path from which we're allowed to infer
404 // a framework module, do so.
405 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000406 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000407
Douglas Gregor7005b902013-01-10 01:43:00 +0000408 // Note: as an egregious but useful hack we use the real path here, because
409 // we might be looking at an embedded framework that symlinks out to a
410 // top-level framework, and we need to infer as if we were naming the
411 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000412 StringRef FrameworkDirName
413 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000414
Douglas Gregor82e52372012-11-06 19:39:40 +0000415 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000416 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000417 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000418 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000419 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
420 // Check whether we have already looked into the parent directory
421 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000422 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000423 inferred = InferredDirectories.find(ParentDir);
424 if (inferred == InferredDirectories.end()) {
425 // We haven't looked here before. Load a module map, if there is
426 // one.
427 SmallString<128> ModMapPath = Parent;
428 llvm::sys::path::append(ModMapPath, "module.map");
429 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
430 parseModuleMapFile(ModMapFile);
431 inferred = InferredDirectories.find(ParentDir);
432 }
433
434 if (inferred == InferredDirectories.end())
435 inferred = InferredDirectories.insert(
436 std::make_pair(ParentDir, InferredDirectory())).first;
437 }
438
439 if (inferred->second.InferModules) {
440 // We're allowed to infer for this directory, but make sure it's okay
441 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000442 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000443 canInfer = std::find(inferred->second.ExcludedModules.begin(),
444 inferred->second.ExcludedModules.end(),
445 Name) == inferred->second.ExcludedModules.end();
446
447 if (inferred->second.InferSystemModules)
448 IsSystem = true;
449 }
450 }
451 }
452
453 // If we're not allowed to infer a framework module, don't.
454 if (!canInfer)
455 return 0;
456 }
457
458
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000459 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000460 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000461 llvm::sys::path::append(UmbrellaName, "Headers");
462 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000463 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000464
465 // FIXME: If there's no umbrella header, we could probably scan the
466 // framework to load *everything*. But, it's not clear that this is a good
467 // idea.
468 if (!UmbrellaHeader)
469 return 0;
470
Douglas Gregorac252a32011-12-06 19:39:29 +0000471 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
472 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000473 if (IsSystem)
474 Result->IsSystem = IsSystem;
475
Douglas Gregorb7a78192012-01-04 23:32:19 +0000476 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000477 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000478
Douglas Gregor489ad432011-12-08 18:00:48 +0000479 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000480 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000481 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000482 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000483
484 // export *
485 Result->Exports.push_back(Module::ExportDecl(0, true));
486
Douglas Gregore209e502011-12-06 01:10:29 +0000487 // module * { export * }
488 Result->InferSubmodules = true;
489 Result->InferExportWildcard = true;
490
Douglas Gregorac252a32011-12-06 19:39:29 +0000491 // Look for subframeworks.
492 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000493 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000494 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000495 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000496 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000497 llvm::sys::path::native(SubframeworksDirName.str(),
498 SubframeworksDirNameNative);
499 for (llvm::sys::fs::directory_iterator
500 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000501 Dir != DirEnd && !EC; Dir.increment(EC)) {
502 if (!StringRef(Dir->path()).endswith(".framework"))
503 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000504
Douglas Gregorac252a32011-12-06 19:39:29 +0000505 if (const DirectoryEntry *SubframeworkDir
506 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000507 // Note: as an egregious but useful hack, we use the real path here and
508 // check whether it is actually a subdirectory of the parent directory.
509 // This will not be the case if the 'subframework' is actually a symlink
510 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000511 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
512 bool FoundParent = false;
513 do {
514 // Get the parent directory name.
515 SubframeworkDirName
516 = llvm::sys::path::parent_path(SubframeworkDirName);
517 if (SubframeworkDirName.empty())
518 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000519
Douglas Gregor713b7c02013-01-26 00:55:12 +0000520 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
521 FoundParent = true;
522 break;
523 }
524 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000525
Douglas Gregor713b7c02013-01-26 00:55:12 +0000526 if (!FoundParent)
527 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000528
Douglas Gregorac252a32011-12-06 19:39:29 +0000529 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000530 SmallString<32> NameBuf;
531 inferFrameworkModule(sanitizeFilenameAsIdentifier(
532 llvm::sys::path::stem(Dir->path()), NameBuf),
533 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000534 }
535 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000536
Douglas Gregor8767dc22013-01-14 17:57:51 +0000537 // If the module is a top-level framework, automatically link against the
538 // framework.
539 if (!Result->isSubFramework()) {
540 inferFrameworkLink(Result, FrameworkDir, FileMgr);
541 }
542
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000543 return Result;
544}
545
Douglas Gregore209e502011-12-06 01:10:29 +0000546void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000547 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000548 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000549 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000550}
551
Douglas Gregor77d029f2011-12-08 19:11:24 +0000552void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
553 Mod->Umbrella = UmbrellaDir;
554 UmbrellaDirs[UmbrellaDir] = Mod;
555}
556
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000557void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
558 bool Excluded) {
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000559 if (Excluded) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000560 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000561 } else {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000562 Mod->Headers.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000563 HeaderInfo.MarkFileModuleHeader(Header);
564 }
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000565 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000566}
567
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000568const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000569ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000570 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
571 return 0;
572
573 return SourceMgr->getFileEntryForID(
574 SourceMgr->getFileID(Module->DefinitionLoc));
575}
576
Douglas Gregora30cfe52011-11-11 19:10:28 +0000577void ModuleMap::dump() {
578 llvm::errs() << "Modules:";
579 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
580 MEnd = Modules.end();
581 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000582 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000583
584 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000585 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000586 H != HEnd; ++H) {
587 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000588 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000589 }
590}
591
Douglas Gregor90db2602011-12-02 01:47:07 +0000592bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
593 bool HadError = false;
594 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
595 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
596 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000597 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000598 Mod->Exports.push_back(Export);
599 else
600 HadError = true;
601 }
602 Mod->UnresolvedExports.clear();
603 return HadError;
604}
605
Douglas Gregor55988682011-12-05 16:33:54 +0000606Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
607 if (Loc.isInvalid())
608 return 0;
609
610 // Use the expansion location to determine which module we're in.
611 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
612 if (!ExpansionLoc.isFileID())
613 return 0;
614
615
616 const SourceManager &SrcMgr = Loc.getManager();
617 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000618
Douglas Gregor303aae92012-01-06 17:19:32 +0000619 while (const FileEntry *ExpansionFile
620 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
621 // Find the module that owns this header (if any).
622 if (Module *Mod = findModuleForHeader(ExpansionFile))
623 return Mod;
624
625 // No module owns this header, so look up the inclusion chain to see if
626 // any included header has an associated module.
627 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
628 if (IncludeLoc.isInvalid())
629 return 0;
630
631 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
632 }
633
634 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000635}
636
Douglas Gregora30cfe52011-11-11 19:10:28 +0000637//----------------------------------------------------------------------------//
638// Module map file parser
639//----------------------------------------------------------------------------//
640
641namespace clang {
642 /// \brief A token in a module map file.
643 struct MMToken {
644 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000645 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000646 ConfigMacros,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000647 EndOfFile,
648 HeaderKeyword,
649 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000650 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000651 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000652 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000653 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000654 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000655 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000656 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000657 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000658 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000659 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000660 StringLiteral,
661 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000662 RBrace,
663 LSquare,
664 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000665 } Kind;
666
667 unsigned Location;
668 unsigned StringLength;
669 const char *StringData;
670
671 void clear() {
672 Kind = EndOfFile;
673 Location = 0;
674 StringLength = 0;
675 StringData = 0;
676 }
677
678 bool is(TokenKind K) const { return Kind == K; }
679
680 SourceLocation getLocation() const {
681 return SourceLocation::getFromRawEncoding(Location);
682 }
683
684 StringRef getString() const {
685 return StringRef(StringData, StringLength);
686 }
687 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000688
689 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000690 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000691 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000692
693 /// \brief Whether this is a system module.
694 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000695
696 /// \brief Whether this is an exhaustive set of configuration macros.
697 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000698 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000699
Douglas Gregor82e52372012-11-06 19:39:40 +0000700
Douglas Gregora30cfe52011-11-11 19:10:28 +0000701 class ModuleMapParser {
702 Lexer &L;
703 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000704
705 /// \brief Default target information, used only for string literal
706 /// parsing.
707 const TargetInfo *Target;
708
Douglas Gregora30cfe52011-11-11 19:10:28 +0000709 DiagnosticsEngine &Diags;
710 ModuleMap &Map;
711
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000712 /// \brief The directory that this module map resides in.
713 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000714
715 /// \brief The directory containing Clang-supplied headers.
716 const DirectoryEntry *BuiltinIncludeDir;
717
Douglas Gregora30cfe52011-11-11 19:10:28 +0000718 /// \brief Whether an error occurred.
719 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000720
Douglas Gregora30cfe52011-11-11 19:10:28 +0000721 /// \brief Stores string data for the various string literals referenced
722 /// during parsing.
723 llvm::BumpPtrAllocator StringData;
724
725 /// \brief The current token.
726 MMToken Tok;
727
728 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000729 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000730
731 /// \brief Consume the current token and return its location.
732 SourceLocation consumeToken();
733
734 /// \brief Skip tokens until we reach the a token with the given kind
735 /// (or the end of the file).
736 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000737
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000738 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000739 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000740 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000741 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000742 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000743 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000744 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000745 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000746 void parseConfigMacros();
Douglas Gregor82e52372012-11-06 19:39:40 +0000747 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000748 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000749
Douglas Gregor6a1db482011-12-09 02:04:43 +0000750 const DirectoryEntry *getOverriddenHeaderSearchDir();
751
Douglas Gregora30cfe52011-11-11 19:10:28 +0000752 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000753 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000754 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000755 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000756 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000757 const DirectoryEntry *Directory,
758 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000759 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000760 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
761 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000762 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000763 Tok.clear();
764 consumeToken();
765 }
766
767 bool parseModuleMapFile();
768 };
769}
770
771SourceLocation ModuleMapParser::consumeToken() {
772retry:
773 SourceLocation Result = Tok.getLocation();
774 Tok.clear();
775
776 Token LToken;
777 L.LexFromRawLexer(LToken);
778 Tok.Location = LToken.getLocation().getRawEncoding();
779 switch (LToken.getKind()) {
780 case tok::raw_identifier:
781 Tok.StringData = LToken.getRawIdentifierData();
782 Tok.StringLength = LToken.getLength();
783 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000784 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000785 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000786 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000787 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000788 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000789 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000790 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000791 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000792 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000793 .Case("umbrella", MMToken::UmbrellaKeyword)
794 .Default(MMToken::Identifier);
795 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000796
797 case tok::comma:
798 Tok.Kind = MMToken::Comma;
799 break;
800
Douglas Gregora30cfe52011-11-11 19:10:28 +0000801 case tok::eof:
802 Tok.Kind = MMToken::EndOfFile;
803 break;
804
805 case tok::l_brace:
806 Tok.Kind = MMToken::LBrace;
807 break;
808
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000809 case tok::l_square:
810 Tok.Kind = MMToken::LSquare;
811 break;
812
Douglas Gregor90db2602011-12-02 01:47:07 +0000813 case tok::period:
814 Tok.Kind = MMToken::Period;
815 break;
816
Douglas Gregora30cfe52011-11-11 19:10:28 +0000817 case tok::r_brace:
818 Tok.Kind = MMToken::RBrace;
819 break;
820
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000821 case tok::r_square:
822 Tok.Kind = MMToken::RSquare;
823 break;
824
Douglas Gregor90db2602011-12-02 01:47:07 +0000825 case tok::star:
826 Tok.Kind = MMToken::Star;
827 break;
828
Douglas Gregora30cfe52011-11-11 19:10:28 +0000829 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000830 if (LToken.hasUDSuffix()) {
831 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
832 HadError = true;
833 goto retry;
834 }
835
Douglas Gregora30cfe52011-11-11 19:10:28 +0000836 // Parse the string literal.
837 LangOptions LangOpts;
838 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
839 if (StringLiteral.hadError)
840 goto retry;
841
842 // Copy the string literal into our string data allocator.
843 unsigned Length = StringLiteral.GetStringLength();
844 char *Saved = StringData.Allocate<char>(Length + 1);
845 memcpy(Saved, StringLiteral.GetString().data(), Length);
846 Saved[Length] = 0;
847
848 // Form the token.
849 Tok.Kind = MMToken::StringLiteral;
850 Tok.StringData = Saved;
851 Tok.StringLength = Length;
852 break;
853 }
854
855 case tok::comment:
856 goto retry;
857
858 default:
859 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
860 HadError = true;
861 goto retry;
862 }
863
864 return Result;
865}
866
867void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
868 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000869 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000870 do {
871 switch (Tok.Kind) {
872 case MMToken::EndOfFile:
873 return;
874
875 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000876 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000877 return;
878
879 ++braceDepth;
880 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000881
882 case MMToken::LSquare:
883 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
884 return;
885
886 ++squareDepth;
887 break;
888
Douglas Gregora30cfe52011-11-11 19:10:28 +0000889 case MMToken::RBrace:
890 if (braceDepth > 0)
891 --braceDepth;
892 else if (Tok.is(K))
893 return;
894 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000895
896 case MMToken::RSquare:
897 if (squareDepth > 0)
898 --squareDepth;
899 else if (Tok.is(K))
900 return;
901 break;
902
Douglas Gregora30cfe52011-11-11 19:10:28 +0000903 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000904 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000905 return;
906 break;
907 }
908
909 consumeToken();
910 } while (true);
911}
912
Douglas Gregor587986e2011-12-07 02:23:45 +0000913/// \brief Parse a module-id.
914///
915/// module-id:
916/// identifier
917/// identifier '.' module-id
918///
919/// \returns true if an error occurred, false otherwise.
920bool ModuleMapParser::parseModuleId(ModuleId &Id) {
921 Id.clear();
922 do {
923 if (Tok.is(MMToken::Identifier)) {
924 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
925 consumeToken();
926 } else {
927 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
928 return true;
929 }
930
931 if (!Tok.is(MMToken::Period))
932 break;
933
934 consumeToken();
935 } while (true);
936
937 return false;
938}
939
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000940namespace {
941 /// \brief Enumerates the known attributes.
942 enum AttributeKind {
943 /// \brief An unknown attribute.
944 AT_unknown,
945 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +0000946 AT_system,
947 /// \brief The 'exhaustive' attribute.
948 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000949 };
950}
951
Douglas Gregora30cfe52011-11-11 19:10:28 +0000952/// \brief Parse a module declaration.
953///
954/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000955/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
956/// { module-member* }
957///
Douglas Gregora30cfe52011-11-11 19:10:28 +0000958/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +0000959/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000960/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +0000961/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +0000962/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000963/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +0000964///
965/// submodule-declaration:
966/// module-declaration
967/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +0000968void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +0000969 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
970 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +0000971 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +0000972 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000973 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +0000974 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +0000975
Douglas Gregord620a842011-12-06 17:16:41 +0000976 // Parse 'explicit' keyword, if present.
977 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +0000978 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +0000979 Explicit = true;
980 }
981
982 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +0000983 if (Tok.is(MMToken::FrameworkKeyword)) {
984 consumeToken();
985 Framework = true;
986 }
Douglas Gregora30cfe52011-11-11 19:10:28 +0000987
988 // Parse 'module' keyword.
989 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +0000990 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000991 consumeToken();
992 HadError = true;
993 return;
994 }
995 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +0000996
997 // If we have a wildcard for the module name, this is an inferred submodule.
998 // Parse it.
999 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001000 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001001
1002 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001003 ModuleId Id;
1004 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001005 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001006 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001007 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001008
Douglas Gregor587986e2011-12-07 02:23:45 +00001009 if (ActiveModule) {
1010 if (Id.size() > 1) {
1011 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1012 << SourceRange(Id.front().second, Id.back().second);
1013
1014 HadError = true;
1015 return;
1016 }
1017 } else if (Id.size() == 1 && Explicit) {
1018 // Top-level modules can't be explicit.
1019 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1020 Explicit = false;
1021 ExplicitLoc = SourceLocation();
1022 HadError = true;
1023 }
1024
1025 Module *PreviousActiveModule = ActiveModule;
1026 if (Id.size() > 1) {
1027 // This module map defines a submodule. Go find the module of which it
1028 // is a submodule.
1029 ActiveModule = 0;
1030 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1031 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1032 ActiveModule = Next;
1033 continue;
1034 }
1035
1036 if (ActiveModule) {
1037 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1038 << Id[I].first << ActiveModule->getTopLevelModule();
1039 } else {
1040 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1041 }
1042 HadError = true;
1043 return;
1044 }
1045 }
1046
1047 StringRef ModuleName = Id.back().first;
1048 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001049
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001050 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001051 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001052 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001053
Douglas Gregora30cfe52011-11-11 19:10:28 +00001054 // Parse the opening brace.
1055 if (!Tok.is(MMToken::LBrace)) {
1056 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1057 << ModuleName;
1058 HadError = true;
1059 return;
1060 }
1061 SourceLocation LBraceLoc = consumeToken();
1062
1063 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001064 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001065 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1066 // Skip the module definition.
1067 skipUntil(MMToken::RBrace);
1068 if (Tok.is(MMToken::RBrace))
1069 consumeToken();
1070 else {
1071 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1072 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1073 HadError = true;
1074 }
1075 return;
1076 }
1077
Douglas Gregora30cfe52011-11-11 19:10:28 +00001078 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1079 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001080 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001081
1082 // Skip the module definition.
1083 skipUntil(MMToken::RBrace);
1084 if (Tok.is(MMToken::RBrace))
1085 consumeToken();
1086
1087 HadError = true;
1088 return;
1089 }
1090
1091 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001092 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1093 Explicit).first;
1094 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001095 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001096 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001097
1098 bool Done = false;
1099 do {
1100 switch (Tok.Kind) {
1101 case MMToken::EndOfFile:
1102 case MMToken::RBrace:
1103 Done = true;
1104 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001105
1106 case MMToken::ConfigMacros:
1107 parseConfigMacros();
1108 break;
1109
Douglas Gregora30cfe52011-11-11 19:10:28 +00001110 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001111 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001112 case MMToken::ModuleKeyword:
1113 parseModuleDecl();
1114 break;
1115
Douglas Gregor90db2602011-12-02 01:47:07 +00001116 case MMToken::ExportKeyword:
1117 parseExportDecl();
1118 break;
1119
Douglas Gregor51f564f2011-12-31 04:05:44 +00001120 case MMToken::RequiresKeyword:
1121 parseRequiresDecl();
1122 break;
1123
Douglas Gregor77d029f2011-12-08 19:11:24 +00001124 case MMToken::UmbrellaKeyword: {
1125 SourceLocation UmbrellaLoc = consumeToken();
1126 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001127 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001128 else
1129 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001130 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001131 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001132
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001133 case MMToken::ExcludeKeyword: {
1134 SourceLocation ExcludeLoc = consumeToken();
1135 if (Tok.is(MMToken::HeaderKeyword)) {
1136 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1137 } else {
1138 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1139 << "exclude";
1140 }
1141 break;
1142 }
1143
Douglas Gregor489ad432011-12-08 18:00:48 +00001144 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001145 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001146 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001147
1148 case MMToken::LinkKeyword:
1149 parseLinkDecl();
1150 break;
1151
Douglas Gregora30cfe52011-11-11 19:10:28 +00001152 default:
1153 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1154 consumeToken();
1155 break;
1156 }
1157 } while (!Done);
1158
1159 if (Tok.is(MMToken::RBrace))
1160 consumeToken();
1161 else {
1162 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1163 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1164 HadError = true;
1165 }
1166
Douglas Gregor8767dc22013-01-14 17:57:51 +00001167 // If the active module is a top-level framework, and there are no link
1168 // libraries, automatically link against the framework.
1169 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1170 ActiveModule->LinkLibraries.empty()) {
1171 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1172 }
1173
Douglas Gregor587986e2011-12-07 02:23:45 +00001174 // We're done parsing this module. Pop back to the previous module.
1175 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001176}
Douglas Gregord620a842011-12-06 17:16:41 +00001177
Douglas Gregor51f564f2011-12-31 04:05:44 +00001178/// \brief Parse a requires declaration.
1179///
1180/// requires-declaration:
1181/// 'requires' feature-list
1182///
1183/// feature-list:
1184/// identifier ',' feature-list
1185/// identifier
1186void ModuleMapParser::parseRequiresDecl() {
1187 assert(Tok.is(MMToken::RequiresKeyword));
1188
1189 // Parse 'requires' keyword.
1190 consumeToken();
1191
1192 // Parse the feature-list.
1193 do {
1194 if (!Tok.is(MMToken::Identifier)) {
1195 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1196 HadError = true;
1197 return;
1198 }
1199
1200 // Consume the feature name.
1201 std::string Feature = Tok.getString();
1202 consumeToken();
1203
1204 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001205 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001206
1207 if (!Tok.is(MMToken::Comma))
1208 break;
1209
1210 // Consume the comma.
1211 consumeToken();
1212 } while (true);
1213}
1214
Douglas Gregord620a842011-12-06 17:16:41 +00001215/// \brief Append to \p Paths the set of paths needed to get to the
1216/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001217static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001218 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001219 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001220 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001221 for (; Mod; Mod = Mod->Parent) {
1222 if (Mod->IsFramework)
1223 Paths.push_back(Mod->Name);
1224 }
1225
1226 if (Paths.empty())
1227 return;
1228
1229 // Add Frameworks/Name.framework for each subframework.
1230 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1231 llvm::sys::path::append(Path, "Frameworks");
1232 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1233 }
1234}
1235
Douglas Gregor2f04f182012-02-02 18:42:48 +00001236/// \brief Determine whether the given file name is the name of a builtin
1237/// header, supplied by Clang to replace, override, or augment existing system
1238/// headers.
1239static bool isBuiltinHeader(StringRef FileName) {
1240 return llvm::StringSwitch<bool>(FileName)
1241 .Case("float.h", true)
1242 .Case("iso646.h", true)
1243 .Case("limits.h", true)
1244 .Case("stdalign.h", true)
1245 .Case("stdarg.h", true)
1246 .Case("stdbool.h", true)
1247 .Case("stddef.h", true)
1248 .Case("stdint.h", true)
1249 .Case("tgmath.h", true)
1250 .Case("unwind.h", true)
1251 .Default(false);
1252}
1253
Douglas Gregora30cfe52011-11-11 19:10:28 +00001254/// \brief Parse a header declaration.
1255///
1256/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001257/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001258/// 'exclude'[opt] 'header' string-literal
1259void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1260 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001261 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001262 consumeToken();
1263
Douglas Gregor489ad432011-12-08 18:00:48 +00001264 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001265 bool Exclude = ExcludeLoc.isValid();
1266 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001267 // Parse the header name.
1268 if (!Tok.is(MMToken::StringLiteral)) {
1269 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1270 << "header";
1271 HadError = true;
1272 return;
1273 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001274 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001275 SourceLocation FileNameLoc = consumeToken();
1276
Douglas Gregor77d029f2011-12-08 19:11:24 +00001277 // Check whether we already have an umbrella.
1278 if (Umbrella && ActiveModule->Umbrella) {
1279 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1280 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001281 HadError = true;
1282 return;
1283 }
1284
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001285 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001286 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001287 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001288 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001289 if (llvm::sys::path::is_absolute(FileName)) {
1290 PathName = FileName;
1291 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001292 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1293 PathName = Dir->getName();
1294 llvm::sys::path::append(PathName, FileName);
1295 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001296 } else {
1297 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001298 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001299 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001300
Douglas Gregord620a842011-12-06 17:16:41 +00001301 if (ActiveModule->isPartOfFramework()) {
1302 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001303
1304 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001305 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001306 llvm::sys::path::append(PathName, FileName);
1307 File = SourceMgr.getFileManager().getFile(PathName);
1308
1309 if (!File) {
1310 // Check whether this file is in the private headers.
1311 PathName.resize(PathLength);
1312 llvm::sys::path::append(PathName, "PrivateHeaders");
1313 llvm::sys::path::append(PathName, FileName);
1314 File = SourceMgr.getFileManager().getFile(PathName);
1315 }
1316 } else {
1317 // Lookup for normal headers.
1318 llvm::sys::path::append(PathName, FileName);
1319 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001320
1321 // If this is a system module with a top-level header, this header
1322 // may have a counterpart (or replacement) in the set of headers
1323 // supplied by Clang. Find that builtin header.
1324 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1325 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001326 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001327 llvm::sys::path::append(BuiltinPathName, FileName);
1328 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1329
1330 // If Clang supplies this header but the underlying system does not,
1331 // just silently swap in our builtin version. Otherwise, we'll end
1332 // up adding both (later).
1333 if (!File && BuiltinFile) {
1334 File = BuiltinFile;
1335 BuiltinFile = 0;
1336 }
1337 }
Douglas Gregord620a842011-12-06 17:16:41 +00001338 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001339 }
Douglas Gregora8654052011-11-17 22:09:43 +00001340
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001341 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1342 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001343 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001344 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001345 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001346 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001347 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001348 } else if (Umbrella) {
1349 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001350 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001351 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001352 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001353 HadError = true;
1354 } else {
1355 // Record this umbrella header.
1356 Map.setUmbrellaHeader(ActiveModule, File);
1357 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001358 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001359 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001360 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001361
1362 // If there is a builtin counterpart to this file, add it now.
1363 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001364 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001365 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001366 } else if (!Exclude) {
1367 // Ignore excluded header files. They're optional anyway.
1368
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001369 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001370 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001371 HadError = true;
1372 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001373}
1374
Douglas Gregor77d029f2011-12-08 19:11:24 +00001375/// \brief Parse an umbrella directory declaration.
1376///
1377/// umbrella-dir-declaration:
1378/// umbrella string-literal
1379void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1380 // Parse the directory name.
1381 if (!Tok.is(MMToken::StringLiteral)) {
1382 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1383 << "umbrella";
1384 HadError = true;
1385 return;
1386 }
1387
1388 std::string DirName = Tok.getString();
1389 SourceLocation DirNameLoc = consumeToken();
1390
1391 // Check whether we already have an umbrella.
1392 if (ActiveModule->Umbrella) {
1393 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1394 << ActiveModule->getFullModuleName();
1395 HadError = true;
1396 return;
1397 }
1398
1399 // Look for this file.
1400 const DirectoryEntry *Dir = 0;
1401 if (llvm::sys::path::is_absolute(DirName))
1402 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1403 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001404 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001405 PathName = Directory->getName();
1406 llvm::sys::path::append(PathName, DirName);
1407 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1408 }
1409
1410 if (!Dir) {
1411 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1412 << DirName;
1413 HadError = true;
1414 return;
1415 }
1416
1417 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1418 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1419 << OwningModule->getFullModuleName();
1420 HadError = true;
1421 return;
1422 }
1423
1424 // Record this umbrella directory.
1425 Map.setUmbrellaDir(ActiveModule, Dir);
1426}
1427
Douglas Gregor90db2602011-12-02 01:47:07 +00001428/// \brief Parse a module export declaration.
1429///
1430/// export-declaration:
1431/// 'export' wildcard-module-id
1432///
1433/// wildcard-module-id:
1434/// identifier
1435/// '*'
1436/// identifier '.' wildcard-module-id
1437void ModuleMapParser::parseExportDecl() {
1438 assert(Tok.is(MMToken::ExportKeyword));
1439 SourceLocation ExportLoc = consumeToken();
1440
1441 // Parse the module-id with an optional wildcard at the end.
1442 ModuleId ParsedModuleId;
1443 bool Wildcard = false;
1444 do {
1445 if (Tok.is(MMToken::Identifier)) {
1446 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1447 Tok.getLocation()));
1448 consumeToken();
1449
1450 if (Tok.is(MMToken::Period)) {
1451 consumeToken();
1452 continue;
1453 }
1454
1455 break;
1456 }
1457
1458 if(Tok.is(MMToken::Star)) {
1459 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001460 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001461 break;
1462 }
1463
1464 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1465 HadError = true;
1466 return;
1467 } while (true);
1468
1469 Module::UnresolvedExportDecl Unresolved = {
1470 ExportLoc, ParsedModuleId, Wildcard
1471 };
1472 ActiveModule->UnresolvedExports.push_back(Unresolved);
1473}
1474
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001475/// \brief Parse a link declaration.
1476///
1477/// module-declaration:
1478/// 'link' 'framework'[opt] string-literal
1479void ModuleMapParser::parseLinkDecl() {
1480 assert(Tok.is(MMToken::LinkKeyword));
1481 SourceLocation LinkLoc = consumeToken();
1482
1483 // Parse the optional 'framework' keyword.
1484 bool IsFramework = false;
1485 if (Tok.is(MMToken::FrameworkKeyword)) {
1486 consumeToken();
1487 IsFramework = true;
1488 }
1489
1490 // Parse the library name
1491 if (!Tok.is(MMToken::StringLiteral)) {
1492 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1493 << IsFramework << SourceRange(LinkLoc);
1494 HadError = true;
1495 return;
1496 }
1497
1498 std::string LibraryName = Tok.getString();
1499 consumeToken();
1500 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1501 IsFramework));
1502}
1503
Douglas Gregor63a72682013-03-20 00:22:05 +00001504/// \brief Parse a configuration macro declaration.
1505///
1506/// module-declaration:
1507/// 'config_macros' attributes[opt] config-macro-list?
1508///
1509/// config-macro-list:
1510/// identifier (',' identifier)?
1511void ModuleMapParser::parseConfigMacros() {
1512 assert(Tok.is(MMToken::ConfigMacros));
1513 SourceLocation ConfigMacrosLoc = consumeToken();
1514
1515 // Only top-level modules can have configuration macros.
1516 if (ActiveModule->Parent) {
1517 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1518 }
1519
1520 // Parse the optional attributes.
1521 Attributes Attrs;
1522 parseOptionalAttributes(Attrs);
1523 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1524 ActiveModule->ConfigMacrosExhaustive = true;
1525 }
1526
1527 // If we don't have an identifier, we're done.
1528 if (!Tok.is(MMToken::Identifier))
1529 return;
1530
1531 // Consume the first identifier.
1532 if (!ActiveModule->Parent) {
1533 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1534 }
1535 consumeToken();
1536
1537 do {
1538 // If there's a comma, consume it.
1539 if (!Tok.is(MMToken::Comma))
1540 break;
1541 consumeToken();
1542
1543 // We expect to see a macro name here.
1544 if (!Tok.is(MMToken::Identifier)) {
1545 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1546 break;
1547 }
1548
1549 // Consume the macro name.
1550 if (!ActiveModule->Parent) {
1551 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1552 }
1553 consumeToken();
1554 } while (true);
1555}
1556
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001557/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001558///
1559/// module-declaration:
1560/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1561/// { inferred-module-member* }
1562///
1563/// inferred-module-member:
1564/// 'export' '*'
1565/// 'exclude' identifier
1566void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001567 assert(Tok.is(MMToken::Star));
1568 SourceLocation StarLoc = consumeToken();
1569 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001570
Douglas Gregor1e123682011-12-05 22:27:44 +00001571 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001572 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001573 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1574 Failed = true;
1575 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001576
1577 if (ActiveModule) {
1578 // Inferred modules must have umbrella directories.
1579 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1580 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1581 Failed = true;
1582 }
1583
1584 // Check for redefinition of an inferred module.
1585 if (!Failed && ActiveModule->InferSubmodules) {
1586 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1587 if (ActiveModule->InferredSubmoduleLoc.isValid())
1588 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1589 diag::note_mmap_prev_definition);
1590 Failed = true;
1591 }
1592
1593 // Check for the 'framework' keyword, which is not permitted here.
1594 if (Framework) {
1595 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1596 Framework = false;
1597 }
1598 } else if (Explicit) {
1599 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1600 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001601 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001602
Douglas Gregor1e123682011-12-05 22:27:44 +00001603 // If there were any problems with this inferred submodule, skip its body.
1604 if (Failed) {
1605 if (Tok.is(MMToken::LBrace)) {
1606 consumeToken();
1607 skipUntil(MMToken::RBrace);
1608 if (Tok.is(MMToken::RBrace))
1609 consumeToken();
1610 }
1611 HadError = true;
1612 return;
1613 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001614
1615 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001616 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001617 parseOptionalAttributes(Attrs);
1618
1619 if (ActiveModule) {
1620 // Note that we have an inferred submodule.
1621 ActiveModule->InferSubmodules = true;
1622 ActiveModule->InferredSubmoduleLoc = StarLoc;
1623 ActiveModule->InferExplicitSubmodules = Explicit;
1624 } else {
1625 // We'll be inferring framework modules for this directory.
1626 Map.InferredDirectories[Directory].InferModules = true;
1627 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1628 }
1629
Douglas Gregor1e123682011-12-05 22:27:44 +00001630 // Parse the opening brace.
1631 if (!Tok.is(MMToken::LBrace)) {
1632 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1633 HadError = true;
1634 return;
1635 }
1636 SourceLocation LBraceLoc = consumeToken();
1637
1638 // Parse the body of the inferred submodule.
1639 bool Done = false;
1640 do {
1641 switch (Tok.Kind) {
1642 case MMToken::EndOfFile:
1643 case MMToken::RBrace:
1644 Done = true;
1645 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001646
1647 case MMToken::ExcludeKeyword: {
1648 if (ActiveModule) {
1649 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001650 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001651 consumeToken();
1652 break;
1653 }
1654
1655 consumeToken();
1656 if (!Tok.is(MMToken::Identifier)) {
1657 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1658 break;
1659 }
1660
1661 Map.InferredDirectories[Directory].ExcludedModules
1662 .push_back(Tok.getString());
1663 consumeToken();
1664 break;
1665 }
1666
1667 case MMToken::ExportKeyword:
1668 if (!ActiveModule) {
1669 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001670 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001671 consumeToken();
1672 break;
1673 }
1674
Douglas Gregor1e123682011-12-05 22:27:44 +00001675 consumeToken();
1676 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001677 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001678 else
1679 Diags.Report(Tok.getLocation(),
1680 diag::err_mmap_expected_export_wildcard);
1681 consumeToken();
1682 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001683
Douglas Gregor1e123682011-12-05 22:27:44 +00001684 case MMToken::ExplicitKeyword:
1685 case MMToken::ModuleKeyword:
1686 case MMToken::HeaderKeyword:
1687 case MMToken::UmbrellaKeyword:
1688 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001689 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001690 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001691 consumeToken();
1692 break;
1693 }
1694 } while (!Done);
1695
1696 if (Tok.is(MMToken::RBrace))
1697 consumeToken();
1698 else {
1699 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1700 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1701 HadError = true;
1702 }
1703}
1704
Douglas Gregor82e52372012-11-06 19:39:40 +00001705/// \brief Parse optional attributes.
1706///
1707/// attributes:
1708/// attribute attributes
1709/// attribute
1710///
1711/// attribute:
1712/// [ identifier ]
1713///
1714/// \param Attrs Will be filled in with the parsed attributes.
1715///
1716/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001717bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001718 bool HadError = false;
1719
1720 while (Tok.is(MMToken::LSquare)) {
1721 // Consume the '['.
1722 SourceLocation LSquareLoc = consumeToken();
1723
1724 // Check whether we have an attribute name here.
1725 if (!Tok.is(MMToken::Identifier)) {
1726 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1727 skipUntil(MMToken::RSquare);
1728 if (Tok.is(MMToken::RSquare))
1729 consumeToken();
1730 HadError = true;
1731 }
1732
1733 // Decode the attribute name.
1734 AttributeKind Attribute
1735 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001736 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00001737 .Case("system", AT_system)
1738 .Default(AT_unknown);
1739 switch (Attribute) {
1740 case AT_unknown:
1741 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1742 << Tok.getString();
1743 break;
1744
1745 case AT_system:
1746 Attrs.IsSystem = true;
1747 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001748
1749 case AT_exhaustive:
1750 Attrs.IsExhaustive = true;
1751 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001752 }
1753 consumeToken();
1754
1755 // Consume the ']'.
1756 if (!Tok.is(MMToken::RSquare)) {
1757 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1758 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1759 skipUntil(MMToken::RSquare);
1760 HadError = true;
1761 }
1762
1763 if (Tok.is(MMToken::RSquare))
1764 consumeToken();
1765 }
1766
1767 return HadError;
1768}
1769
Douglas Gregor6a1db482011-12-09 02:04:43 +00001770/// \brief If there is a specific header search directory due the presence
1771/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1772const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1773 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1774 // If we have an umbrella directory, use that.
1775 if (Mod->hasUmbrellaDir())
1776 return Mod->getUmbrellaDir();
1777
1778 // If we have a framework directory, stop looking.
1779 if (Mod->IsFramework)
1780 return 0;
1781 }
1782
1783 return 0;
1784}
1785
Douglas Gregora30cfe52011-11-11 19:10:28 +00001786/// \brief Parse a module map file.
1787///
1788/// module-map-file:
1789/// module-declaration*
1790bool ModuleMapParser::parseModuleMapFile() {
1791 do {
1792 switch (Tok.Kind) {
1793 case MMToken::EndOfFile:
1794 return HadError;
1795
Douglas Gregor587986e2011-12-07 02:23:45 +00001796 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001797 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001798 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001799 parseModuleDecl();
1800 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001801
Douglas Gregor51f564f2011-12-31 04:05:44 +00001802 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00001803 case MMToken::ConfigMacros:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001804 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001805 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001806 case MMToken::HeaderKeyword:
1807 case MMToken::Identifier:
1808 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001809 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001810 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001811 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001812 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001813 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001814 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001815 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001816 case MMToken::StringLiteral:
1817 case MMToken::UmbrellaKeyword:
1818 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1819 HadError = true;
1820 consumeToken();
1821 break;
1822 }
1823 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001824}
1825
1826bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001827 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1828 = ParsedModuleMap.find(File);
1829 if (Known != ParsedModuleMap.end())
1830 return Known->second;
1831
Douglas Gregordc58aa72012-01-30 06:01:29 +00001832 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001833 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1834 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1835 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001836 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001837
1838 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001839 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1840 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001841 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001842 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001843 bool Result = Parser.parseModuleMapFile();
1844 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001845 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001846 return Result;
1847}