blob: 0f12af361a45acb006ff4e3484c126c3cdffe6a0 [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);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000390 if (LangOpts.CurrentModule == Name) {
391 SourceModule = Result;
392 SourceModuleName = Name;
393 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000394 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000395 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000396 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
397 Name == LangOpts.CurrentModule) {
398 CompilingModule = Result;
399 }
400 }
Douglas Gregor69021972011-11-30 17:33:56 +0000401 return std::make_pair(Result, true);
402}
403
Douglas Gregor9194a912012-11-06 19:39:40 +0000404bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000405 StringRef Name, bool &IsSystem) const {
Douglas Gregor9194a912012-11-06 19:39:40 +0000406 // Check whether we have already looked into the parent directory
407 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000408 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000409 inferred = InferredDirectories.find(ParentDir);
410 if (inferred == InferredDirectories.end())
411 return false;
412
413 if (!inferred->second.InferModules)
414 return false;
415
416 // We're allowed to infer for this directory, but make sure it's okay
417 // to infer this particular module.
418 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
419 inferred->second.ExcludedModules.end(),
420 Name) == inferred->second.ExcludedModules.end();
421
422 if (canInfer && inferred->second.InferSystemModules)
423 IsSystem = true;
424
425 return canInfer;
426}
427
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000428/// \brief For a framework module, infer the framework against which we
429/// should link.
430static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
431 FileManager &FileMgr) {
432 assert(Mod->IsFramework && "Can only infer linking for framework modules");
433 assert(!Mod->isSubFramework() &&
434 "Can only infer linking for top-level frameworks");
435
436 SmallString<128> LibName;
437 LibName += FrameworkDir->getName();
438 llvm::sys::path::append(LibName, Mod->Name);
439 if (FileMgr.getFile(LibName)) {
440 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
441 /*IsFramework=*/true));
442 }
443}
444
Douglas Gregorde3ef502011-11-30 23:21:26 +0000445Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000446ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000447 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000448 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000449 Module *Parent) {
Douglas Gregor56c64012011-11-17 01:41:17 +0000450 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000451 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
452 return Mod;
453
454 FileManager &FileMgr = SourceMgr->getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000455
456 // If the framework has a parent path from which we're allowed to infer
457 // a framework module, do so.
458 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000459 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000460
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000461 // Note: as an egregious but useful hack we use the real path here, because
462 // we might be looking at an embedded framework that symlinks out to a
463 // top-level framework, and we need to infer as if we were naming the
464 // top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000465 StringRef FrameworkDirName
466 = SourceMgr->getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000467
Douglas Gregor9194a912012-11-06 19:39:40 +0000468 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000469 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000470 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000471 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000472 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
473 // Check whether we have already looked into the parent directory
474 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000475 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000476 inferred = InferredDirectories.find(ParentDir);
477 if (inferred == InferredDirectories.end()) {
478 // We haven't looked here before. Load a module map, if there is
479 // one.
480 SmallString<128> ModMapPath = Parent;
481 llvm::sys::path::append(ModMapPath, "module.map");
482 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
Douglas Gregor963c5532013-06-21 16:28:10 +0000483 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor9194a912012-11-06 19:39:40 +0000484 inferred = InferredDirectories.find(ParentDir);
485 }
486
487 if (inferred == InferredDirectories.end())
488 inferred = InferredDirectories.insert(
489 std::make_pair(ParentDir, InferredDirectory())).first;
490 }
491
492 if (inferred->second.InferModules) {
493 // We're allowed to infer for this directory, but make sure it's okay
494 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000495 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000496 canInfer = std::find(inferred->second.ExcludedModules.begin(),
497 inferred->second.ExcludedModules.end(),
498 Name) == inferred->second.ExcludedModules.end();
499
500 if (inferred->second.InferSystemModules)
501 IsSystem = true;
502 }
503 }
504 }
505
506 // If we're not allowed to infer a framework module, don't.
507 if (!canInfer)
508 return 0;
509 }
510
511
Douglas Gregor56c64012011-11-17 01:41:17 +0000512 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000513 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000514 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000515 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000516
517 // FIXME: If there's no umbrella header, we could probably scan the
518 // framework to load *everything*. But, it's not clear that this is a good
519 // idea.
520 if (!UmbrellaHeader)
521 return 0;
522
Douglas Gregore89dbc12011-12-06 19:39:29 +0000523 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
524 /*IsFramework=*/true, /*IsExplicit=*/false);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000525 if (LangOpts.CurrentModule == ModuleName) {
526 SourceModule = Result;
527 SourceModuleName = ModuleName;
528 }
Douglas Gregora686e1b2012-01-27 19:52:33 +0000529 if (IsSystem)
530 Result->IsSystem = IsSystem;
531
Douglas Gregoreb90e832012-01-04 23:32:19 +0000532 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000533 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000534
Douglas Gregor322f6332011-12-08 18:00:48 +0000535 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000536 Result->Umbrella = UmbrellaHeader;
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000537 Headers[UmbrellaHeader] = KnownHeader(Result, NormalHeader);
Douglas Gregor4dc71832011-12-12 23:55:05 +0000538 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000539
540 // export *
541 Result->Exports.push_back(Module::ExportDecl(0, true));
542
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000543 // module * { export * }
544 Result->InferSubmodules = true;
545 Result->InferExportWildcard = true;
546
Douglas Gregore89dbc12011-12-06 19:39:29 +0000547 // Look for subframeworks.
548 llvm::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000549 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000550 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000551 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000552 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000553 for (llvm::sys::fs::directory_iterator
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000554 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000555 Dir != DirEnd && !EC; Dir.increment(EC)) {
556 if (!StringRef(Dir->path()).endswith(".framework"))
557 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000558
Douglas Gregore89dbc12011-12-06 19:39:29 +0000559 if (const DirectoryEntry *SubframeworkDir
560 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000561 // Note: as an egregious but useful hack, we use the real path here and
562 // check whether it is actually a subdirectory of the parent directory.
563 // This will not be the case if the 'subframework' is actually a symlink
564 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000565 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
566 bool FoundParent = false;
567 do {
568 // Get the parent directory name.
569 SubframeworkDirName
570 = llvm::sys::path::parent_path(SubframeworkDirName);
571 if (SubframeworkDirName.empty())
572 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000573
Douglas Gregore00c8b22013-01-26 00:55:12 +0000574 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
575 FoundParent = true;
576 break;
577 }
578 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000579
Douglas Gregore00c8b22013-01-26 00:55:12 +0000580 if (!FoundParent)
581 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000582
Douglas Gregore89dbc12011-12-06 19:39:29 +0000583 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-10-12 21:15:50 +0000584 SmallString<32> NameBuf;
585 inferFrameworkModule(sanitizeFilenameAsIdentifier(
586 llvm::sys::path::stem(Dir->path()), NameBuf),
587 SubframeworkDir, IsSystem, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000588 }
589 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000590
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000591 // If the module is a top-level framework, automatically link against the
592 // framework.
593 if (!Result->isSubFramework()) {
594 inferFrameworkLink(Result, FrameworkDir, FileMgr);
595 }
596
Douglas Gregor56c64012011-11-17 01:41:17 +0000597 return Result;
598}
599
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000600void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000601 Headers[UmbrellaHeader] = KnownHeader(Mod, NormalHeader);
Douglas Gregor73141fa2011-12-08 17:39:04 +0000602 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000603 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000604}
605
Douglas Gregor524e33e2011-12-08 19:11:24 +0000606void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
607 Mod->Umbrella = UmbrellaDir;
608 UmbrellaDirs[UmbrellaDir] = Mod;
609}
610
Douglas Gregor59527662012-10-15 06:28:11 +0000611void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000612 ModuleHeaderRole Role) {
613 if (Role == ExcludedHeader) {
Douglas Gregor59527662012-10-15 06:28:11 +0000614 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000615 } else {
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000616 if (Role == PrivateHeader)
617 Mod->PrivateHeaders.push_back(Header);
618 else
619 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000620 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000621 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000622 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000623 Headers[Header] = KnownHeader(Mod, Role);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000624}
625
Douglas Gregor514b6362011-11-29 19:06:37 +0000626const FileEntry *
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000627ModuleMap::getContainingModuleMapFile(Module *Module) const {
Douglas Gregor514b6362011-11-29 19:06:37 +0000628 if (Module->DefinitionLoc.isInvalid() || !SourceMgr)
629 return 0;
630
631 return SourceMgr->getFileEntryForID(
632 SourceMgr->getFileID(Module->DefinitionLoc));
633}
634
Douglas Gregor718292f2011-11-11 19:10:28 +0000635void ModuleMap::dump() {
636 llvm::errs() << "Modules:";
637 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
638 MEnd = Modules.end();
639 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000640 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000641
642 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000643 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000644 H != HEnd; ++H) {
645 llvm::errs() << " \"" << H->first->getName() << "\" -> "
Douglas Gregor59527662012-10-15 06:28:11 +0000646 << H->second.getModule()->getFullModuleName() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000647 }
648}
649
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000650bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
651 bool HadError = false;
652 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
653 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
654 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000655 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000656 Mod->Exports.push_back(Export);
657 else
658 HadError = true;
659 }
660 Mod->UnresolvedExports.clear();
661 return HadError;
662}
663
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000664bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
665 bool HadError = false;
666 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
667 Module *DirectUse =
668 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
669 if (DirectUse)
670 Mod->DirectUses.push_back(DirectUse);
671 else
672 HadError = true;
673 }
674 Mod->UnresolvedDirectUses.clear();
675 return HadError;
676}
677
Douglas Gregorfb912652013-03-20 21:10:35 +0000678bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
679 bool HadError = false;
680 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
681 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
682 Mod, Complain);
683 if (!OtherMod) {
684 HadError = true;
685 continue;
686 }
687
688 Module::Conflict Conflict;
689 Conflict.Other = OtherMod;
690 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
691 Mod->Conflicts.push_back(Conflict);
692 }
693 Mod->UnresolvedConflicts.clear();
694 return HadError;
695}
696
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000697Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
698 if (Loc.isInvalid())
699 return 0;
700
701 // Use the expansion location to determine which module we're in.
702 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
703 if (!ExpansionLoc.isFileID())
704 return 0;
705
706
707 const SourceManager &SrcMgr = Loc.getManager();
708 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000709
Douglas Gregor224d8a72012-01-06 17:19:32 +0000710 while (const FileEntry *ExpansionFile
711 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
712 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000713 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000714 return Mod;
715
716 // No module owns this header, so look up the inclusion chain to see if
717 // any included header has an associated module.
718 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
719 if (IncludeLoc.isInvalid())
720 return 0;
721
722 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
723 }
724
725 return 0;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000726}
727
Douglas Gregor718292f2011-11-11 19:10:28 +0000728//----------------------------------------------------------------------------//
729// Module map file parser
730//----------------------------------------------------------------------------//
731
732namespace clang {
733 /// \brief A token in a module map file.
734 struct MMToken {
735 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000736 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000737 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000738 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000739 EndOfFile,
740 HeaderKeyword,
741 Identifier,
Douglas Gregor59527662012-10-15 06:28:11 +0000742 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000743 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000744 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000745 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000746 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000747 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000748 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000749 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000750 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000751 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000752 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000753 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000754 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000755 StringLiteral,
756 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000757 RBrace,
758 LSquare,
759 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000760 } Kind;
761
762 unsigned Location;
763 unsigned StringLength;
764 const char *StringData;
765
766 void clear() {
767 Kind = EndOfFile;
768 Location = 0;
769 StringLength = 0;
770 StringData = 0;
771 }
772
773 bool is(TokenKind K) const { return Kind == K; }
774
775 SourceLocation getLocation() const {
776 return SourceLocation::getFromRawEncoding(Location);
777 }
778
779 StringRef getString() const {
780 return StringRef(StringData, StringLength);
781 }
782 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000783
784 /// \brief The set of attributes that can be attached to a module.
Bill Wendling44426052012-12-20 19:22:21 +0000785 struct Attributes {
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000786 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor9194a912012-11-06 19:39:40 +0000787
788 /// \brief Whether this is a system module.
789 unsigned IsSystem : 1;
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000790
791 /// \brief Whether this is an exhaustive set of configuration macros.
792 unsigned IsExhaustive : 1;
Douglas Gregor9194a912012-11-06 19:39:40 +0000793 };
Douglas Gregor718292f2011-11-11 19:10:28 +0000794
Douglas Gregor9194a912012-11-06 19:39:40 +0000795
Douglas Gregor718292f2011-11-11 19:10:28 +0000796 class ModuleMapParser {
797 Lexer &L;
798 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000799
800 /// \brief Default target information, used only for string literal
801 /// parsing.
802 const TargetInfo *Target;
803
Douglas Gregor718292f2011-11-11 19:10:28 +0000804 DiagnosticsEngine &Diags;
805 ModuleMap &Map;
806
Douglas Gregor5257fc62011-11-11 21:55:48 +0000807 /// \brief The directory that this module map resides in.
808 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +0000809
810 /// \brief The directory containing Clang-supplied headers.
811 const DirectoryEntry *BuiltinIncludeDir;
812
Douglas Gregor963c5532013-06-21 16:28:10 +0000813 /// \brief Whether this module map is in a system header directory.
814 bool IsSystem;
815
Douglas Gregor718292f2011-11-11 19:10:28 +0000816 /// \brief Whether an error occurred.
817 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000818
Douglas Gregor718292f2011-11-11 19:10:28 +0000819 /// \brief Stores string data for the various string literals referenced
820 /// during parsing.
821 llvm::BumpPtrAllocator StringData;
822
823 /// \brief The current token.
824 MMToken Tok;
825
826 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +0000827 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +0000828
829 /// \brief Consume the current token and return its location.
830 SourceLocation consumeToken();
831
832 /// \brief Skip tokens until we reach the a token with the given kind
833 /// (or the end of the file).
834 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +0000835
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000836 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +0000837 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +0000838 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +0000839 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000840 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000841 void parseHeaderDecl(clang::MMToken::TokenKind,
842 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +0000843 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000844 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000845 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000846 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000847 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +0000848 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +0000849 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendling44426052012-12-20 19:22:21 +0000850 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor9194a912012-11-06 19:39:40 +0000851
Douglas Gregor70331272011-12-09 02:04:43 +0000852 const DirectoryEntry *getOverriddenHeaderSearchDir();
853
Douglas Gregor718292f2011-11-11 19:10:28 +0000854 public:
Douglas Gregor718292f2011-11-11 19:10:28 +0000855 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000856 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +0000857 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +0000858 ModuleMap &Map,
Douglas Gregor3ec66632012-02-02 18:42:48 +0000859 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +0000860 const DirectoryEntry *BuiltinIncludeDir,
861 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000862 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor963c5532013-06-21 16:28:10 +0000863 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
864 IsSystem(IsSystem), HadError(false), ActiveModule(0)
Douglas Gregor718292f2011-11-11 19:10:28 +0000865 {
Douglas Gregor718292f2011-11-11 19:10:28 +0000866 Tok.clear();
867 consumeToken();
868 }
869
870 bool parseModuleMapFile();
871 };
872}
873
874SourceLocation ModuleMapParser::consumeToken() {
875retry:
876 SourceLocation Result = Tok.getLocation();
877 Tok.clear();
878
879 Token LToken;
880 L.LexFromRawLexer(LToken);
881 Tok.Location = LToken.getLocation().getRawEncoding();
882 switch (LToken.getKind()) {
883 case tok::raw_identifier:
884 Tok.StringData = LToken.getRawIdentifierData();
885 Tok.StringLength = LToken.getLength();
886 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000887 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +0000888 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +0000889 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +0000890 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000891 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +0000892 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +0000893 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000894 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000895 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +0000896 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000897 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000898 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +0000899 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000900 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +0000901 .Default(MMToken::Identifier);
902 break;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000903
904 case tok::comma:
905 Tok.Kind = MMToken::Comma;
906 break;
907
Douglas Gregor718292f2011-11-11 19:10:28 +0000908 case tok::eof:
909 Tok.Kind = MMToken::EndOfFile;
910 break;
911
912 case tok::l_brace:
913 Tok.Kind = MMToken::LBrace;
914 break;
915
Douglas Gregora686e1b2012-01-27 19:52:33 +0000916 case tok::l_square:
917 Tok.Kind = MMToken::LSquare;
918 break;
919
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000920 case tok::period:
921 Tok.Kind = MMToken::Period;
922 break;
923
Douglas Gregor718292f2011-11-11 19:10:28 +0000924 case tok::r_brace:
925 Tok.Kind = MMToken::RBrace;
926 break;
927
Douglas Gregora686e1b2012-01-27 19:52:33 +0000928 case tok::r_square:
929 Tok.Kind = MMToken::RSquare;
930 break;
931
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000932 case tok::star:
933 Tok.Kind = MMToken::Star;
934 break;
935
Douglas Gregor718292f2011-11-11 19:10:28 +0000936 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +0000937 if (LToken.hasUDSuffix()) {
938 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
939 HadError = true;
940 goto retry;
941 }
942
Douglas Gregor718292f2011-11-11 19:10:28 +0000943 // Parse the string literal.
944 LangOptions LangOpts;
945 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
946 if (StringLiteral.hadError)
947 goto retry;
948
949 // Copy the string literal into our string data allocator.
950 unsigned Length = StringLiteral.GetStringLength();
951 char *Saved = StringData.Allocate<char>(Length + 1);
952 memcpy(Saved, StringLiteral.GetString().data(), Length);
953 Saved[Length] = 0;
954
955 // Form the token.
956 Tok.Kind = MMToken::StringLiteral;
957 Tok.StringData = Saved;
958 Tok.StringLength = Length;
959 break;
960 }
961
962 case tok::comment:
963 goto retry;
964
965 default:
966 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
967 HadError = true;
968 goto retry;
969 }
970
971 return Result;
972}
973
974void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
975 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +0000976 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +0000977 do {
978 switch (Tok.Kind) {
979 case MMToken::EndOfFile:
980 return;
981
982 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +0000983 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +0000984 return;
985
986 ++braceDepth;
987 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +0000988
989 case MMToken::LSquare:
990 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
991 return;
992
993 ++squareDepth;
994 break;
995
Douglas Gregor718292f2011-11-11 19:10:28 +0000996 case MMToken::RBrace:
997 if (braceDepth > 0)
998 --braceDepth;
999 else if (Tok.is(K))
1000 return;
1001 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001002
1003 case MMToken::RSquare:
1004 if (squareDepth > 0)
1005 --squareDepth;
1006 else if (Tok.is(K))
1007 return;
1008 break;
1009
Douglas Gregor718292f2011-11-11 19:10:28 +00001010 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001011 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001012 return;
1013 break;
1014 }
1015
1016 consumeToken();
1017 } while (true);
1018}
1019
Douglas Gregore7ab3662011-12-07 02:23:45 +00001020/// \brief Parse a module-id.
1021///
1022/// module-id:
1023/// identifier
1024/// identifier '.' module-id
1025///
1026/// \returns true if an error occurred, false otherwise.
1027bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1028 Id.clear();
1029 do {
1030 if (Tok.is(MMToken::Identifier)) {
1031 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1032 consumeToken();
1033 } else {
1034 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1035 return true;
1036 }
1037
1038 if (!Tok.is(MMToken::Period))
1039 break;
1040
1041 consumeToken();
1042 } while (true);
1043
1044 return false;
1045}
1046
Douglas Gregora686e1b2012-01-27 19:52:33 +00001047namespace {
1048 /// \brief Enumerates the known attributes.
1049 enum AttributeKind {
1050 /// \brief An unknown attribute.
1051 AT_unknown,
1052 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001053 AT_system,
1054 /// \brief The 'exhaustive' attribute.
1055 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001056 };
1057}
1058
Douglas Gregor718292f2011-11-11 19:10:28 +00001059/// \brief Parse a module declaration.
1060///
1061/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001062/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001063/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1064/// { module-member* }
1065///
Douglas Gregor718292f2011-11-11 19:10:28 +00001066/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001067/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001068/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001069/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001070/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001071/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001072///
1073/// submodule-declaration:
1074/// module-declaration
1075/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001076void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001077 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001078 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1079 if (Tok.is(MMToken::ExternKeyword)) {
1080 parseExternModuleDecl();
1081 return;
1082 }
1083
Douglas Gregorf2161a72011-12-06 17:16:41 +00001084 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001085 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001086 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001087 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001088
Douglas Gregorf2161a72011-12-06 17:16:41 +00001089 // Parse 'explicit' keyword, if present.
1090 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001091 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001092 Explicit = true;
1093 }
1094
1095 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001096 if (Tok.is(MMToken::FrameworkKeyword)) {
1097 consumeToken();
1098 Framework = true;
1099 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001100
1101 // Parse 'module' keyword.
1102 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001103 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001104 consumeToken();
1105 HadError = true;
1106 return;
1107 }
1108 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001109
1110 // If we have a wildcard for the module name, this is an inferred submodule.
1111 // Parse it.
1112 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001113 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001114
1115 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001116 ModuleId Id;
1117 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001118 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001119 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001120 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001121
Douglas Gregore7ab3662011-12-07 02:23:45 +00001122 if (ActiveModule) {
1123 if (Id.size() > 1) {
1124 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1125 << SourceRange(Id.front().second, Id.back().second);
1126
1127 HadError = true;
1128 return;
1129 }
1130 } else if (Id.size() == 1 && Explicit) {
1131 // Top-level modules can't be explicit.
1132 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1133 Explicit = false;
1134 ExplicitLoc = SourceLocation();
1135 HadError = true;
1136 }
1137
1138 Module *PreviousActiveModule = ActiveModule;
1139 if (Id.size() > 1) {
1140 // This module map defines a submodule. Go find the module of which it
1141 // is a submodule.
1142 ActiveModule = 0;
1143 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1144 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1145 ActiveModule = Next;
1146 continue;
1147 }
1148
1149 if (ActiveModule) {
1150 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1151 << Id[I].first << ActiveModule->getTopLevelModule();
1152 } else {
1153 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1154 }
1155 HadError = true;
1156 return;
1157 }
1158 }
1159
1160 StringRef ModuleName = Id.back().first;
1161 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001162
Douglas Gregora686e1b2012-01-27 19:52:33 +00001163 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001164 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001165 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001166
Douglas Gregor718292f2011-11-11 19:10:28 +00001167 // Parse the opening brace.
1168 if (!Tok.is(MMToken::LBrace)) {
1169 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1170 << ModuleName;
1171 HadError = true;
1172 return;
1173 }
1174 SourceLocation LBraceLoc = consumeToken();
1175
1176 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001177 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001178 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1179 // Skip the module definition.
1180 skipUntil(MMToken::RBrace);
1181 if (Tok.is(MMToken::RBrace))
1182 consumeToken();
1183 else {
1184 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1185 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1186 HadError = true;
1187 }
1188 return;
1189 }
1190
Douglas Gregor718292f2011-11-11 19:10:28 +00001191 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1192 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001193 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001194
1195 // Skip the module definition.
1196 skipUntil(MMToken::RBrace);
1197 if (Tok.is(MMToken::RBrace))
1198 consumeToken();
1199
1200 HadError = true;
1201 return;
1202 }
1203
1204 // Start defining this module.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001205 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1206 Explicit).first;
1207 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001208 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001209 ActiveModule->IsSystem = true;
Douglas Gregor718292f2011-11-11 19:10:28 +00001210
1211 bool Done = false;
1212 do {
1213 switch (Tok.Kind) {
1214 case MMToken::EndOfFile:
1215 case MMToken::RBrace:
1216 Done = true;
1217 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001218
1219 case MMToken::ConfigMacros:
1220 parseConfigMacros();
1221 break;
1222
Douglas Gregorfb912652013-03-20 21:10:35 +00001223 case MMToken::Conflict:
1224 parseConflict();
1225 break;
1226
Douglas Gregor718292f2011-11-11 19:10:28 +00001227 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001228 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001229 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001230 case MMToken::ModuleKeyword:
1231 parseModuleDecl();
1232 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001233
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001234 case MMToken::ExportKeyword:
1235 parseExportDecl();
1236 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001237
1238 case MMToken::UseKeyword:
1239 parseUseDecl();
1240 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001241
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001242 case MMToken::RequiresKeyword:
1243 parseRequiresDecl();
1244 break;
1245
Douglas Gregor524e33e2011-12-08 19:11:24 +00001246 case MMToken::UmbrellaKeyword: {
1247 SourceLocation UmbrellaLoc = consumeToken();
1248 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001249 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001250 else
1251 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001252 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001253 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001254
Douglas Gregor59527662012-10-15 06:28:11 +00001255 case MMToken::ExcludeKeyword: {
1256 SourceLocation ExcludeLoc = consumeToken();
1257 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001258 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor59527662012-10-15 06:28:11 +00001259 } else {
1260 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1261 << "exclude";
1262 }
1263 break;
1264 }
1265
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001266 case MMToken::PrivateKeyword: {
1267 SourceLocation PrivateLoc = consumeToken();
1268 if (Tok.is(MMToken::HeaderKeyword)) {
1269 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1270 } else {
1271 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1272 << "private";
1273 }
1274 break;
1275 }
1276
Douglas Gregor322f6332011-12-08 18:00:48 +00001277 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001278 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregor718292f2011-11-11 19:10:28 +00001279 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001280
1281 case MMToken::LinkKeyword:
1282 parseLinkDecl();
1283 break;
1284
Douglas Gregor718292f2011-11-11 19:10:28 +00001285 default:
1286 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1287 consumeToken();
1288 break;
1289 }
1290 } while (!Done);
1291
1292 if (Tok.is(MMToken::RBrace))
1293 consumeToken();
1294 else {
1295 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1296 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1297 HadError = true;
1298 }
1299
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001300 // If the active module is a top-level framework, and there are no link
1301 // libraries, automatically link against the framework.
1302 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1303 ActiveModule->LinkLibraries.empty()) {
1304 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1305 }
1306
Douglas Gregore7ab3662011-12-07 02:23:45 +00001307 // We're done parsing this module. Pop back to the previous module.
1308 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001309}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001310
Daniel Jasper97292842013-09-11 07:20:44 +00001311/// \brief Parse an extern module declaration.
1312///
1313/// extern module-declaration:
1314/// 'extern' 'module' module-id string-literal
1315void ModuleMapParser::parseExternModuleDecl() {
1316 assert(Tok.is(MMToken::ExternKeyword));
1317 consumeToken(); // 'extern' keyword
1318
1319 // Parse 'module' keyword.
1320 if (!Tok.is(MMToken::ModuleKeyword)) {
1321 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1322 consumeToken();
1323 HadError = true;
1324 return;
1325 }
1326 consumeToken(); // 'module' keyword
1327
1328 // Parse the module name.
1329 ModuleId Id;
1330 if (parseModuleId(Id)) {
1331 HadError = true;
1332 return;
1333 }
1334
1335 // Parse the referenced module map file name.
1336 if (!Tok.is(MMToken::StringLiteral)) {
1337 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1338 HadError = true;
1339 return;
1340 }
1341 std::string FileName = Tok.getString();
1342 consumeToken(); // filename
1343
1344 StringRef FileNameRef = FileName;
1345 SmallString<128> ModuleMapFileName;
1346 if (llvm::sys::path::is_relative(FileNameRef)) {
1347 ModuleMapFileName += Directory->getName();
1348 llvm::sys::path::append(ModuleMapFileName, FileName);
1349 FileNameRef = ModuleMapFileName.str();
1350 }
1351 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1352 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1353}
1354
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001355/// \brief Parse a requires declaration.
1356///
1357/// requires-declaration:
1358/// 'requires' feature-list
1359///
1360/// feature-list:
1361/// identifier ',' feature-list
1362/// identifier
1363void ModuleMapParser::parseRequiresDecl() {
1364 assert(Tok.is(MMToken::RequiresKeyword));
1365
1366 // Parse 'requires' keyword.
1367 consumeToken();
1368
1369 // Parse the feature-list.
1370 do {
1371 if (!Tok.is(MMToken::Identifier)) {
1372 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1373 HadError = true;
1374 return;
1375 }
1376
1377 // Consume the feature name.
1378 std::string Feature = Tok.getString();
1379 consumeToken();
1380
1381 // Add this feature.
Douglas Gregor89929282012-01-30 06:01:29 +00001382 ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001383
1384 if (!Tok.is(MMToken::Comma))
1385 break;
1386
1387 // Consume the comma.
1388 consumeToken();
1389 } while (true);
1390}
1391
Douglas Gregorf2161a72011-12-06 17:16:41 +00001392/// \brief Append to \p Paths the set of paths needed to get to the
1393/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001394static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001395 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001396 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001397 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001398 for (; Mod; Mod = Mod->Parent) {
1399 if (Mod->IsFramework)
1400 Paths.push_back(Mod->Name);
1401 }
1402
1403 if (Paths.empty())
1404 return;
1405
1406 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001407 for (unsigned I = Paths.size() - 1; I != 0; --I)
1408 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001409}
1410
Douglas Gregor718292f2011-11-11 19:10:28 +00001411/// \brief Parse a header declaration.
1412///
1413/// header-declaration:
Douglas Gregor322f6332011-12-08 18:00:48 +00001414/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor59527662012-10-15 06:28:11 +00001415/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001416void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1417 SourceLocation LeadingLoc) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001418 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001419 consumeToken();
1420
Douglas Gregor718292f2011-11-11 19:10:28 +00001421 // Parse the header name.
1422 if (!Tok.is(MMToken::StringLiteral)) {
1423 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1424 << "header";
1425 HadError = true;
1426 return;
1427 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001428 std::string FileName = Tok.getString();
Douglas Gregor718292f2011-11-11 19:10:28 +00001429 SourceLocation FileNameLoc = consumeToken();
1430
Douglas Gregor524e33e2011-12-08 19:11:24 +00001431 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001432 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Douglas Gregor524e33e2011-12-08 19:11:24 +00001433 Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
1434 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001435 HadError = true;
1436 return;
1437 }
1438
Douglas Gregor5257fc62011-11-11 21:55:48 +00001439 // Look for this file.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001440 const FileEntry *File = 0;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001441 const FileEntry *BuiltinFile = 0;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001442 SmallString<128> PathName;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001443 if (llvm::sys::path::is_absolute(FileName)) {
1444 PathName = FileName;
1445 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor70331272011-12-09 02:04:43 +00001446 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1447 PathName = Dir->getName();
1448 llvm::sys::path::append(PathName, FileName);
1449 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001450 } else {
1451 // Search for the header file within the search directory.
Douglas Gregor70331272011-12-09 02:04:43 +00001452 PathName = Directory->getName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001453 unsigned PathLength = PathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001454
Douglas Gregorf2161a72011-12-06 17:16:41 +00001455 if (ActiveModule->isPartOfFramework()) {
1456 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001457
1458 // Check whether this file is in the public headers.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001459 llvm::sys::path::append(PathName, "Headers", FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001460 File = SourceMgr.getFileManager().getFile(PathName);
1461
1462 if (!File) {
1463 // Check whether this file is in the private headers.
1464 PathName.resize(PathLength);
Benjamin Kramer17381a02013-06-28 16:25:46 +00001465 llvm::sys::path::append(PathName, "PrivateHeaders", FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001466 File = SourceMgr.getFileManager().getFile(PathName);
1467 }
1468 } else {
1469 // Lookup for normal headers.
1470 llvm::sys::path::append(PathName, FileName);
1471 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001472
1473 // If this is a system module with a top-level header, this header
1474 // may have a counterpart (or replacement) in the set of headers
1475 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001476 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1477 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
1478 isBuiltinHeader(FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001479 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Douglas Gregor3ec66632012-02-02 18:42:48 +00001480 llvm::sys::path::append(BuiltinPathName, FileName);
1481 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1482
1483 // If Clang supplies this header but the underlying system does not,
1484 // just silently swap in our builtin version. Otherwise, we'll end
1485 // up adding both (later).
1486 if (!File && BuiltinFile) {
1487 File = BuiltinFile;
1488 BuiltinFile = 0;
1489 }
1490 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001491 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001492 }
Douglas Gregor755b2052011-11-17 22:09:43 +00001493
Douglas Gregor5257fc62011-11-11 21:55:48 +00001494 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1495 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001496 if (File) {
Douglas Gregor59527662012-10-15 06:28:11 +00001497 if (ModuleMap::KnownHeader OwningModule = Map.Headers[File]) {
Douglas Gregor5257fc62011-11-11 21:55:48 +00001498 Diags.Report(FileNameLoc, diag::err_mmap_header_conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001499 << FileName << OwningModule.getModule()->getFullModuleName();
Douglas Gregor5257fc62011-11-11 21:55:48 +00001500 HadError = true;
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001501 } else if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001502 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001503 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001504 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001505 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001506 HadError = true;
1507 } else {
1508 // Record this umbrella header.
1509 Map.setUmbrellaHeader(ActiveModule, File);
1510 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00001511 } else {
Douglas Gregor322f6332011-12-08 18:00:48 +00001512 // Record this header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001513 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1514 if (LeadingToken == MMToken::ExcludeKeyword)
1515 Role = ModuleMap::ExcludedHeader;
1516 else if (LeadingToken == MMToken::PrivateKeyword)
1517 Role = ModuleMap::PrivateHeader;
1518 else
1519 assert(LeadingToken == MMToken::HeaderKeyword);
1520
1521 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001522
1523 // If there is a builtin counterpart to this file, add it now.
1524 if (BuiltinFile)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001525 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001526 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001527 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001528 // Ignore excluded header files. They're optional anyway.
1529
Douglas Gregor5257fc62011-11-11 21:55:48 +00001530 Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001531 << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
Douglas Gregor5257fc62011-11-11 21:55:48 +00001532 HadError = true;
1533 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001534}
1535
Douglas Gregor524e33e2011-12-08 19:11:24 +00001536/// \brief Parse an umbrella directory declaration.
1537///
1538/// umbrella-dir-declaration:
1539/// umbrella string-literal
1540void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1541 // Parse the directory name.
1542 if (!Tok.is(MMToken::StringLiteral)) {
1543 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1544 << "umbrella";
1545 HadError = true;
1546 return;
1547 }
1548
1549 std::string DirName = Tok.getString();
1550 SourceLocation DirNameLoc = consumeToken();
1551
1552 // Check whether we already have an umbrella.
1553 if (ActiveModule->Umbrella) {
1554 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1555 << ActiveModule->getFullModuleName();
1556 HadError = true;
1557 return;
1558 }
1559
1560 // Look for this file.
1561 const DirectoryEntry *Dir = 0;
1562 if (llvm::sys::path::is_absolute(DirName))
1563 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1564 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001565 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001566 PathName = Directory->getName();
1567 llvm::sys::path::append(PathName, DirName);
1568 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1569 }
1570
1571 if (!Dir) {
1572 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1573 << DirName;
1574 HadError = true;
1575 return;
1576 }
1577
1578 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1579 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1580 << OwningModule->getFullModuleName();
1581 HadError = true;
1582 return;
1583 }
1584
1585 // Record this umbrella directory.
1586 Map.setUmbrellaDir(ActiveModule, Dir);
1587}
1588
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001589/// \brief Parse a module export declaration.
1590///
1591/// export-declaration:
1592/// 'export' wildcard-module-id
1593///
1594/// wildcard-module-id:
1595/// identifier
1596/// '*'
1597/// identifier '.' wildcard-module-id
1598void ModuleMapParser::parseExportDecl() {
1599 assert(Tok.is(MMToken::ExportKeyword));
1600 SourceLocation ExportLoc = consumeToken();
1601
1602 // Parse the module-id with an optional wildcard at the end.
1603 ModuleId ParsedModuleId;
1604 bool Wildcard = false;
1605 do {
1606 if (Tok.is(MMToken::Identifier)) {
1607 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1608 Tok.getLocation()));
1609 consumeToken();
1610
1611 if (Tok.is(MMToken::Period)) {
1612 consumeToken();
1613 continue;
1614 }
1615
1616 break;
1617 }
1618
1619 if(Tok.is(MMToken::Star)) {
1620 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001621 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001622 break;
1623 }
1624
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001625 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001626 HadError = true;
1627 return;
1628 } while (true);
1629
1630 Module::UnresolvedExportDecl Unresolved = {
1631 ExportLoc, ParsedModuleId, Wildcard
1632 };
1633 ActiveModule->UnresolvedExports.push_back(Unresolved);
1634}
1635
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001636/// \brief Parse a module uses declaration.
1637///
1638/// uses-declaration:
1639/// 'uses' wildcard-module-id
1640void ModuleMapParser::parseUseDecl() {
1641 assert(Tok.is(MMToken::UseKeyword));
1642 consumeToken();
1643 // Parse the module-id.
1644 ModuleId ParsedModuleId;
1645
1646 do {
1647 if (Tok.is(MMToken::Identifier)) {
1648 ParsedModuleId.push_back(
1649 std::make_pair(Tok.getString(), Tok.getLocation()));
1650 consumeToken();
1651
1652 if (Tok.is(MMToken::Period)) {
1653 consumeToken();
1654 continue;
1655 }
1656
1657 break;
1658 }
1659
1660 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
1661 HadError = true;
1662 return;
1663 } while (true);
1664
1665 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1666}
1667
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001668/// \brief Parse a link declaration.
1669///
1670/// module-declaration:
1671/// 'link' 'framework'[opt] string-literal
1672void ModuleMapParser::parseLinkDecl() {
1673 assert(Tok.is(MMToken::LinkKeyword));
1674 SourceLocation LinkLoc = consumeToken();
1675
1676 // Parse the optional 'framework' keyword.
1677 bool IsFramework = false;
1678 if (Tok.is(MMToken::FrameworkKeyword)) {
1679 consumeToken();
1680 IsFramework = true;
1681 }
1682
1683 // Parse the library name
1684 if (!Tok.is(MMToken::StringLiteral)) {
1685 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1686 << IsFramework << SourceRange(LinkLoc);
1687 HadError = true;
1688 return;
1689 }
1690
1691 std::string LibraryName = Tok.getString();
1692 consumeToken();
1693 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1694 IsFramework));
1695}
1696
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001697/// \brief Parse a configuration macro declaration.
1698///
1699/// module-declaration:
1700/// 'config_macros' attributes[opt] config-macro-list?
1701///
1702/// config-macro-list:
1703/// identifier (',' identifier)?
1704void ModuleMapParser::parseConfigMacros() {
1705 assert(Tok.is(MMToken::ConfigMacros));
1706 SourceLocation ConfigMacrosLoc = consumeToken();
1707
1708 // Only top-level modules can have configuration macros.
1709 if (ActiveModule->Parent) {
1710 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1711 }
1712
1713 // Parse the optional attributes.
1714 Attributes Attrs;
1715 parseOptionalAttributes(Attrs);
1716 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1717 ActiveModule->ConfigMacrosExhaustive = true;
1718 }
1719
1720 // If we don't have an identifier, we're done.
1721 if (!Tok.is(MMToken::Identifier))
1722 return;
1723
1724 // Consume the first identifier.
1725 if (!ActiveModule->Parent) {
1726 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1727 }
1728 consumeToken();
1729
1730 do {
1731 // If there's a comma, consume it.
1732 if (!Tok.is(MMToken::Comma))
1733 break;
1734 consumeToken();
1735
1736 // We expect to see a macro name here.
1737 if (!Tok.is(MMToken::Identifier)) {
1738 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1739 break;
1740 }
1741
1742 // Consume the macro name.
1743 if (!ActiveModule->Parent) {
1744 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1745 }
1746 consumeToken();
1747 } while (true);
1748}
1749
Douglas Gregorfb912652013-03-20 21:10:35 +00001750/// \brief Format a module-id into a string.
1751static std::string formatModuleId(const ModuleId &Id) {
1752 std::string result;
1753 {
1754 llvm::raw_string_ostream OS(result);
1755
1756 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1757 if (I)
1758 OS << ".";
1759 OS << Id[I].first;
1760 }
1761 }
1762
1763 return result;
1764}
1765
1766/// \brief Parse a conflict declaration.
1767///
1768/// module-declaration:
1769/// 'conflict' module-id ',' string-literal
1770void ModuleMapParser::parseConflict() {
1771 assert(Tok.is(MMToken::Conflict));
1772 SourceLocation ConflictLoc = consumeToken();
1773 Module::UnresolvedConflict Conflict;
1774
1775 // Parse the module-id.
1776 if (parseModuleId(Conflict.Id))
1777 return;
1778
1779 // Parse the ','.
1780 if (!Tok.is(MMToken::Comma)) {
1781 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1782 << SourceRange(ConflictLoc);
1783 return;
1784 }
1785 consumeToken();
1786
1787 // Parse the message.
1788 if (!Tok.is(MMToken::StringLiteral)) {
1789 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1790 << formatModuleId(Conflict.Id);
1791 return;
1792 }
1793 Conflict.Message = Tok.getString().str();
1794 consumeToken();
1795
1796 // Add this unresolved conflict.
1797 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1798}
1799
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001800/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00001801///
1802/// module-declaration:
1803/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1804/// { inferred-module-member* }
1805///
1806/// inferred-module-member:
1807/// 'export' '*'
1808/// 'exclude' identifier
1809void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00001810 assert(Tok.is(MMToken::Star));
1811 SourceLocation StarLoc = consumeToken();
1812 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00001813
Douglas Gregor73441092011-12-05 22:27:44 +00001814 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00001815 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00001816 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1817 Failed = true;
1818 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001819
1820 if (ActiveModule) {
1821 // Inferred modules must have umbrella directories.
1822 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1823 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1824 Failed = true;
1825 }
1826
1827 // Check for redefinition of an inferred module.
1828 if (!Failed && ActiveModule->InferSubmodules) {
1829 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1830 if (ActiveModule->InferredSubmoduleLoc.isValid())
1831 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1832 diag::note_mmap_prev_definition);
1833 Failed = true;
1834 }
1835
1836 // Check for the 'framework' keyword, which is not permitted here.
1837 if (Framework) {
1838 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1839 Framework = false;
1840 }
1841 } else if (Explicit) {
1842 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1843 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00001844 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001845
Douglas Gregor73441092011-12-05 22:27:44 +00001846 // If there were any problems with this inferred submodule, skip its body.
1847 if (Failed) {
1848 if (Tok.is(MMToken::LBrace)) {
1849 consumeToken();
1850 skipUntil(MMToken::RBrace);
1851 if (Tok.is(MMToken::RBrace))
1852 consumeToken();
1853 }
1854 HadError = true;
1855 return;
1856 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001857
1858 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00001859 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001860 parseOptionalAttributes(Attrs);
1861
1862 if (ActiveModule) {
1863 // Note that we have an inferred submodule.
1864 ActiveModule->InferSubmodules = true;
1865 ActiveModule->InferredSubmoduleLoc = StarLoc;
1866 ActiveModule->InferExplicitSubmodules = Explicit;
1867 } else {
1868 // We'll be inferring framework modules for this directory.
1869 Map.InferredDirectories[Directory].InferModules = true;
1870 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1871 }
1872
Douglas Gregor73441092011-12-05 22:27:44 +00001873 // Parse the opening brace.
1874 if (!Tok.is(MMToken::LBrace)) {
1875 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1876 HadError = true;
1877 return;
1878 }
1879 SourceLocation LBraceLoc = consumeToken();
1880
1881 // Parse the body of the inferred submodule.
1882 bool Done = false;
1883 do {
1884 switch (Tok.Kind) {
1885 case MMToken::EndOfFile:
1886 case MMToken::RBrace:
1887 Done = true;
1888 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00001889
1890 case MMToken::ExcludeKeyword: {
1891 if (ActiveModule) {
1892 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00001893 << (ActiveModule != 0);
Douglas Gregor9194a912012-11-06 19:39:40 +00001894 consumeToken();
1895 break;
1896 }
1897
1898 consumeToken();
1899 if (!Tok.is(MMToken::Identifier)) {
1900 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
1901 break;
1902 }
1903
1904 Map.InferredDirectories[Directory].ExcludedModules
1905 .push_back(Tok.getString());
1906 consumeToken();
1907 break;
1908 }
1909
1910 case MMToken::ExportKeyword:
1911 if (!ActiveModule) {
1912 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00001913 << (ActiveModule != 0);
Douglas Gregor9194a912012-11-06 19:39:40 +00001914 consumeToken();
1915 break;
1916 }
1917
Douglas Gregor73441092011-12-05 22:27:44 +00001918 consumeToken();
1919 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00001920 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00001921 else
1922 Diags.Report(Tok.getLocation(),
1923 diag::err_mmap_expected_export_wildcard);
1924 consumeToken();
1925 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00001926
Douglas Gregor73441092011-12-05 22:27:44 +00001927 case MMToken::ExplicitKeyword:
1928 case MMToken::ModuleKeyword:
1929 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001930 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00001931 case MMToken::UmbrellaKeyword:
1932 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00001933 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00001934 << (ActiveModule != 0);
Douglas Gregor73441092011-12-05 22:27:44 +00001935 consumeToken();
1936 break;
1937 }
1938 } while (!Done);
1939
1940 if (Tok.is(MMToken::RBrace))
1941 consumeToken();
1942 else {
1943 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1944 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1945 HadError = true;
1946 }
1947}
1948
Douglas Gregor9194a912012-11-06 19:39:40 +00001949/// \brief Parse optional attributes.
1950///
1951/// attributes:
1952/// attribute attributes
1953/// attribute
1954///
1955/// attribute:
1956/// [ identifier ]
1957///
1958/// \param Attrs Will be filled in with the parsed attributes.
1959///
1960/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00001961bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00001962 bool HadError = false;
1963
1964 while (Tok.is(MMToken::LSquare)) {
1965 // Consume the '['.
1966 SourceLocation LSquareLoc = consumeToken();
1967
1968 // Check whether we have an attribute name here.
1969 if (!Tok.is(MMToken::Identifier)) {
1970 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1971 skipUntil(MMToken::RSquare);
1972 if (Tok.is(MMToken::RSquare))
1973 consumeToken();
1974 HadError = true;
1975 }
1976
1977 // Decode the attribute name.
1978 AttributeKind Attribute
1979 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001980 .Case("exhaustive", AT_exhaustive)
Douglas Gregor9194a912012-11-06 19:39:40 +00001981 .Case("system", AT_system)
1982 .Default(AT_unknown);
1983 switch (Attribute) {
1984 case AT_unknown:
1985 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1986 << Tok.getString();
1987 break;
1988
1989 case AT_system:
1990 Attrs.IsSystem = true;
1991 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001992
1993 case AT_exhaustive:
1994 Attrs.IsExhaustive = true;
1995 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00001996 }
1997 consumeToken();
1998
1999 // Consume the ']'.
2000 if (!Tok.is(MMToken::RSquare)) {
2001 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2002 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2003 skipUntil(MMToken::RSquare);
2004 HadError = true;
2005 }
2006
2007 if (Tok.is(MMToken::RSquare))
2008 consumeToken();
2009 }
2010
2011 return HadError;
2012}
2013
Douglas Gregor70331272011-12-09 02:04:43 +00002014/// \brief If there is a specific header search directory due the presence
2015/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
2016const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
2017 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
2018 // If we have an umbrella directory, use that.
2019 if (Mod->hasUmbrellaDir())
2020 return Mod->getUmbrellaDir();
2021
2022 // If we have a framework directory, stop looking.
2023 if (Mod->IsFramework)
2024 return 0;
2025 }
2026
2027 return 0;
2028}
2029
Douglas Gregor718292f2011-11-11 19:10:28 +00002030/// \brief Parse a module map file.
2031///
2032/// module-map-file:
2033/// module-declaration*
2034bool ModuleMapParser::parseModuleMapFile() {
2035 do {
2036 switch (Tok.Kind) {
2037 case MMToken::EndOfFile:
2038 return HadError;
2039
Douglas Gregore7ab3662011-12-07 02:23:45 +00002040 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002041 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002042 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002043 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002044 parseModuleDecl();
2045 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002046
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002047 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002048 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002049 case MMToken::Conflict:
Douglas Gregor59527662012-10-15 06:28:11 +00002050 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002051 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002052 case MMToken::HeaderKeyword:
2053 case MMToken::Identifier:
2054 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002055 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002056 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002057 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002058 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002059 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002060 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002061 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002062 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002063 case MMToken::StringLiteral:
2064 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002065 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002066 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2067 HadError = true;
2068 consumeToken();
2069 break;
2070 }
2071 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002072}
2073
Douglas Gregor963c5532013-06-21 16:28:10 +00002074bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002075 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2076 = ParsedModuleMap.find(File);
2077 if (Known != ParsedModuleMap.end())
2078 return Known->second;
2079
Douglas Gregor89929282012-01-30 06:01:29 +00002080 assert(Target != 0 && "Missing target information");
Douglas Gregor718292f2011-11-11 19:10:28 +00002081 FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User);
2082 const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID);
2083 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002084 return ParsedModuleMap[File] = true;
Douglas Gregor718292f2011-11-11 19:10:28 +00002085
2086 // Parse this module map file.
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002087 Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
2088 Diags->getClient()->BeginSourceFile(MMapLangOpts);
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00002089 ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
Douglas Gregor963c5532013-06-21 16:28:10 +00002090 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002091 bool Result = Parser.parseModuleMapFile();
2092 Diags->getClient()->EndSourceFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002093 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002094 return Result;
2095}