blob: 3e7a44c0e35d3ea0a708b41ab12ef497bd81f00f [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 Gregor906d66a2013-03-20 21:10:35 +000048 // Resolve the module-id.
49 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
50 if (!Context)
51 return Module::ExportDecl();
52
53 return Module::ExportDecl(Context, Unresolved.Wildcard);
54}
55
56Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
57 bool Complain) const {
Douglas Gregor90db2602011-12-02 01:47:07 +000058 // Find the starting module.
Douglas Gregor906d66a2013-03-20 21:10:35 +000059 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor90db2602011-12-02 01:47:07 +000060 if (!Context) {
61 if (Complain)
Douglas Gregor906d66a2013-03-20 21:10:35 +000062 Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
63 << Id[0].first << Mod->getFullModuleName();
64
65 return 0;
Douglas Gregor90db2602011-12-02 01:47:07 +000066 }
67
68 // Dig into the module path.
Douglas Gregor906d66a2013-03-20 21:10:35 +000069 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
70 Module *Sub = lookupModuleQualified(Id[I].first, Context);
Douglas Gregor90db2602011-12-02 01:47:07 +000071 if (!Sub) {
72 if (Complain)
Douglas Gregor906d66a2013-03-20 21:10:35 +000073 Diags->Report(Id[I].second, diag::err_mmap_missing_module_qualified)
74 << Id[I].first << Context->getFullModuleName()
75 << SourceRange(Id[0].second, Id[I-1].second);
76
77 return 0;
Douglas Gregor90db2602011-12-02 01:47:07 +000078 }
Douglas Gregor906d66a2013-03-20 21:10:35 +000079
Douglas Gregor90db2602011-12-02 01:47:07 +000080 Context = Sub;
81 }
Douglas Gregor906d66a2013-03-20 21:10:35 +000082
83 return Context;
Douglas Gregor90db2602011-12-02 01:47:07 +000084}
85
Douglas Gregora4a90ca2013-05-03 22:58:43 +000086ModuleMap::ModuleMap(FileManager &FileMgr, DiagnosticConsumer &DC,
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +000087 const LangOptions &LangOpts, const TargetInfo *Target,
88 HeaderSearch &HeaderInfo)
89 : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
90 BuiltinIncludeDir(0)
Douglas Gregor51f564f2011-12-31 04:05:44 +000091{
Dylan Noblesmithc93dc782012-02-20 14:00:23 +000092 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
93 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor02c23eb2012-10-23 22:26:28 +000094 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregora4a90ca2013-05-03 22:58:43 +000095 Diags->setClient(new ForwardingDiagnosticConsumer(DC),
96 /*ShouldOwnClient=*/true);
Douglas Gregora30cfe52011-11-11 19:10:28 +000097 SourceMgr = new SourceManager(*Diags, FileMgr);
98}
99
100ModuleMap::~ModuleMap() {
Douglas Gregor09fe1bb2011-11-17 02:05:44 +0000101 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
102 IEnd = Modules.end();
103 I != IEnd; ++I) {
104 delete I->getValue();
105 }
106
Douglas Gregora30cfe52011-11-11 19:10:28 +0000107 delete SourceMgr;
108}
109
Douglas Gregordc58aa72012-01-30 06:01:29 +0000110void ModuleMap::setTarget(const TargetInfo &Target) {
111 assert((!this->Target || this->Target == &Target) &&
112 "Improper target override");
113 this->Target = &Target;
114}
115
Douglas Gregor8b48e082012-10-12 21:15:50 +0000116/// \brief "Sanitize" a filename so that it can be used as an identifier.
117static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
118 SmallVectorImpl<char> &Buffer) {
119 if (Name.empty())
120 return Name;
121
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000122 if (!isValidIdentifier(Name)) {
Douglas Gregor8b48e082012-10-12 21:15:50 +0000123 // If we don't already have something with the form of an identifier,
124 // create a buffer with the sanitized name.
125 Buffer.clear();
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000126 if (isDigit(Name[0]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000127 Buffer.push_back('_');
128 Buffer.reserve(Buffer.size() + Name.size());
129 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000130 if (isIdentifierBody(Name[I]))
Douglas Gregor8b48e082012-10-12 21:15:50 +0000131 Buffer.push_back(Name[I]);
132 else
133 Buffer.push_back('_');
134 }
135
136 Name = StringRef(Buffer.data(), Buffer.size());
137 }
138
139 while (llvm::StringSwitch<bool>(Name)
140#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
141#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
142#include "clang/Basic/TokenKinds.def"
143 .Default(false)) {
144 if (Name.data() != Buffer.data())
145 Buffer.append(Name.begin(), Name.end());
146 Buffer.push_back('_');
147 Name = StringRef(Buffer.data(), Buffer.size());
148 }
149
150 return Name;
151}
152
Douglas Gregordb3910b2013-05-02 17:58:30 +0000153/// \brief Determine whether the given file name is the name of a builtin
154/// header, supplied by Clang to replace, override, or augment existing system
155/// headers.
156static bool isBuiltinHeader(StringRef FileName) {
157 return llvm::StringSwitch<bool>(FileName)
158 .Case("float.h", true)
159 .Case("iso646.h", true)
160 .Case("limits.h", true)
161 .Case("stdalign.h", true)
162 .Case("stdarg.h", true)
163 .Case("stdbool.h", true)
164 .Case("stddef.h", true)
165 .Case("stdint.h", true)
166 .Case("tgmath.h", true)
167 .Case("unwind.h", true)
168 .Default(false);
169}
170
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000171Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000172 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000173 if (Known != Headers.end()) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000174 // If a header is not available, don't report that it maps to anything.
175 if (!Known->second.isAvailable())
Douglas Gregor51f564f2011-12-31 04:05:44 +0000176 return 0;
177
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000178 return Known->second.getModule();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000179 }
Douglas Gregordb3910b2013-05-02 17:58:30 +0000180
181 // If we've found a builtin header within Clang's builtin include directory,
182 // load all of the module maps to see if it will get associated with a
183 // specific module (e.g., in /usr/include).
184 if (File->getDir() == BuiltinIncludeDir &&
185 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
186 SmallVector<Module *, 4> AllModules;
187 HeaderInfo.collectAllModules(AllModules);
188
189 // Check again.
190 Known = Headers.find(File);
191 if (Known != Headers.end()) {
192 // If a header is not available, don't report that it maps to anything.
193 if (!Known->second.isAvailable())
194 return 0;
195
196 return Known->second.getModule();
197 }
198 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000199
Douglas Gregoradb97992011-11-16 23:02:25 +0000200 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000201 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000202
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000203 // Note: as an egregious but useful hack we use the real path here, because
204 // frameworks moving from top-level frameworks to embedded frameworks tend
205 // to be symlinked from the top-level location to the embedded location,
206 // and we need to resolve lookups as if we had found the embedded location.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000207 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000208
209 // Keep walking up the directory hierarchy, looking for a directory with
210 // an umbrella header.
211 do {
212 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
213 = UmbrellaDirs.find(Dir);
214 if (KnownDir != UmbrellaDirs.end()) {
215 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000216
217 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000218 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000219 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000220 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000221 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000222
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000223 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000224 // Infer submodules for each of the directories we found between
225 // the directory of the umbrella header and the directory where
226 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000227 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000228
Douglas Gregor6a1db482011-12-09 02:04:43 +0000229 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000230 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000231 SmallString<32> NameBuf;
232 StringRef Name = sanitizeFilenameAsIdentifier(
233 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
234 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000235 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000236 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000237
238 // Associate the module and the directory.
239 UmbrellaDirs[SkippedDirs[I-1]] = Result;
240
241 // If inferred submodules export everything they import, add a
242 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000243 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000244 Result->Exports.push_back(Module::ExportDecl(0, true));
245 }
246
247 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000248 SmallString<32> NameBuf;
249 StringRef Name = sanitizeFilenameAsIdentifier(
250 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000251 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000252 Explicit).first;
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +0000253 Result->addTopHeader(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000254
255 // If inferred submodules export everything they import, add a
256 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000257 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000258 Result->Exports.push_back(Module::ExportDecl(0, true));
259 } else {
260 // Record each of the directories we stepped through as being part of
261 // the module we found, since the umbrella header covers them all.
262 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
263 UmbrellaDirs[SkippedDirs[I]] = Result;
264 }
265
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000266 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000267
268 // If a header corresponds to an unavailable module, don't report
269 // that it maps to anything.
270 if (!Result->isAvailable())
271 return 0;
272
Douglas Gregore209e502011-12-06 01:10:29 +0000273 return Result;
274 }
275
276 SkippedDirs.push_back(Dir);
277
Douglas Gregoradb97992011-11-16 23:02:25 +0000278 // Retrieve our parent path.
279 DirName = llvm::sys::path::parent_path(DirName);
280 if (DirName.empty())
281 break;
282
283 // Resolve the parent path to a directory entry.
284 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000285 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000286
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000287 return 0;
288}
289
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000290bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
291 HeadersMap::const_iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000292 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000293 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000294
295 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000296 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000297 StringRef DirName = Dir->getName();
298
299 // Keep walking up the directory hierarchy, looking for a directory with
300 // an umbrella header.
301 do {
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000302 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor51f564f2011-12-31 04:05:44 +0000303 = UmbrellaDirs.find(Dir);
304 if (KnownDir != UmbrellaDirs.end()) {
305 Module *Found = KnownDir->second;
306 if (!Found->isAvailable())
307 return true;
308
309 // Search up the module stack until we find a module with an umbrella
310 // directory.
311 Module *UmbrellaModule = Found;
312 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
313 UmbrellaModule = UmbrellaModule->Parent;
314
315 if (UmbrellaModule->InferSubmodules) {
316 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
317 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000318 SmallString<32> NameBuf;
319 StringRef Name = sanitizeFilenameAsIdentifier(
320 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
321 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000322 Found = lookupModuleQualified(Name, Found);
323 if (!Found)
324 return false;
325 if (!Found->isAvailable())
326 return true;
327 }
328
329 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000330 SmallString<32> NameBuf;
331 StringRef Name = sanitizeFilenameAsIdentifier(
332 llvm::sys::path::stem(Header->getName()),
333 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000334 Found = lookupModuleQualified(Name, Found);
335 if (!Found)
336 return false;
337 }
338
339 return !Found->isAvailable();
340 }
341
342 SkippedDirs.push_back(Dir);
343
344 // Retrieve our parent path.
345 DirName = llvm::sys::path::parent_path(DirName);
346 if (DirName.empty())
347 break;
348
349 // Resolve the parent path to a directory entry.
350 Dir = SourceMgr->getFileManager().getDirectory(DirName);
351 } while (Dir);
352
353 return false;
354}
355
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000356Module *ModuleMap::findModule(StringRef Name) const {
357 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor484535e2011-11-11 23:20:24 +0000358 if (Known != Modules.end())
359 return Known->getValue();
360
361 return 0;
362}
363
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000364Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
365 Module *Context) const {
Douglas Gregor90db2602011-12-02 01:47:07 +0000366 for(; Context; Context = Context->Parent) {
367 if (Module *Sub = lookupModuleQualified(Name, Context))
368 return Sub;
369 }
370
371 return findModule(Name);
372}
373
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000374Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor90db2602011-12-02 01:47:07 +0000375 if (!Context)
376 return findModule(Name);
377
Douglas Gregorb7a78192012-01-04 23:32:19 +0000378 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000379}
380
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000381std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000382ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
383 bool IsExplicit) {
384 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000385 if (Module *Sub = lookupModuleQualified(Name, Parent))
386 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000387
388 // Create a new module with this name.
389 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
390 IsExplicit);
Douglas Gregorb7a78192012-01-04 23:32:19 +0000391 if (!Parent)
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000392 Modules[Name] = Result;
393 return std::make_pair(Result, true);
394}
395
Douglas Gregor82e52372012-11-06 19:39:40 +0000396bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000397 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000398 // Check whether we have already looked into the parent directory
399 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000400 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000401 inferred = InferredDirectories.find(ParentDir);
402 if (inferred == InferredDirectories.end())
403 return false;
404
405 if (!inferred->second.InferModules)
406 return false;
407
408 // We're allowed to infer for this directory, but make sure it's okay
409 // to infer this particular module.
410 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
411 inferred->second.ExcludedModules.end(),
412 Name) == inferred->second.ExcludedModules.end();
413
414 if (canInfer && inferred->second.InferSystemModules)
415 IsSystem = true;
416
417 return canInfer;
418}
419
Douglas Gregor8767dc22013-01-14 17:57:51 +0000420/// \brief For a framework module, infer the framework against which we
421/// should link.
422static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
423 FileManager &FileMgr) {
424 assert(Mod->IsFramework && "Can only infer linking for framework modules");
425 assert(!Mod->isSubFramework() &&
426 "Can only infer linking for top-level frameworks");
427
428 SmallString<128> LibName;
429 LibName += FrameworkDir->getName();
430 llvm::sys::path::append(LibName, Mod->Name);
431 if (FileMgr.getFile(LibName)) {
432 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
433 /*IsFramework=*/true));
434 }
435}
436
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000437Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000438ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000439 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000440 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000441 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000442 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000443 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
444 return Mod;
445
446 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000447
448 // If the framework has a parent path from which we're allowed to infer
449 // a framework module, do so.
450 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000451 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000452
Douglas Gregor7005b902013-01-10 01:43:00 +0000453 // Note: as an egregious but useful hack we use the real path here, because
454 // we might be looking at an embedded framework that symlinks out to a
455 // top-level framework, and we need to infer as if we were naming the
456 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000457 StringRef FrameworkDirName
458 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000459
Douglas Gregor82e52372012-11-06 19:39:40 +0000460 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000461 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000462 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000463 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000464 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
465 // Check whether we have already looked into the parent directory
466 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000467 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000468 inferred = InferredDirectories.find(ParentDir);
469 if (inferred == InferredDirectories.end()) {
470 // We haven't looked here before. Load a module map, if there is
471 // one.
472 SmallString<128> ModMapPath = Parent;
473 llvm::sys::path::append(ModMapPath, "module.map");
474 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
475 parseModuleMapFile(ModMapFile);
476 inferred = InferredDirectories.find(ParentDir);
477 }
478
479 if (inferred == InferredDirectories.end())
480 inferred = InferredDirectories.insert(
481 std::make_pair(ParentDir, InferredDirectory())).first;
482 }
483
484 if (inferred->second.InferModules) {
485 // We're allowed to infer for this directory, but make sure it's okay
486 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000487 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000488 canInfer = std::find(inferred->second.ExcludedModules.begin(),
489 inferred->second.ExcludedModules.end(),
490 Name) == inferred->second.ExcludedModules.end();
491
492 if (inferred->second.InferSystemModules)
493 IsSystem = true;
494 }
495 }
496 }
497
498 // If we're not allowed to infer a framework module, don't.
499 if (!canInfer)
500 return 0;
501 }
502
503
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000504 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000505 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000506 llvm::sys::path::append(UmbrellaName, "Headers");
507 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000508 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000509
510 // FIXME: If there's no umbrella header, we could probably scan the
511 // framework to load *everything*. But, it's not clear that this is a good
512 // idea.
513 if (!UmbrellaHeader)
514 return 0;
515
Douglas Gregorac252a32011-12-06 19:39:29 +0000516 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
517 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000518 if (IsSystem)
519 Result->IsSystem = IsSystem;
520
Douglas Gregorb7a78192012-01-04 23:32:19 +0000521 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000522 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000523
Douglas Gregor489ad432011-12-08 18:00:48 +0000524 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000525 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000526 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000527 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000528
529 // export *
530 Result->Exports.push_back(Module::ExportDecl(0, true));
531
Douglas Gregore209e502011-12-06 01:10:29 +0000532 // module * { export * }
533 Result->InferSubmodules = true;
534 Result->InferExportWildcard = true;
535
Douglas Gregorac252a32011-12-06 19:39:29 +0000536 // Look for subframeworks.
537 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000538 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000539 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000540 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000541 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000542 llvm::sys::path::native(SubframeworksDirName.str(),
543 SubframeworksDirNameNative);
544 for (llvm::sys::fs::directory_iterator
545 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000546 Dir != DirEnd && !EC; Dir.increment(EC)) {
547 if (!StringRef(Dir->path()).endswith(".framework"))
548 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000549
Douglas Gregorac252a32011-12-06 19:39:29 +0000550 if (const DirectoryEntry *SubframeworkDir
551 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000552 // Note: as an egregious but useful hack, we use the real path here and
553 // check whether it is actually a subdirectory of the parent directory.
554 // This will not be the case if the 'subframework' is actually a symlink
555 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000556 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
557 bool FoundParent = false;
558 do {
559 // Get the parent directory name.
560 SubframeworkDirName
561 = llvm::sys::path::parent_path(SubframeworkDirName);
562 if (SubframeworkDirName.empty())
563 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000564
Douglas Gregor713b7c02013-01-26 00:55:12 +0000565 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
566 FoundParent = true;
567 break;
568 }
569 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000570
Douglas Gregor713b7c02013-01-26 00:55:12 +0000571 if (!FoundParent)
572 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000573
Douglas Gregorac252a32011-12-06 19:39:29 +0000574 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000575 SmallString<32> NameBuf;
576 inferFrameworkModule(sanitizeFilenameAsIdentifier(
577 llvm::sys::path::stem(Dir->path()), NameBuf),
578 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000579 }
580 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000581
Douglas Gregor8767dc22013-01-14 17:57:51 +0000582 // If the module is a top-level framework, automatically link against the
583 // framework.
584 if (!Result->isSubFramework()) {
585 inferFrameworkLink(Result, FrameworkDir, FileMgr);
586 }
587
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000588 return Result;
589}
590
Douglas Gregore209e502011-12-06 01:10:29 +0000591void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000592 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000593 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000594 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000595}
596
Douglas Gregor77d029f2011-12-08 19:11:24 +0000597void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
598 Mod->Umbrella = UmbrellaDir;
599 UmbrellaDirs[UmbrellaDir] = Mod;
600}
601
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000602void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
603 bool Excluded) {
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000604 if (Excluded) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000605 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000606 } else {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000607 Mod->Headers.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000608 HeaderInfo.MarkFileModuleHeader(Header);
609 }
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000610 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000611}
612
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000613const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000614ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000615 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
616 return 0;
617
618 return SourceMgr->getFileEntryForID(
619 SourceMgr->getFileID(Module->DefinitionLoc));
620}
621
Douglas Gregora30cfe52011-11-11 19:10:28 +0000622void ModuleMap::dump() {
623 llvm::errs() << "Modules:";
624 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
625 MEnd = Modules.end();
626 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000627 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000628
629 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000630 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000631 H != HEnd; ++H) {
632 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000633 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000634 }
635}
636
Douglas Gregor90db2602011-12-02 01:47:07 +0000637bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
638 bool HadError = false;
639 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
640 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
641 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000642 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000643 Mod->Exports.push_back(Export);
644 else
645 HadError = true;
646 }
647 Mod->UnresolvedExports.clear();
648 return HadError;
649}
650
Douglas Gregor906d66a2013-03-20 21:10:35 +0000651bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
652 bool HadError = false;
653 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
654 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
655 Mod, Complain);
656 if (!OtherMod) {
657 HadError = true;
658 continue;
659 }
660
661 Module::Conflict Conflict;
662 Conflict.Other = OtherMod;
663 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
664 Mod->Conflicts.push_back(Conflict);
665 }
666 Mod->UnresolvedConflicts.clear();
667 return HadError;
668}
669
Douglas Gregor55988682011-12-05 16:33:54 +0000670Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
671 if (Loc.isInvalid())
672 return 0;
673
674 // Use the expansion location to determine which module we're in.
675 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
676 if (!ExpansionLoc.isFileID())
677 return 0;
678
679
680 const SourceManager &SrcMgr = Loc.getManager();
681 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000682
Douglas Gregor303aae92012-01-06 17:19:32 +0000683 while (const FileEntry *ExpansionFile
684 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
685 // Find the module that owns this header (if any).
686 if (Module *Mod = findModuleForHeader(ExpansionFile))
687 return Mod;
688
689 // No module owns this header, so look up the inclusion chain to see if
690 // any included header has an associated module.
691 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
692 if (IncludeLoc.isInvalid())
693 return 0;
694
695 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
696 }
697
698 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000699}
700
Douglas Gregora30cfe52011-11-11 19:10:28 +0000701//----------------------------------------------------------------------------//
702// Module map file parser
703//----------------------------------------------------------------------------//
704
705namespace clang {
706 /// \brief A token in a module map file.
707 struct MMToken {
708 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000709 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000710 ConfigMacros,
Douglas Gregor906d66a2013-03-20 21:10:35 +0000711 Conflict,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000712 EndOfFile,
713 HeaderKeyword,
714 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000715 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000716 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000717 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000718 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000719 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000720 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000721 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000722 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000723 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000724 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000725 StringLiteral,
726 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000727 RBrace,
728 LSquare,
729 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000730 } Kind;
731
732 unsigned Location;
733 unsigned StringLength;
734 const char *StringData;
735
736 void clear() {
737 Kind = EndOfFile;
738 Location = 0;
739 StringLength = 0;
740 StringData = 0;
741 }
742
743 bool is(TokenKind K) const { return Kind == K; }
744
745 SourceLocation getLocation() const {
746 return SourceLocation::getFromRawEncoding(Location);
747 }
748
749 StringRef getString() const {
750 return StringRef(StringData, StringLength);
751 }
752 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000753
754 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000755 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000756 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000757
758 /// \brief Whether this is a system module.
759 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000760
761 /// \brief Whether this is an exhaustive set of configuration macros.
762 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000763 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000764
Douglas Gregor82e52372012-11-06 19:39:40 +0000765
Douglas Gregora30cfe52011-11-11 19:10:28 +0000766 class ModuleMapParser {
767 Lexer &L;
768 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000769
770 /// \brief Default target information, used only for string literal
771 /// parsing.
772 const TargetInfo *Target;
773
Douglas Gregora30cfe52011-11-11 19:10:28 +0000774 DiagnosticsEngine &Diags;
775 ModuleMap &Map;
776
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000777 /// \brief The directory that this module map resides in.
778 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000779
780 /// \brief The directory containing Clang-supplied headers.
781 const DirectoryEntry *BuiltinIncludeDir;
782
Douglas Gregora30cfe52011-11-11 19:10:28 +0000783 /// \brief Whether an error occurred.
784 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000785
Douglas Gregora30cfe52011-11-11 19:10:28 +0000786 /// \brief Stores string data for the various string literals referenced
787 /// during parsing.
788 llvm::BumpPtrAllocator StringData;
789
790 /// \brief The current token.
791 MMToken Tok;
792
793 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000794 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000795
796 /// \brief Consume the current token and return its location.
797 SourceLocation consumeToken();
798
799 /// \brief Skip tokens until we reach the a token with the given kind
800 /// (or the end of the file).
801 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000802
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000803 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000804 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000805 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000806 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000807 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000808 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000809 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000810 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000811 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000812 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000813 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000814 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000815
Douglas Gregor6a1db482011-12-09 02:04:43 +0000816 const DirectoryEntry *getOverriddenHeaderSearchDir();
817
Douglas Gregora30cfe52011-11-11 19:10:28 +0000818 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000819 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000820 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000821 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000822 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000823 const DirectoryEntry *Directory,
824 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000825 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000826 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
827 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000828 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000829 Tok.clear();
830 consumeToken();
831 }
832
833 bool parseModuleMapFile();
834 };
835}
836
837SourceLocation ModuleMapParser::consumeToken() {
838retry:
839 SourceLocation Result = Tok.getLocation();
840 Tok.clear();
841
842 Token LToken;
843 L.LexFromRawLexer(LToken);
844 Tok.Location = LToken.getLocation().getRawEncoding();
845 switch (LToken.getKind()) {
846 case tok::raw_identifier:
847 Tok.StringData = LToken.getRawIdentifierData();
848 Tok.StringLength = LToken.getLength();
849 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000850 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000851 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000852 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000853 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000854 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000855 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000856 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000857 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000858 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000859 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000860 .Case("umbrella", MMToken::UmbrellaKeyword)
861 .Default(MMToken::Identifier);
862 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000863
864 case tok::comma:
865 Tok.Kind = MMToken::Comma;
866 break;
867
Douglas Gregora30cfe52011-11-11 19:10:28 +0000868 case tok::eof:
869 Tok.Kind = MMToken::EndOfFile;
870 break;
871
872 case tok::l_brace:
873 Tok.Kind = MMToken::LBrace;
874 break;
875
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000876 case tok::l_square:
877 Tok.Kind = MMToken::LSquare;
878 break;
879
Douglas Gregor90db2602011-12-02 01:47:07 +0000880 case tok::period:
881 Tok.Kind = MMToken::Period;
882 break;
883
Douglas Gregora30cfe52011-11-11 19:10:28 +0000884 case tok::r_brace:
885 Tok.Kind = MMToken::RBrace;
886 break;
887
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000888 case tok::r_square:
889 Tok.Kind = MMToken::RSquare;
890 break;
891
Douglas Gregor90db2602011-12-02 01:47:07 +0000892 case tok::star:
893 Tok.Kind = MMToken::Star;
894 break;
895
Douglas Gregora30cfe52011-11-11 19:10:28 +0000896 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000897 if (LToken.hasUDSuffix()) {
898 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
899 HadError = true;
900 goto retry;
901 }
902
Douglas Gregora30cfe52011-11-11 19:10:28 +0000903 // Parse the string literal.
904 LangOptions LangOpts;
905 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
906 if (StringLiteral.hadError)
907 goto retry;
908
909 // Copy the string literal into our string data allocator.
910 unsigned Length = StringLiteral.GetStringLength();
911 char *Saved = StringData.Allocate<char>(Length + 1);
912 memcpy(Saved, StringLiteral.GetString().data(), Length);
913 Saved[Length] = 0;
914
915 // Form the token.
916 Tok.Kind = MMToken::StringLiteral;
917 Tok.StringData = Saved;
918 Tok.StringLength = Length;
919 break;
920 }
921
922 case tok::comment:
923 goto retry;
924
925 default:
926 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
927 HadError = true;
928 goto retry;
929 }
930
931 return Result;
932}
933
934void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
935 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000936 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000937 do {
938 switch (Tok.Kind) {
939 case MMToken::EndOfFile:
940 return;
941
942 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000943 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000944 return;
945
946 ++braceDepth;
947 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000948
949 case MMToken::LSquare:
950 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
951 return;
952
953 ++squareDepth;
954 break;
955
Douglas Gregora30cfe52011-11-11 19:10:28 +0000956 case MMToken::RBrace:
957 if (braceDepth > 0)
958 --braceDepth;
959 else if (Tok.is(K))
960 return;
961 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000962
963 case MMToken::RSquare:
964 if (squareDepth > 0)
965 --squareDepth;
966 else if (Tok.is(K))
967 return;
968 break;
969
Douglas Gregora30cfe52011-11-11 19:10:28 +0000970 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000971 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000972 return;
973 break;
974 }
975
976 consumeToken();
977 } while (true);
978}
979
Douglas Gregor587986e2011-12-07 02:23:45 +0000980/// \brief Parse a module-id.
981///
982/// module-id:
983/// identifier
984/// identifier '.' module-id
985///
986/// \returns true if an error occurred, false otherwise.
987bool ModuleMapParser::parseModuleId(ModuleId &Id) {
988 Id.clear();
989 do {
990 if (Tok.is(MMToken::Identifier)) {
991 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
992 consumeToken();
993 } else {
994 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
995 return true;
996 }
997
998 if (!Tok.is(MMToken::Period))
999 break;
1000
1001 consumeToken();
1002 } while (true);
1003
1004 return false;
1005}
1006
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001007namespace {
1008 /// \brief Enumerates the known attributes.
1009 enum AttributeKind {
1010 /// \brief An unknown attribute.
1011 AT_unknown,
1012 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001013 AT_system,
1014 /// \brief The 'exhaustive' attribute.
1015 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001016 };
1017}
1018
Douglas Gregora30cfe52011-11-11 19:10:28 +00001019/// \brief Parse a module declaration.
1020///
1021/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001022/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1023/// { module-member* }
1024///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001025/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001026/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001027/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001028/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001029/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001030/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001031///
1032/// submodule-declaration:
1033/// module-declaration
1034/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001035void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001036 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1037 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +00001038 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001039 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001040 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001041 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001042
Douglas Gregord620a842011-12-06 17:16:41 +00001043 // Parse 'explicit' keyword, if present.
1044 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001045 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001046 Explicit = true;
1047 }
1048
1049 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001050 if (Tok.is(MMToken::FrameworkKeyword)) {
1051 consumeToken();
1052 Framework = true;
1053 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001054
1055 // Parse 'module' keyword.
1056 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001057 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001058 consumeToken();
1059 HadError = true;
1060 return;
1061 }
1062 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001063
1064 // If we have a wildcard for the module name, this is an inferred submodule.
1065 // Parse it.
1066 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001067 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001068
1069 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001070 ModuleId Id;
1071 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001072 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001073 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001074 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001075
Douglas Gregor587986e2011-12-07 02:23:45 +00001076 if (ActiveModule) {
1077 if (Id.size() > 1) {
1078 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1079 << SourceRange(Id.front().second, Id.back().second);
1080
1081 HadError = true;
1082 return;
1083 }
1084 } else if (Id.size() == 1 && Explicit) {
1085 // Top-level modules can't be explicit.
1086 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1087 Explicit = false;
1088 ExplicitLoc = SourceLocation();
1089 HadError = true;
1090 }
1091
1092 Module *PreviousActiveModule = ActiveModule;
1093 if (Id.size() > 1) {
1094 // This module map defines a submodule. Go find the module of which it
1095 // is a submodule.
1096 ActiveModule = 0;
1097 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1098 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1099 ActiveModule = Next;
1100 continue;
1101 }
1102
1103 if (ActiveModule) {
1104 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1105 << Id[I].first << ActiveModule->getTopLevelModule();
1106 } else {
1107 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1108 }
1109 HadError = true;
1110 return;
1111 }
1112 }
1113
1114 StringRef ModuleName = Id.back().first;
1115 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001116
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001117 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001118 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001119 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001120
Douglas Gregora30cfe52011-11-11 19:10:28 +00001121 // Parse the opening brace.
1122 if (!Tok.is(MMToken::LBrace)) {
1123 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1124 << ModuleName;
1125 HadError = true;
1126 return;
1127 }
1128 SourceLocation LBraceLoc = consumeToken();
1129
1130 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001131 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001132 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1133 // Skip the module definition.
1134 skipUntil(MMToken::RBrace);
1135 if (Tok.is(MMToken::RBrace))
1136 consumeToken();
1137 else {
1138 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1139 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1140 HadError = true;
1141 }
1142 return;
1143 }
1144
Douglas Gregora30cfe52011-11-11 19:10:28 +00001145 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1146 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001147 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001148
1149 // Skip the module definition.
1150 skipUntil(MMToken::RBrace);
1151 if (Tok.is(MMToken::RBrace))
1152 consumeToken();
1153
1154 HadError = true;
1155 return;
1156 }
1157
1158 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001159 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1160 Explicit).first;
1161 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001162 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001163 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001164
1165 bool Done = false;
1166 do {
1167 switch (Tok.Kind) {
1168 case MMToken::EndOfFile:
1169 case MMToken::RBrace:
1170 Done = true;
1171 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001172
1173 case MMToken::ConfigMacros:
1174 parseConfigMacros();
1175 break;
1176
Douglas Gregor906d66a2013-03-20 21:10:35 +00001177 case MMToken::Conflict:
1178 parseConflict();
1179 break;
1180
Douglas Gregora30cfe52011-11-11 19:10:28 +00001181 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001182 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001183 case MMToken::ModuleKeyword:
1184 parseModuleDecl();
1185 break;
1186
Douglas Gregor90db2602011-12-02 01:47:07 +00001187 case MMToken::ExportKeyword:
1188 parseExportDecl();
1189 break;
1190
Douglas Gregor51f564f2011-12-31 04:05:44 +00001191 case MMToken::RequiresKeyword:
1192 parseRequiresDecl();
1193 break;
1194
Douglas Gregor77d029f2011-12-08 19:11:24 +00001195 case MMToken::UmbrellaKeyword: {
1196 SourceLocation UmbrellaLoc = consumeToken();
1197 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001198 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001199 else
1200 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001201 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001202 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001203
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001204 case MMToken::ExcludeKeyword: {
1205 SourceLocation ExcludeLoc = consumeToken();
1206 if (Tok.is(MMToken::HeaderKeyword)) {
1207 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1208 } else {
1209 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1210 << "exclude";
1211 }
1212 break;
1213 }
1214
Douglas Gregor489ad432011-12-08 18:00:48 +00001215 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001216 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001217 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001218
1219 case MMToken::LinkKeyword:
1220 parseLinkDecl();
1221 break;
1222
Douglas Gregora30cfe52011-11-11 19:10:28 +00001223 default:
1224 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1225 consumeToken();
1226 break;
1227 }
1228 } while (!Done);
1229
1230 if (Tok.is(MMToken::RBrace))
1231 consumeToken();
1232 else {
1233 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1234 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1235 HadError = true;
1236 }
1237
Douglas Gregor8767dc22013-01-14 17:57:51 +00001238 // If the active module is a top-level framework, and there are no link
1239 // libraries, automatically link against the framework.
1240 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1241 ActiveModule->LinkLibraries.empty()) {
1242 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1243 }
1244
Douglas Gregor587986e2011-12-07 02:23:45 +00001245 // We're done parsing this module. Pop back to the previous module.
1246 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001247}
Douglas Gregord620a842011-12-06 17:16:41 +00001248
Douglas Gregor51f564f2011-12-31 04:05:44 +00001249/// \brief Parse a requires declaration.
1250///
1251/// requires-declaration:
1252/// 'requires' feature-list
1253///
1254/// feature-list:
1255/// identifier ',' feature-list
1256/// identifier
1257void ModuleMapParser::parseRequiresDecl() {
1258 assert(Tok.is(MMToken::RequiresKeyword));
1259
1260 // Parse 'requires' keyword.
1261 consumeToken();
1262
1263 // Parse the feature-list.
1264 do {
1265 if (!Tok.is(MMToken::Identifier)) {
1266 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1267 HadError = true;
1268 return;
1269 }
1270
1271 // Consume the feature name.
1272 std::string Feature = Tok.getString();
1273 consumeToken();
1274
1275 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001276 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001277
1278 if (!Tok.is(MMToken::Comma))
1279 break;
1280
1281 // Consume the comma.
1282 consumeToken();
1283 } while (true);
1284}
1285
Douglas Gregord620a842011-12-06 17:16:41 +00001286/// \brief Append to \p Paths the set of paths needed to get to the
1287/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001288static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001289 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001290 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001291 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001292 for (; Mod; Mod = Mod->Parent) {
1293 if (Mod->IsFramework)
1294 Paths.push_back(Mod->Name);
1295 }
1296
1297 if (Paths.empty())
1298 return;
1299
1300 // Add Frameworks/Name.framework for each subframework.
1301 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1302 llvm::sys::path::append(Path, "Frameworks");
1303 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1304 }
1305}
1306
Douglas Gregora30cfe52011-11-11 19:10:28 +00001307/// \brief Parse a header declaration.
1308///
1309/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001310/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001311/// 'exclude'[opt] 'header' string-literal
1312void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1313 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001314 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001315 consumeToken();
1316
Douglas Gregor489ad432011-12-08 18:00:48 +00001317 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001318 bool Exclude = ExcludeLoc.isValid();
1319 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001320 // Parse the header name.
1321 if (!Tok.is(MMToken::StringLiteral)) {
1322 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1323 << "header";
1324 HadError = true;
1325 return;
1326 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001327 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001328 SourceLocation FileNameLoc = consumeToken();
1329
Douglas Gregor77d029f2011-12-08 19:11:24 +00001330 // Check whether we already have an umbrella.
1331 if (Umbrella && ActiveModule->Umbrella) {
1332 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1333 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001334 HadError = true;
1335 return;
1336 }
1337
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001338 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001339 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001340 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001341 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001342 if (llvm::sys::path::is_absolute(FileName)) {
1343 PathName = FileName;
1344 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001345 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1346 PathName = Dir->getName();
1347 llvm::sys::path::append(PathName, FileName);
1348 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001349 } else {
1350 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001351 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001352 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001353
Douglas Gregord620a842011-12-06 17:16:41 +00001354 if (ActiveModule->isPartOfFramework()) {
1355 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001356
1357 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001358 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001359 llvm::sys::path::append(PathName, FileName);
1360 File = SourceMgr.getFileManager().getFile(PathName);
1361
1362 if (!File) {
1363 // Check whether this file is in the private headers.
1364 PathName.resize(PathLength);
1365 llvm::sys::path::append(PathName, "PrivateHeaders");
1366 llvm::sys::path::append(PathName, FileName);
1367 File = SourceMgr.getFileManager().getFile(PathName);
1368 }
1369 } else {
1370 // Lookup for normal headers.
1371 llvm::sys::path::append(PathName, FileName);
1372 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001373
1374 // If this is a system module with a top-level header, this header
1375 // may have a counterpart (or replacement) in the set of headers
1376 // supplied by Clang. Find that builtin header.
1377 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1378 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001379 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001380 llvm::sys::path::append(BuiltinPathName, FileName);
1381 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1382
1383 // If Clang supplies this header but the underlying system does not,
1384 // just silently swap in our builtin version. Otherwise, we'll end
1385 // up adding both (later).
1386 if (!File && BuiltinFile) {
1387 File = BuiltinFile;
1388 BuiltinFile = 0;
1389 }
1390 }
Douglas Gregord620a842011-12-06 17:16:41 +00001391 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001392 }
Douglas Gregora8654052011-11-17 22:09:43 +00001393
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001394 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1395 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001396 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001397 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001398 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001399 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001400 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001401 } else if (Umbrella) {
1402 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001403 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001404 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001405 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001406 HadError = true;
1407 } else {
1408 // Record this umbrella header.
1409 Map.setUmbrellaHeader(ActiveModule, File);
1410 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001411 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001412 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001413 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001414
1415 // If there is a builtin counterpart to this file, add it now.
1416 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001417 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001418 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001419 } else if (!Exclude) {
1420 // Ignore excluded header files. They're optional anyway.
1421
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001422 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001423 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001424 HadError = true;
1425 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001426}
1427
Douglas Gregor77d029f2011-12-08 19:11:24 +00001428/// \brief Parse an umbrella directory declaration.
1429///
1430/// umbrella-dir-declaration:
1431/// umbrella string-literal
1432void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1433 // Parse the directory name.
1434 if (!Tok.is(MMToken::StringLiteral)) {
1435 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1436 << "umbrella";
1437 HadError = true;
1438 return;
1439 }
1440
1441 std::string DirName = Tok.getString();
1442 SourceLocation DirNameLoc = consumeToken();
1443
1444 // Check whether we already have an umbrella.
1445 if (ActiveModule->Umbrella) {
1446 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1447 << ActiveModule->getFullModuleName();
1448 HadError = true;
1449 return;
1450 }
1451
1452 // Look for this file.
1453 const DirectoryEntry *Dir = 0;
1454 if (llvm::sys::path::is_absolute(DirName))
1455 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1456 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001457 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001458 PathName = Directory->getName();
1459 llvm::sys::path::append(PathName, DirName);
1460 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1461 }
1462
1463 if (!Dir) {
1464 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1465 << DirName;
1466 HadError = true;
1467 return;
1468 }
1469
1470 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1471 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1472 << OwningModule->getFullModuleName();
1473 HadError = true;
1474 return;
1475 }
1476
1477 // Record this umbrella directory.
1478 Map.setUmbrellaDir(ActiveModule, Dir);
1479}
1480
Douglas Gregor90db2602011-12-02 01:47:07 +00001481/// \brief Parse a module export declaration.
1482///
1483/// export-declaration:
1484/// 'export' wildcard-module-id
1485///
1486/// wildcard-module-id:
1487/// identifier
1488/// '*'
1489/// identifier '.' wildcard-module-id
1490void ModuleMapParser::parseExportDecl() {
1491 assert(Tok.is(MMToken::ExportKeyword));
1492 SourceLocation ExportLoc = consumeToken();
1493
1494 // Parse the module-id with an optional wildcard at the end.
1495 ModuleId ParsedModuleId;
1496 bool Wildcard = false;
1497 do {
1498 if (Tok.is(MMToken::Identifier)) {
1499 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1500 Tok.getLocation()));
1501 consumeToken();
1502
1503 if (Tok.is(MMToken::Period)) {
1504 consumeToken();
1505 continue;
1506 }
1507
1508 break;
1509 }
1510
1511 if(Tok.is(MMToken::Star)) {
1512 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001513 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001514 break;
1515 }
1516
1517 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1518 HadError = true;
1519 return;
1520 } while (true);
1521
1522 Module::UnresolvedExportDecl Unresolved = {
1523 ExportLoc, ParsedModuleId, Wildcard
1524 };
1525 ActiveModule->UnresolvedExports.push_back(Unresolved);
1526}
1527
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001528/// \brief Parse a link declaration.
1529///
1530/// module-declaration:
1531/// 'link' 'framework'[opt] string-literal
1532void ModuleMapParser::parseLinkDecl() {
1533 assert(Tok.is(MMToken::LinkKeyword));
1534 SourceLocation LinkLoc = consumeToken();
1535
1536 // Parse the optional 'framework' keyword.
1537 bool IsFramework = false;
1538 if (Tok.is(MMToken::FrameworkKeyword)) {
1539 consumeToken();
1540 IsFramework = true;
1541 }
1542
1543 // Parse the library name
1544 if (!Tok.is(MMToken::StringLiteral)) {
1545 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1546 << IsFramework << SourceRange(LinkLoc);
1547 HadError = true;
1548 return;
1549 }
1550
1551 std::string LibraryName = Tok.getString();
1552 consumeToken();
1553 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1554 IsFramework));
1555}
1556
Douglas Gregor63a72682013-03-20 00:22:05 +00001557/// \brief Parse a configuration macro declaration.
1558///
1559/// module-declaration:
1560/// 'config_macros' attributes[opt] config-macro-list?
1561///
1562/// config-macro-list:
1563/// identifier (',' identifier)?
1564void ModuleMapParser::parseConfigMacros() {
1565 assert(Tok.is(MMToken::ConfigMacros));
1566 SourceLocation ConfigMacrosLoc = consumeToken();
1567
1568 // Only top-level modules can have configuration macros.
1569 if (ActiveModule->Parent) {
1570 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1571 }
1572
1573 // Parse the optional attributes.
1574 Attributes Attrs;
1575 parseOptionalAttributes(Attrs);
1576 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1577 ActiveModule->ConfigMacrosExhaustive = true;
1578 }
1579
1580 // If we don't have an identifier, we're done.
1581 if (!Tok.is(MMToken::Identifier))
1582 return;
1583
1584 // Consume the first identifier.
1585 if (!ActiveModule->Parent) {
1586 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1587 }
1588 consumeToken();
1589
1590 do {
1591 // If there's a comma, consume it.
1592 if (!Tok.is(MMToken::Comma))
1593 break;
1594 consumeToken();
1595
1596 // We expect to see a macro name here.
1597 if (!Tok.is(MMToken::Identifier)) {
1598 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1599 break;
1600 }
1601
1602 // Consume the macro name.
1603 if (!ActiveModule->Parent) {
1604 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1605 }
1606 consumeToken();
1607 } while (true);
1608}
1609
Douglas Gregor906d66a2013-03-20 21:10:35 +00001610/// \brief Format a module-id into a string.
1611static std::string formatModuleId(const ModuleId &Id) {
1612 std::string result;
1613 {
1614 llvm::raw_string_ostream OS(result);
1615
1616 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1617 if (I)
1618 OS << ".";
1619 OS << Id[I].first;
1620 }
1621 }
1622
1623 return result;
1624}
1625
1626/// \brief Parse a conflict declaration.
1627///
1628/// module-declaration:
1629/// 'conflict' module-id ',' string-literal
1630void ModuleMapParser::parseConflict() {
1631 assert(Tok.is(MMToken::Conflict));
1632 SourceLocation ConflictLoc = consumeToken();
1633 Module::UnresolvedConflict Conflict;
1634
1635 // Parse the module-id.
1636 if (parseModuleId(Conflict.Id))
1637 return;
1638
1639 // Parse the ','.
1640 if (!Tok.is(MMToken::Comma)) {
1641 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1642 << SourceRange(ConflictLoc);
1643 return;
1644 }
1645 consumeToken();
1646
1647 // Parse the message.
1648 if (!Tok.is(MMToken::StringLiteral)) {
1649 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1650 << formatModuleId(Conflict.Id);
1651 return;
1652 }
1653 Conflict.Message = Tok.getString().str();
1654 consumeToken();
1655
1656 // Add this unresolved conflict.
1657 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1658}
1659
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001660/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001661///
1662/// module-declaration:
1663/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1664/// { inferred-module-member* }
1665///
1666/// inferred-module-member:
1667/// 'export' '*'
1668/// 'exclude' identifier
1669void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001670 assert(Tok.is(MMToken::Star));
1671 SourceLocation StarLoc = consumeToken();
1672 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001673
Douglas Gregor1e123682011-12-05 22:27:44 +00001674 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001675 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001676 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1677 Failed = true;
1678 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001679
1680 if (ActiveModule) {
1681 // Inferred modules must have umbrella directories.
1682 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1683 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1684 Failed = true;
1685 }
1686
1687 // Check for redefinition of an inferred module.
1688 if (!Failed && ActiveModule->InferSubmodules) {
1689 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1690 if (ActiveModule->InferredSubmoduleLoc.isValid())
1691 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1692 diag::note_mmap_prev_definition);
1693 Failed = true;
1694 }
1695
1696 // Check for the 'framework' keyword, which is not permitted here.
1697 if (Framework) {
1698 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1699 Framework = false;
1700 }
1701 } else if (Explicit) {
1702 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1703 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001704 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001705
Douglas Gregor1e123682011-12-05 22:27:44 +00001706 // If there were any problems with this inferred submodule, skip its body.
1707 if (Failed) {
1708 if (Tok.is(MMToken::LBrace)) {
1709 consumeToken();
1710 skipUntil(MMToken::RBrace);
1711 if (Tok.is(MMToken::RBrace))
1712 consumeToken();
1713 }
1714 HadError = true;
1715 return;
1716 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001717
1718 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001719 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001720 parseOptionalAttributes(Attrs);
1721
1722 if (ActiveModule) {
1723 // Note that we have an inferred submodule.
1724 ActiveModule->InferSubmodules = true;
1725 ActiveModule->InferredSubmoduleLoc = StarLoc;
1726 ActiveModule->InferExplicitSubmodules = Explicit;
1727 } else {
1728 // We'll be inferring framework modules for this directory.
1729 Map.InferredDirectories[Directory].InferModules = true;
1730 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1731 }
1732
Douglas Gregor1e123682011-12-05 22:27:44 +00001733 // Parse the opening brace.
1734 if (!Tok.is(MMToken::LBrace)) {
1735 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1736 HadError = true;
1737 return;
1738 }
1739 SourceLocation LBraceLoc = consumeToken();
1740
1741 // Parse the body of the inferred submodule.
1742 bool Done = false;
1743 do {
1744 switch (Tok.Kind) {
1745 case MMToken::EndOfFile:
1746 case MMToken::RBrace:
1747 Done = true;
1748 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001749
1750 case MMToken::ExcludeKeyword: {
1751 if (ActiveModule) {
1752 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001753 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001754 consumeToken();
1755 break;
1756 }
1757
1758 consumeToken();
1759 if (!Tok.is(MMToken::Identifier)) {
1760 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1761 break;
1762 }
1763
1764 Map.InferredDirectories[Directory].ExcludedModules
1765 .push_back(Tok.getString());
1766 consumeToken();
1767 break;
1768 }
1769
1770 case MMToken::ExportKeyword:
1771 if (!ActiveModule) {
1772 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001773 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001774 consumeToken();
1775 break;
1776 }
1777
Douglas Gregor1e123682011-12-05 22:27:44 +00001778 consumeToken();
1779 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001780 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001781 else
1782 Diags.Report(Tok.getLocation(),
1783 diag::err_mmap_expected_export_wildcard);
1784 consumeToken();
1785 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001786
Douglas Gregor1e123682011-12-05 22:27:44 +00001787 case MMToken::ExplicitKeyword:
1788 case MMToken::ModuleKeyword:
1789 case MMToken::HeaderKeyword:
1790 case MMToken::UmbrellaKeyword:
1791 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001792 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001793 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001794 consumeToken();
1795 break;
1796 }
1797 } while (!Done);
1798
1799 if (Tok.is(MMToken::RBrace))
1800 consumeToken();
1801 else {
1802 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1803 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1804 HadError = true;
1805 }
1806}
1807
Douglas Gregor82e52372012-11-06 19:39:40 +00001808/// \brief Parse optional attributes.
1809///
1810/// attributes:
1811/// attribute attributes
1812/// attribute
1813///
1814/// attribute:
1815/// [ identifier ]
1816///
1817/// \param Attrs Will be filled in with the parsed attributes.
1818///
1819/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001820bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001821 bool HadError = false;
1822
1823 while (Tok.is(MMToken::LSquare)) {
1824 // Consume the '['.
1825 SourceLocation LSquareLoc = consumeToken();
1826
1827 // Check whether we have an attribute name here.
1828 if (!Tok.is(MMToken::Identifier)) {
1829 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1830 skipUntil(MMToken::RSquare);
1831 if (Tok.is(MMToken::RSquare))
1832 consumeToken();
1833 HadError = true;
1834 }
1835
1836 // Decode the attribute name.
1837 AttributeKind Attribute
1838 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001839 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00001840 .Case("system", AT_system)
1841 .Default(AT_unknown);
1842 switch (Attribute) {
1843 case AT_unknown:
1844 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1845 << Tok.getString();
1846 break;
1847
1848 case AT_system:
1849 Attrs.IsSystem = true;
1850 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001851
1852 case AT_exhaustive:
1853 Attrs.IsExhaustive = true;
1854 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001855 }
1856 consumeToken();
1857
1858 // Consume the ']'.
1859 if (!Tok.is(MMToken::RSquare)) {
1860 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1861 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1862 skipUntil(MMToken::RSquare);
1863 HadError = true;
1864 }
1865
1866 if (Tok.is(MMToken::RSquare))
1867 consumeToken();
1868 }
1869
1870 return HadError;
1871}
1872
Douglas Gregor6a1db482011-12-09 02:04:43 +00001873/// \brief If there is a specific header search directory due the presence
1874/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1875const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1876 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1877 // If we have an umbrella directory, use that.
1878 if (Mod->hasUmbrellaDir())
1879 return Mod->getUmbrellaDir();
1880
1881 // If we have a framework directory, stop looking.
1882 if (Mod->IsFramework)
1883 return 0;
1884 }
1885
1886 return 0;
1887}
1888
Douglas Gregora30cfe52011-11-11 19:10:28 +00001889/// \brief Parse a module map file.
1890///
1891/// module-map-file:
1892/// module-declaration*
1893bool ModuleMapParser::parseModuleMapFile() {
1894 do {
1895 switch (Tok.Kind) {
1896 case MMToken::EndOfFile:
1897 return HadError;
1898
Douglas Gregor587986e2011-12-07 02:23:45 +00001899 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001900 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001901 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001902 parseModuleDecl();
1903 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001904
Douglas Gregor51f564f2011-12-31 04:05:44 +00001905 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00001906 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00001907 case MMToken::Conflict:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001908 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001909 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001910 case MMToken::HeaderKeyword:
1911 case MMToken::Identifier:
1912 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001913 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001914 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001915 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001916 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001917 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001918 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001919 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001920 case MMToken::StringLiteral:
1921 case MMToken::UmbrellaKeyword:
1922 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1923 HadError = true;
1924 consumeToken();
1925 break;
1926 }
1927 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001928}
1929
1930bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001931 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1932 = ParsedModuleMap.find(File);
1933 if (Known != ParsedModuleMap.end())
1934 return Known->second;
1935
Douglas Gregordc58aa72012-01-30 06:01:29 +00001936 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001937 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1938 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1939 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001940 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001941
1942 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001943 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1944 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001945 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001946 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001947 bool Result = Parser.parseModuleMapFile();
1948 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001949 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001950 return Result;
1951}