blob: bdf71b5f4a16118922023f784108f2fdca941439 [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
Ben Langmuir44691382014-04-10 00:39:10 +0000173ModuleMap::KnownHeader
174ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
175 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
176 const DirectoryEntry *Dir = File->getDir();
177 assert(Dir && "file in no directory");
178
179 // Note: as an egregious but useful hack we use the real path here, because
180 // frameworks moving from top-level frameworks to embedded frameworks tend
181 // to be symlinked from the top-level location to the embedded location,
182 // and we need to resolve lookups as if we had found the embedded location.
183 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
184
185 // Keep walking up the directory hierarchy, looking for a directory with
186 // an umbrella header.
187 do {
188 auto KnownDir = UmbrellaDirs.find(Dir);
189 if (KnownDir != UmbrellaDirs.end())
190 return KnownHeader(KnownDir->second, NormalHeader);
191
192 IntermediateDirs.push_back(Dir);
193
194 // Retrieve our parent path.
195 DirName = llvm::sys::path::parent_path(DirName);
196 if (DirName.empty())
197 break;
198
199 // Resolve the parent path to a directory entry.
200 Dir = SourceMgr.getFileManager().getDirectory(DirName);
201 } while (Dir);
202 return KnownHeader();
203}
204
Daniel Jasper92669ee2013-12-20 12:09:36 +0000205// Returns 'true' if 'RequestingModule directly uses 'RequestedModule'.
206static bool directlyUses(const Module *RequestingModule,
207 const Module *RequestedModule) {
208 return std::find(RequestingModule->DirectUses.begin(),
209 RequestingModule->DirectUses.end(),
210 RequestedModule) != RequestingModule->DirectUses.end();
211}
212
213static bool violatesPrivateInclude(Module *RequestingModule,
214 const FileEntry *IncFileEnt,
215 ModuleMap::ModuleHeaderRole Role,
216 Module *RequestedModule) {
217 #ifndef NDEBUG
218 // Check for consistency between the module header role
219 // as obtained from the lookup and as obtained from the module.
220 // This check is not cheap, so enable it only for debugging.
221 SmallVectorImpl<const FileEntry *> &PvtHdrs
222 = RequestedModule->PrivateHeaders;
223 SmallVectorImpl<const FileEntry *>::iterator Look
224 = std::find(PvtHdrs.begin(), PvtHdrs.end(), IncFileEnt);
225 bool IsPrivate = Look != PvtHdrs.end();
226 assert((IsPrivate && Role == ModuleMap::PrivateHeader)
227 || (!IsPrivate && Role != ModuleMap::PrivateHeader));
228 #endif
229 return Role == ModuleMap::PrivateHeader &&
230 RequestedModule->getTopLevelModule() != RequestingModule;
231}
232
Ben Langmuir71e1a642014-05-05 21:44:13 +0000233static Module *getTopLevelOrNull(Module *M) {
234 return M ? M->getTopLevelModule() : nullptr;
235}
236
Daniel Jasper92669ee2013-12-20 12:09:36 +0000237void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
238 SourceLocation FilenameLoc,
239 StringRef Filename,
240 const FileEntry *File) {
241 // No errors for indirect modules. This may be a bit of a problem for modules
242 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000243 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000244 return;
245
246 if (RequestingModule)
247 resolveUses(RequestingModule, /*Complain=*/false);
248
Ben Langmuir71e1a642014-05-05 21:44:13 +0000249 bool Excluded = false;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000250 Module *Private = NULL;
251 Module *NotUsed = NULL;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000252
Ben Langmuir71e1a642014-05-05 21:44:13 +0000253 HeadersMap::iterator Known = findKnownHeader(File);
254 if (Known != Headers.end()) {
255 for (const KnownHeader &Header : Known->second) {
256 // Excluded headers don't really belong to a module.
257 if (Header.getRole() == ModuleMap::ExcludedHeader) {
258 Excluded = true;
259 continue;
260 }
261
262 // If 'File' is part of 'RequestingModule' we can definitely include it.
263 if (Header.getModule() == RequestingModule)
264 return;
265
266 // Remember private headers for later printing of a diagnostic.
267 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
268 Header.getModule())) {
269 Private = Header.getModule();
270 continue;
271 }
272
273 // If uses need to be specified explicitly, we are only allowed to return
274 // modules that are explicitly used by the requesting module.
275 if (RequestingModule && LangOpts.ModulesDeclUse &&
276 !directlyUses(RequestingModule, Header.getModule())) {
277 NotUsed = Header.getModule();
278 continue;
279 }
280
281 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000282 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000283 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000284 }
285
286 // We have found a header, but it is private.
287 if (Private != NULL) {
288 Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module)
289 << Filename;
290 return;
291 }
292
293 // We have found a module, but we don't use it.
294 if (NotUsed != NULL) {
295 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
296 << RequestingModule->getFullModuleName() << Filename;
297 return;
298 }
299
Ben Langmuir71e1a642014-05-05 21:44:13 +0000300 if (Excluded || isHeaderInUmbrellaDirs(File))
301 return;
302
303 // At this point, only non-modular includes remain.
304
305 if (LangOpts.ModulesStrictDeclUse) {
306 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
307 << RequestingModule->getFullModuleName() << Filename;
308 } else if (RequestingModule) {
309 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
310 diag::warn_non_modular_include_in_framework_module :
311 diag::warn_non_modular_include_in_module;
312 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000313 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000314}
315
316ModuleMap::KnownHeader
317ModuleMap::findModuleForHeader(const FileEntry *File,
318 Module *RequestingModule) {
319 HeadersMap::iterator Known = findKnownHeader(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000320
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000321 if (Known != Headers.end()) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000322 ModuleMap::KnownHeader Result = KnownHeader();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000323
Daniel Jasper97da9172013-10-22 08:09:47 +0000324 // Iterate over all modules that 'File' is part of to find the best fit.
325 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
326 E = Known->second.end();
327 I != E; ++I) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000328 // Cannot use a module if the header is excluded in it.
329 if (I->getRole() == ModuleMap::ExcludedHeader)
330 continue;
331
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000332 // Cannot use a module if it is unavailable.
333 if (!I->getModule()->isAvailable())
Daniel Jasper97da9172013-10-22 08:09:47 +0000334 continue;
335
336 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
337 // module we are looking for.
338 if (I->getModule() == RequestingModule)
339 return *I;
340
341 // If uses need to be specified explicitly, we are only allowed to return
342 // modules that are explicitly used by the requesting module.
343 if (RequestingModule && LangOpts.ModulesDeclUse &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000344 !directlyUses(RequestingModule, I->getModule()))
Daniel Jasper97da9172013-10-22 08:09:47 +0000345 continue;
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000346
Daniel Jasper97da9172013-10-22 08:09:47 +0000347 Result = *I;
348 // If 'File' is a public header of this module, this is as good as we
349 // are going to get.
Richard Smith8c71eba2014-03-05 20:51:45 +0000350 // FIXME: If we have a RequestingModule, we should prefer the header from
351 // that module.
Daniel Jasper97da9172013-10-22 08:09:47 +0000352 if (I->getRole() == ModuleMap::NormalHeader)
353 break;
354 }
355 return Result;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000356 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000357
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000358 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000359 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
360 if (H) {
361 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000362
Ben Langmuir44691382014-04-10 00:39:10 +0000363 // Search up the module stack until we find a module with an umbrella
364 // directory.
365 Module *UmbrellaModule = Result;
366 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
367 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000368
Ben Langmuir44691382014-04-10 00:39:10 +0000369 if (UmbrellaModule->InferSubmodules) {
370 // Infer submodules for each of the directories we found between
371 // the directory of the umbrella header and the directory where
372 // the actual header is located.
373 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000374
Ben Langmuir44691382014-04-10 00:39:10 +0000375 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
376 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000377 SmallString<32> NameBuf;
378 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000379 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000380 Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap,
381 /*IsFramework=*/false, Explicit).first;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000382 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000383
384 // Associate the module and the directory.
385 UmbrellaDirs[SkippedDirs[I-1]] = Result;
386
387 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000388 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000389 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000390 Result->Exports.push_back(Module::ExportDecl(0, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000391 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000392
Ben Langmuir44691382014-04-10 00:39:10 +0000393 // Infer a submodule with the same name as this header file.
394 SmallString<32> NameBuf;
395 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000396 llvm::sys::path::stem(File->getName()), NameBuf);
397 Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap,
398 /*IsFramework=*/false, Explicit).first;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000399 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000400 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000401
Ben Langmuir44691382014-04-10 00:39:10 +0000402 // If inferred submodules export everything they import, add a
403 // wildcard to the set of exports.
404 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
405 Result->Exports.push_back(Module::ExportDecl(0, true));
406 } else {
407 // Record each of the directories we stepped through as being part of
408 // the module we found, since the umbrella header covers them all.
409 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
410 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000411 }
Ben Langmuir44691382014-04-10 00:39:10 +0000412
413 Headers[File].push_back(KnownHeader(Result, NormalHeader));
414
415 // If a header corresponds to an unavailable module, don't report
416 // that it maps to anything.
417 if (!Result->isAvailable())
418 return KnownHeader();
419
420 return Headers[File].back();
421 }
Douglas Gregorb65dbff2011-11-16 23:02:25 +0000422
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000423 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000424}
425
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000426bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Richard Smith50996ce2014-04-08 13:13:04 +0000427 return isHeaderUnavailableInModule(Header, 0);
428}
429
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000430bool
431ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
432 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000433 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000434 if (Known != Headers.end()) {
435 for (SmallVectorImpl<KnownHeader>::const_iterator
436 I = Known->second.begin(),
437 E = Known->second.end();
438 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000439 if (I->isAvailable() && (!RequestingModule ||
440 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000441 return false;
442 }
443 return true;
444 }
Richard Smith50996ce2014-04-08 13:13:04 +0000445
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000446 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000447 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000448 StringRef DirName = Dir->getName();
449
Richard Smith50996ce2014-04-08 13:13:04 +0000450 auto IsUnavailable = [&](const Module *M) {
451 return !M->isAvailable() && (!RequestingModule ||
452 M->isSubModuleOf(RequestingModule));
453 };
454
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000455 // Keep walking up the directory hierarchy, looking for a directory with
456 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000457 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000458 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000459 = UmbrellaDirs.find(Dir);
460 if (KnownDir != UmbrellaDirs.end()) {
461 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000462 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000463 return true;
464
465 // Search up the module stack until we find a module with an umbrella
466 // directory.
467 Module *UmbrellaModule = Found;
468 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
469 UmbrellaModule = UmbrellaModule->Parent;
470
471 if (UmbrellaModule->InferSubmodules) {
472 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
473 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000474 SmallString<32> NameBuf;
475 StringRef Name = sanitizeFilenameAsIdentifier(
476 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
477 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000478 Found = lookupModuleQualified(Name, Found);
479 if (!Found)
480 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000481 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000482 return true;
483 }
484
485 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000486 SmallString<32> NameBuf;
487 StringRef Name = sanitizeFilenameAsIdentifier(
488 llvm::sys::path::stem(Header->getName()),
489 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000490 Found = lookupModuleQualified(Name, Found);
491 if (!Found)
492 return false;
493 }
494
Richard Smith50996ce2014-04-08 13:13:04 +0000495 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000496 }
497
498 SkippedDirs.push_back(Dir);
499
500 // Retrieve our parent path.
501 DirName = llvm::sys::path::parent_path(DirName);
502 if (DirName.empty())
503 break;
504
505 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000506 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000507 } while (Dir);
508
509 return false;
510}
511
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000512Module *ModuleMap::findModule(StringRef Name) const {
513 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000514 if (Known != Modules.end())
515 return Known->getValue();
516
517 return 0;
518}
519
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000520Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
521 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000522 for(; Context; Context = Context->Parent) {
523 if (Module *Sub = lookupModuleQualified(Name, Context))
524 return Sub;
525 }
526
527 return findModule(Name);
528}
529
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000530Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000531 if (!Context)
532 return findModule(Name);
533
Douglas Gregoreb90e832012-01-04 23:32:19 +0000534 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000535}
536
Douglas Gregorde3ef502011-11-30 23:21:26 +0000537std::pair<Module *, bool>
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000538ModuleMap::findOrCreateModule(StringRef Name, Module *Parent,
539 const FileEntry *ModuleMap, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000540 bool IsExplicit) {
541 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000542 if (Module *Sub = lookupModuleQualified(Name, Parent))
543 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000544
545 // Create a new module with this name.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000546 Module *Result = new Module(Name, SourceLocation(), Parent, ModuleMap,
547 IsFramework, IsExplicit);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000548 if (LangOpts.CurrentModule == Name) {
549 SourceModule = Result;
550 SourceModuleName = Name;
551 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000552 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000553 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000554 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
555 Name == LangOpts.CurrentModule) {
556 CompilingModule = Result;
557 }
558 }
Douglas Gregor69021972011-11-30 17:33:56 +0000559 return std::make_pair(Result, true);
560}
561
Douglas Gregor9194a912012-11-06 19:39:40 +0000562bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000563 StringRef Name, bool &IsSystem) const {
Douglas Gregor9194a912012-11-06 19:39:40 +0000564 // Check whether we have already looked into the parent directory
565 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000566 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000567 inferred = InferredDirectories.find(ParentDir);
568 if (inferred == InferredDirectories.end())
569 return false;
570
571 if (!inferred->second.InferModules)
572 return false;
573
574 // We're allowed to infer for this directory, but make sure it's okay
575 // to infer this particular module.
576 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
577 inferred->second.ExcludedModules.end(),
578 Name) == inferred->second.ExcludedModules.end();
579
580 if (canInfer && inferred->second.InferSystemModules)
581 IsSystem = true;
582
583 return canInfer;
584}
585
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000586/// \brief For a framework module, infer the framework against which we
587/// should link.
588static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
589 FileManager &FileMgr) {
590 assert(Mod->IsFramework && "Can only infer linking for framework modules");
591 assert(!Mod->isSubFramework() &&
592 "Can only infer linking for top-level frameworks");
593
594 SmallString<128> LibName;
595 LibName += FrameworkDir->getName();
596 llvm::sys::path::append(LibName, Mod->Name);
597 if (FileMgr.getFile(LibName)) {
598 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
599 /*IsFramework=*/true));
600 }
601}
602
Douglas Gregorde3ef502011-11-30 23:21:26 +0000603Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000604ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000605 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000606 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000607 Module *Parent) {
Douglas Gregor56c64012011-11-17 01:41:17 +0000608 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000609 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
610 return Mod;
611
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000612 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000613
614 // If the framework has a parent path from which we're allowed to infer
615 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000616 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000617 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000618 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000619
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000620 // Note: as an egregious but useful hack we use the real path here, because
621 // we might be looking at an embedded framework that symlinks out to a
622 // top-level framework, and we need to infer as if we were naming the
623 // top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000624 StringRef FrameworkDirName
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000625 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000626
Douglas Gregor9194a912012-11-06 19:39:40 +0000627 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000628 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000629 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000630 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000631 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
632 // Check whether we have already looked into the parent directory
633 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000634 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000635 inferred = InferredDirectories.find(ParentDir);
636 if (inferred == InferredDirectories.end()) {
637 // We haven't looked here before. Load a module map, if there is
638 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000639 bool IsFrameworkDir = Parent.endswith(".framework");
640 if (const FileEntry *ModMapFile =
641 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Douglas Gregor963c5532013-06-21 16:28:10 +0000642 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor9194a912012-11-06 19:39:40 +0000643 inferred = InferredDirectories.find(ParentDir);
644 }
645
646 if (inferred == InferredDirectories.end())
647 inferred = InferredDirectories.insert(
648 std::make_pair(ParentDir, InferredDirectory())).first;
649 }
650
651 if (inferred->second.InferModules) {
652 // We're allowed to infer for this directory, but make sure it's okay
653 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000654 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000655 canInfer = std::find(inferred->second.ExcludedModules.begin(),
656 inferred->second.ExcludedModules.end(),
657 Name) == inferred->second.ExcludedModules.end();
658
659 if (inferred->second.InferSystemModules)
660 IsSystem = true;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000661 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000662 }
663 }
664 }
665
666 // If we're not allowed to infer a framework module, don't.
667 if (!canInfer)
668 return 0;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000669 } else
670 ModuleMapFile = Parent->ModuleMap;
Douglas Gregor9194a912012-11-06 19:39:40 +0000671
672
Douglas Gregor56c64012011-11-17 01:41:17 +0000673 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000674 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000675 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000676 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000677
678 // FIXME: If there's no umbrella header, we could probably scan the
679 // framework to load *everything*. But, it's not clear that this is a good
680 // idea.
681 if (!UmbrellaHeader)
682 return 0;
683
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000684 Module *Result = new Module(ModuleName, SourceLocation(), Parent, ModuleMapFile,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000685 /*IsFramework=*/true, /*IsExplicit=*/false);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000686 if (LangOpts.CurrentModule == ModuleName) {
687 SourceModule = Result;
688 SourceModuleName = ModuleName;
689 }
Douglas Gregora686e1b2012-01-27 19:52:33 +0000690 if (IsSystem)
691 Result->IsSystem = IsSystem;
692
Douglas Gregoreb90e832012-01-04 23:32:19 +0000693 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000694 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000695
Douglas Gregor322f6332011-12-08 18:00:48 +0000696 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000697 Result->Umbrella = UmbrellaHeader;
Daniel Jasper97da9172013-10-22 08:09:47 +0000698 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor4dc71832011-12-12 23:55:05 +0000699 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000700
701 // export *
702 Result->Exports.push_back(Module::ExportDecl(0, true));
703
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000704 // module * { export * }
705 Result->InferSubmodules = true;
706 Result->InferExportWildcard = true;
707
Douglas Gregore89dbc12011-12-06 19:39:29 +0000708 // Look for subframeworks.
709 llvm::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000710 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000711 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000712 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000713 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000714 for (llvm::sys::fs::directory_iterator
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000715 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000716 Dir != DirEnd && !EC; Dir.increment(EC)) {
717 if (!StringRef(Dir->path()).endswith(".framework"))
718 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000719
Douglas Gregore89dbc12011-12-06 19:39:29 +0000720 if (const DirectoryEntry *SubframeworkDir
721 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000722 // Note: as an egregious but useful hack, we use the real path here and
723 // check whether it is actually a subdirectory of the parent directory.
724 // This will not be the case if the 'subframework' is actually a symlink
725 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000726 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
727 bool FoundParent = false;
728 do {
729 // Get the parent directory name.
730 SubframeworkDirName
731 = llvm::sys::path::parent_path(SubframeworkDirName);
732 if (SubframeworkDirName.empty())
733 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000734
Douglas Gregore00c8b22013-01-26 00:55:12 +0000735 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
736 FoundParent = true;
737 break;
738 }
739 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000740
Douglas Gregore00c8b22013-01-26 00:55:12 +0000741 if (!FoundParent)
742 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000743
Douglas Gregore89dbc12011-12-06 19:39:29 +0000744 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-10-12 21:15:50 +0000745 SmallString<32> NameBuf;
746 inferFrameworkModule(sanitizeFilenameAsIdentifier(
747 llvm::sys::path::stem(Dir->path()), NameBuf),
748 SubframeworkDir, IsSystem, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000749 }
750 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000751
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000752 // If the module is a top-level framework, automatically link against the
753 // framework.
754 if (!Result->isSubFramework()) {
755 inferFrameworkLink(Result, FrameworkDir, FileMgr);
756 }
757
Douglas Gregor56c64012011-11-17 01:41:17 +0000758 return Result;
759}
760
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000761void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasper97da9172013-10-22 08:09:47 +0000762 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000763 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000764 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000765}
766
Douglas Gregor524e33e2011-12-08 19:11:24 +0000767void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
768 Mod->Umbrella = UmbrellaDir;
769 UmbrellaDirs[UmbrellaDir] = Mod;
770}
771
Douglas Gregor59527662012-10-15 06:28:11 +0000772void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000773 ModuleHeaderRole Role) {
774 if (Role == ExcludedHeader) {
Douglas Gregor59527662012-10-15 06:28:11 +0000775 Mod->ExcludedHeaders.push_back(Header);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000776 } else {
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000777 if (Role == PrivateHeader)
778 Mod->PrivateHeaders.push_back(Header);
779 else
780 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000781 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000782 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000783 }
Daniel Jasper97da9172013-10-22 08:09:47 +0000784 Headers[Header].push_back(KnownHeader(Mod, Role));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000785}
786
Douglas Gregor514b6362011-11-29 19:06:37 +0000787const FileEntry *
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000788ModuleMap::getContainingModuleMapFile(Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000789 if (Module->DefinitionLoc.isInvalid())
Douglas Gregor514b6362011-11-29 19:06:37 +0000790 return 0;
791
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000792 return SourceMgr.getFileEntryForID(
793 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000794}
795
Douglas Gregor718292f2011-11-11 19:10:28 +0000796void ModuleMap::dump() {
797 llvm::errs() << "Modules:";
798 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
799 MEnd = Modules.end();
800 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000801 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000802
803 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000804 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000805 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000806 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
807 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
808 E = H->second.end();
809 I != E; ++I) {
810 if (I != H->second.begin())
811 llvm::errs() << ",";
812 llvm::errs() << I->getModule()->getFullModuleName();
813 }
814 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000815 }
816}
817
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000818bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
819 bool HadError = false;
820 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
821 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
822 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000823 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000824 Mod->Exports.push_back(Export);
825 else
826 HadError = true;
827 }
828 Mod->UnresolvedExports.clear();
829 return HadError;
830}
831
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000832bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
833 bool HadError = false;
834 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
835 Module *DirectUse =
836 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
837 if (DirectUse)
838 Mod->DirectUses.push_back(DirectUse);
839 else
840 HadError = true;
841 }
842 Mod->UnresolvedDirectUses.clear();
843 return HadError;
844}
845
Douglas Gregorfb912652013-03-20 21:10:35 +0000846bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
847 bool HadError = false;
848 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
849 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
850 Mod, Complain);
851 if (!OtherMod) {
852 HadError = true;
853 continue;
854 }
855
856 Module::Conflict Conflict;
857 Conflict.Other = OtherMod;
858 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
859 Mod->Conflicts.push_back(Conflict);
860 }
861 Mod->UnresolvedConflicts.clear();
862 return HadError;
863}
864
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000865Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
866 if (Loc.isInvalid())
867 return 0;
868
869 // Use the expansion location to determine which module we're in.
870 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
871 if (!ExpansionLoc.isFileID())
872 return 0;
873
874
875 const SourceManager &SrcMgr = Loc.getManager();
876 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000877
Douglas Gregor224d8a72012-01-06 17:19:32 +0000878 while (const FileEntry *ExpansionFile
879 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
880 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000881 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000882 return Mod;
883
884 // No module owns this header, so look up the inclusion chain to see if
885 // any included header has an associated module.
886 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
887 if (IncludeLoc.isInvalid())
888 return 0;
889
890 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
891 }
892
893 return 0;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000894}
895
Douglas Gregor718292f2011-11-11 19:10:28 +0000896//----------------------------------------------------------------------------//
897// Module map file parser
898//----------------------------------------------------------------------------//
899
900namespace clang {
901 /// \brief A token in a module map file.
902 struct MMToken {
903 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000904 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000905 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000906 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000907 EndOfFile,
908 HeaderKeyword,
909 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000910 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000911 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000912 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000913 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000914 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000915 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000916 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000917 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000918 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000919 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000920 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000921 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000922 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000923 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000924 StringLiteral,
925 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000926 RBrace,
927 LSquare,
928 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000929 } Kind;
930
931 unsigned Location;
932 unsigned StringLength;
933 const char *StringData;
934
935 void clear() {
936 Kind = EndOfFile;
937 Location = 0;
938 StringLength = 0;
939 StringData = 0;
940 }
941
942 bool is(TokenKind K) const { return Kind == K; }
943
944 SourceLocation getLocation() const {
945 return SourceLocation::getFromRawEncoding(Location);
946 }
947
948 StringRef getString() const {
949 return StringRef(StringData, StringLength);
950 }
951 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000952
953 /// \brief The set of attributes that can be attached to a module.
Bill Wendling44426052012-12-20 19:22:21 +0000954 struct Attributes {
Richard Smith77944862014-03-02 05:58:18 +0000955 Attributes() : IsSystem(), IsExternC(), IsExhaustive() { }
Douglas Gregor9194a912012-11-06 19:39:40 +0000956
957 /// \brief Whether this is a system module.
958 unsigned IsSystem : 1;
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000959
Richard Smith77944862014-03-02 05:58:18 +0000960 /// \brief Whether this is an extern "C" module.
961 unsigned IsExternC : 1;
962
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000963 /// \brief Whether this is an exhaustive set of configuration macros.
964 unsigned IsExhaustive : 1;
Douglas Gregor9194a912012-11-06 19:39:40 +0000965 };
Douglas Gregor718292f2011-11-11 19:10:28 +0000966
Douglas Gregor9194a912012-11-06 19:39:40 +0000967
Douglas Gregor718292f2011-11-11 19:10:28 +0000968 class ModuleMapParser {
969 Lexer &L;
970 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000971
972 /// \brief Default target information, used only for string literal
973 /// parsing.
974 const TargetInfo *Target;
975
Douglas Gregor718292f2011-11-11 19:10:28 +0000976 DiagnosticsEngine &Diags;
977 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000978
979 /// \brief The current module map file.
980 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +0000981
Douglas Gregor5257fc62011-11-11 21:55:48 +0000982 /// \brief The directory that this module map resides in.
983 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +0000984
985 /// \brief The directory containing Clang-supplied headers.
986 const DirectoryEntry *BuiltinIncludeDir;
987
Douglas Gregor963c5532013-06-21 16:28:10 +0000988 /// \brief Whether this module map is in a system header directory.
989 bool IsSystem;
990
Douglas Gregor718292f2011-11-11 19:10:28 +0000991 /// \brief Whether an error occurred.
992 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +0000993
Douglas Gregor718292f2011-11-11 19:10:28 +0000994 /// \brief Stores string data for the various string literals referenced
995 /// during parsing.
996 llvm::BumpPtrAllocator StringData;
997
998 /// \brief The current token.
999 MMToken Tok;
1000
1001 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001002 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001003
1004 /// \brief Consume the current token and return its location.
1005 SourceLocation consumeToken();
1006
1007 /// \brief Skip tokens until we reach the a token with the given kind
1008 /// (or the end of the file).
1009 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001010
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001011 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001012 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001013 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001014 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001015 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001016 void parseHeaderDecl(clang::MMToken::TokenKind,
1017 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001018 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001019 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001020 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001021 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001022 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001023 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001024 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendling44426052012-12-20 19:22:21 +00001025 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001026
Douglas Gregor718292f2011-11-11 19:10:28 +00001027 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001028 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001029 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001030 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001031 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001032 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001033 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001034 const DirectoryEntry *BuiltinIncludeDir,
1035 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001036 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001037 ModuleMapFile(ModuleMapFile), Directory(Directory),
1038 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
1039 HadError(false), ActiveModule(0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001040 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001041 Tok.clear();
1042 consumeToken();
1043 }
1044
1045 bool parseModuleMapFile();
1046 };
1047}
1048
1049SourceLocation ModuleMapParser::consumeToken() {
1050retry:
1051 SourceLocation Result = Tok.getLocation();
1052 Tok.clear();
1053
1054 Token LToken;
1055 L.LexFromRawLexer(LToken);
1056 Tok.Location = LToken.getLocation().getRawEncoding();
1057 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001058 case tok::raw_identifier: {
1059 StringRef RI = LToken.getRawIdentifier();
1060 Tok.StringData = RI.data();
1061 Tok.StringLength = RI.size();
1062 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001063 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001064 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001065 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001066 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001067 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001068 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001069 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001070 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001071 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001072 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001073 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001074 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001075 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001076 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001077 .Default(MMToken::Identifier);
1078 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001079 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001080
1081 case tok::comma:
1082 Tok.Kind = MMToken::Comma;
1083 break;
1084
Douglas Gregor718292f2011-11-11 19:10:28 +00001085 case tok::eof:
1086 Tok.Kind = MMToken::EndOfFile;
1087 break;
1088
1089 case tok::l_brace:
1090 Tok.Kind = MMToken::LBrace;
1091 break;
1092
Douglas Gregora686e1b2012-01-27 19:52:33 +00001093 case tok::l_square:
1094 Tok.Kind = MMToken::LSquare;
1095 break;
1096
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001097 case tok::period:
1098 Tok.Kind = MMToken::Period;
1099 break;
1100
Douglas Gregor718292f2011-11-11 19:10:28 +00001101 case tok::r_brace:
1102 Tok.Kind = MMToken::RBrace;
1103 break;
1104
Douglas Gregora686e1b2012-01-27 19:52:33 +00001105 case tok::r_square:
1106 Tok.Kind = MMToken::RSquare;
1107 break;
1108
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001109 case tok::star:
1110 Tok.Kind = MMToken::Star;
1111 break;
1112
Richard Smitha3feee22013-10-28 22:18:19 +00001113 case tok::exclaim:
1114 Tok.Kind = MMToken::Exclaim;
1115 break;
1116
Douglas Gregor718292f2011-11-11 19:10:28 +00001117 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001118 if (LToken.hasUDSuffix()) {
1119 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1120 HadError = true;
1121 goto retry;
1122 }
1123
Douglas Gregor718292f2011-11-11 19:10:28 +00001124 // Parse the string literal.
1125 LangOptions LangOpts;
1126 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
1127 if (StringLiteral.hadError)
1128 goto retry;
1129
1130 // Copy the string literal into our string data allocator.
1131 unsigned Length = StringLiteral.GetStringLength();
1132 char *Saved = StringData.Allocate<char>(Length + 1);
1133 memcpy(Saved, StringLiteral.GetString().data(), Length);
1134 Saved[Length] = 0;
1135
1136 // Form the token.
1137 Tok.Kind = MMToken::StringLiteral;
1138 Tok.StringData = Saved;
1139 Tok.StringLength = Length;
1140 break;
1141 }
1142
1143 case tok::comment:
1144 goto retry;
1145
1146 default:
1147 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1148 HadError = true;
1149 goto retry;
1150 }
1151
1152 return Result;
1153}
1154
1155void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1156 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001157 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001158 do {
1159 switch (Tok.Kind) {
1160 case MMToken::EndOfFile:
1161 return;
1162
1163 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001164 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001165 return;
1166
1167 ++braceDepth;
1168 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001169
1170 case MMToken::LSquare:
1171 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1172 return;
1173
1174 ++squareDepth;
1175 break;
1176
Douglas Gregor718292f2011-11-11 19:10:28 +00001177 case MMToken::RBrace:
1178 if (braceDepth > 0)
1179 --braceDepth;
1180 else if (Tok.is(K))
1181 return;
1182 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001183
1184 case MMToken::RSquare:
1185 if (squareDepth > 0)
1186 --squareDepth;
1187 else if (Tok.is(K))
1188 return;
1189 break;
1190
Douglas Gregor718292f2011-11-11 19:10:28 +00001191 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001192 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001193 return;
1194 break;
1195 }
1196
1197 consumeToken();
1198 } while (true);
1199}
1200
Douglas Gregore7ab3662011-12-07 02:23:45 +00001201/// \brief Parse a module-id.
1202///
1203/// module-id:
1204/// identifier
1205/// identifier '.' module-id
1206///
1207/// \returns true if an error occurred, false otherwise.
1208bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1209 Id.clear();
1210 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001211 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001212 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1213 consumeToken();
1214 } else {
1215 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1216 return true;
1217 }
1218
1219 if (!Tok.is(MMToken::Period))
1220 break;
1221
1222 consumeToken();
1223 } while (true);
1224
1225 return false;
1226}
1227
Douglas Gregora686e1b2012-01-27 19:52:33 +00001228namespace {
1229 /// \brief Enumerates the known attributes.
1230 enum AttributeKind {
1231 /// \brief An unknown attribute.
1232 AT_unknown,
1233 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001234 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001235 /// \brief The 'extern_c' attribute.
1236 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001237 /// \brief The 'exhaustive' attribute.
1238 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001239 };
1240}
1241
Douglas Gregor718292f2011-11-11 19:10:28 +00001242/// \brief Parse a module declaration.
1243///
1244/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001245/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001246/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1247/// { module-member* }
1248///
Douglas Gregor718292f2011-11-11 19:10:28 +00001249/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001250/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001251/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001252/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001253/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001254/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001255///
1256/// submodule-declaration:
1257/// module-declaration
1258/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001259void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001260 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001261 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1262 if (Tok.is(MMToken::ExternKeyword)) {
1263 parseExternModuleDecl();
1264 return;
1265 }
1266
Douglas Gregorf2161a72011-12-06 17:16:41 +00001267 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001268 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001269 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001270 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001271
Douglas Gregorf2161a72011-12-06 17:16:41 +00001272 // Parse 'explicit' keyword, if present.
1273 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001274 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001275 Explicit = true;
1276 }
1277
1278 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001279 if (Tok.is(MMToken::FrameworkKeyword)) {
1280 consumeToken();
1281 Framework = true;
1282 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001283
1284 // Parse 'module' keyword.
1285 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001286 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001287 consumeToken();
1288 HadError = true;
1289 return;
1290 }
1291 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001292
1293 // If we have a wildcard for the module name, this is an inferred submodule.
1294 // Parse it.
1295 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001296 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001297
1298 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001299 ModuleId Id;
1300 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001301 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001302 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001303 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001304
Douglas Gregore7ab3662011-12-07 02:23:45 +00001305 if (ActiveModule) {
1306 if (Id.size() > 1) {
1307 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1308 << SourceRange(Id.front().second, Id.back().second);
1309
1310 HadError = true;
1311 return;
1312 }
1313 } else if (Id.size() == 1 && Explicit) {
1314 // Top-level modules can't be explicit.
1315 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1316 Explicit = false;
1317 ExplicitLoc = SourceLocation();
1318 HadError = true;
1319 }
1320
1321 Module *PreviousActiveModule = ActiveModule;
1322 if (Id.size() > 1) {
1323 // This module map defines a submodule. Go find the module of which it
1324 // is a submodule.
1325 ActiveModule = 0;
1326 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1327 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1328 ActiveModule = Next;
1329 continue;
1330 }
1331
1332 if (ActiveModule) {
1333 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001334 << Id[I].first
1335 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001336 } else {
1337 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1338 }
1339 HadError = true;
1340 return;
1341 }
1342 }
1343
1344 StringRef ModuleName = Id.back().first;
1345 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001346
Douglas Gregora686e1b2012-01-27 19:52:33 +00001347 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001348 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001349 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001350
Douglas Gregor718292f2011-11-11 19:10:28 +00001351 // Parse the opening brace.
1352 if (!Tok.is(MMToken::LBrace)) {
1353 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1354 << ModuleName;
1355 HadError = true;
1356 return;
1357 }
1358 SourceLocation LBraceLoc = consumeToken();
1359
1360 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001361 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001362 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1363 // Skip the module definition.
1364 skipUntil(MMToken::RBrace);
1365 if (Tok.is(MMToken::RBrace))
1366 consumeToken();
1367 else {
1368 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1369 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1370 HadError = true;
1371 }
1372 return;
1373 }
1374
Douglas Gregor718292f2011-11-11 19:10:28 +00001375 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1376 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001377 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001378
1379 // Skip the module definition.
1380 skipUntil(MMToken::RBrace);
1381 if (Tok.is(MMToken::RBrace))
1382 consumeToken();
1383
1384 HadError = true;
1385 return;
1386 }
1387
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001388 // If this is a submodule, use the parent's module map, since we don't want
1389 // the private module map file.
1390 const FileEntry *ModuleMap = ActiveModule ? ActiveModule->ModuleMap
1391 : ModuleMapFile;
1392
Douglas Gregor718292f2011-11-11 19:10:28 +00001393 // Start defining this module.
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001394 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, ModuleMap,
1395 Framework, Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001396 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001397 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001398 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001399 if (Attrs.IsExternC)
1400 ActiveModule->IsExternC = true;
1401
Douglas Gregor718292f2011-11-11 19:10:28 +00001402 bool Done = false;
1403 do {
1404 switch (Tok.Kind) {
1405 case MMToken::EndOfFile:
1406 case MMToken::RBrace:
1407 Done = true;
1408 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001409
1410 case MMToken::ConfigMacros:
1411 parseConfigMacros();
1412 break;
1413
Douglas Gregorfb912652013-03-20 21:10:35 +00001414 case MMToken::Conflict:
1415 parseConflict();
1416 break;
1417
Douglas Gregor718292f2011-11-11 19:10:28 +00001418 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001419 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001420 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001421 case MMToken::ModuleKeyword:
1422 parseModuleDecl();
1423 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001424
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001425 case MMToken::ExportKeyword:
1426 parseExportDecl();
1427 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001428
1429 case MMToken::UseKeyword:
1430 parseUseDecl();
1431 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001432
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001433 case MMToken::RequiresKeyword:
1434 parseRequiresDecl();
1435 break;
1436
Douglas Gregor524e33e2011-12-08 19:11:24 +00001437 case MMToken::UmbrellaKeyword: {
1438 SourceLocation UmbrellaLoc = consumeToken();
1439 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001440 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001441 else
1442 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001443 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001444 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001445
Douglas Gregor59527662012-10-15 06:28:11 +00001446 case MMToken::ExcludeKeyword: {
1447 SourceLocation ExcludeLoc = consumeToken();
1448 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001449 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor59527662012-10-15 06:28:11 +00001450 } else {
1451 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1452 << "exclude";
1453 }
1454 break;
1455 }
1456
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001457 case MMToken::PrivateKeyword: {
1458 SourceLocation PrivateLoc = consumeToken();
1459 if (Tok.is(MMToken::HeaderKeyword)) {
1460 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1461 } else {
1462 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1463 << "private";
1464 }
1465 break;
1466 }
1467
Douglas Gregor322f6332011-12-08 18:00:48 +00001468 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001469 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregor718292f2011-11-11 19:10:28 +00001470 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001471
1472 case MMToken::LinkKeyword:
1473 parseLinkDecl();
1474 break;
1475
Douglas Gregor718292f2011-11-11 19:10:28 +00001476 default:
1477 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1478 consumeToken();
1479 break;
1480 }
1481 } while (!Done);
1482
1483 if (Tok.is(MMToken::RBrace))
1484 consumeToken();
1485 else {
1486 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1487 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1488 HadError = true;
1489 }
1490
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001491 // If the active module is a top-level framework, and there are no link
1492 // libraries, automatically link against the framework.
1493 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1494 ActiveModule->LinkLibraries.empty()) {
1495 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1496 }
1497
Ben Langmuirec8c9752014-04-18 22:07:31 +00001498 // If the module meets all requirements but is still unavailable, mark the
1499 // whole tree as unavailable to prevent it from building.
1500 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1501 ActiveModule->Parent) {
1502 ActiveModule->getTopLevelModule()->markUnavailable();
1503 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1504 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1505 }
1506
Douglas Gregore7ab3662011-12-07 02:23:45 +00001507 // We're done parsing this module. Pop back to the previous module.
1508 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001509}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001510
Daniel Jasper97292842013-09-11 07:20:44 +00001511/// \brief Parse an extern module declaration.
1512///
1513/// extern module-declaration:
1514/// 'extern' 'module' module-id string-literal
1515void ModuleMapParser::parseExternModuleDecl() {
1516 assert(Tok.is(MMToken::ExternKeyword));
1517 consumeToken(); // 'extern' keyword
1518
1519 // Parse 'module' keyword.
1520 if (!Tok.is(MMToken::ModuleKeyword)) {
1521 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1522 consumeToken();
1523 HadError = true;
1524 return;
1525 }
1526 consumeToken(); // 'module' keyword
1527
1528 // Parse the module name.
1529 ModuleId Id;
1530 if (parseModuleId(Id)) {
1531 HadError = true;
1532 return;
1533 }
1534
1535 // Parse the referenced module map file name.
1536 if (!Tok.is(MMToken::StringLiteral)) {
1537 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1538 HadError = true;
1539 return;
1540 }
1541 std::string FileName = Tok.getString();
1542 consumeToken(); // filename
1543
1544 StringRef FileNameRef = FileName;
1545 SmallString<128> ModuleMapFileName;
1546 if (llvm::sys::path::is_relative(FileNameRef)) {
1547 ModuleMapFileName += Directory->getName();
1548 llvm::sys::path::append(ModuleMapFileName, FileName);
1549 FileNameRef = ModuleMapFileName.str();
1550 }
1551 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1552 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1553}
1554
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001555/// \brief Parse a requires declaration.
1556///
1557/// requires-declaration:
1558/// 'requires' feature-list
1559///
1560/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001561/// feature ',' feature-list
1562/// feature
1563///
1564/// feature:
1565/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001566void ModuleMapParser::parseRequiresDecl() {
1567 assert(Tok.is(MMToken::RequiresKeyword));
1568
1569 // Parse 'requires' keyword.
1570 consumeToken();
1571
1572 // Parse the feature-list.
1573 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001574 bool RequiredState = true;
1575 if (Tok.is(MMToken::Exclaim)) {
1576 RequiredState = false;
1577 consumeToken();
1578 }
1579
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001580 if (!Tok.is(MMToken::Identifier)) {
1581 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1582 HadError = true;
1583 return;
1584 }
1585
1586 // Consume the feature name.
1587 std::string Feature = Tok.getString();
1588 consumeToken();
1589
1590 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001591 ActiveModule->addRequirement(Feature, RequiredState,
1592 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001593
1594 if (!Tok.is(MMToken::Comma))
1595 break;
1596
1597 // Consume the comma.
1598 consumeToken();
1599 } while (true);
1600}
1601
Douglas Gregorf2161a72011-12-06 17:16:41 +00001602/// \brief Append to \p Paths the set of paths needed to get to the
1603/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001604static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001605 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001606 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001607 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001608 for (; Mod; Mod = Mod->Parent) {
1609 if (Mod->IsFramework)
1610 Paths.push_back(Mod->Name);
1611 }
1612
1613 if (Paths.empty())
1614 return;
1615
1616 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001617 for (unsigned I = Paths.size() - 1; I != 0; --I)
1618 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001619}
1620
Douglas Gregor718292f2011-11-11 19:10:28 +00001621/// \brief Parse a header declaration.
1622///
1623/// header-declaration:
Douglas Gregor322f6332011-12-08 18:00:48 +00001624/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor59527662012-10-15 06:28:11 +00001625/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001626void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1627 SourceLocation LeadingLoc) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001628 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001629 consumeToken();
1630
Douglas Gregor718292f2011-11-11 19:10:28 +00001631 // Parse the header name.
1632 if (!Tok.is(MMToken::StringLiteral)) {
1633 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1634 << "header";
1635 HadError = true;
1636 return;
1637 }
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001638 Module::HeaderDirective Header;
1639 Header.FileName = Tok.getString();
1640 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001641
Douglas Gregor524e33e2011-12-08 19:11:24 +00001642 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001643 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001644 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001645 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001646 HadError = true;
1647 return;
1648 }
1649
Douglas Gregor5257fc62011-11-11 21:55:48 +00001650 // Look for this file.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001651 const FileEntry *File = 0;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001652 const FileEntry *BuiltinFile = 0;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001653 SmallString<128> PathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001654 if (llvm::sys::path::is_absolute(Header.FileName)) {
1655 PathName = Header.FileName;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001656 File = SourceMgr.getFileManager().getFile(PathName);
1657 } else {
1658 // Search for the header file within the search directory.
Douglas Gregor70331272011-12-09 02:04:43 +00001659 PathName = Directory->getName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001660 unsigned PathLength = PathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001661
Douglas Gregorf2161a72011-12-06 17:16:41 +00001662 if (ActiveModule->isPartOfFramework()) {
1663 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001664
1665 // Check whether this file is in the public headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001666 llvm::sys::path::append(PathName, "Headers", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001667 File = SourceMgr.getFileManager().getFile(PathName);
1668
1669 if (!File) {
1670 // Check whether this file is in the private headers.
1671 PathName.resize(PathLength);
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001672 llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001673 File = SourceMgr.getFileManager().getFile(PathName);
1674 }
1675 } else {
1676 // Lookup for normal headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001677 llvm::sys::path::append(PathName, Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001678 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001679
1680 // If this is a system module with a top-level header, this header
1681 // may have a counterpart (or replacement) in the set of headers
1682 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001683 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1684 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001685 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001686 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001687 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001688 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1689
1690 // If Clang supplies this header but the underlying system does not,
1691 // just silently swap in our builtin version. Otherwise, we'll end
1692 // up adding both (later).
1693 if (!File && BuiltinFile) {
1694 File = BuiltinFile;
1695 BuiltinFile = 0;
1696 }
1697 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001698 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001699 }
Douglas Gregor755b2052011-11-17 22:09:43 +00001700
Douglas Gregor5257fc62011-11-11 21:55:48 +00001701 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1702 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001703 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001704 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001705 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001706 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001707 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001708 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001709 HadError = true;
1710 } else {
1711 // Record this umbrella header.
1712 Map.setUmbrellaHeader(ActiveModule, File);
1713 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00001714 } else {
Douglas Gregor322f6332011-12-08 18:00:48 +00001715 // Record this header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001716 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1717 if (LeadingToken == MMToken::ExcludeKeyword)
1718 Role = ModuleMap::ExcludedHeader;
1719 else if (LeadingToken == MMToken::PrivateKeyword)
1720 Role = ModuleMap::PrivateHeader;
1721 else
1722 assert(LeadingToken == MMToken::HeaderKeyword);
1723
1724 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001725
1726 // If there is a builtin counterpart to this file, add it now.
1727 if (BuiltinFile)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001728 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001729 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001730 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001731 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001732
1733 // If we find a module that has a missing header, we mark this module as
1734 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001735 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001736 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001737 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001738 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001739}
1740
Douglas Gregor524e33e2011-12-08 19:11:24 +00001741/// \brief Parse an umbrella directory declaration.
1742///
1743/// umbrella-dir-declaration:
1744/// umbrella string-literal
1745void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1746 // Parse the directory name.
1747 if (!Tok.is(MMToken::StringLiteral)) {
1748 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1749 << "umbrella";
1750 HadError = true;
1751 return;
1752 }
1753
1754 std::string DirName = Tok.getString();
1755 SourceLocation DirNameLoc = consumeToken();
1756
1757 // Check whether we already have an umbrella.
1758 if (ActiveModule->Umbrella) {
1759 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1760 << ActiveModule->getFullModuleName();
1761 HadError = true;
1762 return;
1763 }
1764
1765 // Look for this file.
1766 const DirectoryEntry *Dir = 0;
1767 if (llvm::sys::path::is_absolute(DirName))
1768 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1769 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001770 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001771 PathName = Directory->getName();
1772 llvm::sys::path::append(PathName, DirName);
1773 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1774 }
1775
1776 if (!Dir) {
1777 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1778 << DirName;
1779 HadError = true;
1780 return;
1781 }
1782
1783 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1784 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1785 << OwningModule->getFullModuleName();
1786 HadError = true;
1787 return;
1788 }
1789
1790 // Record this umbrella directory.
1791 Map.setUmbrellaDir(ActiveModule, Dir);
1792}
1793
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001794/// \brief Parse a module export declaration.
1795///
1796/// export-declaration:
1797/// 'export' wildcard-module-id
1798///
1799/// wildcard-module-id:
1800/// identifier
1801/// '*'
1802/// identifier '.' wildcard-module-id
1803void ModuleMapParser::parseExportDecl() {
1804 assert(Tok.is(MMToken::ExportKeyword));
1805 SourceLocation ExportLoc = consumeToken();
1806
1807 // Parse the module-id with an optional wildcard at the end.
1808 ModuleId ParsedModuleId;
1809 bool Wildcard = false;
1810 do {
1811 if (Tok.is(MMToken::Identifier)) {
1812 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1813 Tok.getLocation()));
1814 consumeToken();
1815
1816 if (Tok.is(MMToken::Period)) {
1817 consumeToken();
1818 continue;
1819 }
1820
1821 break;
1822 }
1823
1824 if(Tok.is(MMToken::Star)) {
1825 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001826 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001827 break;
1828 }
1829
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001830 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001831 HadError = true;
1832 return;
1833 } while (true);
1834
1835 Module::UnresolvedExportDecl Unresolved = {
1836 ExportLoc, ParsedModuleId, Wildcard
1837 };
1838 ActiveModule->UnresolvedExports.push_back(Unresolved);
1839}
1840
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001841/// \brief Parse a module uses declaration.
1842///
1843/// uses-declaration:
1844/// 'uses' wildcard-module-id
1845void ModuleMapParser::parseUseDecl() {
1846 assert(Tok.is(MMToken::UseKeyword));
1847 consumeToken();
1848 // Parse the module-id.
1849 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001850 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001851
1852 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1853}
1854
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001855/// \brief Parse a link declaration.
1856///
1857/// module-declaration:
1858/// 'link' 'framework'[opt] string-literal
1859void ModuleMapParser::parseLinkDecl() {
1860 assert(Tok.is(MMToken::LinkKeyword));
1861 SourceLocation LinkLoc = consumeToken();
1862
1863 // Parse the optional 'framework' keyword.
1864 bool IsFramework = false;
1865 if (Tok.is(MMToken::FrameworkKeyword)) {
1866 consumeToken();
1867 IsFramework = true;
1868 }
1869
1870 // Parse the library name
1871 if (!Tok.is(MMToken::StringLiteral)) {
1872 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1873 << IsFramework << SourceRange(LinkLoc);
1874 HadError = true;
1875 return;
1876 }
1877
1878 std::string LibraryName = Tok.getString();
1879 consumeToken();
1880 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1881 IsFramework));
1882}
1883
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001884/// \brief Parse a configuration macro declaration.
1885///
1886/// module-declaration:
1887/// 'config_macros' attributes[opt] config-macro-list?
1888///
1889/// config-macro-list:
1890/// identifier (',' identifier)?
1891void ModuleMapParser::parseConfigMacros() {
1892 assert(Tok.is(MMToken::ConfigMacros));
1893 SourceLocation ConfigMacrosLoc = consumeToken();
1894
1895 // Only top-level modules can have configuration macros.
1896 if (ActiveModule->Parent) {
1897 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1898 }
1899
1900 // Parse the optional attributes.
1901 Attributes Attrs;
1902 parseOptionalAttributes(Attrs);
1903 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1904 ActiveModule->ConfigMacrosExhaustive = true;
1905 }
1906
1907 // If we don't have an identifier, we're done.
1908 if (!Tok.is(MMToken::Identifier))
1909 return;
1910
1911 // Consume the first identifier.
1912 if (!ActiveModule->Parent) {
1913 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1914 }
1915 consumeToken();
1916
1917 do {
1918 // If there's a comma, consume it.
1919 if (!Tok.is(MMToken::Comma))
1920 break;
1921 consumeToken();
1922
1923 // We expect to see a macro name here.
1924 if (!Tok.is(MMToken::Identifier)) {
1925 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1926 break;
1927 }
1928
1929 // Consume the macro name.
1930 if (!ActiveModule->Parent) {
1931 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1932 }
1933 consumeToken();
1934 } while (true);
1935}
1936
Douglas Gregorfb912652013-03-20 21:10:35 +00001937/// \brief Format a module-id into a string.
1938static std::string formatModuleId(const ModuleId &Id) {
1939 std::string result;
1940 {
1941 llvm::raw_string_ostream OS(result);
1942
1943 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1944 if (I)
1945 OS << ".";
1946 OS << Id[I].first;
1947 }
1948 }
1949
1950 return result;
1951}
1952
1953/// \brief Parse a conflict declaration.
1954///
1955/// module-declaration:
1956/// 'conflict' module-id ',' string-literal
1957void ModuleMapParser::parseConflict() {
1958 assert(Tok.is(MMToken::Conflict));
1959 SourceLocation ConflictLoc = consumeToken();
1960 Module::UnresolvedConflict Conflict;
1961
1962 // Parse the module-id.
1963 if (parseModuleId(Conflict.Id))
1964 return;
1965
1966 // Parse the ','.
1967 if (!Tok.is(MMToken::Comma)) {
1968 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1969 << SourceRange(ConflictLoc);
1970 return;
1971 }
1972 consumeToken();
1973
1974 // Parse the message.
1975 if (!Tok.is(MMToken::StringLiteral)) {
1976 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1977 << formatModuleId(Conflict.Id);
1978 return;
1979 }
1980 Conflict.Message = Tok.getString().str();
1981 consumeToken();
1982
1983 // Add this unresolved conflict.
1984 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1985}
1986
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001987/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00001988///
1989/// module-declaration:
1990/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1991/// { inferred-module-member* }
1992///
1993/// inferred-module-member:
1994/// 'export' '*'
1995/// 'exclude' identifier
1996void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00001997 assert(Tok.is(MMToken::Star));
1998 SourceLocation StarLoc = consumeToken();
1999 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002000
Douglas Gregor73441092011-12-05 22:27:44 +00002001 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002002 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002003 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2004 Failed = true;
2005 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002006
2007 if (ActiveModule) {
2008 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002009 if (!Failed && ActiveModule->IsAvailable &&
2010 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002011 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2012 Failed = true;
2013 }
2014
2015 // Check for redefinition of an inferred module.
2016 if (!Failed && ActiveModule->InferSubmodules) {
2017 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2018 if (ActiveModule->InferredSubmoduleLoc.isValid())
2019 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2020 diag::note_mmap_prev_definition);
2021 Failed = true;
2022 }
2023
2024 // Check for the 'framework' keyword, which is not permitted here.
2025 if (Framework) {
2026 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2027 Framework = false;
2028 }
2029 } else if (Explicit) {
2030 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2031 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002032 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002033
Douglas Gregor73441092011-12-05 22:27:44 +00002034 // If there were any problems with this inferred submodule, skip its body.
2035 if (Failed) {
2036 if (Tok.is(MMToken::LBrace)) {
2037 consumeToken();
2038 skipUntil(MMToken::RBrace);
2039 if (Tok.is(MMToken::RBrace))
2040 consumeToken();
2041 }
2042 HadError = true;
2043 return;
2044 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002045
2046 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002047 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002048 parseOptionalAttributes(Attrs);
2049
2050 if (ActiveModule) {
2051 // Note that we have an inferred submodule.
2052 ActiveModule->InferSubmodules = true;
2053 ActiveModule->InferredSubmoduleLoc = StarLoc;
2054 ActiveModule->InferExplicitSubmodules = Explicit;
2055 } else {
2056 // We'll be inferring framework modules for this directory.
2057 Map.InferredDirectories[Directory].InferModules = true;
2058 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002059 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002060 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002061 }
2062
Douglas Gregor73441092011-12-05 22:27:44 +00002063 // Parse the opening brace.
2064 if (!Tok.is(MMToken::LBrace)) {
2065 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2066 HadError = true;
2067 return;
2068 }
2069 SourceLocation LBraceLoc = consumeToken();
2070
2071 // Parse the body of the inferred submodule.
2072 bool Done = false;
2073 do {
2074 switch (Tok.Kind) {
2075 case MMToken::EndOfFile:
2076 case MMToken::RBrace:
2077 Done = true;
2078 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002079
2080 case MMToken::ExcludeKeyword: {
2081 if (ActiveModule) {
2082 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00002083 << (ActiveModule != 0);
Douglas Gregor9194a912012-11-06 19:39:40 +00002084 consumeToken();
2085 break;
2086 }
2087
2088 consumeToken();
2089 if (!Tok.is(MMToken::Identifier)) {
2090 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2091 break;
2092 }
2093
2094 Map.InferredDirectories[Directory].ExcludedModules
2095 .push_back(Tok.getString());
2096 consumeToken();
2097 break;
2098 }
2099
2100 case MMToken::ExportKeyword:
2101 if (!ActiveModule) {
2102 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00002103 << (ActiveModule != 0);
Douglas Gregor9194a912012-11-06 19:39:40 +00002104 consumeToken();
2105 break;
2106 }
2107
Douglas Gregor73441092011-12-05 22:27:44 +00002108 consumeToken();
2109 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002110 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002111 else
2112 Diags.Report(Tok.getLocation(),
2113 diag::err_mmap_expected_export_wildcard);
2114 consumeToken();
2115 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002116
Douglas Gregor73441092011-12-05 22:27:44 +00002117 case MMToken::ExplicitKeyword:
2118 case MMToken::ModuleKeyword:
2119 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002120 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002121 case MMToken::UmbrellaKeyword:
2122 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002123 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00002124 << (ActiveModule != 0);
Douglas Gregor73441092011-12-05 22:27:44 +00002125 consumeToken();
2126 break;
2127 }
2128 } while (!Done);
2129
2130 if (Tok.is(MMToken::RBrace))
2131 consumeToken();
2132 else {
2133 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2134 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2135 HadError = true;
2136 }
2137}
2138
Douglas Gregor9194a912012-11-06 19:39:40 +00002139/// \brief Parse optional attributes.
2140///
2141/// attributes:
2142/// attribute attributes
2143/// attribute
2144///
2145/// attribute:
2146/// [ identifier ]
2147///
2148/// \param Attrs Will be filled in with the parsed attributes.
2149///
2150/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002151bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002152 bool HadError = false;
2153
2154 while (Tok.is(MMToken::LSquare)) {
2155 // Consume the '['.
2156 SourceLocation LSquareLoc = consumeToken();
2157
2158 // Check whether we have an attribute name here.
2159 if (!Tok.is(MMToken::Identifier)) {
2160 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2161 skipUntil(MMToken::RSquare);
2162 if (Tok.is(MMToken::RSquare))
2163 consumeToken();
2164 HadError = true;
2165 }
2166
2167 // Decode the attribute name.
2168 AttributeKind Attribute
2169 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002170 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002171 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002172 .Case("system", AT_system)
2173 .Default(AT_unknown);
2174 switch (Attribute) {
2175 case AT_unknown:
2176 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2177 << Tok.getString();
2178 break;
2179
2180 case AT_system:
2181 Attrs.IsSystem = true;
2182 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002183
Richard Smith77944862014-03-02 05:58:18 +00002184 case AT_extern_c:
2185 Attrs.IsExternC = true;
2186 break;
2187
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002188 case AT_exhaustive:
2189 Attrs.IsExhaustive = true;
2190 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002191 }
2192 consumeToken();
2193
2194 // Consume the ']'.
2195 if (!Tok.is(MMToken::RSquare)) {
2196 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2197 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2198 skipUntil(MMToken::RSquare);
2199 HadError = true;
2200 }
2201
2202 if (Tok.is(MMToken::RSquare))
2203 consumeToken();
2204 }
2205
2206 return HadError;
2207}
2208
Douglas Gregor718292f2011-11-11 19:10:28 +00002209/// \brief Parse a module map file.
2210///
2211/// module-map-file:
2212/// module-declaration*
2213bool ModuleMapParser::parseModuleMapFile() {
2214 do {
2215 switch (Tok.Kind) {
2216 case MMToken::EndOfFile:
2217 return HadError;
2218
Douglas Gregore7ab3662011-12-07 02:23:45 +00002219 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002220 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002221 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002222 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002223 parseModuleDecl();
2224 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002225
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002226 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002227 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002228 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002229 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002230 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002231 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002232 case MMToken::HeaderKeyword:
2233 case MMToken::Identifier:
2234 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002235 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002236 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002237 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002238 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002239 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002240 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002241 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002242 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002243 case MMToken::StringLiteral:
2244 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002245 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002246 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2247 HadError = true;
2248 consumeToken();
2249 break;
2250 }
2251 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002252}
2253
Douglas Gregor963c5532013-06-21 16:28:10 +00002254bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002255 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2256 = ParsedModuleMap.find(File);
2257 if (Known != ParsedModuleMap.end())
2258 return Known->second;
2259
Douglas Gregor89929282012-01-30 06:01:29 +00002260 assert(Target != 0 && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002261 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2262 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002263 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002264 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002265 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002266
2267 // Find the directory for the module. For frameworks, that may require going
2268 // up from the 'Modules' directory.
2269 const DirectoryEntry *Dir = File->getDir();
2270 StringRef DirName(Dir->getName());
2271 if (llvm::sys::path::filename(DirName) == "Modules") {
2272 DirName = llvm::sys::path::parent_path(DirName);
2273 if (DirName.endswith(".framework"))
2274 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2275 assert(Dir && "parent must exist");
2276 }
Douglas Gregor718292f2011-11-11 19:10:28 +00002277
2278 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002279 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002280 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002281 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002282 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002283 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002284 return Result;
2285}