blob: f46a87abc97ee1c5ce226d134a3db9e785e657df [file] [log] [blame]
Douglas Gregor718292f2011-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 Rosea7d03842013-02-08 22:30:41 +000015#include "clang/Basic/CharInfo.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000016#include "clang/Basic/Diagnostic.h"
Douglas Gregor811db4e2012-10-23 22:26:28 +000017#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000018#include "clang/Basic/FileManager.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Basic/TargetOptions.h"
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000021#include "clang/Lex/HeaderSearch.h"
Chandler Carruth3a022472012-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 Gregor718292f2011-11-11 19:10:28 +000027#include "llvm/Support/Allocator.h"
Douglas Gregore89dbc12011-12-06 19:39:29 +000028#include "llvm/Support/FileSystem.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000029#include "llvm/Support/Host.h"
Rafael Espindola552c1692013-06-11 22:15:02 +000030#include "llvm/Support/Path.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000031#include "llvm/Support/raw_ostream.h"
Douglas Gregor07c22b72012-09-27 14:50:15 +000032#include <stdlib.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000033#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoeadae012013-01-26 16:29:36 +000034#include <limits.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000035#endif
Douglas Gregor718292f2011-11-11 19:10:28 +000036using namespace clang;
37
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000038Module::ExportDecl
39ModuleMap::resolveExport(Module *Mod,
40 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +000041 bool Complain) const {
Douglas Gregorf5eedd02011-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 Gregorfb912652013-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 Gregor2b82c2a2011-12-02 01:47:07 +000058 // Find the starting module.
Douglas Gregorfb912652013-03-20 21:10:35 +000059 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000060 if (!Context) {
61 if (Complain)
Douglas Gregorfb912652013-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 Gregor2b82c2a2011-12-02 01:47:07 +000066 }
67
68 // Dig into the module path.
Douglas Gregorfb912652013-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 Gregor2b82c2a2011-12-02 01:47:07 +000071 if (!Sub) {
72 if (Complain)
Douglas Gregorfb912652013-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 Gregor2b82c2a2011-12-02 01:47:07 +000078 }
Douglas Gregorfb912652013-03-20 21:10:35 +000079
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000080 Context = Sub;
81 }
Douglas Gregorfb912652013-03-20 21:10:35 +000082
83 return Context;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000084}
85
Douglas Gregor6b930962013-05-03 22:58:43 +000086ModuleMap::ModuleMap(FileManager &FileMgr, DiagnosticConsumer &DC,
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000087 const LangOptions &LangOpts, const TargetInfo *Target,
88 HeaderSearch &HeaderInfo)
89 : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +000090 BuiltinIncludeDir(0), CompilingModule(0)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +000091{
Dylan Noblesmithc95d8192012-02-20 14:00:23 +000092 IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
93 Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
Douglas Gregor811db4e2012-10-23 22:26:28 +000094 new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
Douglas Gregor6b930962013-05-03 22:58:43 +000095 Diags->setClient(new ForwardingDiagnosticConsumer(DC),
96 /*ShouldOwnClient=*/true);
Douglas Gregor718292f2011-11-11 19:10:28 +000097 SourceMgr = new SourceManager(*Diags, FileMgr);
98}
99
100ModuleMap::~ModuleMap() {
Douglas Gregor5acdf592011-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 Gregor718292f2011-11-11 19:10:28 +0000107 delete SourceMgr;
108}
109
Douglas Gregor89929282012-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 Gregor056396a2012-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 Rosea7d03842013-02-08 22:30:41 +0000122 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-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 Rosea7d03842013-02-08 22:30:41 +0000126 if (isDigit(Name[0]))
Douglas Gregor056396a2012-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 Rosea7d03842013-02-08 22:30:41 +0000130 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-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 Gregor34d52742013-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
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000171ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
Douglas Gregor59527662012-10-15 06:28:11 +0000172 HeadersMap::iterator Known = Headers.find(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000173 if (Known != Headers.end()) {
Douglas Gregor59527662012-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())
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000176 return KnownHeader();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000177
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000178 return Known->second;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000179 }
Douglas Gregor34d52742013-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 Gregor64a1fa52013-05-10 22:52:27 +0000186 HeaderInfo.loadTopLevelSystemModules();
Douglas Gregor34d52742013-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())
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000193 return KnownHeader();
Douglas Gregor34d52742013-05-02 17:58:30 +0000194
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000195 return Known->second;
Douglas Gregor34d52742013-05-02 17:58:30 +0000196 }
197 }
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000198
Douglas Gregorb65dbff2011-11-16 23:02:25 +0000199 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000200 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregore00c8b22013-01-26 00:55:12 +0000201
Douglas Gregor74260502013-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 Gregore00c8b22013-01-26 00:55:12 +0000206 StringRef DirName = SourceMgr->getFileManager().getCanonicalName(Dir);
Douglas Gregora89c5ac2011-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 Gregor930a85c2011-12-06 16:17:15 +0000215
216 // Search up the module stack until we find a module with an umbrella
Douglas Gregor73141fa2011-12-08 17:39:04 +0000217 // directory.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000218 Module *UmbrellaModule = Result;
Douglas Gregor73141fa2011-12-08 17:39:04 +0000219 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor930a85c2011-12-06 16:17:15 +0000220 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000221
Douglas Gregor930a85c2011-12-06 16:17:15 +0000222 if (UmbrellaModule->InferSubmodules) {
Douglas Gregora89c5ac2011-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 Gregor9458f822011-12-07 22:05:21 +0000226 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000227
Douglas Gregor70331272011-12-09 02:04:43 +0000228 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000229 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-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 Gregora89c5ac2011-12-06 01:10:29 +0000234 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor9458f822011-12-07 22:05:21 +0000235 Explicit).first;
Douglas Gregora89c5ac2011-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 Gregor930a85c2011-12-06 16:17:15 +0000242 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregora89c5ac2011-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 Gregor056396a2012-10-12 21:15:50 +0000247 SmallString<32> NameBuf;
248 StringRef Name = sanitizeFilenameAsIdentifier(
249 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000250 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor9458f822011-12-07 22:05:21 +0000251 Explicit).first;
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +0000252 Result->addTopHeader(File);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000253
254 // If inferred submodules export everything they import, add a
255 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000256 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregora89c5ac2011-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
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000265 Headers[File] = KnownHeader(Result, NormalHeader);
Douglas Gregor1fb5c3a2011-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())
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000270 return KnownHeader();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000271
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000272 return Headers[File];
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000273 }
274
275 SkippedDirs.push_back(Dir);
276
Douglas Gregorb65dbff2011-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 Gregora89c5ac2011-12-06 01:10:29 +0000284 } while (Dir);
Douglas Gregorb65dbff2011-11-16 23:02:25 +0000285
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000286 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000287}
288
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000289bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
290 HeadersMap::const_iterator Known = Headers.find(Header);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000291 if (Known != Headers.end())
Douglas Gregor59527662012-10-15 06:28:11 +0000292 return !Known->second.isAvailable();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000293
294 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000295 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-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 Kyrtzidise4412642013-02-19 19:58:45 +0000301 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-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 Gregor056396a2012-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 Gregor1fb5c3a2011-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 Gregor056396a2012-10-12 21:15:50 +0000329 SmallString<32> NameBuf;
330 StringRef Name = sanitizeFilenameAsIdentifier(
331 llvm::sys::path::stem(Header->getName()),
332 NameBuf);
Douglas Gregor1fb5c3a2011-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 Kyrtzidise4412642013-02-19 19:58:45 +0000355Module *ModuleMap::findModule(StringRef Name) const {
356 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000357 if (Known != Modules.end())
358 return Known->getValue();
359
360 return 0;
361}
362
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000363Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
364 Module *Context) const {
Douglas Gregor2b82c2a2011-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 Kyrtzidise4412642013-02-19 19:58:45 +0000373Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000374 if (!Context)
375 return findModule(Name);
376
Douglas Gregoreb90e832012-01-04 23:32:19 +0000377 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000378}
379
Douglas Gregorde3ef502011-11-30 23:21:26 +0000380std::pair<Module *, bool>
Douglas Gregor69021972011-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 Gregoreb90e832012-01-04 23:32:19 +0000384 if (Module *Sub = lookupModuleQualified(Name, Parent))
385 return std::make_pair(Sub, false);
Douglas Gregor69021972011-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 Kyrtzidis6f722b42013-05-08 23:46:46 +0000390 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000391 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000392 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
393 Name == LangOpts.CurrentModule) {
394 CompilingModule = Result;
395 }
396 }
Douglas Gregor69021972011-11-30 17:33:56 +0000397 return std::make_pair(Result, true);
398}
399
Douglas Gregor9194a912012-11-06 19:39:40 +0000400bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000401 StringRef Name, bool &IsSystem) const {
Douglas Gregor9194a912012-11-06 19:39:40 +0000402 // Check whether we have already looked into the parent directory
403 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000404 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-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 Gregor11dfe6f2013-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 Gregorde3ef502011-11-30 23:21:26 +0000441Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000442ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000443 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000444 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000445 Module *Parent) {
Douglas Gregor56c64012011-11-17 01:41:17 +0000446 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000447 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
448 return Mod;
449
450 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor9194a912012-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 Gregor4ddf2222013-01-10 01:43:00 +0000455 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000456
Douglas Gregor4ddf2222013-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 Gregore00c8b22013-01-26 00:55:12 +0000461 StringRef FrameworkDirName
462 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000463
Douglas Gregor9194a912012-11-06 19:39:40 +0000464 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000465 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000466 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000467 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-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 Kyrtzidise4412642013-02-19 19:58:45 +0000471 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-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 Gregor4ddf2222013-01-10 01:43:00 +0000491 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-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 Gregor56c64012011-11-17 01:41:17 +0000508 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000509 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Douglas Gregor56c64012011-11-17 01:41:17 +0000510 llvm::sys::path::append(UmbrellaName, "Headers");
511 llvm::sys::path::append(UmbrellaName, ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000512 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-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 Gregore89dbc12011-12-06 19:39:29 +0000520 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
521 /*IsFramework=*/true, /*IsExplicit=*/false);
Douglas Gregora686e1b2012-01-27 19:52:33 +0000522 if (IsSystem)
523 Result->IsSystem = IsSystem;
524
Douglas Gregoreb90e832012-01-04 23:32:19 +0000525 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000526 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000527
Douglas Gregor322f6332011-12-08 18:00:48 +0000528 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000529 Result->Umbrella = UmbrellaHeader;
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000530 Headers[UmbrellaHeader] = KnownHeader(Result, NormalHeader);
Douglas Gregor4dc71832011-12-12 23:55:05 +0000531 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000532
533 // export *
534 Result->Exports.push_back(Module::ExportDecl(0, true));
535
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000536 // module * { export * }
537 Result->InferSubmodules = true;
538 Result->InferExportWildcard = true;
539
Douglas Gregore89dbc12011-12-06 19:39:29 +0000540 // Look for subframeworks.
541 llvm::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000542 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000543 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000544 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000545 SmallString<128> SubframeworksDirNameNative;
Douglas Gregorddaa69c2011-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 Gregore89dbc12011-12-06 19:39:29 +0000550 Dir != DirEnd && !EC; Dir.increment(EC)) {
551 if (!StringRef(Dir->path()).endswith(".framework"))
552 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000553
Douglas Gregore89dbc12011-12-06 19:39:29 +0000554 if (const DirectoryEntry *SubframeworkDir
555 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-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 Gregore00c8b22013-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 Gregor07c22b72012-09-27 14:50:15 +0000568
Douglas Gregore00c8b22013-01-26 00:55:12 +0000569 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
570 FoundParent = true;
571 break;
572 }
573 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000574
Douglas Gregore00c8b22013-01-26 00:55:12 +0000575 if (!FoundParent)
576 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000577
Douglas Gregore89dbc12011-12-06 19:39:29 +0000578 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-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 Gregore89dbc12011-12-06 19:39:29 +0000583 }
584 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000585
Douglas Gregor11dfe6f2013-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 Gregor56c64012011-11-17 01:41:17 +0000592 return Result;
593}
594
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000595void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000596 Headers[UmbrellaHeader] = KnownHeader(Mod, NormalHeader);
Douglas Gregor73141fa2011-12-08 17:39:04 +0000597 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000598 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000599}
600
Douglas Gregor524e33e2011-12-08 19:11:24 +0000601void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
602 Mod->Umbrella = UmbrellaDir;
603 UmbrellaDirs[UmbrellaDir] = Mod;
604}
605
Douglas Gregor59527662012-10-15 06:28:11 +0000606void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000607 ModuleHeaderRole Role) {
608 if (Role == ExcludedHeader) {
Douglas Gregor59527662012-10-15 06:28:11 +0000609 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000610 } else {
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000611 if (Role == PrivateHeader)
612 Mod->PrivateHeaders.push_back(Header);
613 else
614 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000615 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000616 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000617 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000618 Headers[Header] = KnownHeader(Mod, Role);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000619}
620
Douglas Gregor514b6362011-11-29 19:06:37 +0000621const FileEntry *
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000622ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregor514b6362011-11-29 19:06:37 +0000623 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
624 return 0;
625
626 return SourceMgr->getFileEntryForID(
627 SourceMgr->getFileID(Module->DefinitionLoc));
628}
629
Douglas Gregor718292f2011-11-11 19:10:28 +0000630void ModuleMap::dump() {
631 llvm::errs() << "Modules:";
632 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
633 MEnd = Modules.end();
634 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000635 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000636
637 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000638 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000639 H != HEnd; ++H) {
640 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor59527662012-10-15 06:28:11 +0000641 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000642 }
643}
644
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000645bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
646 bool HadError = false;
647 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
648 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
649 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000650 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000651 Mod->Exports.push_back(Export);
652 else
653 HadError = true;
654 }
655 Mod->UnresolvedExports.clear();
656 return HadError;
657}
658
Douglas Gregorfb912652013-03-20 21:10:35 +0000659bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
660 bool HadError = false;
661 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
662 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
663 Mod, Complain);
664 if (!OtherMod) {
665 HadError = true;
666 continue;
667 }
668
669 Module::Conflict Conflict;
670 Conflict.Other = OtherMod;
671 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
672 Mod->Conflicts.push_back(Conflict);
673 }
674 Mod->UnresolvedConflicts.clear();
675 return HadError;
676}
677
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000678Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
679 if (Loc.isInvalid())
680 return 0;
681
682 // Use the expansion location to determine which module we're in.
683 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
684 if (!ExpansionLoc.isFileID())
685 return 0;
686
687
688 const SourceManager &SrcMgr = Loc.getManager();
689 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000690
Douglas Gregor224d8a72012-01-06 17:19:32 +0000691 while (const FileEntry *ExpansionFile
692 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
693 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000694 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000695 return Mod;
696
697 // No module owns this header, so look up the inclusion chain to see if
698 // any included header has an associated module.
699 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
700 if (IncludeLoc.isInvalid())
701 return 0;
702
703 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
704 }
705
706 return 0;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000707}
708
Douglas Gregor718292f2011-11-11 19:10:28 +0000709//----------------------------------------------------------------------------//
710// Module map file parser
711//----------------------------------------------------------------------------//
712
713namespace clang {
714 /// \brief A token in a module map file.
715 struct MMToken {
716 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000717 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000718 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000719 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000720 EndOfFile,
721 HeaderKeyword,
722 Identifier,
Douglas Gregor59527662012-10-15 06:28:11 +0000723 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000724 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000725 ExportKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000726 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000727 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000728 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000729 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000730 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000731 UmbrellaKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000732 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000733 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000734 StringLiteral,
735 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000736 RBrace,
737 LSquare,
738 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000739 } Kind;
740
741 unsigned Location;
742 unsigned StringLength;
743 const char *StringData;
744
745 void clear() {
746 Kind = EndOfFile;
747 Location = 0;
748 StringLength = 0;
749 StringData = 0;
750 }
751
752 bool is(TokenKind K) const { return Kind == K; }
753
754 SourceLocation getLocation() const {
755 return SourceLocation::getFromRawEncoding(Location);
756 }
757
758 StringRef getString() const {
759 return StringRef(StringData, StringLength);
760 }
761 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000762
763 /// \brief The set of attributes that can be attached to a module.
Bill Wendling44426052012-12-20 19:22:21 +0000764 struct Attributes {
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000765 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor9194a912012-11-06 19:39:40 +0000766
767 /// \brief Whether this is a system module.
768 unsigned IsSystem : 1;
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000769
770 /// \brief Whether this is an exhaustive set of configuration macros.
771 unsigned IsExhaustive : 1;
Douglas Gregor9194a912012-11-06 19:39:40 +0000772 };
Douglas Gregor718292f2011-11-11 19:10:28 +0000773
Douglas Gregor9194a912012-11-06 19:39:40 +0000774
Douglas Gregor718292f2011-11-11 19:10:28 +0000775 class ModuleMapParser {
776 Lexer &L;
777 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000778
779 /// \brief Default target information, used only for string literal
780 /// parsing.
781 const TargetInfo *Target;
782
Douglas Gregor718292f2011-11-11 19:10:28 +0000783 DiagnosticsEngine &Diags;
784 ModuleMap &Map;
785
Douglas Gregor5257fc62011-11-11 21:55:48 +0000786 /// \brief The directory that this module map resides in.
787 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +0000788
789 /// \brief The directory containing Clang-supplied headers.
790 const DirectoryEntry *BuiltinIncludeDir;
791
Douglas Gregor718292f2011-11-11 19:10:28 +0000792 /// \brief Whether an error occurred.
793 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000794
Douglas Gregor718292f2011-11-11 19:10:28 +0000795 /// \brief Stores string data for the various string literals referenced
796 /// during parsing.
797 llvm::BumpPtrAllocator StringData;
798
799 /// \brief The current token.
800 MMToken Tok;
801
802 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +0000803 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +0000804
805 /// \brief Consume the current token and return its location.
806 SourceLocation consumeToken();
807
808 /// \brief Skip tokens until we reach the a token with the given kind
809 /// (or the end of the file).
810 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +0000811
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000812 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +0000813 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +0000814 void parseModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000815 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000816 void parseHeaderDecl(clang::MMToken::TokenKind,
817 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +0000818 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000819 void parseExportDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000820 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000821 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +0000822 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +0000823 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendling44426052012-12-20 19:22:21 +0000824 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor9194a912012-11-06 19:39:40 +0000825
Douglas Gregor70331272011-12-09 02:04:43 +0000826 const DirectoryEntry *getOverriddenHeaderSearchDir();
827
Douglas Gregor718292f2011-11-11 19:10:28 +0000828 public:
Douglas Gregor718292f2011-11-11 19:10:28 +0000829 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000830 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +0000831 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +0000832 ModuleMap &Map,
Douglas Gregor3ec66632012-02-02 18:42:48 +0000833 const DirectoryEntry *Directory,
834 const DirectoryEntry *BuiltinIncludeDir)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000835 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor3ec66632012-02-02 18:42:48 +0000836 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
837 HadError(false), ActiveModule(0)
Douglas Gregor718292f2011-11-11 19:10:28 +0000838 {
Douglas Gregor718292f2011-11-11 19:10:28 +0000839 Tok.clear();
840 consumeToken();
841 }
842
843 bool parseModuleMapFile();
844 };
845}
846
847SourceLocation ModuleMapParser::consumeToken() {
848retry:
849 SourceLocation Result = Tok.getLocation();
850 Tok.clear();
851
852 Token LToken;
853 L.LexFromRawLexer(LToken);
854 Tok.Location = LToken.getLocation().getRawEncoding();
855 switch (LToken.getKind()) {
856 case tok::raw_identifier:
857 Tok.StringData = LToken.getRawIdentifierData();
858 Tok.StringLength = LToken.getLength();
859 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000860 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +0000861 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +0000862 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +0000863 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000864 .Case("export", MMToken::ExportKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +0000865 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000866 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000867 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +0000868 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000869 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000870 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +0000871 .Case("umbrella", MMToken::UmbrellaKeyword)
872 .Default(MMToken::Identifier);
873 break;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000874
875 case tok::comma:
876 Tok.Kind = MMToken::Comma;
877 break;
878
Douglas Gregor718292f2011-11-11 19:10:28 +0000879 case tok::eof:
880 Tok.Kind = MMToken::EndOfFile;
881 break;
882
883 case tok::l_brace:
884 Tok.Kind = MMToken::LBrace;
885 break;
886
Douglas Gregora686e1b2012-01-27 19:52:33 +0000887 case tok::l_square:
888 Tok.Kind = MMToken::LSquare;
889 break;
890
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000891 case tok::period:
892 Tok.Kind = MMToken::Period;
893 break;
894
Douglas Gregor718292f2011-11-11 19:10:28 +0000895 case tok::r_brace:
896 Tok.Kind = MMToken::RBrace;
897 break;
898
Douglas Gregora686e1b2012-01-27 19:52:33 +0000899 case tok::r_square:
900 Tok.Kind = MMToken::RSquare;
901 break;
902
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000903 case tok::star:
904 Tok.Kind = MMToken::Star;
905 break;
906
Douglas Gregor718292f2011-11-11 19:10:28 +0000907 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +0000908 if (LToken.hasUDSuffix()) {
909 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
910 HadError = true;
911 goto retry;
912 }
913
Douglas Gregor718292f2011-11-11 19:10:28 +0000914 // Parse the string literal.
915 LangOptions LangOpts;
916 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
917 if (StringLiteral.hadError)
918 goto retry;
919
920 // Copy the string literal into our string data allocator.
921 unsigned Length = StringLiteral.GetStringLength();
922 char *Saved = StringData.Allocate<char>(Length + 1);
923 memcpy(Saved, StringLiteral.GetString().data(), Length);
924 Saved[Length] = 0;
925
926 // Form the token.
927 Tok.Kind = MMToken::StringLiteral;
928 Tok.StringData = Saved;
929 Tok.StringLength = Length;
930 break;
931 }
932
933 case tok::comment:
934 goto retry;
935
936 default:
937 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
938 HadError = true;
939 goto retry;
940 }
941
942 return Result;
943}
944
945void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
946 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +0000947 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +0000948 do {
949 switch (Tok.Kind) {
950 case MMToken::EndOfFile:
951 return;
952
953 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +0000954 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +0000955 return;
956
957 ++braceDepth;
958 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +0000959
960 case MMToken::LSquare:
961 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
962 return;
963
964 ++squareDepth;
965 break;
966
Douglas Gregor718292f2011-11-11 19:10:28 +0000967 case MMToken::RBrace:
968 if (braceDepth > 0)
969 --braceDepth;
970 else if (Tok.is(K))
971 return;
972 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +0000973
974 case MMToken::RSquare:
975 if (squareDepth > 0)
976 --squareDepth;
977 else if (Tok.is(K))
978 return;
979 break;
980
Douglas Gregor718292f2011-11-11 19:10:28 +0000981 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +0000982 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +0000983 return;
984 break;
985 }
986
987 consumeToken();
988 } while (true);
989}
990
Douglas Gregore7ab3662011-12-07 02:23:45 +0000991/// \brief Parse a module-id.
992///
993/// module-id:
994/// identifier
995/// identifier '.' module-id
996///
997/// \returns true if an error occurred, false otherwise.
998bool ModuleMapParser::parseModuleId(ModuleId &Id) {
999 Id.clear();
1000 do {
1001 if (Tok.is(MMToken::Identifier)) {
1002 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1003 consumeToken();
1004 } else {
1005 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1006 return true;
1007 }
1008
1009 if (!Tok.is(MMToken::Period))
1010 break;
1011
1012 consumeToken();
1013 } while (true);
1014
1015 return false;
1016}
1017
Douglas Gregora686e1b2012-01-27 19:52:33 +00001018namespace {
1019 /// \brief Enumerates the known attributes.
1020 enum AttributeKind {
1021 /// \brief An unknown attribute.
1022 AT_unknown,
1023 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001024 AT_system,
1025 /// \brief The 'exhaustive' attribute.
1026 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001027 };
1028}
1029
Douglas Gregor718292f2011-11-11 19:10:28 +00001030/// \brief Parse a module declaration.
1031///
1032/// module-declaration:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001033/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1034/// { module-member* }
1035///
Douglas Gregor718292f2011-11-11 19:10:28 +00001036/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001037/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001038/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001039/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001040/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001041/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001042///
1043/// submodule-declaration:
1044/// module-declaration
1045/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001046void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001047 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
1048 Tok.is(MMToken::FrameworkKeyword));
Douglas Gregorf2161a72011-12-06 17:16:41 +00001049 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001050 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001051 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001052 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001053
Douglas Gregorf2161a72011-12-06 17:16:41 +00001054 // Parse 'explicit' keyword, if present.
1055 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001056 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001057 Explicit = true;
1058 }
1059
1060 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001061 if (Tok.is(MMToken::FrameworkKeyword)) {
1062 consumeToken();
1063 Framework = true;
1064 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001065
1066 // Parse 'module' keyword.
1067 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001068 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001069 consumeToken();
1070 HadError = true;
1071 return;
1072 }
1073 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001074
1075 // If we have a wildcard for the module name, this is an inferred submodule.
1076 // Parse it.
1077 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001078 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001079
1080 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001081 ModuleId Id;
1082 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001083 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001084 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001085 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001086
Douglas Gregore7ab3662011-12-07 02:23:45 +00001087 if (ActiveModule) {
1088 if (Id.size() > 1) {
1089 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1090 << SourceRange(Id.front().second, Id.back().second);
1091
1092 HadError = true;
1093 return;
1094 }
1095 } else if (Id.size() == 1 && Explicit) {
1096 // Top-level modules can't be explicit.
1097 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1098 Explicit = false;
1099 ExplicitLoc = SourceLocation();
1100 HadError = true;
1101 }
1102
1103 Module *PreviousActiveModule = ActiveModule;
1104 if (Id.size() > 1) {
1105 // This module map defines a submodule. Go find the module of which it
1106 // is a submodule.
1107 ActiveModule = 0;
1108 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1109 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1110 ActiveModule = Next;
1111 continue;
1112 }
1113
1114 if (ActiveModule) {
1115 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1116 << Id[I].first << ActiveModule->getTopLevelModule();
1117 } else {
1118 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1119 }
1120 HadError = true;
1121 return;
1122 }
1123 }
1124
1125 StringRef ModuleName = Id.back().first;
1126 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001127
Douglas Gregora686e1b2012-01-27 19:52:33 +00001128 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001129 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001130 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001131
Douglas Gregor718292f2011-11-11 19:10:28 +00001132 // Parse the opening brace.
1133 if (!Tok.is(MMToken::LBrace)) {
1134 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1135 << ModuleName;
1136 HadError = true;
1137 return;
1138 }
1139 SourceLocation LBraceLoc = consumeToken();
1140
1141 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001142 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001143 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1144 // Skip the module definition.
1145 skipUntil(MMToken::RBrace);
1146 if (Tok.is(MMToken::RBrace))
1147 consumeToken();
1148 else {
1149 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1150 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1151 HadError = true;
1152 }
1153 return;
1154 }
1155
Douglas Gregor718292f2011-11-11 19:10:28 +00001156 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1157 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001158 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001159
1160 // Skip the module definition.
1161 skipUntil(MMToken::RBrace);
1162 if (Tok.is(MMToken::RBrace))
1163 consumeToken();
1164
1165 HadError = true;
1166 return;
1167 }
1168
1169 // Start defining this module.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001170 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1171 Explicit).first;
1172 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor9194a912012-11-06 19:39:40 +00001173 if (Attrs.IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001174 ActiveModule->IsSystem = true;
Douglas Gregor718292f2011-11-11 19:10:28 +00001175
1176 bool Done = false;
1177 do {
1178 switch (Tok.Kind) {
1179 case MMToken::EndOfFile:
1180 case MMToken::RBrace:
1181 Done = true;
1182 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001183
1184 case MMToken::ConfigMacros:
1185 parseConfigMacros();
1186 break;
1187
Douglas Gregorfb912652013-03-20 21:10:35 +00001188 case MMToken::Conflict:
1189 parseConflict();
1190 break;
1191
Douglas Gregor718292f2011-11-11 19:10:28 +00001192 case MMToken::ExplicitKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001193 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001194 case MMToken::ModuleKeyword:
1195 parseModuleDecl();
1196 break;
1197
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001198 case MMToken::ExportKeyword:
1199 parseExportDecl();
1200 break;
1201
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001202 case MMToken::RequiresKeyword:
1203 parseRequiresDecl();
1204 break;
1205
Douglas Gregor524e33e2011-12-08 19:11:24 +00001206 case MMToken::UmbrellaKeyword: {
1207 SourceLocation UmbrellaLoc = consumeToken();
1208 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001209 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001210 else
1211 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001212 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001213 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001214
Douglas Gregor59527662012-10-15 06:28:11 +00001215 case MMToken::ExcludeKeyword: {
1216 SourceLocation ExcludeLoc = consumeToken();
1217 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001218 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor59527662012-10-15 06:28:11 +00001219 } else {
1220 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1221 << "exclude";
1222 }
1223 break;
1224 }
1225
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001226 case MMToken::PrivateKeyword: {
1227 SourceLocation PrivateLoc = consumeToken();
1228 if (Tok.is(MMToken::HeaderKeyword)) {
1229 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1230 } else {
1231 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1232 << "private";
1233 }
1234 break;
1235 }
1236
Douglas Gregor322f6332011-12-08 18:00:48 +00001237 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001238 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregor718292f2011-11-11 19:10:28 +00001239 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001240
1241 case MMToken::LinkKeyword:
1242 parseLinkDecl();
1243 break;
1244
Douglas Gregor718292f2011-11-11 19:10:28 +00001245 default:
1246 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1247 consumeToken();
1248 break;
1249 }
1250 } while (!Done);
1251
1252 if (Tok.is(MMToken::RBrace))
1253 consumeToken();
1254 else {
1255 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1256 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1257 HadError = true;
1258 }
1259
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001260 // If the active module is a top-level framework, and there are no link
1261 // libraries, automatically link against the framework.
1262 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1263 ActiveModule->LinkLibraries.empty()) {
1264 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1265 }
1266
Douglas Gregore7ab3662011-12-07 02:23:45 +00001267 // We're done parsing this module. Pop back to the previous module.
1268 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001269}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001270
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001271/// \brief Parse a requires declaration.
1272///
1273/// requires-declaration:
1274/// 'requires' feature-list
1275///
1276/// feature-list:
1277/// identifier ',' feature-list
1278/// identifier
1279void ModuleMapParser::parseRequiresDecl() {
1280 assert(Tok.is(MMToken::RequiresKeyword));
1281
1282 // Parse 'requires' keyword.
1283 consumeToken();
1284
1285 // Parse the feature-list.
1286 do {
1287 if (!Tok.is(MMToken::Identifier)) {
1288 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1289 HadError = true;
1290 return;
1291 }
1292
1293 // Consume the feature name.
1294 std::string Feature = Tok.getString();
1295 consumeToken();
1296
1297 // Add this feature.
Douglas Gregor89929282012-01-30 06:01:29 +00001298 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001299
1300 if (!Tok.is(MMToken::Comma))
1301 break;
1302
1303 // Consume the comma.
1304 consumeToken();
1305 } while (true);
1306}
1307
Douglas Gregorf2161a72011-12-06 17:16:41 +00001308/// \brief Append to \p Paths the set of paths needed to get to the
1309/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001310static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001311 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001312 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001313 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001314 for (; Mod; Mod = Mod->Parent) {
1315 if (Mod->IsFramework)
1316 Paths.push_back(Mod->Name);
1317 }
1318
1319 if (Paths.empty())
1320 return;
1321
1322 // Add Frameworks/Name.framework for each subframework.
1323 for (unsigned I = Paths.size() - 1; I != 0; --I) {
1324 llvm::sys::path::append(Path, "Frameworks");
1325 llvm::sys::path::append(Path, Paths[I-1] + ".framework");
1326 }
1327}
1328
Douglas Gregor718292f2011-11-11 19:10:28 +00001329/// \brief Parse a header declaration.
1330///
1331/// header-declaration:
Douglas Gregor322f6332011-12-08 18:00:48 +00001332/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor59527662012-10-15 06:28:11 +00001333/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001334void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1335 SourceLocation LeadingLoc) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001336 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001337 consumeToken();
1338
Douglas Gregor718292f2011-11-11 19:10:28 +00001339 // Parse the header name.
1340 if (!Tok.is(MMToken::StringLiteral)) {
1341 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1342 << "header";
1343 HadError = true;
1344 return;
1345 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001346 std::string FileName = Tok.getString();
Douglas Gregor718292f2011-11-11 19:10:28 +00001347 SourceLocation FileNameLoc = consumeToken();
1348
Douglas Gregor524e33e2011-12-08 19:11:24 +00001349 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001350 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Douglas Gregor524e33e2011-12-08 19:11:24 +00001351 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1352 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001353 HadError = true;
1354 return;
1355 }
1356
Douglas Gregor5257fc62011-11-11 21:55:48 +00001357 // Look for this file.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001358 const FileEntry *File = 0;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001359 const FileEntry *BuiltinFile = 0;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001360 SmallString<128> PathName;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001361 if (llvm::sys::path::is_absolute(FileName)) {
1362 PathName = FileName;
1363 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor70331272011-12-09 02:04:43 +00001364 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1365 PathName = Dir->getName();
1366 llvm::sys::path::append(PathName, FileName);
1367 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001368 } else {
1369 // Search for the header file within the search directory.
Douglas Gregor70331272011-12-09 02:04:43 +00001370 PathName = Directory->getName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001371 unsigned PathLength = PathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001372
Douglas Gregorf2161a72011-12-06 17:16:41 +00001373 if (ActiveModule->isPartOfFramework()) {
1374 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001375
1376 // Check whether this file is in the public headers.
Douglas Gregorf545f672011-11-29 21:59:16 +00001377 llvm::sys::path::append(PathName, "Headers");
Douglas Gregore7ab3662011-12-07 02:23:45 +00001378 llvm::sys::path::append(PathName, FileName);
1379 File = SourceMgr.getFileManager().getFile(PathName);
1380
1381 if (!File) {
1382 // Check whether this file is in the private headers.
1383 PathName.resize(PathLength);
1384 llvm::sys::path::append(PathName, "PrivateHeaders");
1385 llvm::sys::path::append(PathName, FileName);
1386 File = SourceMgr.getFileManager().getFile(PathName);
1387 }
1388 } else {
1389 // Lookup for normal headers.
1390 llvm::sys::path::append(PathName, FileName);
1391 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001392
1393 // If this is a system module with a top-level header, this header
1394 // may have a counterpart (or replacement) in the set of headers
1395 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001396 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1397 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1398 isBuiltinHeader(FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001399 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor3ec66632012-02-02 18:42:48 +00001400 llvm::sys::path::append(BuiltinPathName, FileName);
1401 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1402
1403 // If Clang supplies this header but the underlying system does not,
1404 // just silently swap in our builtin version. Otherwise, we'll end
1405 // up adding both (later).
1406 if (!File && BuiltinFile) {
1407 File = BuiltinFile;
1408 BuiltinFile = 0;
1409 }
1410 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001411 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001412 }
Douglas Gregor755b2052011-11-17 22:09:43 +00001413
Douglas Gregor5257fc62011-11-11 21:55:48 +00001414 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1415 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001416 if (File) {
Douglas Gregor59527662012-10-15 06:28:11 +00001417 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor5257fc62011-11-11 21:55:48 +00001418 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001419 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor5257fc62011-11-11 21:55:48 +00001420 HadError = true;
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001421 } else if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001422 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001423 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001424 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001425 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001426 HadError = true;
1427 } else {
1428 // Record this umbrella header.
1429 Map.setUmbrellaHeader(ActiveModule, File);
1430 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00001431 } else {
Douglas Gregor322f6332011-12-08 18:00:48 +00001432 // Record this header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001433 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1434 if (LeadingToken == MMToken::ExcludeKeyword)
1435 Role = ModuleMap::ExcludedHeader;
1436 else if (LeadingToken == MMToken::PrivateKeyword)
1437 Role = ModuleMap::PrivateHeader;
1438 else
1439 assert(LeadingToken == MMToken::HeaderKeyword);
1440
1441 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001442
1443 // If there is a builtin counterpart to this file, add it now.
1444 if (BuiltinFile)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001445 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001446 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001447 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001448 // Ignore excluded header files. They're optional anyway.
1449
Douglas Gregor5257fc62011-11-11 21:55:48 +00001450 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001451 << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
Douglas Gregor5257fc62011-11-11 21:55:48 +00001452 HadError = true;
1453 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001454}
1455
Douglas Gregor524e33e2011-12-08 19:11:24 +00001456/// \brief Parse an umbrella directory declaration.
1457///
1458/// umbrella-dir-declaration:
1459/// umbrella string-literal
1460void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1461 // Parse the directory name.
1462 if (!Tok.is(MMToken::StringLiteral)) {
1463 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1464 << "umbrella";
1465 HadError = true;
1466 return;
1467 }
1468
1469 std::string DirName = Tok.getString();
1470 SourceLocation DirNameLoc = consumeToken();
1471
1472 // Check whether we already have an umbrella.
1473 if (ActiveModule->Umbrella) {
1474 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1475 << ActiveModule->getFullModuleName();
1476 HadError = true;
1477 return;
1478 }
1479
1480 // Look for this file.
1481 const DirectoryEntry *Dir = 0;
1482 if (llvm::sys::path::is_absolute(DirName))
1483 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1484 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001485 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001486 PathName = Directory->getName();
1487 llvm::sys::path::append(PathName, DirName);
1488 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1489 }
1490
1491 if (!Dir) {
1492 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1493 << DirName;
1494 HadError = true;
1495 return;
1496 }
1497
1498 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1499 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1500 << OwningModule->getFullModuleName();
1501 HadError = true;
1502 return;
1503 }
1504
1505 // Record this umbrella directory.
1506 Map.setUmbrellaDir(ActiveModule, Dir);
1507}
1508
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001509/// \brief Parse a module export declaration.
1510///
1511/// export-declaration:
1512/// 'export' wildcard-module-id
1513///
1514/// wildcard-module-id:
1515/// identifier
1516/// '*'
1517/// identifier '.' wildcard-module-id
1518void ModuleMapParser::parseExportDecl() {
1519 assert(Tok.is(MMToken::ExportKeyword));
1520 SourceLocation ExportLoc = consumeToken();
1521
1522 // Parse the module-id with an optional wildcard at the end.
1523 ModuleId ParsedModuleId;
1524 bool Wildcard = false;
1525 do {
1526 if (Tok.is(MMToken::Identifier)) {
1527 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1528 Tok.getLocation()));
1529 consumeToken();
1530
1531 if (Tok.is(MMToken::Period)) {
1532 consumeToken();
1533 continue;
1534 }
1535
1536 break;
1537 }
1538
1539 if(Tok.is(MMToken::Star)) {
1540 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001541 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001542 break;
1543 }
1544
1545 Diags.Report(Tok.getLocation(), diag::err_mmap_export_module_id);
1546 HadError = true;
1547 return;
1548 } while (true);
1549
1550 Module::UnresolvedExportDecl Unresolved = {
1551 ExportLoc, ParsedModuleId, Wildcard
1552 };
1553 ActiveModule->UnresolvedExports.push_back(Unresolved);
1554}
1555
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001556/// \brief Parse a link declaration.
1557///
1558/// module-declaration:
1559/// 'link' 'framework'[opt] string-literal
1560void ModuleMapParser::parseLinkDecl() {
1561 assert(Tok.is(MMToken::LinkKeyword));
1562 SourceLocation LinkLoc = consumeToken();
1563
1564 // Parse the optional 'framework' keyword.
1565 bool IsFramework = false;
1566 if (Tok.is(MMToken::FrameworkKeyword)) {
1567 consumeToken();
1568 IsFramework = true;
1569 }
1570
1571 // Parse the library name
1572 if (!Tok.is(MMToken::StringLiteral)) {
1573 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1574 << IsFramework << SourceRange(LinkLoc);
1575 HadError = true;
1576 return;
1577 }
1578
1579 std::string LibraryName = Tok.getString();
1580 consumeToken();
1581 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1582 IsFramework));
1583}
1584
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001585/// \brief Parse a configuration macro declaration.
1586///
1587/// module-declaration:
1588/// 'config_macros' attributes[opt] config-macro-list?
1589///
1590/// config-macro-list:
1591/// identifier (',' identifier)?
1592void ModuleMapParser::parseConfigMacros() {
1593 assert(Tok.is(MMToken::ConfigMacros));
1594 SourceLocation ConfigMacrosLoc = consumeToken();
1595
1596 // Only top-level modules can have configuration macros.
1597 if (ActiveModule->Parent) {
1598 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1599 }
1600
1601 // Parse the optional attributes.
1602 Attributes Attrs;
1603 parseOptionalAttributes(Attrs);
1604 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1605 ActiveModule->ConfigMacrosExhaustive = true;
1606 }
1607
1608 // If we don't have an identifier, we're done.
1609 if (!Tok.is(MMToken::Identifier))
1610 return;
1611
1612 // Consume the first identifier.
1613 if (!ActiveModule->Parent) {
1614 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1615 }
1616 consumeToken();
1617
1618 do {
1619 // If there's a comma, consume it.
1620 if (!Tok.is(MMToken::Comma))
1621 break;
1622 consumeToken();
1623
1624 // We expect to see a macro name here.
1625 if (!Tok.is(MMToken::Identifier)) {
1626 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1627 break;
1628 }
1629
1630 // Consume the macro name.
1631 if (!ActiveModule->Parent) {
1632 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1633 }
1634 consumeToken();
1635 } while (true);
1636}
1637
Douglas Gregorfb912652013-03-20 21:10:35 +00001638/// \brief Format a module-id into a string.
1639static std::string formatModuleId(const ModuleId &Id) {
1640 std::string result;
1641 {
1642 llvm::raw_string_ostream OS(result);
1643
1644 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1645 if (I)
1646 OS << ".";
1647 OS << Id[I].first;
1648 }
1649 }
1650
1651 return result;
1652}
1653
1654/// \brief Parse a conflict declaration.
1655///
1656/// module-declaration:
1657/// 'conflict' module-id ',' string-literal
1658void ModuleMapParser::parseConflict() {
1659 assert(Tok.is(MMToken::Conflict));
1660 SourceLocation ConflictLoc = consumeToken();
1661 Module::UnresolvedConflict Conflict;
1662
1663 // Parse the module-id.
1664 if (parseModuleId(Conflict.Id))
1665 return;
1666
1667 // Parse the ','.
1668 if (!Tok.is(MMToken::Comma)) {
1669 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1670 << SourceRange(ConflictLoc);
1671 return;
1672 }
1673 consumeToken();
1674
1675 // Parse the message.
1676 if (!Tok.is(MMToken::StringLiteral)) {
1677 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1678 << formatModuleId(Conflict.Id);
1679 return;
1680 }
1681 Conflict.Message = Tok.getString().str();
1682 consumeToken();
1683
1684 // Add this unresolved conflict.
1685 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1686}
1687
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001688/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00001689///
1690/// module-declaration:
1691/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1692/// { inferred-module-member* }
1693///
1694/// inferred-module-member:
1695/// 'export' '*'
1696/// 'exclude' identifier
1697void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00001698 assert(Tok.is(MMToken::Star));
1699 SourceLocation StarLoc = consumeToken();
1700 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00001701
Douglas Gregor73441092011-12-05 22:27:44 +00001702 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00001703 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00001704 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1705 Failed = true;
1706 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001707
1708 if (ActiveModule) {
1709 // Inferred modules must have umbrella directories.
1710 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1711 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1712 Failed = true;
1713 }
1714
1715 // Check for redefinition of an inferred module.
1716 if (!Failed && ActiveModule->InferSubmodules) {
1717 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1718 if (ActiveModule->InferredSubmoduleLoc.isValid())
1719 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1720 diag::note_mmap_prev_definition);
1721 Failed = true;
1722 }
1723
1724 // Check for the 'framework' keyword, which is not permitted here.
1725 if (Framework) {
1726 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1727 Framework = false;
1728 }
1729 } else if (Explicit) {
1730 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1731 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00001732 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001733
Douglas Gregor73441092011-12-05 22:27:44 +00001734 // If there were any problems with this inferred submodule, skip its body.
1735 if (Failed) {
1736 if (Tok.is(MMToken::LBrace)) {
1737 consumeToken();
1738 skipUntil(MMToken::RBrace);
1739 if (Tok.is(MMToken::RBrace))
1740 consumeToken();
1741 }
1742 HadError = true;
1743 return;
1744 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001745
1746 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00001747 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001748 parseOptionalAttributes(Attrs);
1749
1750 if (ActiveModule) {
1751 // Note that we have an inferred submodule.
1752 ActiveModule->InferSubmodules = true;
1753 ActiveModule->InferredSubmoduleLoc = StarLoc;
1754 ActiveModule->InferExplicitSubmodules = Explicit;
1755 } else {
1756 // We'll be inferring framework modules for this directory.
1757 Map.InferredDirectories[Directory].InferModules = true;
1758 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1759 }
1760
Douglas Gregor73441092011-12-05 22:27:44 +00001761 // Parse the opening brace.
1762 if (!Tok.is(MMToken::LBrace)) {
1763 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1764 HadError = true;
1765 return;
1766 }
1767 SourceLocation LBraceLoc = consumeToken();
1768
1769 // Parse the body of the inferred submodule.
1770 bool Done = false;
1771 do {
1772 switch (Tok.Kind) {
1773 case MMToken::EndOfFile:
1774 case MMToken::RBrace:
1775 Done = true;
1776 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00001777
1778 case MMToken::ExcludeKeyword: {
1779 if (ActiveModule) {
1780 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00001781 << (ActiveModule != 0);
Douglas Gregor9194a912012-11-06 19:39:40 +00001782 consumeToken();
1783 break;
1784 }
1785
1786 consumeToken();
1787 if (!Tok.is(MMToken::Identifier)) {
1788 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1789 break;
1790 }
1791
1792 Map.InferredDirectories[Directory].ExcludedModules
1793 .push_back(Tok.getString());
1794 consumeToken();
1795 break;
1796 }
1797
1798 case MMToken::ExportKeyword:
1799 if (!ActiveModule) {
1800 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00001801 << (ActiveModule != 0);
Douglas Gregor9194a912012-11-06 19:39:40 +00001802 consumeToken();
1803 break;
1804 }
1805
Douglas Gregor73441092011-12-05 22:27:44 +00001806 consumeToken();
1807 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00001808 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00001809 else
1810 Diags.Report(Tok.getLocation(),
1811 diag::err_mmap_expected_export_wildcard);
1812 consumeToken();
1813 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00001814
Douglas Gregor73441092011-12-05 22:27:44 +00001815 case MMToken::ExplicitKeyword:
1816 case MMToken::ModuleKeyword:
1817 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001818 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00001819 case MMToken::UmbrellaKeyword:
1820 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00001821 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00001822 << (ActiveModule != 0);
Douglas Gregor73441092011-12-05 22:27:44 +00001823 consumeToken();
1824 break;
1825 }
1826 } while (!Done);
1827
1828 if (Tok.is(MMToken::RBrace))
1829 consumeToken();
1830 else {
1831 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1832 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1833 HadError = true;
1834 }
1835}
1836
Douglas Gregor9194a912012-11-06 19:39:40 +00001837/// \brief Parse optional attributes.
1838///
1839/// attributes:
1840/// attribute attributes
1841/// attribute
1842///
1843/// attribute:
1844/// [ identifier ]
1845///
1846/// \param Attrs Will be filled in with the parsed attributes.
1847///
1848/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00001849bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00001850 bool HadError = false;
1851
1852 while (Tok.is(MMToken::LSquare)) {
1853 // Consume the '['.
1854 SourceLocation LSquareLoc = consumeToken();
1855
1856 // Check whether we have an attribute name here.
1857 if (!Tok.is(MMToken::Identifier)) {
1858 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1859 skipUntil(MMToken::RSquare);
1860 if (Tok.is(MMToken::RSquare))
1861 consumeToken();
1862 HadError = true;
1863 }
1864
1865 // Decode the attribute name.
1866 AttributeKind Attribute
1867 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001868 .Case("exhaustive", AT_exhaustive)
Douglas Gregor9194a912012-11-06 19:39:40 +00001869 .Case("system", AT_system)
1870 .Default(AT_unknown);
1871 switch (Attribute) {
1872 case AT_unknown:
1873 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1874 << Tok.getString();
1875 break;
1876
1877 case AT_system:
1878 Attrs.IsSystem = true;
1879 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001880
1881 case AT_exhaustive:
1882 Attrs.IsExhaustive = true;
1883 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00001884 }
1885 consumeToken();
1886
1887 // Consume the ']'.
1888 if (!Tok.is(MMToken::RSquare)) {
1889 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1890 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
1891 skipUntil(MMToken::RSquare);
1892 HadError = true;
1893 }
1894
1895 if (Tok.is(MMToken::RSquare))
1896 consumeToken();
1897 }
1898
1899 return HadError;
1900}
1901
Douglas Gregor70331272011-12-09 02:04:43 +00001902/// \brief If there is a specific header search directory due the presence
1903/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
1904const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
1905 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
1906 // If we have an umbrella directory, use that.
1907 if (Mod->hasUmbrellaDir())
1908 return Mod->getUmbrellaDir();
1909
1910 // If we have a framework directory, stop looking.
1911 if (Mod->IsFramework)
1912 return 0;
1913 }
1914
1915 return 0;
1916}
1917
Douglas Gregor718292f2011-11-11 19:10:28 +00001918/// \brief Parse a module map file.
1919///
1920/// module-map-file:
1921/// module-declaration*
1922bool ModuleMapParser::parseModuleMapFile() {
1923 do {
1924 switch (Tok.Kind) {
1925 case MMToken::EndOfFile:
1926 return HadError;
1927
Douglas Gregore7ab3662011-12-07 02:23:45 +00001928 case MMToken::ExplicitKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001929 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00001930 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001931 parseModuleDecl();
1932 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001933
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001934 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001935 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00001936 case MMToken::Conflict:
Douglas Gregor59527662012-10-15 06:28:11 +00001937 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001938 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001939 case MMToken::HeaderKeyword:
1940 case MMToken::Identifier:
1941 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001942 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001943 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001944 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001945 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001946 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001947 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001948 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001949 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00001950 case MMToken::StringLiteral:
1951 case MMToken::UmbrellaKeyword:
1952 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1953 HadError = true;
1954 consumeToken();
1955 break;
1956 }
1957 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00001958}
1959
1960bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00001961 llvm::DenseMap<const FileEntry *, bool>::iterator Known
1962 = ParsedModuleMap.find(File);
1963 if (Known != ParsedModuleMap.end())
1964 return Known->second;
1965
Douglas Gregor89929282012-01-30 06:01:29 +00001966 assert(Target != 0 && "Missing target information");
Douglas Gregor718292f2011-11-11 19:10:28 +00001967 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
1968 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
1969 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00001970 return ParsedModuleMap[File] = true;
Douglas Gregor718292f2011-11-11 19:10:28 +00001971
1972 // Parse this module map file.
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001973 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
1974 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001975 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor3ec66632012-02-02 18:42:48 +00001976 BuiltinIncludeDir);
Douglas Gregor718292f2011-11-11 19:10:28 +00001977 bool Result = Parser.parseModuleMapFile();
1978 Diags->getClient()->EndSourceFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00001979 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00001980 return Result;
1981}