blob: acb5694191e2354131e50b11d2ade4514effb162 [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"
Rafael Espindola8229d222013-06-11 22:15:02 +000030#include "llvm/Support/Path.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),
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +000090 BuiltinIncludeDir(0), CompilingModule(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()))) {
Douglas Gregor30a16f12013-05-10 22:52:27 +0000186 HeaderInfo.loadTopLevelSystemModules();
Douglas Gregordb3910b2013-05-02 17:58:30 +0000187
188 // Check again.
189 Known = Headers.find(File);
190 if (Known != Headers.end()) {
191 // If a header is not available, don't report that it maps to anything.
192 if (!Known->second.isAvailable())
193 return 0;
194
195 return Known->second.getModule();
196 }
197 }
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000198
Douglas Gregoradb97992011-11-16 23:02:25 +0000199 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000200 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor713b7c02013-01-26 00:55:12 +0000201
Douglas Gregoraa60f9c2013-01-04 19:44:26 +0000202 // Note: as an egregious but useful hack we use the real path here, because
203 // frameworks moving from top-level frameworks to embedded frameworks tend
204 // to be symlinked from the top-level location to the embedded location,
205 // and we need to resolve lookups as if we had found the embedded location.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000206 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregore209e502011-12-06 01:10:29 +0000207
208 // Keep walking up the directory hierarchy, looking for a directory with
209 // an umbrella header.
210 do {
211 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
212 = UmbrellaDirs.find(Dir);
213 if (KnownDir != UmbrellaDirs.end()) {
214 Module *Result = KnownDir->second;
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000215
216 // Search up the module stack until we find a module with an umbrella
Douglas Gregor10694ce2011-12-08 17:39:04 +0000217 // directory.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000218 Module *UmbrellaModule = Result;
Douglas Gregor10694ce2011-12-08 17:39:04 +0000219 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000220 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000221
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000222 if (UmbrellaModule->InferSubmodules) {
Douglas Gregore209e502011-12-06 01:10:29 +0000223 // Infer submodules for each of the directories we found between
224 // the directory of the umbrella header and the directory where
225 // the actual header is located.
Douglas Gregor23af6d52011-12-07 22:05:21 +0000226 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregore209e502011-12-06 01:10:29 +0000227
Douglas Gregor6a1db482011-12-09 02:04:43 +0000228 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregore209e502011-12-06 01:10:29 +0000229 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000230 SmallString<32> NameBuf;
231 StringRef Name = sanitizeFilenameAsIdentifier(
232 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
233 NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000234 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000235 Explicit).first;
Douglas Gregore209e502011-12-06 01:10:29 +0000236
237 // Associate the module and the directory.
238 UmbrellaDirs[SkippedDirs[I-1]] = Result;
239
240 // If inferred submodules export everything they import, add a
241 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000242 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000243 Result->Exports.push_back(Module::ExportDecl(0, true));
244 }
245
246 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000247 SmallString<32> NameBuf;
248 StringRef Name = sanitizeFilenameAsIdentifier(
249 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregore209e502011-12-06 01:10:29 +0000250 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor23af6d52011-12-07 22:05:21 +0000251 Explicit).first;
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +0000252 Result->addTopHeader(File);
Douglas Gregore209e502011-12-06 01:10:29 +0000253
254 // If inferred submodules export everything they import, add a
255 // wildcard to the set of exports.
Douglas Gregor9f74f4f2011-12-06 16:17:15 +0000256 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregore209e502011-12-06 01:10:29 +0000257 Result->Exports.push_back(Module::ExportDecl(0, true));
258 } else {
259 // Record each of the directories we stepped through as being part of
260 // the module we found, since the umbrella header covers them all.
261 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
262 UmbrellaDirs[SkippedDirs[I]] = Result;
263 }
264
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000265 Headers[File] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000266
267 // If a header corresponds to an unavailable module, don't report
268 // that it maps to anything.
269 if (!Result->isAvailable())
270 return 0;
271
Douglas Gregore209e502011-12-06 01:10:29 +0000272 return Result;
273 }
274
275 SkippedDirs.push_back(Dir);
276
Douglas Gregoradb97992011-11-16 23:02:25 +0000277 // Retrieve our parent path.
278 DirName = llvm::sys::path::parent_path(DirName);
279 if (DirName.empty())
280 break;
281
282 // Resolve the parent path to a directory entry.
283 Dir = SourceMgr->getFileManager().getDirectory(DirName);
Douglas Gregore209e502011-12-06 01:10:29 +0000284 } while (Dir);
Douglas Gregoradb97992011-11-16 23:02:25 +0000285
Douglas Gregor65f3b5e2011-11-11 22:18:48 +0000286 return 0;
287}
288
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000289bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
290 HeadersMap::const_iterator Known = Headers.find(Header);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000291 if (Known != Headers.end())
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000292 return !Known->second.isAvailable();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000293
294 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000295 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000296 StringRef DirName = Dir->getName();
297
298 // Keep walking up the directory hierarchy, looking for a directory with
299 // an umbrella header.
300 do {
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000301 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor51f564f2011-12-31 04:05:44 +0000302 = UmbrellaDirs.find(Dir);
303 if (KnownDir != UmbrellaDirs.end()) {
304 Module *Found = KnownDir->second;
305 if (!Found->isAvailable())
306 return true;
307
308 // Search up the module stack until we find a module with an umbrella
309 // directory.
310 Module *UmbrellaModule = Found;
311 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
312 UmbrellaModule = UmbrellaModule->Parent;
313
314 if (UmbrellaModule->InferSubmodules) {
315 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
316 // Find or create the module that corresponds to this directory name.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000317 SmallString<32> NameBuf;
318 StringRef Name = sanitizeFilenameAsIdentifier(
319 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
320 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000321 Found = lookupModuleQualified(Name, Found);
322 if (!Found)
323 return false;
324 if (!Found->isAvailable())
325 return true;
326 }
327
328 // Infer a submodule with the same name as this header file.
Douglas Gregor8b48e082012-10-12 21:15:50 +0000329 SmallString<32> NameBuf;
330 StringRef Name = sanitizeFilenameAsIdentifier(
331 llvm::sys::path::stem(Header->getName()),
332 NameBuf);
Douglas Gregor51f564f2011-12-31 04:05:44 +0000333 Found = lookupModuleQualified(Name, Found);
334 if (!Found)
335 return false;
336 }
337
338 return !Found->isAvailable();
339 }
340
341 SkippedDirs.push_back(Dir);
342
343 // Retrieve our parent path.
344 DirName = llvm::sys::path::parent_path(DirName);
345 if (DirName.empty())
346 break;
347
348 // Resolve the parent path to a directory entry.
349 Dir = SourceMgr->getFileManager().getDirectory(DirName);
350 } while (Dir);
351
352 return false;
353}
354
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000355Module *ModuleMap::findModule(StringRef Name) const {
356 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor484535e2011-11-11 23:20:24 +0000357 if (Known != Modules.end())
358 return Known->getValue();
359
360 return 0;
361}
362
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000363Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
364 Module *Context) const {
Douglas Gregor90db2602011-12-02 01:47:07 +0000365 for(; Context; Context = Context->Parent) {
366 if (Module *Sub = lookupModuleQualified(Name, Context))
367 return Sub;
368 }
369
370 return findModule(Name);
371}
372
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000373Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor90db2602011-12-02 01:47:07 +0000374 if (!Context)
375 return findModule(Name);
376
Douglas Gregorb7a78192012-01-04 23:32:19 +0000377 return Context->findSubmodule(Name);
Douglas Gregor90db2602011-12-02 01:47:07 +0000378}
379
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000380std::pair<Module *, bool>
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000381ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
382 bool IsExplicit) {
383 // Try to find an existing module with this name.
Douglas Gregorb7a78192012-01-04 23:32:19 +0000384 if (Module *Sub = lookupModuleQualified(Name, Parent))
385 return std::make_pair(Sub, false);
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000386
387 // Create a new module with this name.
388 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
389 IsExplicit);
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000390 if (!Parent) {
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000391 Modules[Name] = Result;
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000392 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
393 Name == LangOpts.CurrentModule) {
394 CompilingModule = Result;
395 }
396 }
Douglas Gregor392ed2b2011-11-30 17:33:56 +0000397 return std::make_pair(Result, true);
398}
399
Douglas Gregor82e52372012-11-06 19:39:40 +0000400bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000401 StringRef Name, bool &IsSystem) const {
Douglas Gregor82e52372012-11-06 19:39:40 +0000402 // Check whether we have already looked into the parent directory
403 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000404 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000405 inferred = InferredDirectories.find(ParentDir);
406 if (inferred == InferredDirectories.end())
407 return false;
408
409 if (!inferred->second.InferModules)
410 return false;
411
412 // We're allowed to infer for this directory, but make sure it's okay
413 // to infer this particular module.
414 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
415 inferred->second.ExcludedModules.end(),
416 Name) == inferred->second.ExcludedModules.end();
417
418 if (canInfer && inferred->second.InferSystemModules)
419 IsSystem = true;
420
421 return canInfer;
422}
423
Douglas Gregor8767dc22013-01-14 17:57:51 +0000424/// \brief For a framework module, infer the framework against which we
425/// should link.
426static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
427 FileManager &FileMgr) {
428 assert(Mod->IsFramework && "Can only infer linking for framework modules");
429 assert(!Mod->isSubFramework() &&
430 "Can only infer linking for top-level frameworks");
431
432 SmallString<128> LibName;
433 LibName += FrameworkDir->getName();
434 llvm::sys::path::append(LibName, Mod->Name);
435 if (FileMgr.getFile(LibName)) {
436 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
437 /*IsFramework=*/true));
438 }
439}
440
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000441Module *
Douglas Gregor82e52372012-11-06 19:39:40 +0000442ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregorac252a32011-12-06 19:39:29 +0000443 const DirectoryEntry *FrameworkDir,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000444 bool IsSystem,
Douglas Gregorac252a32011-12-06 19:39:29 +0000445 Module *Parent) {
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000446 // Check whether we've already found this module.
Douglas Gregorac252a32011-12-06 19:39:29 +0000447 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
448 return Mod;
449
450 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor82e52372012-11-06 19:39:40 +0000451
452 // If the framework has a parent path from which we're allowed to infer
453 // a framework module, do so.
454 if (!Parent) {
Douglas Gregor7005b902013-01-10 01:43:00 +0000455 // Determine whether we're allowed to infer a module map.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000456
Douglas Gregor7005b902013-01-10 01:43:00 +0000457 // Note: as an egregious but useful hack we use the real path here, because
458 // we might be looking at an embedded framework that symlinks out to a
459 // top-level framework, and we need to infer as if we were naming the
460 // top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000461 StringRef FrameworkDirName
462 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor7005b902013-01-10 01:43:00 +0000463
Douglas Gregor82e52372012-11-06 19:39:40 +0000464 bool canInfer = false;
Douglas Gregor7005b902013-01-10 01:43:00 +0000465 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor82e52372012-11-06 19:39:40 +0000466 // Figure out the parent path.
Douglas Gregor7005b902013-01-10 01:43:00 +0000467 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000468 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
469 // Check whether we have already looked into the parent directory
470 // for a module map.
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000471 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor82e52372012-11-06 19:39:40 +0000472 inferred = InferredDirectories.find(ParentDir);
473 if (inferred == InferredDirectories.end()) {
474 // We haven't looked here before. Load a module map, if there is
475 // one.
476 SmallString<128> ModMapPath = Parent;
477 llvm::sys::path::append(ModMapPath, "module.map");
478 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
479 parseModuleMapFile(ModMapFile);
480 inferred = InferredDirectories.find(ParentDir);
481 }
482
483 if (inferred == InferredDirectories.end())
484 inferred = InferredDirectories.insert(
485 std::make_pair(ParentDir, InferredDirectory())).first;
486 }
487
488 if (inferred->second.InferModules) {
489 // We're allowed to infer for this directory, but make sure it's okay
490 // to infer this particular module.
Douglas Gregor7005b902013-01-10 01:43:00 +0000491 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor82e52372012-11-06 19:39:40 +0000492 canInfer = std::find(inferred->second.ExcludedModules.begin(),
493 inferred->second.ExcludedModules.end(),
494 Name) == inferred->second.ExcludedModules.end();
495
496 if (inferred->second.InferSystemModules)
497 IsSystem = true;
498 }
499 }
500 }
501
502 // If we're not allowed to infer a framework module, don't.
503 if (!canInfer)
504 return 0;
505 }
506
507
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000508 // Look for an umbrella header.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000509 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000510 llvm::sys::path::append(UmbrellaName, "Headers");
511 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregorac252a32011-12-06 19:39:29 +0000512 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000513
514 // FIXME: If there's no umbrella header, we could probably scan the
515 // framework to load *everything*. But, it's not clear that this is a good
516 // idea.
517 if (!UmbrellaHeader)
518 return 0;
519
Douglas Gregorac252a32011-12-06 19:39:29 +0000520 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
521 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000522 if (IsSystem)
523 Result->IsSystem = IsSystem;
524
Douglas Gregorb7a78192012-01-04 23:32:19 +0000525 if (!Parent)
Douglas Gregorac252a32011-12-06 19:39:29 +0000526 Modules[ModuleName] = Result;
Douglas Gregorb7a78192012-01-04 23:32:19 +0000527
Douglas Gregor489ad432011-12-08 18:00:48 +0000528 // umbrella header "umbrella-header-name"
Douglas Gregor10694ce2011-12-08 17:39:04 +0000529 Result->Umbrella = UmbrellaHeader;
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000530 Headers[UmbrellaHeader] = KnownHeader(Result, /*Excluded=*/false);
Douglas Gregor3cee31e2011-12-12 23:55:05 +0000531 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregor209977c2011-12-05 17:40:25 +0000532
533 // export *
534 Result->Exports.push_back(Module::ExportDecl(0, true));
535
Douglas Gregore209e502011-12-06 01:10:29 +0000536 // module * { export * }
537 Result->InferSubmodules = true;
538 Result->InferExportWildcard = true;
539
Douglas Gregorac252a32011-12-06 19:39:29 +0000540 // Look for subframeworks.
541 llvm::error_code EC;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000542 SmallString<128> SubframeworksDirName
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000543 = StringRef(FrameworkDir->getName());
Douglas Gregorac252a32011-12-06 19:39:29 +0000544 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000545 SmallString<128> SubframeworksDirNameNative;
Douglas Gregor52b1ed32011-12-08 16:13:24 +0000546 llvm::sys::path::native(SubframeworksDirName.str(),
547 SubframeworksDirNameNative);
548 for (llvm::sys::fs::directory_iterator
549 Dir(SubframeworksDirNameNative.str(), EC), DirEnd;
Douglas Gregorac252a32011-12-06 19:39:29 +0000550 Dir != DirEnd && !EC; Dir.increment(EC)) {
551 if (!StringRef(Dir->path()).endswith(".framework"))
552 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000553
Douglas Gregorac252a32011-12-06 19:39:29 +0000554 if (const DirectoryEntry *SubframeworkDir
555 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000556 // Note: as an egregious but useful hack, we use the real path here and
557 // check whether it is actually a subdirectory of the parent directory.
558 // This will not be the case if the 'subframework' is actually a symlink
559 // out to a top-level framework.
Douglas Gregor713b7c02013-01-26 00:55:12 +0000560 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
561 bool FoundParent = false;
562 do {
563 // Get the parent directory name.
564 SubframeworkDirName
565 = llvm::sys::path::parent_path(SubframeworkDirName);
566 if (SubframeworkDirName.empty())
567 break;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000568
Douglas Gregor713b7c02013-01-26 00:55:12 +0000569 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
570 FoundParent = true;
571 break;
572 }
573 } while (true);
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000574
Douglas Gregor713b7c02013-01-26 00:55:12 +0000575 if (!FoundParent)
576 continue;
Douglas Gregor98cfcbf2012-09-27 14:50:15 +0000577
Douglas Gregorac252a32011-12-06 19:39:29 +0000578 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor8b48e082012-10-12 21:15:50 +0000579 SmallString<32> NameBuf;
580 inferFrameworkModule(sanitizeFilenameAsIdentifier(
581 llvm::sys::path::stem(Dir->path()), NameBuf),
582 SubframeworkDir, IsSystem, Result);
Douglas Gregorac252a32011-12-06 19:39:29 +0000583 }
584 }
Douglas Gregor3a110f72012-01-13 16:54:27 +0000585
Douglas Gregor8767dc22013-01-14 17:57:51 +0000586 // If the module is a top-level framework, automatically link against the
587 // framework.
588 if (!Result->isSubFramework()) {
589 inferFrameworkLink(Result, FrameworkDir, FileMgr);
590 }
591
Douglas Gregor2821c7f2011-11-17 01:41:17 +0000592 return Result;
593}
594
Douglas Gregore209e502011-12-06 01:10:29 +0000595void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000596 Headers[UmbrellaHeader] = KnownHeader(Mod, /*Excluded=*/false);
Douglas Gregor10694ce2011-12-08 17:39:04 +0000597 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor6a1db482011-12-09 02:04:43 +0000598 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregore209e502011-12-06 01:10:29 +0000599}
600
Douglas Gregor77d029f2011-12-08 19:11:24 +0000601void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
602 Mod->Umbrella = UmbrellaDir;
603 UmbrellaDirs[UmbrellaDir] = Mod;
604}
605
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000606void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
607 bool Excluded) {
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000608 if (Excluded) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000609 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000610 } else {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000611 Mod->Headers.push_back(Header);
Argyrios Kyrtzidisd3220db2013-05-08 23:46:46 +0000612 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
613 HeaderInfo.MarkFileModuleHeader(Header, isCompilingModuleHeader);
Argyrios Kyrtzidis55ea75b2013-03-13 21:13:51 +0000614 }
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000615 Headers[Header] = KnownHeader(Mod, Excluded);
Douglas Gregore209e502011-12-06 01:10:29 +0000616}
617
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000618const FileEntry *
Argyrios Kyrtzidis0be5e562013-02-19 19:58:45 +0000619ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregorf9e357d2011-11-29 19:06:37 +0000620 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
621 return 0;
622
623 return SourceMgr->getFileEntryForID(
624 SourceMgr->getFileID(Module->DefinitionLoc));
625}
626
Douglas Gregora30cfe52011-11-11 19:10:28 +0000627void ModuleMap::dump() {
628 llvm::errs() << "Modules:";
629 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
630 MEnd = Modules.end();
631 M != MEnd; ++M)
Douglas Gregor804c3bf2011-11-29 18:17:59 +0000632 M->getValue()->print(llvm::errs(), 2);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000633
634 llvm::errs() << "Headers:";
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000635 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregora30cfe52011-11-11 19:10:28 +0000636 H != HEnd; ++H) {
637 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000638 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregora30cfe52011-11-11 19:10:28 +0000639 }
640}
641
Douglas Gregor90db2602011-12-02 01:47:07 +0000642bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
643 bool HadError = false;
644 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
645 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
646 Complain);
Douglas Gregor0adaa882011-12-05 17:28:06 +0000647 if (Export.getPointer() || Export.getInt())
Douglas Gregor90db2602011-12-02 01:47:07 +0000648 Mod->Exports.push_back(Export);
649 else
650 HadError = true;
651 }
652 Mod->UnresolvedExports.clear();
653 return HadError;
654}
655
Douglas Gregor906d66a2013-03-20 21:10:35 +0000656bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
657 bool HadError = false;
658 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
659 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
660 Mod, Complain);
661 if (!OtherMod) {
662 HadError = true;
663 continue;
664 }
665
666 Module::Conflict Conflict;
667 Conflict.Other = OtherMod;
668 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
669 Mod->Conflicts.push_back(Conflict);
670 }
671 Mod->UnresolvedConflicts.clear();
672 return HadError;
673}
674
Douglas Gregor55988682011-12-05 16:33:54 +0000675Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
676 if (Loc.isInvalid())
677 return 0;
678
679 // Use the expansion location to determine which module we're in.
680 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
681 if (!ExpansionLoc.isFileID())
682 return 0;
683
684
685 const SourceManager &SrcMgr = Loc.getManager();
686 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor55988682011-12-05 16:33:54 +0000687
Douglas Gregor303aae92012-01-06 17:19:32 +0000688 while (const FileEntry *ExpansionFile
689 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
690 // Find the module that owns this header (if any).
691 if (Module *Mod = findModuleForHeader(ExpansionFile))
692 return Mod;
693
694 // No module owns this header, so look up the inclusion chain to see if
695 // any included header has an associated module.
696 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
697 if (IncludeLoc.isInvalid())
698 return 0;
699
700 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
701 }
702
703 return 0;
Douglas Gregor55988682011-12-05 16:33:54 +0000704}
705
Douglas Gregora30cfe52011-11-11 19:10:28 +0000706//----------------------------------------------------------------------------//
707// Module map file parser
708//----------------------------------------------------------------------------//
709
710namespace clang {
711 /// \brief A token in a module map file.
712 struct MMToken {
713 enum TokenKind {
Douglas Gregor51f564f2011-12-31 04:05:44 +0000714 Comma,
Douglas Gregor63a72682013-03-20 00:22:05 +0000715 ConfigMacros,
Douglas Gregor906d66a2013-03-20 21:10:35 +0000716 Conflict,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000717 EndOfFile,
718 HeaderKeyword,
719 Identifier,
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000720 ExcludeKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000721 ExplicitKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000722 ExportKeyword,
Douglas Gregora8654052011-11-17 22:09:43 +0000723 FrameworkKeyword,
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000724 LinkKeyword,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000725 ModuleKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000726 Period,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000727 UmbrellaKeyword,
Douglas Gregor51f564f2011-12-31 04:05:44 +0000728 RequiresKeyword,
Douglas Gregor90db2602011-12-02 01:47:07 +0000729 Star,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000730 StringLiteral,
731 LBrace,
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000732 RBrace,
733 LSquare,
734 RSquare
Douglas Gregora30cfe52011-11-11 19:10:28 +0000735 } Kind;
736
737 unsigned Location;
738 unsigned StringLength;
739 const char *StringData;
740
741 void clear() {
742 Kind = EndOfFile;
743 Location = 0;
744 StringLength = 0;
745 StringData = 0;
746 }
747
748 bool is(TokenKind K) const { return Kind == K; }
749
750 SourceLocation getLocation() const {
751 return SourceLocation::getFromRawEncoding(Location);
752 }
753
754 StringRef getString() const {
755 return StringRef(StringData, StringLength);
756 }
757 };
Douglas Gregor82e52372012-11-06 19:39:40 +0000758
759 /// \brief The set of attributes that can be attached to a module.
Bill Wendlingad017fa2012-12-20 19:22:21 +0000760 struct Attributes {
Douglas Gregor63a72682013-03-20 00:22:05 +0000761 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor82e52372012-11-06 19:39:40 +0000762
763 /// \brief Whether this is a system module.
764 unsigned IsSystem : 1;
Douglas Gregor63a72682013-03-20 00:22:05 +0000765
766 /// \brief Whether this is an exhaustive set of configuration macros.
767 unsigned IsExhaustive : 1;
Douglas Gregor82e52372012-11-06 19:39:40 +0000768 };
Douglas Gregora30cfe52011-11-11 19:10:28 +0000769
Douglas Gregor82e52372012-11-06 19:39:40 +0000770
Douglas Gregora30cfe52011-11-11 19:10:28 +0000771 class ModuleMapParser {
772 Lexer &L;
773 SourceManager &SourceMgr;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000774
775 /// \brief Default target information, used only for string literal
776 /// parsing.
777 const TargetInfo *Target;
778
Douglas Gregora30cfe52011-11-11 19:10:28 +0000779 DiagnosticsEngine &Diags;
780 ModuleMap &Map;
781
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000782 /// \brief The directory that this module map resides in.
783 const DirectoryEntry *Directory;
Douglas Gregor2f04f182012-02-02 18:42:48 +0000784
785 /// \brief The directory containing Clang-supplied headers.
786 const DirectoryEntry *BuiltinIncludeDir;
787
Douglas Gregora30cfe52011-11-11 19:10:28 +0000788 /// \brief Whether an error occurred.
789 bool HadError;
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000790
Douglas Gregora30cfe52011-11-11 19:10:28 +0000791 /// \brief Stores string data for the various string literals referenced
792 /// during parsing.
793 llvm::BumpPtrAllocator StringData;
794
795 /// \brief The current token.
796 MMToken Tok;
797
798 /// \brief The active module.
Douglas Gregor1a4761e2011-11-30 23:21:26 +0000799 Module *ActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000800
801 /// \brief Consume the current token and return its location.
802 SourceLocation consumeToken();
803
804 /// \brief Skip tokens until we reach the a token with the given kind
805 /// (or the end of the file).
806 void skipUntil(MMToken::TokenKind K);
Douglas Gregor587986e2011-12-07 02:23:45 +0000807
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000808 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregor587986e2011-12-07 02:23:45 +0000809 bool parseModuleId(ModuleId &Id);
Douglas Gregora30cfe52011-11-11 19:10:28 +0000810 void parseModuleDecl();
Douglas Gregor51f564f2011-12-31 04:05:44 +0000811 void parseRequiresDecl();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000812 void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
Douglas Gregor77d029f2011-12-08 19:11:24 +0000813 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor90db2602011-12-02 01:47:07 +0000814 void parseExportDecl();
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000815 void parseLinkDecl();
Douglas Gregor63a72682013-03-20 00:22:05 +0000816 void parseConfigMacros();
Douglas Gregor906d66a2013-03-20 21:10:35 +0000817 void parseConflict();
Douglas Gregor82e52372012-11-06 19:39:40 +0000818 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendlingad017fa2012-12-20 19:22:21 +0000819 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor82e52372012-11-06 19:39:40 +0000820
Douglas Gregor6a1db482011-12-09 02:04:43 +0000821 const DirectoryEntry *getOverriddenHeaderSearchDir();
822
Douglas Gregora30cfe52011-11-11 19:10:28 +0000823 public:
Douglas Gregora30cfe52011-11-11 19:10:28 +0000824 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000825 const TargetInfo *Target,
Douglas Gregora30cfe52011-11-11 19:10:28 +0000826 DiagnosticsEngine &Diags,
Douglas Gregor8b6d3de2011-11-11 21:55:48 +0000827 ModuleMap &Map,
Douglas Gregor2f04f182012-02-02 18:42:48 +0000828 const DirectoryEntry *Directory,
829 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregor9a022bb2012-10-15 16:45:32 +0000830 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor2f04f182012-02-02 18:42:48 +0000831 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
832 HadError(false), ActiveModule(0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000833 {
Douglas Gregora30cfe52011-11-11 19:10:28 +0000834 Tok.clear();
835 consumeToken();
836 }
837
838 bool parseModuleMapFile();
839 };
840}
841
842SourceLocation ModuleMapParser::consumeToken() {
843retry:
844 SourceLocation Result = Tok.getLocation();
845 Tok.clear();
846
847 Token LToken;
848 L.LexFromRawLexer(LToken);
849 Tok.Location = LToken.getLocation().getRawEncoding();
850 switch (LToken.getKind()) {
851 case tok::raw_identifier:
852 Tok.StringData = LToken.getRawIdentifierData();
853 Tok.StringLength = LToken.getLength();
854 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +0000855 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregor906d66a2013-03-20 21:10:35 +0000856 .Case("conflict", MMToken::Conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +0000857 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000858 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor90db2602011-12-02 01:47:07 +0000859 .Case("export", MMToken::ExportKeyword)
Douglas Gregora8654052011-11-17 22:09:43 +0000860 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor63a72682013-03-20 00:22:05 +0000861 .Case("header", MMToken::HeaderKeyword)
Douglas Gregorb6cbe512013-01-14 17:21:00 +0000862 .Case("link", MMToken::LinkKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000863 .Case("module", MMToken::ModuleKeyword)
Douglas Gregor51f564f2011-12-31 04:05:44 +0000864 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000865 .Case("umbrella", MMToken::UmbrellaKeyword)
866 .Default(MMToken::Identifier);
867 break;
Douglas Gregor51f564f2011-12-31 04:05:44 +0000868
869 case tok::comma:
870 Tok.Kind = MMToken::Comma;
871 break;
872
Douglas Gregora30cfe52011-11-11 19:10:28 +0000873 case tok::eof:
874 Tok.Kind = MMToken::EndOfFile;
875 break;
876
877 case tok::l_brace:
878 Tok.Kind = MMToken::LBrace;
879 break;
880
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000881 case tok::l_square:
882 Tok.Kind = MMToken::LSquare;
883 break;
884
Douglas Gregor90db2602011-12-02 01:47:07 +0000885 case tok::period:
886 Tok.Kind = MMToken::Period;
887 break;
888
Douglas Gregora30cfe52011-11-11 19:10:28 +0000889 case tok::r_brace:
890 Tok.Kind = MMToken::RBrace;
891 break;
892
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000893 case tok::r_square:
894 Tok.Kind = MMToken::RSquare;
895 break;
896
Douglas Gregor90db2602011-12-02 01:47:07 +0000897 case tok::star:
898 Tok.Kind = MMToken::Star;
899 break;
900
Douglas Gregora30cfe52011-11-11 19:10:28 +0000901 case tok::string_literal: {
Richard Smith99831e42012-03-06 03:21:47 +0000902 if (LToken.hasUDSuffix()) {
903 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
904 HadError = true;
905 goto retry;
906 }
907
Douglas Gregora30cfe52011-11-11 19:10:28 +0000908 // Parse the string literal.
909 LangOptions LangOpts;
910 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
911 if (StringLiteral.hadError)
912 goto retry;
913
914 // Copy the string literal into our string data allocator.
915 unsigned Length = StringLiteral.GetStringLength();
916 char *Saved = StringData.Allocate<char>(Length + 1);
917 memcpy(Saved, StringLiteral.GetString().data(), Length);
918 Saved[Length] = 0;
919
920 // Form the token.
921 Tok.Kind = MMToken::StringLiteral;
922 Tok.StringData = Saved;
923 Tok.StringLength = Length;
924 break;
925 }
926
927 case tok::comment:
928 goto retry;
929
930 default:
931 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
932 HadError = true;
933 goto retry;
934 }
935
936 return Result;
937}
938
939void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
940 unsigned braceDepth = 0;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000941 unsigned squareDepth = 0;
Douglas Gregora30cfe52011-11-11 19:10:28 +0000942 do {
943 switch (Tok.Kind) {
944 case MMToken::EndOfFile:
945 return;
946
947 case MMToken::LBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000948 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregora30cfe52011-11-11 19:10:28 +0000949 return;
950
951 ++braceDepth;
952 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000953
954 case MMToken::LSquare:
955 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
956 return;
957
958 ++squareDepth;
959 break;
960
Douglas Gregora30cfe52011-11-11 19:10:28 +0000961 case MMToken::RBrace:
962 if (braceDepth > 0)
963 --braceDepth;
964 else if (Tok.is(K))
965 return;
966 break;
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000967
968 case MMToken::RSquare:
969 if (squareDepth > 0)
970 --squareDepth;
971 else if (Tok.is(K))
972 return;
973 break;
974
Douglas Gregora30cfe52011-11-11 19:10:28 +0000975 default:
Douglas Gregora1f1fad2012-01-27 19:52:33 +0000976 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregora30cfe52011-11-11 19:10:28 +0000977 return;
978 break;
979 }
980
981 consumeToken();
982 } while (true);
983}
984
Douglas Gregor587986e2011-12-07 02:23:45 +0000985/// \brief Parse a module-id.
986///
987/// module-id:
988/// identifier
989/// identifier '.' module-id
990///
991/// \returns true if an error occurred, false otherwise.
992bool ModuleMapParser::parseModuleId(ModuleId &Id) {
993 Id.clear();
994 do {
995 if (Tok.is(MMToken::Identifier)) {
996 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
997 consumeToken();
998 } else {
999 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1000 return true;
1001 }
1002
1003 if (!Tok.is(MMToken::Period))
1004 break;
1005
1006 consumeToken();
1007 } while (true);
1008
1009 return false;
1010}
1011
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001012namespace {
1013 /// \brief Enumerates the known attributes.
1014 enum AttributeKind {
1015 /// \brief An unknown attribute.
1016 AT_unknown,
1017 /// \brief The 'system' attribute.
Douglas Gregor63a72682013-03-20 00:22:05 +00001018 AT_system,
1019 /// \brief The 'exhaustive' attribute.
1020 AT_exhaustive
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001021 };
1022}
1023
Douglas Gregora30cfe52011-11-11 19:10:28 +00001024/// \brief Parse a module declaration.
1025///
1026/// module-declaration:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001027/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1028/// { module-member* }
1029///
Douglas Gregora30cfe52011-11-11 19:10:28 +00001030/// module-member:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001031/// requires-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001032/// header-declaration
Douglas Gregor587986e2011-12-07 02:23:45 +00001033/// submodule-declaration
Douglas Gregor90db2602011-12-02 01:47:07 +00001034/// export-declaration
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001035/// link-declaration
Douglas Gregor1e123682011-12-05 22:27:44 +00001036///
1037/// submodule-declaration:
1038/// module-declaration
1039/// inferred-submodule-declaration
Douglas Gregora30cfe52011-11-11 19:10:28 +00001040void ModuleMapParser::parseModuleDecl() {
Douglas Gregora8654052011-11-17 22:09:43 +00001041 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1042 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregord620a842011-12-06 17:16:41 +00001043 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregor587986e2011-12-07 02:23:45 +00001044 SourceLocation ExplicitLoc;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001045 bool Explicit = false;
Douglas Gregord620a842011-12-06 17:16:41 +00001046 bool Framework = false;
Douglas Gregora8654052011-11-17 22:09:43 +00001047
Douglas Gregord620a842011-12-06 17:16:41 +00001048 // Parse 'explicit' keyword, if present.
1049 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregor587986e2011-12-07 02:23:45 +00001050 ExplicitLoc = consumeToken();
Douglas Gregord620a842011-12-06 17:16:41 +00001051 Explicit = true;
1052 }
1053
1054 // Parse 'framework' keyword, if present.
Douglas Gregora8654052011-11-17 22:09:43 +00001055 if (Tok.is(MMToken::FrameworkKeyword)) {
1056 consumeToken();
1057 Framework = true;
1058 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001059
1060 // Parse 'module' keyword.
1061 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregore6fb9872011-12-06 19:57:48 +00001062 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001063 consumeToken();
1064 HadError = true;
1065 return;
1066 }
1067 consumeToken(); // 'module' keyword
Douglas Gregor1e123682011-12-05 22:27:44 +00001068
1069 // If we have a wildcard for the module name, this is an inferred submodule.
1070 // Parse it.
1071 if (Tok.is(MMToken::Star))
Douglas Gregor82e52372012-11-06 19:39:40 +00001072 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001073
1074 // Parse the module name.
Douglas Gregor587986e2011-12-07 02:23:45 +00001075 ModuleId Id;
1076 if (parseModuleId(Id)) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001077 HadError = true;
Douglas Gregor587986e2011-12-07 02:23:45 +00001078 return;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001079 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001080
Douglas Gregor587986e2011-12-07 02:23:45 +00001081 if (ActiveModule) {
1082 if (Id.size() > 1) {
1083 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1084 << SourceRange(Id.front().second, Id.back().second);
1085
1086 HadError = true;
1087 return;
1088 }
1089 } else if (Id.size() == 1 && Explicit) {
1090 // Top-level modules can't be explicit.
1091 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1092 Explicit = false;
1093 ExplicitLoc = SourceLocation();
1094 HadError = true;
1095 }
1096
1097 Module *PreviousActiveModule = ActiveModule;
1098 if (Id.size() > 1) {
1099 // This module map defines a submodule. Go find the module of which it
1100 // is a submodule.
1101 ActiveModule = 0;
1102 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1103 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1104 ActiveModule = Next;
1105 continue;
1106 }
1107
1108 if (ActiveModule) {
1109 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1110 << Id[I].first << ActiveModule->getTopLevelModule();
1111 } else {
1112 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1113 }
1114 HadError = true;
1115 return;
1116 }
1117 }
1118
1119 StringRef ModuleName = Id.back().first;
1120 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001121
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001122 // Parse the optional attribute list.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001123 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001124 parseOptionalAttributes(Attrs);
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001125
Douglas Gregora30cfe52011-11-11 19:10:28 +00001126 // Parse the opening brace.
1127 if (!Tok.is(MMToken::LBrace)) {
1128 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1129 << ModuleName;
1130 HadError = true;
1131 return;
1132 }
1133 SourceLocation LBraceLoc = consumeToken();
1134
1135 // Determine whether this (sub)module has already been defined.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001136 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorc634f502012-01-05 00:12:00 +00001137 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1138 // Skip the module definition.
1139 skipUntil(MMToken::RBrace);
1140 if (Tok.is(MMToken::RBrace))
1141 consumeToken();
1142 else {
1143 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1144 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1145 HadError = true;
1146 }
1147 return;
1148 }
1149
Douglas Gregora30cfe52011-11-11 19:10:28 +00001150 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1151 << ModuleName;
Douglas Gregorb7a78192012-01-04 23:32:19 +00001152 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001153
1154 // Skip the module definition.
1155 skipUntil(MMToken::RBrace);
1156 if (Tok.is(MMToken::RBrace))
1157 consumeToken();
1158
1159 HadError = true;
1160 return;
1161 }
1162
1163 // Start defining this module.
Douglas Gregorb7a78192012-01-04 23:32:19 +00001164 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1165 Explicit).first;
1166 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor82e52372012-11-06 19:39:40 +00001167 if (Attrs.IsSystem)
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001168 ActiveModule->IsSystem = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001169
1170 bool Done = false;
1171 do {
1172 switch (Tok.Kind) {
1173 case MMToken::EndOfFile:
1174 case MMToken::RBrace:
1175 Done = true;
1176 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001177
1178 case MMToken::ConfigMacros:
1179 parseConfigMacros();
1180 break;
1181
Douglas Gregor906d66a2013-03-20 21:10:35 +00001182 case MMToken::Conflict:
1183 parseConflict();
1184 break;
1185
Douglas Gregora30cfe52011-11-11 19:10:28 +00001186 case MMToken::ExplicitKeyword:
Douglas Gregord620a842011-12-06 17:16:41 +00001187 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001188 case MMToken::ModuleKeyword:
1189 parseModuleDecl();
1190 break;
1191
Douglas Gregor90db2602011-12-02 01:47:07 +00001192 case MMToken::ExportKeyword:
1193 parseExportDecl();
1194 break;
1195
Douglas Gregor51f564f2011-12-31 04:05:44 +00001196 case MMToken::RequiresKeyword:
1197 parseRequiresDecl();
1198 break;
1199
Douglas Gregor77d029f2011-12-08 19:11:24 +00001200 case MMToken::UmbrellaKeyword: {
1201 SourceLocation UmbrellaLoc = consumeToken();
1202 if (Tok.is(MMToken::HeaderKeyword))
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001203 parseHeaderDecl(UmbrellaLoc, SourceLocation());
Douglas Gregor77d029f2011-12-08 19:11:24 +00001204 else
1205 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001206 break;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001207 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001208
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001209 case MMToken::ExcludeKeyword: {
1210 SourceLocation ExcludeLoc = consumeToken();
1211 if (Tok.is(MMToken::HeaderKeyword)) {
1212 parseHeaderDecl(SourceLocation(), ExcludeLoc);
1213 } else {
1214 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1215 << "exclude";
1216 }
1217 break;
1218 }
1219
Douglas Gregor489ad432011-12-08 18:00:48 +00001220 case MMToken::HeaderKeyword:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001221 parseHeaderDecl(SourceLocation(), SourceLocation());
Douglas Gregora30cfe52011-11-11 19:10:28 +00001222 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001223
1224 case MMToken::LinkKeyword:
1225 parseLinkDecl();
1226 break;
1227
Douglas Gregora30cfe52011-11-11 19:10:28 +00001228 default:
1229 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1230 consumeToken();
1231 break;
1232 }
1233 } while (!Done);
1234
1235 if (Tok.is(MMToken::RBrace))
1236 consumeToken();
1237 else {
1238 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1239 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1240 HadError = true;
1241 }
1242
Douglas Gregor8767dc22013-01-14 17:57:51 +00001243 // If the active module is a top-level framework, and there are no link
1244 // libraries, automatically link against the framework.
1245 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1246 ActiveModule->LinkLibraries.empty()) {
1247 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1248 }
1249
Douglas Gregor587986e2011-12-07 02:23:45 +00001250 // We're done parsing this module. Pop back to the previous module.
1251 ActiveModule = PreviousActiveModule;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001252}
Douglas Gregord620a842011-12-06 17:16:41 +00001253
Douglas Gregor51f564f2011-12-31 04:05:44 +00001254/// \brief Parse a requires declaration.
1255///
1256/// requires-declaration:
1257/// 'requires' feature-list
1258///
1259/// feature-list:
1260/// identifier ',' feature-list
1261/// identifier
1262void ModuleMapParser::parseRequiresDecl() {
1263 assert(Tok.is(MMToken::RequiresKeyword));
1264
1265 // Parse 'requires' keyword.
1266 consumeToken();
1267
1268 // Parse the feature-list.
1269 do {
1270 if (!Tok.is(MMToken::Identifier)) {
1271 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1272 HadError = true;
1273 return;
1274 }
1275
1276 // Consume the feature name.
1277 std::string Feature = Tok.getString();
1278 consumeToken();
1279
1280 // Add this feature.
Douglas Gregordc58aa72012-01-30 06:01:29 +00001281 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor51f564f2011-12-31 04:05:44 +00001282
1283 if (!Tok.is(MMToken::Comma))
1284 break;
1285
1286 // Consume the comma.
1287 consumeToken();
1288 } while (true);
1289}
1290
Douglas Gregord620a842011-12-06 17:16:41 +00001291/// \brief Append to \p Paths the set of paths needed to get to the
1292/// subframework in which the given module lives.
Benjamin Kramer5bbc3852012-02-06 11:13:08 +00001293static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001294 SmallVectorImpl<char> &Path) {
Douglas Gregord620a842011-12-06 17:16:41 +00001295 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001296 SmallVector<StringRef, 2> Paths;
Douglas Gregord620a842011-12-06 17:16:41 +00001297 for (; Mod; Mod = Mod->Parent) {
1298 if (Mod->IsFramework)
1299 Paths.push_back(Mod->Name);
1300 }
1301
1302 if (Paths.empty())
1303 return;
1304
1305 // Add Frameworks/Name.framework for each subframework.
1306 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1307 llvm::sys::path::append(Path, "Frameworks");
1308 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1309 }
1310}
1311
Douglas Gregora30cfe52011-11-11 19:10:28 +00001312/// \brief Parse a header declaration.
1313///
1314/// header-declaration:
Douglas Gregor489ad432011-12-08 18:00:48 +00001315/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001316/// 'exclude'[opt] 'header' string-literal
1317void ModuleMapParser::parseHeaderDecl(SourceLocation UmbrellaLoc,
1318 SourceLocation ExcludeLoc) {
Douglas Gregora30cfe52011-11-11 19:10:28 +00001319 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramerc96c7212011-11-13 16:52:09 +00001320 consumeToken();
1321
Douglas Gregor489ad432011-12-08 18:00:48 +00001322 bool Umbrella = UmbrellaLoc.isValid();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001323 bool Exclude = ExcludeLoc.isValid();
1324 assert(!(Umbrella && Exclude) && "Cannot have both 'umbrella' and 'exclude'");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001325 // Parse the header name.
1326 if (!Tok.is(MMToken::StringLiteral)) {
1327 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1328 << "header";
1329 HadError = true;
1330 return;
1331 }
Douglas Gregor587986e2011-12-07 02:23:45 +00001332 std::string FileName = Tok.getString();
Douglas Gregora30cfe52011-11-11 19:10:28 +00001333 SourceLocation FileNameLoc = consumeToken();
1334
Douglas Gregor77d029f2011-12-08 19:11:24 +00001335 // Check whether we already have an umbrella.
1336 if (Umbrella && ActiveModule->Umbrella) {
1337 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1338 << ActiveModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001339 HadError = true;
1340 return;
1341 }
1342
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001343 // Look for this file.
Douglas Gregor587986e2011-12-07 02:23:45 +00001344 const FileEntry *File = 0;
Douglas Gregor2f04f182012-02-02 18:42:48 +00001345 const FileEntry *BuiltinFile = 0;
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001346 SmallString<128> PathName;
Douglas Gregor587986e2011-12-07 02:23:45 +00001347 if (llvm::sys::path::is_absolute(FileName)) {
1348 PathName = FileName;
1349 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor6a1db482011-12-09 02:04:43 +00001350 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1351 PathName = Dir->getName();
1352 llvm::sys::path::append(PathName, FileName);
1353 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001354 } else {
1355 // Search for the header file within the search directory.
Douglas Gregor6a1db482011-12-09 02:04:43 +00001356 PathName = Directory->getName();
Douglas Gregor587986e2011-12-07 02:23:45 +00001357 unsigned PathLength = PathName.size();
Douglas Gregor18ee5472011-11-29 21:59:16 +00001358
Douglas Gregord620a842011-12-06 17:16:41 +00001359 if (ActiveModule->isPartOfFramework()) {
1360 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregor587986e2011-12-07 02:23:45 +00001361
1362 // Check whether this file is in the public headers.
Douglas Gregor18ee5472011-11-29 21:59:16 +00001363 llvm::sys::path::append(PathName, "Headers");
Douglas Gregor587986e2011-12-07 02:23:45 +00001364 llvm::sys::path::append(PathName, FileName);
1365 File = SourceMgr.getFileManager().getFile(PathName);
1366
1367 if (!File) {
1368 // Check whether this file is in the private headers.
1369 PathName.resize(PathLength);
1370 llvm::sys::path::append(PathName, "PrivateHeaders");
1371 llvm::sys::path::append(PathName, FileName);
1372 File = SourceMgr.getFileManager().getFile(PathName);
1373 }
1374 } else {
1375 // Lookup for normal headers.
1376 llvm::sys::path::append(PathName, FileName);
1377 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001378
1379 // If this is a system module with a top-level header, this header
1380 // may have a counterpart (or replacement) in the set of headers
1381 // supplied by Clang. Find that builtin header.
1382 if (ActiveModule->IsSystem && !Umbrella && BuiltinIncludeDir &&
1383 BuiltinIncludeDir != Directory && isBuiltinHeader(FileName)) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001384 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor2f04f182012-02-02 18:42:48 +00001385 llvm::sys::path::append(BuiltinPathName, FileName);
1386 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1387
1388 // If Clang supplies this header but the underlying system does not,
1389 // just silently swap in our builtin version. Otherwise, we'll end
1390 // up adding both (later).
1391 if (!File && BuiltinFile) {
1392 File = BuiltinFile;
1393 BuiltinFile = 0;
1394 }
1395 }
Douglas Gregord620a842011-12-06 17:16:41 +00001396 }
Douglas Gregor18ee5472011-11-29 21:59:16 +00001397 }
Douglas Gregora8654052011-11-17 22:09:43 +00001398
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001399 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1400 // Come up with a lazy way to do this.
Douglas Gregor587986e2011-12-07 02:23:45 +00001401 if (File) {
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001402 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001403 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001404 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001405 HadError = true;
Douglas Gregor489ad432011-12-08 18:00:48 +00001406 } else if (Umbrella) {
1407 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001408 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Douglas Gregor489ad432011-12-08 18:00:48 +00001409 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001410 << UmbrellaModule->getFullModuleName();
Douglas Gregor489ad432011-12-08 18:00:48 +00001411 HadError = true;
1412 } else {
1413 // Record this umbrella header.
1414 Map.setUmbrellaHeader(ActiveModule, File);
1415 }
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001416 } else {
Douglas Gregor489ad432011-12-08 18:00:48 +00001417 // Record this header.
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001418 Map.addHeader(ActiveModule, File, Exclude);
Douglas Gregor2f04f182012-02-02 18:42:48 +00001419
1420 // If there is a builtin counterpart to this file, add it now.
1421 if (BuiltinFile)
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001422 Map.addHeader(ActiveModule, BuiltinFile, Exclude);
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001423 }
Douglas Gregor71f49f52012-11-15 19:47:16 +00001424 } else if (!Exclude) {
1425 // Ignore excluded header files. They're optional anyway.
1426
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001427 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Douglas Gregor77d029f2011-12-08 19:11:24 +00001428 << Umbrella << FileName;
Douglas Gregor8b6d3de2011-11-11 21:55:48 +00001429 HadError = true;
1430 }
Douglas Gregora30cfe52011-11-11 19:10:28 +00001431}
1432
Douglas Gregor77d029f2011-12-08 19:11:24 +00001433/// \brief Parse an umbrella directory declaration.
1434///
1435/// umbrella-dir-declaration:
1436/// umbrella string-literal
1437void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1438 // Parse the directory name.
1439 if (!Tok.is(MMToken::StringLiteral)) {
1440 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1441 << "umbrella";
1442 HadError = true;
1443 return;
1444 }
1445
1446 std::string DirName = Tok.getString();
1447 SourceLocation DirNameLoc = consumeToken();
1448
1449 // Check whether we already have an umbrella.
1450 if (ActiveModule->Umbrella) {
1451 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1452 << ActiveModule->getFullModuleName();
1453 HadError = true;
1454 return;
1455 }
1456
1457 // Look for this file.
1458 const DirectoryEntry *Dir = 0;
1459 if (llvm::sys::path::is_absolute(DirName))
1460 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1461 else {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00001462 SmallString<128> PathName;
Douglas Gregor77d029f2011-12-08 19:11:24 +00001463 PathName = Directory->getName();
1464 llvm::sys::path::append(PathName, DirName);
1465 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1466 }
1467
1468 if (!Dir) {
1469 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1470 << DirName;
1471 HadError = true;
1472 return;
1473 }
1474
1475 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1476 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1477 << OwningModule->getFullModuleName();
1478 HadError = true;
1479 return;
1480 }
1481
1482 // Record this umbrella directory.
1483 Map.setUmbrellaDir(ActiveModule, Dir);
1484}
1485
Douglas Gregor90db2602011-12-02 01:47:07 +00001486/// \brief Parse a module export declaration.
1487///
1488/// export-declaration:
1489/// 'export' wildcard-module-id
1490///
1491/// wildcard-module-id:
1492/// identifier
1493/// '*'
1494/// identifier '.' wildcard-module-id
1495void ModuleMapParser::parseExportDecl() {
1496 assert(Tok.is(MMToken::ExportKeyword));
1497 SourceLocation ExportLoc = consumeToken();
1498
1499 // Parse the module-id with an optional wildcard at the end.
1500 ModuleId ParsedModuleId;
1501 bool Wildcard = false;
1502 do {
1503 if (Tok.is(MMToken::Identifier)) {
1504 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1505 Tok.getLocation()));
1506 consumeToken();
1507
1508 if (Tok.is(MMToken::Period)) {
1509 consumeToken();
1510 continue;
1511 }
1512
1513 break;
1514 }
1515
1516 if(Tok.is(MMToken::Star)) {
1517 Wildcard = true;
Douglas Gregor0adaa882011-12-05 17:28:06 +00001518 consumeToken();
Douglas Gregor90db2602011-12-02 01:47:07 +00001519 break;
1520 }
1521
1522 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1523 HadError = true;
1524 return;
1525 } while (true);
1526
1527 Module::UnresolvedExportDecl Unresolved = {
1528 ExportLoc, ParsedModuleId, Wildcard
1529 };
1530 ActiveModule->UnresolvedExports.push_back(Unresolved);
1531}
1532
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001533/// \brief Parse a link declaration.
1534///
1535/// module-declaration:
1536/// 'link' 'framework'[opt] string-literal
1537void ModuleMapParser::parseLinkDecl() {
1538 assert(Tok.is(MMToken::LinkKeyword));
1539 SourceLocation LinkLoc = consumeToken();
1540
1541 // Parse the optional 'framework' keyword.
1542 bool IsFramework = false;
1543 if (Tok.is(MMToken::FrameworkKeyword)) {
1544 consumeToken();
1545 IsFramework = true;
1546 }
1547
1548 // Parse the library name
1549 if (!Tok.is(MMToken::StringLiteral)) {
1550 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1551 << IsFramework << SourceRange(LinkLoc);
1552 HadError = true;
1553 return;
1554 }
1555
1556 std::string LibraryName = Tok.getString();
1557 consumeToken();
1558 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1559 IsFramework));
1560}
1561
Douglas Gregor63a72682013-03-20 00:22:05 +00001562/// \brief Parse a configuration macro declaration.
1563///
1564/// module-declaration:
1565/// 'config_macros' attributes[opt] config-macro-list?
1566///
1567/// config-macro-list:
1568/// identifier (',' identifier)?
1569void ModuleMapParser::parseConfigMacros() {
1570 assert(Tok.is(MMToken::ConfigMacros));
1571 SourceLocation ConfigMacrosLoc = consumeToken();
1572
1573 // Only top-level modules can have configuration macros.
1574 if (ActiveModule->Parent) {
1575 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1576 }
1577
1578 // Parse the optional attributes.
1579 Attributes Attrs;
1580 parseOptionalAttributes(Attrs);
1581 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1582 ActiveModule->ConfigMacrosExhaustive = true;
1583 }
1584
1585 // If we don't have an identifier, we're done.
1586 if (!Tok.is(MMToken::Identifier))
1587 return;
1588
1589 // Consume the first identifier.
1590 if (!ActiveModule->Parent) {
1591 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1592 }
1593 consumeToken();
1594
1595 do {
1596 // If there's a comma, consume it.
1597 if (!Tok.is(MMToken::Comma))
1598 break;
1599 consumeToken();
1600
1601 // We expect to see a macro name here.
1602 if (!Tok.is(MMToken::Identifier)) {
1603 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1604 break;
1605 }
1606
1607 // Consume the macro name.
1608 if (!ActiveModule->Parent) {
1609 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1610 }
1611 consumeToken();
1612 } while (true);
1613}
1614
Douglas Gregor906d66a2013-03-20 21:10:35 +00001615/// \brief Format a module-id into a string.
1616static std::string formatModuleId(const ModuleId &Id) {
1617 std::string result;
1618 {
1619 llvm::raw_string_ostream OS(result);
1620
1621 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1622 if (I)
1623 OS << ".";
1624 OS << Id[I].first;
1625 }
1626 }
1627
1628 return result;
1629}
1630
1631/// \brief Parse a conflict declaration.
1632///
1633/// module-declaration:
1634/// 'conflict' module-id ',' string-literal
1635void ModuleMapParser::parseConflict() {
1636 assert(Tok.is(MMToken::Conflict));
1637 SourceLocation ConflictLoc = consumeToken();
1638 Module::UnresolvedConflict Conflict;
1639
1640 // Parse the module-id.
1641 if (parseModuleId(Conflict.Id))
1642 return;
1643
1644 // Parse the ','.
1645 if (!Tok.is(MMToken::Comma)) {
1646 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1647 << SourceRange(ConflictLoc);
1648 return;
1649 }
1650 consumeToken();
1651
1652 // Parse the message.
1653 if (!Tok.is(MMToken::StringLiteral)) {
1654 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1655 << formatModuleId(Conflict.Id);
1656 return;
1657 }
1658 Conflict.Message = Tok.getString().str();
1659 consumeToken();
1660
1661 // Add this unresolved conflict.
1662 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1663}
1664
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001665/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor82e52372012-11-06 19:39:40 +00001666///
1667/// module-declaration:
1668/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1669/// { inferred-module-member* }
1670///
1671/// inferred-module-member:
1672/// 'export' '*'
1673/// 'exclude' identifier
1674void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001675 assert(Tok.is(MMToken::Star));
1676 SourceLocation StarLoc = consumeToken();
1677 bool Failed = false;
Douglas Gregor82e52372012-11-06 19:39:40 +00001678
Douglas Gregor1e123682011-12-05 22:27:44 +00001679 // Inferred modules must be submodules.
Douglas Gregor82e52372012-11-06 19:39:40 +00001680 if (!ActiveModule && !Framework) {
Douglas Gregor1e123682011-12-05 22:27:44 +00001681 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1682 Failed = true;
1683 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001684
1685 if (ActiveModule) {
1686 // Inferred modules must have umbrella directories.
1687 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1688 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1689 Failed = true;
1690 }
1691
1692 // Check for redefinition of an inferred module.
1693 if (!Failed && ActiveModule->InferSubmodules) {
1694 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1695 if (ActiveModule->InferredSubmoduleLoc.isValid())
1696 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1697 diag::note_mmap_prev_definition);
1698 Failed = true;
1699 }
1700
1701 // Check for the 'framework' keyword, which is not permitted here.
1702 if (Framework) {
1703 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1704 Framework = false;
1705 }
1706 } else if (Explicit) {
1707 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1708 Explicit = false;
Douglas Gregor1e123682011-12-05 22:27:44 +00001709 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001710
Douglas Gregor1e123682011-12-05 22:27:44 +00001711 // If there were any problems with this inferred submodule, skip its body.
1712 if (Failed) {
1713 if (Tok.is(MMToken::LBrace)) {
1714 consumeToken();
1715 skipUntil(MMToken::RBrace);
1716 if (Tok.is(MMToken::RBrace))
1717 consumeToken();
1718 }
1719 HadError = true;
1720 return;
1721 }
Douglas Gregor82e52372012-11-06 19:39:40 +00001722
1723 // Parse optional attributes.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001724 Attributes Attrs;
Douglas Gregor82e52372012-11-06 19:39:40 +00001725 parseOptionalAttributes(Attrs);
1726
1727 if (ActiveModule) {
1728 // Note that we have an inferred submodule.
1729 ActiveModule->InferSubmodules = true;
1730 ActiveModule->InferredSubmoduleLoc = StarLoc;
1731 ActiveModule->InferExplicitSubmodules = Explicit;
1732 } else {
1733 // We'll be inferring framework modules for this directory.
1734 Map.InferredDirectories[Directory].InferModules = true;
1735 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1736 }
1737
Douglas Gregor1e123682011-12-05 22:27:44 +00001738 // Parse the opening brace.
1739 if (!Tok.is(MMToken::LBrace)) {
1740 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1741 HadError = true;
1742 return;
1743 }
1744 SourceLocation LBraceLoc = consumeToken();
1745
1746 // Parse the body of the inferred submodule.
1747 bool Done = false;
1748 do {
1749 switch (Tok.Kind) {
1750 case MMToken::EndOfFile:
1751 case MMToken::RBrace:
1752 Done = true;
1753 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001754
1755 case MMToken::ExcludeKeyword: {
1756 if (ActiveModule) {
1757 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001758 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001759 consumeToken();
1760 break;
1761 }
1762
1763 consumeToken();
1764 if (!Tok.is(MMToken::Identifier)) {
1765 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1766 break;
1767 }
1768
1769 Map.InferredDirectories[Directory].ExcludedModules
1770 .push_back(Tok.getString());
1771 consumeToken();
1772 break;
1773 }
1774
1775 case MMToken::ExportKeyword:
1776 if (!ActiveModule) {
1777 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001778 << (ActiveModule != 0);
Douglas Gregor82e52372012-11-06 19:39:40 +00001779 consumeToken();
1780 break;
1781 }
1782
Douglas Gregor1e123682011-12-05 22:27:44 +00001783 consumeToken();
1784 if (Tok.is(MMToken::Star))
Douglas Gregoref85b562011-12-06 17:34:58 +00001785 ActiveModule->InferExportWildcard = true;
Douglas Gregor1e123682011-12-05 22:27:44 +00001786 else
1787 Diags.Report(Tok.getLocation(),
1788 diag::err_mmap_expected_export_wildcard);
1789 consumeToken();
1790 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001791
Douglas Gregor1e123682011-12-05 22:27:44 +00001792 case MMToken::ExplicitKeyword:
1793 case MMToken::ModuleKeyword:
1794 case MMToken::HeaderKeyword:
1795 case MMToken::UmbrellaKeyword:
1796 default:
Douglas Gregor82e52372012-11-06 19:39:40 +00001797 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregorb7ac5ac2012-11-06 19:41:11 +00001798 << (ActiveModule != 0);
Douglas Gregor1e123682011-12-05 22:27:44 +00001799 consumeToken();
1800 break;
1801 }
1802 } while (!Done);
1803
1804 if (Tok.is(MMToken::RBrace))
1805 consumeToken();
1806 else {
1807 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1808 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1809 HadError = true;
1810 }
1811}
1812
Douglas Gregor82e52372012-11-06 19:39:40 +00001813/// \brief Parse optional attributes.
1814///
1815/// attributes:
1816/// attribute attributes
1817/// attribute
1818///
1819/// attribute:
1820/// [ identifier ]
1821///
1822/// \param Attrs Will be filled in with the parsed attributes.
1823///
1824/// \returns true if an error occurred, false otherwise.
Bill Wendlingad017fa2012-12-20 19:22:21 +00001825bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor82e52372012-11-06 19:39:40 +00001826 bool HadError = false;
1827
1828 while (Tok.is(MMToken::LSquare)) {
1829 // Consume the '['.
1830 SourceLocation LSquareLoc = consumeToken();
1831
1832 // Check whether we have an attribute name here.
1833 if (!Tok.is(MMToken::Identifier)) {
1834 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1835 skipUntil(MMToken::RSquare);
1836 if (Tok.is(MMToken::RSquare))
1837 consumeToken();
1838 HadError = true;
1839 }
1840
1841 // Decode the attribute name.
1842 AttributeKind Attribute
1843 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor63a72682013-03-20 00:22:05 +00001844 .Case("exhaustive", AT_exhaustive)
Douglas Gregor82e52372012-11-06 19:39:40 +00001845 .Case("system", AT_system)
1846 .Default(AT_unknown);
1847 switch (Attribute) {
1848 case AT_unknown:
1849 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1850 << Tok.getString();
1851 break;
1852
1853 case AT_system:
1854 Attrs.IsSystem = true;
1855 break;
Douglas Gregor63a72682013-03-20 00:22:05 +00001856
1857 case AT_exhaustive:
1858 Attrs.IsExhaustive = true;
1859 break;
Douglas Gregor82e52372012-11-06 19:39:40 +00001860 }
1861 consumeToken();
1862
1863 // Consume the ']'.
1864 if (!Tok.is(MMToken::RSquare)) {
1865 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1866 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1867 skipUntil(MMToken::RSquare);
1868 HadError = true;
1869 }
1870
1871 if (Tok.is(MMToken::RSquare))
1872 consumeToken();
1873 }
1874
1875 return HadError;
1876}
1877
Douglas Gregor6a1db482011-12-09 02:04:43 +00001878/// \brief If there is a specific header search directory due the presence
1879/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1880const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1881 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1882 // If we have an umbrella directory, use that.
1883 if (Mod->hasUmbrellaDir())
1884 return Mod->getUmbrellaDir();
1885
1886 // If we have a framework directory, stop looking.
1887 if (Mod->IsFramework)
1888 return 0;
1889 }
1890
1891 return 0;
1892}
1893
Douglas Gregora30cfe52011-11-11 19:10:28 +00001894/// \brief Parse a module map file.
1895///
1896/// module-map-file:
1897/// module-declaration*
1898bool ModuleMapParser::parseModuleMapFile() {
1899 do {
1900 switch (Tok.Kind) {
1901 case MMToken::EndOfFile:
1902 return HadError;
1903
Douglas Gregor587986e2011-12-07 02:23:45 +00001904 case MMToken::ExplicitKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001905 case MMToken::ModuleKeyword:
Douglas Gregora8654052011-11-17 22:09:43 +00001906 case MMToken::FrameworkKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001907 parseModuleDecl();
1908 break;
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001909
Douglas Gregor51f564f2011-12-31 04:05:44 +00001910 case MMToken::Comma:
Douglas Gregor63a72682013-03-20 00:22:05 +00001911 case MMToken::ConfigMacros:
Douglas Gregor906d66a2013-03-20 21:10:35 +00001912 case MMToken::Conflict:
Douglas Gregor2b49d1f2012-10-15 06:28:11 +00001913 case MMToken::ExcludeKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001914 case MMToken::ExportKeyword:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001915 case MMToken::HeaderKeyword:
1916 case MMToken::Identifier:
1917 case MMToken::LBrace:
Douglas Gregorb6cbe512013-01-14 17:21:00 +00001918 case MMToken::LinkKeyword:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001919 case MMToken::LSquare:
Douglas Gregor90db2602011-12-02 01:47:07 +00001920 case MMToken::Period:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001921 case MMToken::RBrace:
Douglas Gregora1f1fad2012-01-27 19:52:33 +00001922 case MMToken::RSquare:
Douglas Gregor51f564f2011-12-31 04:05:44 +00001923 case MMToken::RequiresKeyword:
Douglas Gregor90db2602011-12-02 01:47:07 +00001924 case MMToken::Star:
Douglas Gregora30cfe52011-11-11 19:10:28 +00001925 case MMToken::StringLiteral:
1926 case MMToken::UmbrellaKeyword:
1927 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1928 HadError = true;
1929 consumeToken();
1930 break;
1931 }
1932 } while (true);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001933}
1934
1935bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor7005b902013-01-10 01:43:00 +00001936 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1937 = ParsedModuleMap.find(File);
1938 if (Known != ParsedModuleMap.end())
1939 return Known->second;
1940
Douglas Gregordc58aa72012-01-30 06:01:29 +00001941 assert(Target != 0 && "Missing target information");
Douglas Gregora30cfe52011-11-11 19:10:28 +00001942 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1943 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1944 if (!Buffer)
Douglas Gregor7005b902013-01-10 01:43:00 +00001945 return ParsedModuleMap[File] = true;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001946
1947 // Parse this module map file.
Douglas Gregor51f564f2011-12-31 04:05:44 +00001948 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1949 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregor9a022bb2012-10-15 16:45:32 +00001950 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor2f04f182012-02-02 18:42:48 +00001951 BuiltinIncludeDir);
Douglas Gregora30cfe52011-11-11 19:10:28 +00001952 bool Result = Parser.parseModuleMapFile();
1953 Diags->getClient()->EndSourceFile();
Douglas Gregor7005b902013-01-10 01:43:00 +00001954 ParsedModuleMap[File] = Result;
Douglas Gregora30cfe52011-11-11 19:10:28 +00001955 return Result;
1956}