blob: 05238278bad93ba99fc1e795039187c8a93ea50f [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)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000062 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
Douglas Gregorfb912652013-03-20 21:10:35 +000063 << 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)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000073 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Douglas Gregorfb912652013-03-20 21:10:35 +000074 << 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
Daniel Jasper0761a8a2013-12-17 10:31:37 +000086ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000087 const LangOptions &LangOpts, const TargetInfo *Target,
88 HeaderSearch &HeaderInfo)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000089 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
Manuel Klimek1f76c4e2013-10-24 07:51:24 +000090 HeaderInfo(HeaderInfo), BuiltinIncludeDir(0), CompilingModule(0),
Daniel Jasper0761a8a2013-12-17 10:31:37 +000091 SourceModule(0) {}
Douglas Gregor718292f2011-11-11 19:10:28 +000092
93ModuleMap::~ModuleMap() {
Douglas Gregor5acdf592011-11-17 02:05:44 +000094 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
95 IEnd = Modules.end();
96 I != IEnd; ++I) {
97 delete I->getValue();
98 }
Douglas Gregor718292f2011-11-11 19:10:28 +000099}
100
Douglas Gregor89929282012-01-30 06:01:29 +0000101void ModuleMap::setTarget(const TargetInfo &Target) {
102 assert((!this->Target || this->Target == &Target) &&
103 "Improper target override");
104 this->Target = &Target;
105}
106
Douglas Gregor056396a2012-10-12 21:15:50 +0000107/// \brief "Sanitize" a filename so that it can be used as an identifier.
108static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
109 SmallVectorImpl<char> &Buffer) {
110 if (Name.empty())
111 return Name;
112
Jordan Rosea7d03842013-02-08 22:30:41 +0000113 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-10-12 21:15:50 +0000114 // If we don't already have something with the form of an identifier,
115 // create a buffer with the sanitized name.
116 Buffer.clear();
Jordan Rosea7d03842013-02-08 22:30:41 +0000117 if (isDigit(Name[0]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000118 Buffer.push_back('_');
119 Buffer.reserve(Buffer.size() + Name.size());
120 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rosea7d03842013-02-08 22:30:41 +0000121 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000122 Buffer.push_back(Name[I]);
123 else
124 Buffer.push_back('_');
125 }
126
127 Name = StringRef(Buffer.data(), Buffer.size());
128 }
129
130 while (llvm::StringSwitch<bool>(Name)
131#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
132#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
133#include "clang/Basic/TokenKinds.def"
134 .Default(false)) {
135 if (Name.data() != Buffer.data())
136 Buffer.append(Name.begin(), Name.end());
137 Buffer.push_back('_');
138 Name = StringRef(Buffer.data(), Buffer.size());
139 }
140
141 return Name;
142}
143
Douglas Gregor34d52742013-05-02 17:58:30 +0000144/// \brief Determine whether the given file name is the name of a builtin
145/// header, supplied by Clang to replace, override, or augment existing system
146/// headers.
147static bool isBuiltinHeader(StringRef FileName) {
148 return llvm::StringSwitch<bool>(FileName)
149 .Case("float.h", true)
150 .Case("iso646.h", true)
151 .Case("limits.h", true)
152 .Case("stdalign.h", true)
153 .Case("stdarg.h", true)
154 .Case("stdbool.h", true)
155 .Case("stddef.h", true)
156 .Case("stdint.h", true)
157 .Case("tgmath.h", true)
158 .Case("unwind.h", true)
159 .Default(false);
160}
161
Daniel Jasper92669ee2013-12-20 12:09:36 +0000162ModuleMap::HeadersMap::iterator
163ModuleMap::findKnownHeader(const FileEntry *File) {
Douglas Gregor59527662012-10-15 06:28:11 +0000164 HeadersMap::iterator Known = Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000165 if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
166 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
167 HeaderInfo.loadTopLevelSystemModules();
Daniel Jasper92669ee2013-12-20 12:09:36 +0000168 return Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000169 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000170 return Known;
171}
172
173// Returns 'true' if 'RequestingModule directly uses 'RequestedModule'.
174static bool directlyUses(const Module *RequestingModule,
175 const Module *RequestedModule) {
176 return std::find(RequestingModule->DirectUses.begin(),
177 RequestingModule->DirectUses.end(),
178 RequestedModule) != RequestingModule->DirectUses.end();
179}
180
181static bool violatesPrivateInclude(Module *RequestingModule,
182 const FileEntry *IncFileEnt,
183 ModuleMap::ModuleHeaderRole Role,
184 Module *RequestedModule) {
185 #ifndef NDEBUG
186 // Check for consistency between the module header role
187 // as obtained from the lookup and as obtained from the module.
188 // This check is not cheap, so enable it only for debugging.
189 SmallVectorImpl<const FileEntry *> &PvtHdrs
190 = RequestedModule->PrivateHeaders;
191 SmallVectorImpl<const FileEntry *>::iterator Look
192 = std::find(PvtHdrs.begin(), PvtHdrs.end(), IncFileEnt);
193 bool IsPrivate = Look != PvtHdrs.end();
194 assert((IsPrivate && Role == ModuleMap::PrivateHeader)
195 || (!IsPrivate && Role != ModuleMap::PrivateHeader));
196 #endif
197 return Role == ModuleMap::PrivateHeader &&
198 RequestedModule->getTopLevelModule() != RequestingModule;
199}
200
201void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
202 SourceLocation FilenameLoc,
203 StringRef Filename,
204 const FileEntry *File) {
205 // No errors for indirect modules. This may be a bit of a problem for modules
206 // with no source files.
207 if (RequestingModule != SourceModule)
208 return;
209
210 if (RequestingModule)
211 resolveUses(RequestingModule, /*Complain=*/false);
212
213 HeadersMap::iterator Known = findKnownHeader(File);
214 if (Known == Headers.end())
215 return;
216
217 Module *Private = NULL;
218 Module *NotUsed = NULL;
219 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
220 E = Known->second.end();
221 I != E; ++I) {
222 // Excluded headers don't really belong to a module.
223 if (I->getRole() == ModuleMap::ExcludedHeader)
224 continue;
225
226 // If 'File' is part of 'RequestingModule' we can definitely include it.
227 if (I->getModule() == RequestingModule)
228 return;
229
230 // Remember private headers for later printing of a diagnostic.
231 if (violatesPrivateInclude(RequestingModule, File, I->getRole(),
232 I->getModule())) {
233 Private = I->getModule();
234 continue;
235 }
236
237 // If uses need to be specified explicitly, we are only allowed to return
238 // modules that are explicitly used by the requesting module.
239 if (RequestingModule && LangOpts.ModulesDeclUse &&
240 !directlyUses(RequestingModule, I->getModule())) {
241 NotUsed = I->getModule();
242 continue;
243 }
244
245 // We have found a module that we can happily use.
246 return;
247 }
248
249 // We have found a header, but it is private.
250 if (Private != NULL) {
251 Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module)
252 << Filename;
253 return;
254 }
255
256 // We have found a module, but we don't use it.
257 if (NotUsed != NULL) {
258 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
259 << RequestingModule->getFullModuleName() << Filename;
260 return;
261 }
262
263 // Headers for which we have not found a module are fine to include.
264}
265
266ModuleMap::KnownHeader
267ModuleMap::findModuleForHeader(const FileEntry *File,
268 Module *RequestingModule) {
269 HeadersMap::iterator Known = findKnownHeader(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000270
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000271 if (Known != Headers.end()) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000272 ModuleMap::KnownHeader Result = KnownHeader();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000273
Daniel Jasper97da9172013-10-22 08:09:47 +0000274 // Iterate over all modules that 'File' is part of to find the best fit.
275 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
276 E = Known->second.end();
277 I != E; ++I) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000278 // Cannot use a module if the header is excluded in it.
279 if (I->getRole() == ModuleMap::ExcludedHeader)
280 continue;
281
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000282 // Cannot use a module if it is unavailable.
283 if (!I->getModule()->isAvailable())
Daniel Jasper97da9172013-10-22 08:09:47 +0000284 continue;
285
286 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
287 // module we are looking for.
288 if (I->getModule() == RequestingModule)
289 return *I;
290
291 // If uses need to be specified explicitly, we are only allowed to return
292 // modules that are explicitly used by the requesting module.
293 if (RequestingModule && LangOpts.ModulesDeclUse &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000294 !directlyUses(RequestingModule, I->getModule()))
Daniel Jasper97da9172013-10-22 08:09:47 +0000295 continue;
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000296
Daniel Jasper97da9172013-10-22 08:09:47 +0000297 Result = *I;
298 // If 'File' is a public header of this module, this is as good as we
299 // are going to get.
300 if (I->getRole() == ModuleMap::NormalHeader)
301 break;
302 }
303 return Result;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000304 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000305
Douglas Gregorb65dbff2011-11-16 23:02:25 +0000306 const DirectoryEntry *Dir = File->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000307 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregore00c8b22013-01-26 00:55:12 +0000308
Douglas Gregor74260502013-01-04 19:44:26 +0000309 // Note: as an egregious but useful hack we use the real path here, because
310 // frameworks moving from top-level frameworks to embedded frameworks tend
311 // to be symlinked from the top-level location to the embedded location,
312 // and we need to resolve lookups as if we had found the embedded location.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000313 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000314
315 // Keep walking up the directory hierarchy, looking for a directory with
316 // an umbrella header.
317 do {
318 llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
319 = UmbrellaDirs.find(Dir);
320 if (KnownDir != UmbrellaDirs.end()) {
321 Module *Result = KnownDir->second;
Douglas Gregor930a85c2011-12-06 16:17:15 +0000322
323 // Search up the module stack until we find a module with an umbrella
Douglas Gregor73141fa2011-12-08 17:39:04 +0000324 // directory.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000325 Module *UmbrellaModule = Result;
Douglas Gregor73141fa2011-12-08 17:39:04 +0000326 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
Douglas Gregor930a85c2011-12-06 16:17:15 +0000327 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000328
Douglas Gregor930a85c2011-12-06 16:17:15 +0000329 if (UmbrellaModule->InferSubmodules) {
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000330 // Infer submodules for each of the directories we found between
331 // the directory of the umbrella header and the directory where
332 // the actual header is located.
Douglas Gregor9458f822011-12-07 22:05:21 +0000333 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000334
Douglas Gregor70331272011-12-09 02:04:43 +0000335 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000336 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000337 SmallString<32> NameBuf;
338 StringRef Name = sanitizeFilenameAsIdentifier(
339 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
340 NameBuf);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000341 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor9458f822011-12-07 22:05:21 +0000342 Explicit).first;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000343
344 // Associate the module and the directory.
345 UmbrellaDirs[SkippedDirs[I-1]] = Result;
346
347 // If inferred submodules export everything they import, add a
348 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000349 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000350 Result->Exports.push_back(Module::ExportDecl(0, true));
351 }
352
353 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000354 SmallString<32> NameBuf;
355 StringRef Name = sanitizeFilenameAsIdentifier(
356 llvm::sys::path::stem(File->getName()), NameBuf);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000357 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Douglas Gregor9458f822011-12-07 22:05:21 +0000358 Explicit).first;
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +0000359 Result->addTopHeader(File);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000360
361 // If inferred submodules export everything they import, add a
362 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000363 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000364 Result->Exports.push_back(Module::ExportDecl(0, true));
365 } else {
366 // Record each of the directories we stepped through as being part of
367 // the module we found, since the umbrella header covers them all.
368 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
369 UmbrellaDirs[SkippedDirs[I]] = Result;
370 }
371
Daniel Jasper97da9172013-10-22 08:09:47 +0000372 Headers[File].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000373
374 // If a header corresponds to an unavailable module, don't report
375 // that it maps to anything.
376 if (!Result->isAvailable())
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000377 return KnownHeader();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000378
Daniel Jasper97da9172013-10-22 08:09:47 +0000379 return Headers[File].back();
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000380 }
381
382 SkippedDirs.push_back(Dir);
383
Douglas Gregorb65dbff2011-11-16 23:02:25 +0000384 // Retrieve our parent path.
385 DirName = llvm::sys::path::parent_path(DirName);
386 if (DirName.empty())
387 break;
388
389 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000390 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000391 } while (Dir);
Douglas Gregorb65dbff2011-11-16 23:02:25 +0000392
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000393 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000394}
395
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000396bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
397 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000398 if (Known != Headers.end()) {
399 for (SmallVectorImpl<KnownHeader>::const_iterator
400 I = Known->second.begin(),
401 E = Known->second.end();
402 I != E; ++I) {
403 if (I->isAvailable())
404 return false;
405 }
406 return true;
407 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000408
409 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000410 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000411 StringRef DirName = Dir->getName();
412
413 // Keep walking up the directory hierarchy, looking for a directory with
414 // an umbrella header.
415 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000416 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000417 = UmbrellaDirs.find(Dir);
418 if (KnownDir != UmbrellaDirs.end()) {
419 Module *Found = KnownDir->second;
420 if (!Found->isAvailable())
421 return true;
422
423 // Search up the module stack until we find a module with an umbrella
424 // directory.
425 Module *UmbrellaModule = Found;
426 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
427 UmbrellaModule = UmbrellaModule->Parent;
428
429 if (UmbrellaModule->InferSubmodules) {
430 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
431 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000432 SmallString<32> NameBuf;
433 StringRef Name = sanitizeFilenameAsIdentifier(
434 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
435 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000436 Found = lookupModuleQualified(Name, Found);
437 if (!Found)
438 return false;
439 if (!Found->isAvailable())
440 return true;
441 }
442
443 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000444 SmallString<32> NameBuf;
445 StringRef Name = sanitizeFilenameAsIdentifier(
446 llvm::sys::path::stem(Header->getName()),
447 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000448 Found = lookupModuleQualified(Name, Found);
449 if (!Found)
450 return false;
451 }
452
453 return !Found->isAvailable();
454 }
455
456 SkippedDirs.push_back(Dir);
457
458 // Retrieve our parent path.
459 DirName = llvm::sys::path::parent_path(DirName);
460 if (DirName.empty())
461 break;
462
463 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000464 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000465 } while (Dir);
466
467 return false;
468}
469
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000470Module *ModuleMap::findModule(StringRef Name) const {
471 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000472 if (Known != Modules.end())
473 return Known->getValue();
474
475 return 0;
476}
477
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000478Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
479 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000480 for(; Context; Context = Context->Parent) {
481 if (Module *Sub = lookupModuleQualified(Name, Context))
482 return Sub;
483 }
484
485 return findModule(Name);
486}
487
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000488Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000489 if (!Context)
490 return findModule(Name);
491
Douglas Gregoreb90e832012-01-04 23:32:19 +0000492 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000493}
494
Douglas Gregorde3ef502011-11-30 23:21:26 +0000495std::pair<Module *, bool>
Douglas Gregor69021972011-11-30 17:33:56 +0000496ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
497 bool IsExplicit) {
498 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000499 if (Module *Sub = lookupModuleQualified(Name, Parent))
500 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000501
502 // Create a new module with this name.
503 Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
504 IsExplicit);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000505 if (LangOpts.CurrentModule == Name) {
506 SourceModule = Result;
507 SourceModuleName = Name;
508 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000509 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000510 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000511 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
512 Name == LangOpts.CurrentModule) {
513 CompilingModule = Result;
514 }
515 }
Douglas Gregor69021972011-11-30 17:33:56 +0000516 return std::make_pair(Result, true);
517}
518
Douglas Gregor9194a912012-11-06 19:39:40 +0000519bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000520 StringRef Name, bool &IsSystem) const {
Douglas Gregor9194a912012-11-06 19:39:40 +0000521 // Check whether we have already looked into the parent directory
522 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000523 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000524 inferred = InferredDirectories.find(ParentDir);
525 if (inferred == InferredDirectories.end())
526 return false;
527
528 if (!inferred->second.InferModules)
529 return false;
530
531 // We're allowed to infer for this directory, but make sure it's okay
532 // to infer this particular module.
533 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
534 inferred->second.ExcludedModules.end(),
535 Name) == inferred->second.ExcludedModules.end();
536
537 if (canInfer && inferred->second.InferSystemModules)
538 IsSystem = true;
539
540 return canInfer;
541}
542
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000543/// \brief For a framework module, infer the framework against which we
544/// should link.
545static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
546 FileManager &FileMgr) {
547 assert(Mod->IsFramework && "Can only infer linking for framework modules");
548 assert(!Mod->isSubFramework() &&
549 "Can only infer linking for top-level frameworks");
550
551 SmallString<128> LibName;
552 LibName += FrameworkDir->getName();
553 llvm::sys::path::append(LibName, Mod->Name);
554 if (FileMgr.getFile(LibName)) {
555 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
556 /*IsFramework=*/true));
557 }
558}
559
Douglas Gregorde3ef502011-11-30 23:21:26 +0000560Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000561ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000562 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000563 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000564 Module *Parent) {
Douglas Gregor56c64012011-11-17 01:41:17 +0000565 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000566 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
567 return Mod;
568
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000569 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000570
571 // If the framework has a parent path from which we're allowed to infer
572 // a framework module, do so.
573 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000574 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000575
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000576 // Note: as an egregious but useful hack we use the real path here, because
577 // we might be looking at an embedded framework that symlinks out to a
578 // top-level framework, and we need to infer as if we were naming the
579 // top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000580 StringRef FrameworkDirName
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000581 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000582
Douglas Gregor9194a912012-11-06 19:39:40 +0000583 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000584 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000585 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000586 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000587 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
588 // Check whether we have already looked into the parent directory
589 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000590 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000591 inferred = InferredDirectories.find(ParentDir);
592 if (inferred == InferredDirectories.end()) {
593 // We haven't looked here before. Load a module map, if there is
594 // one.
595 SmallString<128> ModMapPath = Parent;
596 llvm::sys::path::append(ModMapPath, "module.map");
597 if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
Douglas Gregor963c5532013-06-21 16:28:10 +0000598 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor9194a912012-11-06 19:39:40 +0000599 inferred = InferredDirectories.find(ParentDir);
600 }
601
602 if (inferred == InferredDirectories.end())
603 inferred = InferredDirectories.insert(
604 std::make_pair(ParentDir, InferredDirectory())).first;
605 }
606
607 if (inferred->second.InferModules) {
608 // We're allowed to infer for this directory, but make sure it's okay
609 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000610 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000611 canInfer = std::find(inferred->second.ExcludedModules.begin(),
612 inferred->second.ExcludedModules.end(),
613 Name) == inferred->second.ExcludedModules.end();
614
615 if (inferred->second.InferSystemModules)
616 IsSystem = true;
617 }
618 }
619 }
620
621 // If we're not allowed to infer a framework module, don't.
622 if (!canInfer)
623 return 0;
624 }
625
626
Douglas Gregor56c64012011-11-17 01:41:17 +0000627 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000628 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000629 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000630 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000631
632 // FIXME: If there's no umbrella header, we could probably scan the
633 // framework to load *everything*. But, it's not clear that this is a good
634 // idea.
635 if (!UmbrellaHeader)
636 return 0;
637
Douglas Gregore89dbc12011-12-06 19:39:29 +0000638 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
639 /*IsFramework=*/true, /*IsExplicit=*/false);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000640 if (LangOpts.CurrentModule == ModuleName) {
641 SourceModule = Result;
642 SourceModuleName = ModuleName;
643 }
Douglas Gregora686e1b2012-01-27 19:52:33 +0000644 if (IsSystem)
645 Result->IsSystem = IsSystem;
646
Douglas Gregoreb90e832012-01-04 23:32:19 +0000647 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000648 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000649
Douglas Gregor322f6332011-12-08 18:00:48 +0000650 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000651 Result->Umbrella = UmbrellaHeader;
Daniel Jasper97da9172013-10-22 08:09:47 +0000652 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor4dc71832011-12-12 23:55:05 +0000653 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000654
655 // export *
656 Result->Exports.push_back(Module::ExportDecl(0, true));
657
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000658 // module * { export * }
659 Result->InferSubmodules = true;
660 Result->InferExportWildcard = true;
661
Douglas Gregore89dbc12011-12-06 19:39:29 +0000662 // Look for subframeworks.
663 llvm::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000664 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000665 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000666 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000667 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000668 for (llvm::sys::fs::directory_iterator
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000669 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000670 Dir != DirEnd && !EC; Dir.increment(EC)) {
671 if (!StringRef(Dir->path()).endswith(".framework"))
672 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000673
Douglas Gregore89dbc12011-12-06 19:39:29 +0000674 if (const DirectoryEntry *SubframeworkDir
675 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000676 // Note: as an egregious but useful hack, we use the real path here and
677 // check whether it is actually a subdirectory of the parent directory.
678 // This will not be the case if the 'subframework' is actually a symlink
679 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000680 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
681 bool FoundParent = false;
682 do {
683 // Get the parent directory name.
684 SubframeworkDirName
685 = llvm::sys::path::parent_path(SubframeworkDirName);
686 if (SubframeworkDirName.empty())
687 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000688
Douglas Gregore00c8b22013-01-26 00:55:12 +0000689 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
690 FoundParent = true;
691 break;
692 }
693 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000694
Douglas Gregore00c8b22013-01-26 00:55:12 +0000695 if (!FoundParent)
696 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000697
Douglas Gregore89dbc12011-12-06 19:39:29 +0000698 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-10-12 21:15:50 +0000699 SmallString<32> NameBuf;
700 inferFrameworkModule(sanitizeFilenameAsIdentifier(
701 llvm::sys::path::stem(Dir->path()), NameBuf),
702 SubframeworkDir, IsSystem, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000703 }
704 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000705
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000706 // If the module is a top-level framework, automatically link against the
707 // framework.
708 if (!Result->isSubFramework()) {
709 inferFrameworkLink(Result, FrameworkDir, FileMgr);
710 }
711
Douglas Gregor56c64012011-11-17 01:41:17 +0000712 return Result;
713}
714
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000715void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasper97da9172013-10-22 08:09:47 +0000716 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000717 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000718 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000719}
720
Douglas Gregor524e33e2011-12-08 19:11:24 +0000721void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
722 Mod->Umbrella = UmbrellaDir;
723 UmbrellaDirs[UmbrellaDir] = Mod;
724}
725
Douglas Gregor59527662012-10-15 06:28:11 +0000726void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000727 ModuleHeaderRole Role) {
728 if (Role == ExcludedHeader) {
Douglas Gregor59527662012-10-15 06:28:11 +0000729 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000730 } else {
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000731 if (Role == PrivateHeader)
732 Mod->PrivateHeaders.push_back(Header);
733 else
734 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000735 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000736 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000737 }
Daniel Jasper97da9172013-10-22 08:09:47 +0000738 Headers[Header].push_back(KnownHeader(Mod, Role));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000739}
740
Douglas Gregor514b6362011-11-29 19:06:37 +0000741const FileEntry *
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000742ModuleMap::getContainingModuleMapFile(Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000743 if (Module->DefinitionLoc.isInvalid())
Douglas Gregor514b6362011-11-29 19:06:37 +0000744 return 0;
745
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000746 return SourceMgr.getFileEntryForID(
747 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000748}
749
Douglas Gregor718292f2011-11-11 19:10:28 +0000750void ModuleMap::dump() {
751 llvm::errs() << "Modules:";
752 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
753 MEnd = Modules.end();
754 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000755 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000756
757 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000758 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000759 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000760 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
761 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
762 E = H->second.end();
763 I != E; ++I) {
764 if (I != H->second.begin())
765 llvm::errs() << ",";
766 llvm::errs() << I->getModule()->getFullModuleName();
767 }
768 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000769 }
770}
771
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000772bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
773 bool HadError = false;
774 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
775 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
776 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000777 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000778 Mod->Exports.push_back(Export);
779 else
780 HadError = true;
781 }
782 Mod->UnresolvedExports.clear();
783 return HadError;
784}
785
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000786bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
787 bool HadError = false;
788 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
789 Module *DirectUse =
790 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
791 if (DirectUse)
792 Mod->DirectUses.push_back(DirectUse);
793 else
794 HadError = true;
795 }
796 Mod->UnresolvedDirectUses.clear();
797 return HadError;
798}
799
Douglas Gregorfb912652013-03-20 21:10:35 +0000800bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
801 bool HadError = false;
802 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
803 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
804 Mod, Complain);
805 if (!OtherMod) {
806 HadError = true;
807 continue;
808 }
809
810 Module::Conflict Conflict;
811 Conflict.Other = OtherMod;
812 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
813 Mod->Conflicts.push_back(Conflict);
814 }
815 Mod->UnresolvedConflicts.clear();
816 return HadError;
817}
818
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000819Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
820 if (Loc.isInvalid())
821 return 0;
822
823 // Use the expansion location to determine which module we're in.
824 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
825 if (!ExpansionLoc.isFileID())
826 return 0;
827
828
829 const SourceManager &SrcMgr = Loc.getManager();
830 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000831
Douglas Gregor224d8a72012-01-06 17:19:32 +0000832 while (const FileEntry *ExpansionFile
833 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
834 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000835 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000836 return Mod;
837
838 // No module owns this header, so look up the inclusion chain to see if
839 // any included header has an associated module.
840 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
841 if (IncludeLoc.isInvalid())
842 return 0;
843
844 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
845 }
846
847 return 0;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000848}
849
Douglas Gregor718292f2011-11-11 19:10:28 +0000850//----------------------------------------------------------------------------//
851// Module map file parser
852//----------------------------------------------------------------------------//
853
854namespace clang {
855 /// \brief A token in a module map file.
856 struct MMToken {
857 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000858 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000859 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000860 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000861 EndOfFile,
862 HeaderKeyword,
863 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000864 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000865 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000866 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000867 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000868 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000869 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000870 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000871 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000872 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000873 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000874 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000875 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000876 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000877 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000878 StringLiteral,
879 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000880 RBrace,
881 LSquare,
882 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000883 } Kind;
884
885 unsigned Location;
886 unsigned StringLength;
887 const char *StringData;
888
889 void clear() {
890 Kind = EndOfFile;
891 Location = 0;
892 StringLength = 0;
893 StringData = 0;
894 }
895
896 bool is(TokenKind K) const { return Kind == K; }
897
898 SourceLocation getLocation() const {
899 return SourceLocation::getFromRawEncoding(Location);
900 }
901
902 StringRef getString() const {
903 return StringRef(StringData, StringLength);
904 }
905 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000906
907 /// \brief The set of attributes that can be attached to a module.
Bill Wendling44426052012-12-20 19:22:21 +0000908 struct Attributes {
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000909 Attributes() : IsSystem(), IsExhaustive() { }
Douglas Gregor9194a912012-11-06 19:39:40 +0000910
911 /// \brief Whether this is a system module.
912 unsigned IsSystem : 1;
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000913
914 /// \brief Whether this is an exhaustive set of configuration macros.
915 unsigned IsExhaustive : 1;
Douglas Gregor9194a912012-11-06 19:39:40 +0000916 };
Douglas Gregor718292f2011-11-11 19:10:28 +0000917
Douglas Gregor9194a912012-11-06 19:39:40 +0000918
Douglas Gregor718292f2011-11-11 19:10:28 +0000919 class ModuleMapParser {
920 Lexer &L;
921 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000922
923 /// \brief Default target information, used only for string literal
924 /// parsing.
925 const TargetInfo *Target;
926
Douglas Gregor718292f2011-11-11 19:10:28 +0000927 DiagnosticsEngine &Diags;
928 ModuleMap &Map;
929
Douglas Gregor5257fc62011-11-11 21:55:48 +0000930 /// \brief The directory that this module map resides in.
931 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +0000932
933 /// \brief The directory containing Clang-supplied headers.
934 const DirectoryEntry *BuiltinIncludeDir;
935
Douglas Gregor963c5532013-06-21 16:28:10 +0000936 /// \brief Whether this module map is in a system header directory.
937 bool IsSystem;
938
Douglas Gregor718292f2011-11-11 19:10:28 +0000939 /// \brief Whether an error occurred.
940 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000941
Douglas Gregor718292f2011-11-11 19:10:28 +0000942 /// \brief Stores string data for the various string literals referenced
943 /// during parsing.
944 llvm::BumpPtrAllocator StringData;
945
946 /// \brief The current token.
947 MMToken Tok;
948
949 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +0000950 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +0000951
952 /// \brief Consume the current token and return its location.
953 SourceLocation consumeToken();
954
955 /// \brief Skip tokens until we reach the a token with the given kind
956 /// (or the end of the file).
957 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +0000958
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000959 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +0000960 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +0000961 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +0000962 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000963 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000964 void parseHeaderDecl(clang::MMToken::TokenKind,
965 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +0000966 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000967 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000968 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000969 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000970 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +0000971 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +0000972 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendling44426052012-12-20 19:22:21 +0000973 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor9194a912012-11-06 19:39:40 +0000974
Douglas Gregor70331272011-12-09 02:04:43 +0000975 const DirectoryEntry *getOverriddenHeaderSearchDir();
976
Douglas Gregor718292f2011-11-11 19:10:28 +0000977 public:
Douglas Gregor718292f2011-11-11 19:10:28 +0000978 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000979 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +0000980 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +0000981 ModuleMap &Map,
Douglas Gregor3ec66632012-02-02 18:42:48 +0000982 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +0000983 const DirectoryEntry *BuiltinIncludeDir,
984 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000985 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Douglas Gregor963c5532013-06-21 16:28:10 +0000986 Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
987 IsSystem(IsSystem), HadError(false), ActiveModule(0)
Douglas Gregor718292f2011-11-11 19:10:28 +0000988 {
Douglas Gregor718292f2011-11-11 19:10:28 +0000989 Tok.clear();
990 consumeToken();
991 }
992
993 bool parseModuleMapFile();
994 };
995}
996
997SourceLocation ModuleMapParser::consumeToken() {
998retry:
999 SourceLocation Result = Tok.getLocation();
1000 Tok.clear();
1001
1002 Token LToken;
1003 L.LexFromRawLexer(LToken);
1004 Tok.Location = LToken.getLocation().getRawEncoding();
1005 switch (LToken.getKind()) {
1006 case tok::raw_identifier:
1007 Tok.StringData = LToken.getRawIdentifierData();
1008 Tok.StringLength = LToken.getLength();
1009 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001010 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001011 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001012 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001013 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001014 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001015 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001016 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001017 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001018 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001019 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001020 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001021 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001022 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001023 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001024 .Default(MMToken::Identifier);
1025 break;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001026
1027 case tok::comma:
1028 Tok.Kind = MMToken::Comma;
1029 break;
1030
Douglas Gregor718292f2011-11-11 19:10:28 +00001031 case tok::eof:
1032 Tok.Kind = MMToken::EndOfFile;
1033 break;
1034
1035 case tok::l_brace:
1036 Tok.Kind = MMToken::LBrace;
1037 break;
1038
Douglas Gregora686e1b2012-01-27 19:52:33 +00001039 case tok::l_square:
1040 Tok.Kind = MMToken::LSquare;
1041 break;
1042
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001043 case tok::period:
1044 Tok.Kind = MMToken::Period;
1045 break;
1046
Douglas Gregor718292f2011-11-11 19:10:28 +00001047 case tok::r_brace:
1048 Tok.Kind = MMToken::RBrace;
1049 break;
1050
Douglas Gregora686e1b2012-01-27 19:52:33 +00001051 case tok::r_square:
1052 Tok.Kind = MMToken::RSquare;
1053 break;
1054
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001055 case tok::star:
1056 Tok.Kind = MMToken::Star;
1057 break;
1058
Richard Smitha3feee22013-10-28 22:18:19 +00001059 case tok::exclaim:
1060 Tok.Kind = MMToken::Exclaim;
1061 break;
1062
Douglas Gregor718292f2011-11-11 19:10:28 +00001063 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001064 if (LToken.hasUDSuffix()) {
1065 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1066 HadError = true;
1067 goto retry;
1068 }
1069
Douglas Gregor718292f2011-11-11 19:10:28 +00001070 // Parse the string literal.
1071 LangOptions LangOpts;
1072 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
1073 if (StringLiteral.hadError)
1074 goto retry;
1075
1076 // Copy the string literal into our string data allocator.
1077 unsigned Length = StringLiteral.GetStringLength();
1078 char *Saved = StringData.Allocate<char>(Length + 1);
1079 memcpy(Saved, StringLiteral.GetString().data(), Length);
1080 Saved[Length] = 0;
1081
1082 // Form the token.
1083 Tok.Kind = MMToken::StringLiteral;
1084 Tok.StringData = Saved;
1085 Tok.StringLength = Length;
1086 break;
1087 }
1088
1089 case tok::comment:
1090 goto retry;
1091
1092 default:
1093 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1094 HadError = true;
1095 goto retry;
1096 }
1097
1098 return Result;
1099}
1100
1101void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1102 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001103 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001104 do {
1105 switch (Tok.Kind) {
1106 case MMToken::EndOfFile:
1107 return;
1108
1109 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001110 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001111 return;
1112
1113 ++braceDepth;
1114 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001115
1116 case MMToken::LSquare:
1117 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1118 return;
1119
1120 ++squareDepth;
1121 break;
1122
Douglas Gregor718292f2011-11-11 19:10:28 +00001123 case MMToken::RBrace:
1124 if (braceDepth > 0)
1125 --braceDepth;
1126 else if (Tok.is(K))
1127 return;
1128 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001129
1130 case MMToken::RSquare:
1131 if (squareDepth > 0)
1132 --squareDepth;
1133 else if (Tok.is(K))
1134 return;
1135 break;
1136
Douglas Gregor718292f2011-11-11 19:10:28 +00001137 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001138 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001139 return;
1140 break;
1141 }
1142
1143 consumeToken();
1144 } while (true);
1145}
1146
Douglas Gregore7ab3662011-12-07 02:23:45 +00001147/// \brief Parse a module-id.
1148///
1149/// module-id:
1150/// identifier
1151/// identifier '.' module-id
1152///
1153/// \returns true if an error occurred, false otherwise.
1154bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1155 Id.clear();
1156 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001157 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001158 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1159 consumeToken();
1160 } else {
1161 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1162 return true;
1163 }
1164
1165 if (!Tok.is(MMToken::Period))
1166 break;
1167
1168 consumeToken();
1169 } while (true);
1170
1171 return false;
1172}
1173
Douglas Gregora686e1b2012-01-27 19:52:33 +00001174namespace {
1175 /// \brief Enumerates the known attributes.
1176 enum AttributeKind {
1177 /// \brief An unknown attribute.
1178 AT_unknown,
1179 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001180 AT_system,
1181 /// \brief The 'exhaustive' attribute.
1182 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001183 };
1184}
1185
Douglas Gregor718292f2011-11-11 19:10:28 +00001186/// \brief Parse a module declaration.
1187///
1188/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001189/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001190/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1191/// { module-member* }
1192///
Douglas Gregor718292f2011-11-11 19:10:28 +00001193/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001194/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001195/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001196/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001197/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001198/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001199///
1200/// submodule-declaration:
1201/// module-declaration
1202/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001203void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001204 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001205 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1206 if (Tok.is(MMToken::ExternKeyword)) {
1207 parseExternModuleDecl();
1208 return;
1209 }
1210
Douglas Gregorf2161a72011-12-06 17:16:41 +00001211 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001212 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001213 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001214 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001215
Douglas Gregorf2161a72011-12-06 17:16:41 +00001216 // Parse 'explicit' keyword, if present.
1217 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001218 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001219 Explicit = true;
1220 }
1221
1222 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001223 if (Tok.is(MMToken::FrameworkKeyword)) {
1224 consumeToken();
1225 Framework = true;
1226 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001227
1228 // Parse 'module' keyword.
1229 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001230 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001231 consumeToken();
1232 HadError = true;
1233 return;
1234 }
1235 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001236
1237 // If we have a wildcard for the module name, this is an inferred submodule.
1238 // Parse it.
1239 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001240 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001241
1242 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001243 ModuleId Id;
1244 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001245 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001246 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001247 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001248
Douglas Gregore7ab3662011-12-07 02:23:45 +00001249 if (ActiveModule) {
1250 if (Id.size() > 1) {
1251 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1252 << SourceRange(Id.front().second, Id.back().second);
1253
1254 HadError = true;
1255 return;
1256 }
1257 } else if (Id.size() == 1 && Explicit) {
1258 // Top-level modules can't be explicit.
1259 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1260 Explicit = false;
1261 ExplicitLoc = SourceLocation();
1262 HadError = true;
1263 }
1264
1265 Module *PreviousActiveModule = ActiveModule;
1266 if (Id.size() > 1) {
1267 // This module map defines a submodule. Go find the module of which it
1268 // is a submodule.
1269 ActiveModule = 0;
1270 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1271 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1272 ActiveModule = Next;
1273 continue;
1274 }
1275
1276 if (ActiveModule) {
1277 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
1278 << Id[I].first << ActiveModule->getTopLevelModule();
1279 } else {
1280 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1281 }
1282 HadError = true;
1283 return;
1284 }
1285 }
1286
1287 StringRef ModuleName = Id.back().first;
1288 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001289
Douglas Gregora686e1b2012-01-27 19:52:33 +00001290 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001291 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001292 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001293
Douglas Gregor718292f2011-11-11 19:10:28 +00001294 // Parse the opening brace.
1295 if (!Tok.is(MMToken::LBrace)) {
1296 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1297 << ModuleName;
1298 HadError = true;
1299 return;
1300 }
1301 SourceLocation LBraceLoc = consumeToken();
1302
1303 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001304 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001305 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1306 // Skip the module definition.
1307 skipUntil(MMToken::RBrace);
1308 if (Tok.is(MMToken::RBrace))
1309 consumeToken();
1310 else {
1311 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1312 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1313 HadError = true;
1314 }
1315 return;
1316 }
1317
Douglas Gregor718292f2011-11-11 19:10:28 +00001318 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1319 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001320 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001321
1322 // Skip the module definition.
1323 skipUntil(MMToken::RBrace);
1324 if (Tok.is(MMToken::RBrace))
1325 consumeToken();
1326
1327 HadError = true;
1328 return;
1329 }
1330
1331 // Start defining this module.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001332 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1333 Explicit).first;
1334 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001335 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001336 ActiveModule->IsSystem = true;
Douglas Gregor718292f2011-11-11 19:10:28 +00001337
1338 bool Done = false;
1339 do {
1340 switch (Tok.Kind) {
1341 case MMToken::EndOfFile:
1342 case MMToken::RBrace:
1343 Done = true;
1344 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001345
1346 case MMToken::ConfigMacros:
1347 parseConfigMacros();
1348 break;
1349
Douglas Gregorfb912652013-03-20 21:10:35 +00001350 case MMToken::Conflict:
1351 parseConflict();
1352 break;
1353
Douglas Gregor718292f2011-11-11 19:10:28 +00001354 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001355 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001356 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001357 case MMToken::ModuleKeyword:
1358 parseModuleDecl();
1359 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001360
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001361 case MMToken::ExportKeyword:
1362 parseExportDecl();
1363 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001364
1365 case MMToken::UseKeyword:
1366 parseUseDecl();
1367 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001368
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001369 case MMToken::RequiresKeyword:
1370 parseRequiresDecl();
1371 break;
1372
Douglas Gregor524e33e2011-12-08 19:11:24 +00001373 case MMToken::UmbrellaKeyword: {
1374 SourceLocation UmbrellaLoc = consumeToken();
1375 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001376 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001377 else
1378 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001379 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001380 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001381
Douglas Gregor59527662012-10-15 06:28:11 +00001382 case MMToken::ExcludeKeyword: {
1383 SourceLocation ExcludeLoc = consumeToken();
1384 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001385 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor59527662012-10-15 06:28:11 +00001386 } else {
1387 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1388 << "exclude";
1389 }
1390 break;
1391 }
1392
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001393 case MMToken::PrivateKeyword: {
1394 SourceLocation PrivateLoc = consumeToken();
1395 if (Tok.is(MMToken::HeaderKeyword)) {
1396 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1397 } else {
1398 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1399 << "private";
1400 }
1401 break;
1402 }
1403
Douglas Gregor322f6332011-12-08 18:00:48 +00001404 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001405 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregor718292f2011-11-11 19:10:28 +00001406 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001407
1408 case MMToken::LinkKeyword:
1409 parseLinkDecl();
1410 break;
1411
Douglas Gregor718292f2011-11-11 19:10:28 +00001412 default:
1413 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1414 consumeToken();
1415 break;
1416 }
1417 } while (!Done);
1418
1419 if (Tok.is(MMToken::RBrace))
1420 consumeToken();
1421 else {
1422 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1423 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1424 HadError = true;
1425 }
1426
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001427 // If the active module is a top-level framework, and there are no link
1428 // libraries, automatically link against the framework.
1429 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1430 ActiveModule->LinkLibraries.empty()) {
1431 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1432 }
1433
Douglas Gregore7ab3662011-12-07 02:23:45 +00001434 // We're done parsing this module. Pop back to the previous module.
1435 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001436}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001437
Daniel Jasper97292842013-09-11 07:20:44 +00001438/// \brief Parse an extern module declaration.
1439///
1440/// extern module-declaration:
1441/// 'extern' 'module' module-id string-literal
1442void ModuleMapParser::parseExternModuleDecl() {
1443 assert(Tok.is(MMToken::ExternKeyword));
1444 consumeToken(); // 'extern' keyword
1445
1446 // Parse 'module' keyword.
1447 if (!Tok.is(MMToken::ModuleKeyword)) {
1448 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1449 consumeToken();
1450 HadError = true;
1451 return;
1452 }
1453 consumeToken(); // 'module' keyword
1454
1455 // Parse the module name.
1456 ModuleId Id;
1457 if (parseModuleId(Id)) {
1458 HadError = true;
1459 return;
1460 }
1461
1462 // Parse the referenced module map file name.
1463 if (!Tok.is(MMToken::StringLiteral)) {
1464 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1465 HadError = true;
1466 return;
1467 }
1468 std::string FileName = Tok.getString();
1469 consumeToken(); // filename
1470
1471 StringRef FileNameRef = FileName;
1472 SmallString<128> ModuleMapFileName;
1473 if (llvm::sys::path::is_relative(FileNameRef)) {
1474 ModuleMapFileName += Directory->getName();
1475 llvm::sys::path::append(ModuleMapFileName, FileName);
1476 FileNameRef = ModuleMapFileName.str();
1477 }
1478 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1479 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1480}
1481
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001482/// \brief Parse a requires declaration.
1483///
1484/// requires-declaration:
1485/// 'requires' feature-list
1486///
1487/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001488/// feature ',' feature-list
1489/// feature
1490///
1491/// feature:
1492/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001493void ModuleMapParser::parseRequiresDecl() {
1494 assert(Tok.is(MMToken::RequiresKeyword));
1495
1496 // Parse 'requires' keyword.
1497 consumeToken();
1498
1499 // Parse the feature-list.
1500 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001501 bool RequiredState = true;
1502 if (Tok.is(MMToken::Exclaim)) {
1503 RequiredState = false;
1504 consumeToken();
1505 }
1506
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001507 if (!Tok.is(MMToken::Identifier)) {
1508 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1509 HadError = true;
1510 return;
1511 }
1512
1513 // Consume the feature name.
1514 std::string Feature = Tok.getString();
1515 consumeToken();
1516
1517 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001518 ActiveModule->addRequirement(Feature, RequiredState,
1519 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001520
1521 if (!Tok.is(MMToken::Comma))
1522 break;
1523
1524 // Consume the comma.
1525 consumeToken();
1526 } while (true);
1527}
1528
Douglas Gregorf2161a72011-12-06 17:16:41 +00001529/// \brief Append to \p Paths the set of paths needed to get to the
1530/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001531static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001532 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001533 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001534 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001535 for (; Mod; Mod = Mod->Parent) {
1536 if (Mod->IsFramework)
1537 Paths.push_back(Mod->Name);
1538 }
1539
1540 if (Paths.empty())
1541 return;
1542
1543 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001544 for (unsigned I = Paths.size() - 1; I != 0; --I)
1545 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001546}
1547
Douglas Gregor718292f2011-11-11 19:10:28 +00001548/// \brief Parse a header declaration.
1549///
1550/// header-declaration:
Douglas Gregor322f6332011-12-08 18:00:48 +00001551/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor59527662012-10-15 06:28:11 +00001552/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001553void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1554 SourceLocation LeadingLoc) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001555 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001556 consumeToken();
1557
Douglas Gregor718292f2011-11-11 19:10:28 +00001558 // Parse the header name.
1559 if (!Tok.is(MMToken::StringLiteral)) {
1560 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1561 << "header";
1562 HadError = true;
1563 return;
1564 }
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001565 Module::HeaderDirective Header;
1566 Header.FileName = Tok.getString();
1567 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001568
Douglas Gregor524e33e2011-12-08 19:11:24 +00001569 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001570 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001571 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001572 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001573 HadError = true;
1574 return;
1575 }
1576
Douglas Gregor5257fc62011-11-11 21:55:48 +00001577 // Look for this file.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001578 const FileEntry *File = 0;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001579 const FileEntry *BuiltinFile = 0;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001580 SmallString<128> PathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001581 if (llvm::sys::path::is_absolute(Header.FileName)) {
1582 PathName = Header.FileName;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001583 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor70331272011-12-09 02:04:43 +00001584 } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
1585 PathName = Dir->getName();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001586 llvm::sys::path::append(PathName, Header.FileName);
Douglas Gregor70331272011-12-09 02:04:43 +00001587 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001588 } else {
1589 // Search for the header file within the search directory.
Douglas Gregor70331272011-12-09 02:04:43 +00001590 PathName = Directory->getName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001591 unsigned PathLength = PathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001592
Douglas Gregorf2161a72011-12-06 17:16:41 +00001593 if (ActiveModule->isPartOfFramework()) {
1594 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001595
1596 // Check whether this file is in the public headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001597 llvm::sys::path::append(PathName, "Headers", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001598 File = SourceMgr.getFileManager().getFile(PathName);
1599
1600 if (!File) {
1601 // Check whether this file is in the private headers.
1602 PathName.resize(PathLength);
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001603 llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001604 File = SourceMgr.getFileManager().getFile(PathName);
1605 }
1606 } else {
1607 // Lookup for normal headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001608 llvm::sys::path::append(PathName, Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001609 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001610
1611 // If this is a system module with a top-level header, this header
1612 // may have a counterpart (or replacement) in the set of headers
1613 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001614 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1615 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001616 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001617 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001618 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001619 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1620
1621 // If Clang supplies this header but the underlying system does not,
1622 // just silently swap in our builtin version. Otherwise, we'll end
1623 // up adding both (later).
1624 if (!File && BuiltinFile) {
1625 File = BuiltinFile;
1626 BuiltinFile = 0;
1627 }
1628 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001629 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001630 }
Douglas Gregor755b2052011-11-17 22:09:43 +00001631
Douglas Gregor5257fc62011-11-11 21:55:48 +00001632 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1633 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001634 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001635 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001636 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001637 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001638 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001639 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001640 HadError = true;
1641 } else {
1642 // Record this umbrella header.
1643 Map.setUmbrellaHeader(ActiveModule, File);
1644 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00001645 } else {
Douglas Gregor322f6332011-12-08 18:00:48 +00001646 // Record this header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001647 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1648 if (LeadingToken == MMToken::ExcludeKeyword)
1649 Role = ModuleMap::ExcludedHeader;
1650 else if (LeadingToken == MMToken::PrivateKeyword)
1651 Role = ModuleMap::PrivateHeader;
1652 else
1653 assert(LeadingToken == MMToken::HeaderKeyword);
1654
1655 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001656
1657 // If there is a builtin counterpart to this file, add it now.
1658 if (BuiltinFile)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001659 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001660 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001661 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001662 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001663
1664 // If we find a module that has a missing header, we mark this module as
1665 // unavailable and store the header directive for displaying diagnostics.
1666 // Other submodules in the same module can still be used.
1667 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
1668 ActiveModule->IsAvailable = false;
1669 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001670 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001671}
1672
Douglas Gregor524e33e2011-12-08 19:11:24 +00001673/// \brief Parse an umbrella directory declaration.
1674///
1675/// umbrella-dir-declaration:
1676/// umbrella string-literal
1677void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1678 // Parse the directory name.
1679 if (!Tok.is(MMToken::StringLiteral)) {
1680 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1681 << "umbrella";
1682 HadError = true;
1683 return;
1684 }
1685
1686 std::string DirName = Tok.getString();
1687 SourceLocation DirNameLoc = consumeToken();
1688
1689 // Check whether we already have an umbrella.
1690 if (ActiveModule->Umbrella) {
1691 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1692 << ActiveModule->getFullModuleName();
1693 HadError = true;
1694 return;
1695 }
1696
1697 // Look for this file.
1698 const DirectoryEntry *Dir = 0;
1699 if (llvm::sys::path::is_absolute(DirName))
1700 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1701 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001702 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001703 PathName = Directory->getName();
1704 llvm::sys::path::append(PathName, DirName);
1705 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1706 }
1707
1708 if (!Dir) {
1709 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1710 << DirName;
1711 HadError = true;
1712 return;
1713 }
1714
1715 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1716 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1717 << OwningModule->getFullModuleName();
1718 HadError = true;
1719 return;
1720 }
1721
1722 // Record this umbrella directory.
1723 Map.setUmbrellaDir(ActiveModule, Dir);
1724}
1725
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001726/// \brief Parse a module export declaration.
1727///
1728/// export-declaration:
1729/// 'export' wildcard-module-id
1730///
1731/// wildcard-module-id:
1732/// identifier
1733/// '*'
1734/// identifier '.' wildcard-module-id
1735void ModuleMapParser::parseExportDecl() {
1736 assert(Tok.is(MMToken::ExportKeyword));
1737 SourceLocation ExportLoc = consumeToken();
1738
1739 // Parse the module-id with an optional wildcard at the end.
1740 ModuleId ParsedModuleId;
1741 bool Wildcard = false;
1742 do {
1743 if (Tok.is(MMToken::Identifier)) {
1744 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1745 Tok.getLocation()));
1746 consumeToken();
1747
1748 if (Tok.is(MMToken::Period)) {
1749 consumeToken();
1750 continue;
1751 }
1752
1753 break;
1754 }
1755
1756 if(Tok.is(MMToken::Star)) {
1757 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001758 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001759 break;
1760 }
1761
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001762 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001763 HadError = true;
1764 return;
1765 } while (true);
1766
1767 Module::UnresolvedExportDecl Unresolved = {
1768 ExportLoc, ParsedModuleId, Wildcard
1769 };
1770 ActiveModule->UnresolvedExports.push_back(Unresolved);
1771}
1772
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001773/// \brief Parse a module uses declaration.
1774///
1775/// uses-declaration:
1776/// 'uses' wildcard-module-id
1777void ModuleMapParser::parseUseDecl() {
1778 assert(Tok.is(MMToken::UseKeyword));
1779 consumeToken();
1780 // Parse the module-id.
1781 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001782 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001783
1784 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1785}
1786
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001787/// \brief Parse a link declaration.
1788///
1789/// module-declaration:
1790/// 'link' 'framework'[opt] string-literal
1791void ModuleMapParser::parseLinkDecl() {
1792 assert(Tok.is(MMToken::LinkKeyword));
1793 SourceLocation LinkLoc = consumeToken();
1794
1795 // Parse the optional 'framework' keyword.
1796 bool IsFramework = false;
1797 if (Tok.is(MMToken::FrameworkKeyword)) {
1798 consumeToken();
1799 IsFramework = true;
1800 }
1801
1802 // Parse the library name
1803 if (!Tok.is(MMToken::StringLiteral)) {
1804 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1805 << IsFramework << SourceRange(LinkLoc);
1806 HadError = true;
1807 return;
1808 }
1809
1810 std::string LibraryName = Tok.getString();
1811 consumeToken();
1812 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1813 IsFramework));
1814}
1815
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001816/// \brief Parse a configuration macro declaration.
1817///
1818/// module-declaration:
1819/// 'config_macros' attributes[opt] config-macro-list?
1820///
1821/// config-macro-list:
1822/// identifier (',' identifier)?
1823void ModuleMapParser::parseConfigMacros() {
1824 assert(Tok.is(MMToken::ConfigMacros));
1825 SourceLocation ConfigMacrosLoc = consumeToken();
1826
1827 // Only top-level modules can have configuration macros.
1828 if (ActiveModule->Parent) {
1829 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1830 }
1831
1832 // Parse the optional attributes.
1833 Attributes Attrs;
1834 parseOptionalAttributes(Attrs);
1835 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1836 ActiveModule->ConfigMacrosExhaustive = true;
1837 }
1838
1839 // If we don't have an identifier, we're done.
1840 if (!Tok.is(MMToken::Identifier))
1841 return;
1842
1843 // Consume the first identifier.
1844 if (!ActiveModule->Parent) {
1845 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1846 }
1847 consumeToken();
1848
1849 do {
1850 // If there's a comma, consume it.
1851 if (!Tok.is(MMToken::Comma))
1852 break;
1853 consumeToken();
1854
1855 // We expect to see a macro name here.
1856 if (!Tok.is(MMToken::Identifier)) {
1857 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1858 break;
1859 }
1860
1861 // Consume the macro name.
1862 if (!ActiveModule->Parent) {
1863 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1864 }
1865 consumeToken();
1866 } while (true);
1867}
1868
Douglas Gregorfb912652013-03-20 21:10:35 +00001869/// \brief Format a module-id into a string.
1870static std::string formatModuleId(const ModuleId &Id) {
1871 std::string result;
1872 {
1873 llvm::raw_string_ostream OS(result);
1874
1875 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1876 if (I)
1877 OS << ".";
1878 OS << Id[I].first;
1879 }
1880 }
1881
1882 return result;
1883}
1884
1885/// \brief Parse a conflict declaration.
1886///
1887/// module-declaration:
1888/// 'conflict' module-id ',' string-literal
1889void ModuleMapParser::parseConflict() {
1890 assert(Tok.is(MMToken::Conflict));
1891 SourceLocation ConflictLoc = consumeToken();
1892 Module::UnresolvedConflict Conflict;
1893
1894 // Parse the module-id.
1895 if (parseModuleId(Conflict.Id))
1896 return;
1897
1898 // Parse the ','.
1899 if (!Tok.is(MMToken::Comma)) {
1900 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1901 << SourceRange(ConflictLoc);
1902 return;
1903 }
1904 consumeToken();
1905
1906 // Parse the message.
1907 if (!Tok.is(MMToken::StringLiteral)) {
1908 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1909 << formatModuleId(Conflict.Id);
1910 return;
1911 }
1912 Conflict.Message = Tok.getString().str();
1913 consumeToken();
1914
1915 // Add this unresolved conflict.
1916 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1917}
1918
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001919/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00001920///
1921/// module-declaration:
1922/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1923/// { inferred-module-member* }
1924///
1925/// inferred-module-member:
1926/// 'export' '*'
1927/// 'exclude' identifier
1928void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00001929 assert(Tok.is(MMToken::Star));
1930 SourceLocation StarLoc = consumeToken();
1931 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00001932
Douglas Gregor73441092011-12-05 22:27:44 +00001933 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00001934 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00001935 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
1936 Failed = true;
1937 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001938
1939 if (ActiveModule) {
1940 // Inferred modules must have umbrella directories.
1941 if (!Failed && !ActiveModule->getUmbrellaDir()) {
1942 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
1943 Failed = true;
1944 }
1945
1946 // Check for redefinition of an inferred module.
1947 if (!Failed && ActiveModule->InferSubmodules) {
1948 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
1949 if (ActiveModule->InferredSubmoduleLoc.isValid())
1950 Diags.Report(ActiveModule->InferredSubmoduleLoc,
1951 diag::note_mmap_prev_definition);
1952 Failed = true;
1953 }
1954
1955 // Check for the 'framework' keyword, which is not permitted here.
1956 if (Framework) {
1957 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
1958 Framework = false;
1959 }
1960 } else if (Explicit) {
1961 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
1962 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00001963 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001964
Douglas Gregor73441092011-12-05 22:27:44 +00001965 // If there were any problems with this inferred submodule, skip its body.
1966 if (Failed) {
1967 if (Tok.is(MMToken::LBrace)) {
1968 consumeToken();
1969 skipUntil(MMToken::RBrace);
1970 if (Tok.is(MMToken::RBrace))
1971 consumeToken();
1972 }
1973 HadError = true;
1974 return;
1975 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001976
1977 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00001978 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001979 parseOptionalAttributes(Attrs);
1980
1981 if (ActiveModule) {
1982 // Note that we have an inferred submodule.
1983 ActiveModule->InferSubmodules = true;
1984 ActiveModule->InferredSubmoduleLoc = StarLoc;
1985 ActiveModule->InferExplicitSubmodules = Explicit;
1986 } else {
1987 // We'll be inferring framework modules for this directory.
1988 Map.InferredDirectories[Directory].InferModules = true;
1989 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
1990 }
1991
Douglas Gregor73441092011-12-05 22:27:44 +00001992 // Parse the opening brace.
1993 if (!Tok.is(MMToken::LBrace)) {
1994 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
1995 HadError = true;
1996 return;
1997 }
1998 SourceLocation LBraceLoc = consumeToken();
1999
2000 // Parse the body of the inferred submodule.
2001 bool Done = false;
2002 do {
2003 switch (Tok.Kind) {
2004 case MMToken::EndOfFile:
2005 case MMToken::RBrace:
2006 Done = true;
2007 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002008
2009 case MMToken::ExcludeKeyword: {
2010 if (ActiveModule) {
2011 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00002012 << (ActiveModule != 0);
Douglas Gregor9194a912012-11-06 19:39:40 +00002013 consumeToken();
2014 break;
2015 }
2016
2017 consumeToken();
2018 if (!Tok.is(MMToken::Identifier)) {
2019 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2020 break;
2021 }
2022
2023 Map.InferredDirectories[Directory].ExcludedModules
2024 .push_back(Tok.getString());
2025 consumeToken();
2026 break;
2027 }
2028
2029 case MMToken::ExportKeyword:
2030 if (!ActiveModule) {
2031 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00002032 << (ActiveModule != 0);
Douglas Gregor9194a912012-11-06 19:39:40 +00002033 consumeToken();
2034 break;
2035 }
2036
Douglas Gregor73441092011-12-05 22:27:44 +00002037 consumeToken();
2038 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002039 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002040 else
2041 Diags.Report(Tok.getLocation(),
2042 diag::err_mmap_expected_export_wildcard);
2043 consumeToken();
2044 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002045
Douglas Gregor73441092011-12-05 22:27:44 +00002046 case MMToken::ExplicitKeyword:
2047 case MMToken::ModuleKeyword:
2048 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002049 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002050 case MMToken::UmbrellaKeyword:
2051 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002052 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00002053 << (ActiveModule != 0);
Douglas Gregor73441092011-12-05 22:27:44 +00002054 consumeToken();
2055 break;
2056 }
2057 } while (!Done);
2058
2059 if (Tok.is(MMToken::RBrace))
2060 consumeToken();
2061 else {
2062 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2063 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2064 HadError = true;
2065 }
2066}
2067
Douglas Gregor9194a912012-11-06 19:39:40 +00002068/// \brief Parse optional attributes.
2069///
2070/// attributes:
2071/// attribute attributes
2072/// attribute
2073///
2074/// attribute:
2075/// [ identifier ]
2076///
2077/// \param Attrs Will be filled in with the parsed attributes.
2078///
2079/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002080bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002081 bool HadError = false;
2082
2083 while (Tok.is(MMToken::LSquare)) {
2084 // Consume the '['.
2085 SourceLocation LSquareLoc = consumeToken();
2086
2087 // Check whether we have an attribute name here.
2088 if (!Tok.is(MMToken::Identifier)) {
2089 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2090 skipUntil(MMToken::RSquare);
2091 if (Tok.is(MMToken::RSquare))
2092 consumeToken();
2093 HadError = true;
2094 }
2095
2096 // Decode the attribute name.
2097 AttributeKind Attribute
2098 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002099 .Case("exhaustive", AT_exhaustive)
Douglas Gregor9194a912012-11-06 19:39:40 +00002100 .Case("system", AT_system)
2101 .Default(AT_unknown);
2102 switch (Attribute) {
2103 case AT_unknown:
2104 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2105 << Tok.getString();
2106 break;
2107
2108 case AT_system:
2109 Attrs.IsSystem = true;
2110 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002111
2112 case AT_exhaustive:
2113 Attrs.IsExhaustive = true;
2114 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002115 }
2116 consumeToken();
2117
2118 // Consume the ']'.
2119 if (!Tok.is(MMToken::RSquare)) {
2120 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2121 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2122 skipUntil(MMToken::RSquare);
2123 HadError = true;
2124 }
2125
2126 if (Tok.is(MMToken::RSquare))
2127 consumeToken();
2128 }
2129
2130 return HadError;
2131}
2132
Douglas Gregor70331272011-12-09 02:04:43 +00002133/// \brief If there is a specific header search directory due the presence
2134/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
2135const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
2136 for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
2137 // If we have an umbrella directory, use that.
2138 if (Mod->hasUmbrellaDir())
2139 return Mod->getUmbrellaDir();
2140
2141 // If we have a framework directory, stop looking.
2142 if (Mod->IsFramework)
2143 return 0;
2144 }
2145
2146 return 0;
2147}
2148
Douglas Gregor718292f2011-11-11 19:10:28 +00002149/// \brief Parse a module map file.
2150///
2151/// module-map-file:
2152/// module-declaration*
2153bool ModuleMapParser::parseModuleMapFile() {
2154 do {
2155 switch (Tok.Kind) {
2156 case MMToken::EndOfFile:
2157 return HadError;
2158
Douglas Gregore7ab3662011-12-07 02:23:45 +00002159 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002160 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002161 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002162 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002163 parseModuleDecl();
2164 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002165
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002166 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002167 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002168 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002169 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002170 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002171 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002172 case MMToken::HeaderKeyword:
2173 case MMToken::Identifier:
2174 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002175 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002176 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002177 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002178 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002179 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002180 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002181 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002182 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002183 case MMToken::StringLiteral:
2184 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002185 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002186 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2187 HadError = true;
2188 consumeToken();
2189 break;
2190 }
2191 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002192}
2193
Douglas Gregor963c5532013-06-21 16:28:10 +00002194bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002195 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2196 = ParsedModuleMap.find(File);
2197 if (Known != ParsedModuleMap.end())
2198 return Known->second;
2199
Douglas Gregor89929282012-01-30 06:01:29 +00002200 assert(Target != 0 && "Missing target information");
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002201 FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
2202 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002203 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002204 return ParsedModuleMap[File] = true;
Douglas Gregor718292f2011-11-11 19:10:28 +00002205
2206 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002207 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Daniel Jasper0761a8a2013-12-17 10:31:37 +00002208 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File->getDir(),
Douglas Gregor963c5532013-06-21 16:28:10 +00002209 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002210 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002211 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002212 return Result;
2213}