blob: ce2c4f02e395e9be95b90977b53000c0df6a1b1b [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()) {
1058 case tok::raw_identifier:
1059 Tok.StringData = LToken.getRawIdentifierData();
1060 Tok.StringLength = LToken.getLength();
1061 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001062 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001063 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001064 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001065 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001066 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001067 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001068 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001069 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001070 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001071 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001072 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001073 .Case("requires", MMToken::RequiresKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001074 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001075 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001076 .Default(MMToken::Identifier);
1077 break;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001078
1079 case tok::comma:
1080 Tok.Kind = MMToken::Comma;
1081 break;
1082
Douglas Gregor718292f2011-11-11 19:10:28 +00001083 case tok::eof:
1084 Tok.Kind = MMToken::EndOfFile;
1085 break;
1086
1087 case tok::l_brace:
1088 Tok.Kind = MMToken::LBrace;
1089 break;
1090
Douglas Gregora686e1b2012-01-27 19:52:33 +00001091 case tok::l_square:
1092 Tok.Kind = MMToken::LSquare;
1093 break;
1094
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001095 case tok::period:
1096 Tok.Kind = MMToken::Period;
1097 break;
1098
Douglas Gregor718292f2011-11-11 19:10:28 +00001099 case tok::r_brace:
1100 Tok.Kind = MMToken::RBrace;
1101 break;
1102
Douglas Gregora686e1b2012-01-27 19:52:33 +00001103 case tok::r_square:
1104 Tok.Kind = MMToken::RSquare;
1105 break;
1106
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001107 case tok::star:
1108 Tok.Kind = MMToken::Star;
1109 break;
1110
Richard Smitha3feee22013-10-28 22:18:19 +00001111 case tok::exclaim:
1112 Tok.Kind = MMToken::Exclaim;
1113 break;
1114
Douglas Gregor718292f2011-11-11 19:10:28 +00001115 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001116 if (LToken.hasUDSuffix()) {
1117 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1118 HadError = true;
1119 goto retry;
1120 }
1121
Douglas Gregor718292f2011-11-11 19:10:28 +00001122 // Parse the string literal.
1123 LangOptions LangOpts;
1124 StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
1125 if (StringLiteral.hadError)
1126 goto retry;
1127
1128 // Copy the string literal into our string data allocator.
1129 unsigned Length = StringLiteral.GetStringLength();
1130 char *Saved = StringData.Allocate<char>(Length + 1);
1131 memcpy(Saved, StringLiteral.GetString().data(), Length);
1132 Saved[Length] = 0;
1133
1134 // Form the token.
1135 Tok.Kind = MMToken::StringLiteral;
1136 Tok.StringData = Saved;
1137 Tok.StringLength = Length;
1138 break;
1139 }
1140
1141 case tok::comment:
1142 goto retry;
1143
1144 default:
1145 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1146 HadError = true;
1147 goto retry;
1148 }
1149
1150 return Result;
1151}
1152
1153void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1154 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001155 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001156 do {
1157 switch (Tok.Kind) {
1158 case MMToken::EndOfFile:
1159 return;
1160
1161 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001162 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001163 return;
1164
1165 ++braceDepth;
1166 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001167
1168 case MMToken::LSquare:
1169 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1170 return;
1171
1172 ++squareDepth;
1173 break;
1174
Douglas Gregor718292f2011-11-11 19:10:28 +00001175 case MMToken::RBrace:
1176 if (braceDepth > 0)
1177 --braceDepth;
1178 else if (Tok.is(K))
1179 return;
1180 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001181
1182 case MMToken::RSquare:
1183 if (squareDepth > 0)
1184 --squareDepth;
1185 else if (Tok.is(K))
1186 return;
1187 break;
1188
Douglas Gregor718292f2011-11-11 19:10:28 +00001189 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001190 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001191 return;
1192 break;
1193 }
1194
1195 consumeToken();
1196 } while (true);
1197}
1198
Douglas Gregore7ab3662011-12-07 02:23:45 +00001199/// \brief Parse a module-id.
1200///
1201/// module-id:
1202/// identifier
1203/// identifier '.' module-id
1204///
1205/// \returns true if an error occurred, false otherwise.
1206bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1207 Id.clear();
1208 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001209 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001210 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1211 consumeToken();
1212 } else {
1213 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1214 return true;
1215 }
1216
1217 if (!Tok.is(MMToken::Period))
1218 break;
1219
1220 consumeToken();
1221 } while (true);
1222
1223 return false;
1224}
1225
Douglas Gregora686e1b2012-01-27 19:52:33 +00001226namespace {
1227 /// \brief Enumerates the known attributes.
1228 enum AttributeKind {
1229 /// \brief An unknown attribute.
1230 AT_unknown,
1231 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001232 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001233 /// \brief The 'extern_c' attribute.
1234 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001235 /// \brief The 'exhaustive' attribute.
1236 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001237 };
1238}
1239
Douglas Gregor718292f2011-11-11 19:10:28 +00001240/// \brief Parse a module declaration.
1241///
1242/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001243/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001244/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1245/// { module-member* }
1246///
Douglas Gregor718292f2011-11-11 19:10:28 +00001247/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001248/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001249/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001250/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001251/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001252/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001253///
1254/// submodule-declaration:
1255/// module-declaration
1256/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001257void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001258 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001259 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1260 if (Tok.is(MMToken::ExternKeyword)) {
1261 parseExternModuleDecl();
1262 return;
1263 }
1264
Douglas Gregorf2161a72011-12-06 17:16:41 +00001265 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001266 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001267 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001268 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001269
Douglas Gregorf2161a72011-12-06 17:16:41 +00001270 // Parse 'explicit' keyword, if present.
1271 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001272 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001273 Explicit = true;
1274 }
1275
1276 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001277 if (Tok.is(MMToken::FrameworkKeyword)) {
1278 consumeToken();
1279 Framework = true;
1280 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001281
1282 // Parse 'module' keyword.
1283 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001284 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001285 consumeToken();
1286 HadError = true;
1287 return;
1288 }
1289 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001290
1291 // If we have a wildcard for the module name, this is an inferred submodule.
1292 // Parse it.
1293 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001294 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001295
1296 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001297 ModuleId Id;
1298 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001299 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001300 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001301 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001302
Douglas Gregore7ab3662011-12-07 02:23:45 +00001303 if (ActiveModule) {
1304 if (Id.size() > 1) {
1305 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1306 << SourceRange(Id.front().second, Id.back().second);
1307
1308 HadError = true;
1309 return;
1310 }
1311 } else if (Id.size() == 1 && Explicit) {
1312 // Top-level modules can't be explicit.
1313 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1314 Explicit = false;
1315 ExplicitLoc = SourceLocation();
1316 HadError = true;
1317 }
1318
1319 Module *PreviousActiveModule = ActiveModule;
1320 if (Id.size() > 1) {
1321 // This module map defines a submodule. Go find the module of which it
1322 // is a submodule.
1323 ActiveModule = 0;
1324 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1325 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
1326 ActiveModule = Next;
1327 continue;
1328 }
1329
1330 if (ActiveModule) {
1331 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001332 << Id[I].first
1333 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001334 } else {
1335 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1336 }
1337 HadError = true;
1338 return;
1339 }
1340 }
1341
1342 StringRef ModuleName = Id.back().first;
1343 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001344
Douglas Gregora686e1b2012-01-27 19:52:33 +00001345 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001346 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001347 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001348
Douglas Gregor718292f2011-11-11 19:10:28 +00001349 // Parse the opening brace.
1350 if (!Tok.is(MMToken::LBrace)) {
1351 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1352 << ModuleName;
1353 HadError = true;
1354 return;
1355 }
1356 SourceLocation LBraceLoc = consumeToken();
1357
1358 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001359 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001360 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1361 // Skip the module definition.
1362 skipUntil(MMToken::RBrace);
1363 if (Tok.is(MMToken::RBrace))
1364 consumeToken();
1365 else {
1366 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1367 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1368 HadError = true;
1369 }
1370 return;
1371 }
1372
Douglas Gregor718292f2011-11-11 19:10:28 +00001373 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1374 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001375 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001376
1377 // Skip the module definition.
1378 skipUntil(MMToken::RBrace);
1379 if (Tok.is(MMToken::RBrace))
1380 consumeToken();
1381
1382 HadError = true;
1383 return;
1384 }
1385
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001386 // If this is a submodule, use the parent's module map, since we don't want
1387 // the private module map file.
1388 const FileEntry *ModuleMap = ActiveModule ? ActiveModule->ModuleMap
1389 : ModuleMapFile;
1390
Douglas Gregor718292f2011-11-11 19:10:28 +00001391 // Start defining this module.
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001392 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, ModuleMap,
1393 Framework, Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001394 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001395 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001396 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001397 if (Attrs.IsExternC)
1398 ActiveModule->IsExternC = true;
1399
Douglas Gregor718292f2011-11-11 19:10:28 +00001400 bool Done = false;
1401 do {
1402 switch (Tok.Kind) {
1403 case MMToken::EndOfFile:
1404 case MMToken::RBrace:
1405 Done = true;
1406 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001407
1408 case MMToken::ConfigMacros:
1409 parseConfigMacros();
1410 break;
1411
Douglas Gregorfb912652013-03-20 21:10:35 +00001412 case MMToken::Conflict:
1413 parseConflict();
1414 break;
1415
Douglas Gregor718292f2011-11-11 19:10:28 +00001416 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001417 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001418 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001419 case MMToken::ModuleKeyword:
1420 parseModuleDecl();
1421 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001422
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001423 case MMToken::ExportKeyword:
1424 parseExportDecl();
1425 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001426
1427 case MMToken::UseKeyword:
1428 parseUseDecl();
1429 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001430
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001431 case MMToken::RequiresKeyword:
1432 parseRequiresDecl();
1433 break;
1434
Douglas Gregor524e33e2011-12-08 19:11:24 +00001435 case MMToken::UmbrellaKeyword: {
1436 SourceLocation UmbrellaLoc = consumeToken();
1437 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001438 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001439 else
1440 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001441 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001442 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001443
Douglas Gregor59527662012-10-15 06:28:11 +00001444 case MMToken::ExcludeKeyword: {
1445 SourceLocation ExcludeLoc = consumeToken();
1446 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001447 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor59527662012-10-15 06:28:11 +00001448 } else {
1449 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1450 << "exclude";
1451 }
1452 break;
1453 }
1454
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001455 case MMToken::PrivateKeyword: {
1456 SourceLocation PrivateLoc = consumeToken();
1457 if (Tok.is(MMToken::HeaderKeyword)) {
1458 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1459 } else {
1460 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1461 << "private";
1462 }
1463 break;
1464 }
1465
Douglas Gregor322f6332011-12-08 18:00:48 +00001466 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001467 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregor718292f2011-11-11 19:10:28 +00001468 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001469
1470 case MMToken::LinkKeyword:
1471 parseLinkDecl();
1472 break;
1473
Douglas Gregor718292f2011-11-11 19:10:28 +00001474 default:
1475 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1476 consumeToken();
1477 break;
1478 }
1479 } while (!Done);
1480
1481 if (Tok.is(MMToken::RBrace))
1482 consumeToken();
1483 else {
1484 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1485 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1486 HadError = true;
1487 }
1488
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001489 // If the active module is a top-level framework, and there are no link
1490 // libraries, automatically link against the framework.
1491 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1492 ActiveModule->LinkLibraries.empty()) {
1493 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1494 }
1495
Ben Langmuirec8c9752014-04-18 22:07:31 +00001496 // If the module meets all requirements but is still unavailable, mark the
1497 // whole tree as unavailable to prevent it from building.
1498 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1499 ActiveModule->Parent) {
1500 ActiveModule->getTopLevelModule()->markUnavailable();
1501 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1502 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1503 }
1504
Douglas Gregore7ab3662011-12-07 02:23:45 +00001505 // We're done parsing this module. Pop back to the previous module.
1506 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001507}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001508
Daniel Jasper97292842013-09-11 07:20:44 +00001509/// \brief Parse an extern module declaration.
1510///
1511/// extern module-declaration:
1512/// 'extern' 'module' module-id string-literal
1513void ModuleMapParser::parseExternModuleDecl() {
1514 assert(Tok.is(MMToken::ExternKeyword));
1515 consumeToken(); // 'extern' keyword
1516
1517 // Parse 'module' keyword.
1518 if (!Tok.is(MMToken::ModuleKeyword)) {
1519 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1520 consumeToken();
1521 HadError = true;
1522 return;
1523 }
1524 consumeToken(); // 'module' keyword
1525
1526 // Parse the module name.
1527 ModuleId Id;
1528 if (parseModuleId(Id)) {
1529 HadError = true;
1530 return;
1531 }
1532
1533 // Parse the referenced module map file name.
1534 if (!Tok.is(MMToken::StringLiteral)) {
1535 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1536 HadError = true;
1537 return;
1538 }
1539 std::string FileName = Tok.getString();
1540 consumeToken(); // filename
1541
1542 StringRef FileNameRef = FileName;
1543 SmallString<128> ModuleMapFileName;
1544 if (llvm::sys::path::is_relative(FileNameRef)) {
1545 ModuleMapFileName += Directory->getName();
1546 llvm::sys::path::append(ModuleMapFileName, FileName);
1547 FileNameRef = ModuleMapFileName.str();
1548 }
1549 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1550 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1551}
1552
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001553/// \brief Parse a requires declaration.
1554///
1555/// requires-declaration:
1556/// 'requires' feature-list
1557///
1558/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001559/// feature ',' feature-list
1560/// feature
1561///
1562/// feature:
1563/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001564void ModuleMapParser::parseRequiresDecl() {
1565 assert(Tok.is(MMToken::RequiresKeyword));
1566
1567 // Parse 'requires' keyword.
1568 consumeToken();
1569
1570 // Parse the feature-list.
1571 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001572 bool RequiredState = true;
1573 if (Tok.is(MMToken::Exclaim)) {
1574 RequiredState = false;
1575 consumeToken();
1576 }
1577
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001578 if (!Tok.is(MMToken::Identifier)) {
1579 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1580 HadError = true;
1581 return;
1582 }
1583
1584 // Consume the feature name.
1585 std::string Feature = Tok.getString();
1586 consumeToken();
1587
1588 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001589 ActiveModule->addRequirement(Feature, RequiredState,
1590 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001591
1592 if (!Tok.is(MMToken::Comma))
1593 break;
1594
1595 // Consume the comma.
1596 consumeToken();
1597 } while (true);
1598}
1599
Douglas Gregorf2161a72011-12-06 17:16:41 +00001600/// \brief Append to \p Paths the set of paths needed to get to the
1601/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001602static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001603 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001604 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001605 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001606 for (; Mod; Mod = Mod->Parent) {
1607 if (Mod->IsFramework)
1608 Paths.push_back(Mod->Name);
1609 }
1610
1611 if (Paths.empty())
1612 return;
1613
1614 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001615 for (unsigned I = Paths.size() - 1; I != 0; --I)
1616 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001617}
1618
Douglas Gregor718292f2011-11-11 19:10:28 +00001619/// \brief Parse a header declaration.
1620///
1621/// header-declaration:
Douglas Gregor322f6332011-12-08 18:00:48 +00001622/// 'umbrella'[opt] 'header' string-literal
Douglas Gregor59527662012-10-15 06:28:11 +00001623/// 'exclude'[opt] 'header' string-literal
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001624void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1625 SourceLocation LeadingLoc) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001626 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001627 consumeToken();
1628
Douglas Gregor718292f2011-11-11 19:10:28 +00001629 // Parse the header name.
1630 if (!Tok.is(MMToken::StringLiteral)) {
1631 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1632 << "header";
1633 HadError = true;
1634 return;
1635 }
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001636 Module::HeaderDirective Header;
1637 Header.FileName = Tok.getString();
1638 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001639
Douglas Gregor524e33e2011-12-08 19:11:24 +00001640 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001641 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001642 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001643 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001644 HadError = true;
1645 return;
1646 }
1647
Douglas Gregor5257fc62011-11-11 21:55:48 +00001648 // Look for this file.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001649 const FileEntry *File = 0;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001650 const FileEntry *BuiltinFile = 0;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001651 SmallString<128> PathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001652 if (llvm::sys::path::is_absolute(Header.FileName)) {
1653 PathName = Header.FileName;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001654 File = SourceMgr.getFileManager().getFile(PathName);
1655 } else {
1656 // Search for the header file within the search directory.
Douglas Gregor70331272011-12-09 02:04:43 +00001657 PathName = Directory->getName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001658 unsigned PathLength = PathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001659
Douglas Gregorf2161a72011-12-06 17:16:41 +00001660 if (ActiveModule->isPartOfFramework()) {
1661 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001662
1663 // Check whether this file is in the public headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001664 llvm::sys::path::append(PathName, "Headers", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001665 File = SourceMgr.getFileManager().getFile(PathName);
1666
1667 if (!File) {
1668 // Check whether this file is in the private headers.
1669 PathName.resize(PathLength);
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001670 llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001671 File = SourceMgr.getFileManager().getFile(PathName);
1672 }
1673 } else {
1674 // Lookup for normal headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001675 llvm::sys::path::append(PathName, Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001676 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001677
1678 // If this is a system module with a top-level header, this header
1679 // may have a counterpart (or replacement) in the set of headers
1680 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001681 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1682 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001683 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001684 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001685 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001686 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1687
1688 // If Clang supplies this header but the underlying system does not,
1689 // just silently swap in our builtin version. Otherwise, we'll end
1690 // up adding both (later).
1691 if (!File && BuiltinFile) {
1692 File = BuiltinFile;
1693 BuiltinFile = 0;
1694 }
1695 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001696 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001697 }
Douglas Gregor755b2052011-11-17 22:09:43 +00001698
Douglas Gregor5257fc62011-11-11 21:55:48 +00001699 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1700 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001701 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001702 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001703 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001704 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001705 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001706 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001707 HadError = true;
1708 } else {
1709 // Record this umbrella header.
1710 Map.setUmbrellaHeader(ActiveModule, File);
1711 }
Douglas Gregor5257fc62011-11-11 21:55:48 +00001712 } else {
Douglas Gregor322f6332011-12-08 18:00:48 +00001713 // Record this header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001714 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1715 if (LeadingToken == MMToken::ExcludeKeyword)
1716 Role = ModuleMap::ExcludedHeader;
1717 else if (LeadingToken == MMToken::PrivateKeyword)
1718 Role = ModuleMap::PrivateHeader;
1719 else
1720 assert(LeadingToken == MMToken::HeaderKeyword);
1721
1722 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001723
1724 // If there is a builtin counterpart to this file, add it now.
1725 if (BuiltinFile)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001726 Map.addHeader(ActiveModule, BuiltinFile, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001727 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001728 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001729 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001730
1731 // If we find a module that has a missing header, we mark this module as
1732 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001733 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001734 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001735 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001736 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001737}
1738
Douglas Gregor524e33e2011-12-08 19:11:24 +00001739/// \brief Parse an umbrella directory declaration.
1740///
1741/// umbrella-dir-declaration:
1742/// umbrella string-literal
1743void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1744 // Parse the directory name.
1745 if (!Tok.is(MMToken::StringLiteral)) {
1746 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1747 << "umbrella";
1748 HadError = true;
1749 return;
1750 }
1751
1752 std::string DirName = Tok.getString();
1753 SourceLocation DirNameLoc = consumeToken();
1754
1755 // Check whether we already have an umbrella.
1756 if (ActiveModule->Umbrella) {
1757 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1758 << ActiveModule->getFullModuleName();
1759 HadError = true;
1760 return;
1761 }
1762
1763 // Look for this file.
1764 const DirectoryEntry *Dir = 0;
1765 if (llvm::sys::path::is_absolute(DirName))
1766 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1767 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001768 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001769 PathName = Directory->getName();
1770 llvm::sys::path::append(PathName, DirName);
1771 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1772 }
1773
1774 if (!Dir) {
1775 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1776 << DirName;
1777 HadError = true;
1778 return;
1779 }
1780
1781 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1782 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1783 << OwningModule->getFullModuleName();
1784 HadError = true;
1785 return;
1786 }
1787
1788 // Record this umbrella directory.
1789 Map.setUmbrellaDir(ActiveModule, Dir);
1790}
1791
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001792/// \brief Parse a module export declaration.
1793///
1794/// export-declaration:
1795/// 'export' wildcard-module-id
1796///
1797/// wildcard-module-id:
1798/// identifier
1799/// '*'
1800/// identifier '.' wildcard-module-id
1801void ModuleMapParser::parseExportDecl() {
1802 assert(Tok.is(MMToken::ExportKeyword));
1803 SourceLocation ExportLoc = consumeToken();
1804
1805 // Parse the module-id with an optional wildcard at the end.
1806 ModuleId ParsedModuleId;
1807 bool Wildcard = false;
1808 do {
1809 if (Tok.is(MMToken::Identifier)) {
1810 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1811 Tok.getLocation()));
1812 consumeToken();
1813
1814 if (Tok.is(MMToken::Period)) {
1815 consumeToken();
1816 continue;
1817 }
1818
1819 break;
1820 }
1821
1822 if(Tok.is(MMToken::Star)) {
1823 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001824 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001825 break;
1826 }
1827
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001828 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001829 HadError = true;
1830 return;
1831 } while (true);
1832
1833 Module::UnresolvedExportDecl Unresolved = {
1834 ExportLoc, ParsedModuleId, Wildcard
1835 };
1836 ActiveModule->UnresolvedExports.push_back(Unresolved);
1837}
1838
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001839/// \brief Parse a module uses declaration.
1840///
1841/// uses-declaration:
1842/// 'uses' wildcard-module-id
1843void ModuleMapParser::parseUseDecl() {
1844 assert(Tok.is(MMToken::UseKeyword));
1845 consumeToken();
1846 // Parse the module-id.
1847 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001848 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001849
1850 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1851}
1852
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001853/// \brief Parse a link declaration.
1854///
1855/// module-declaration:
1856/// 'link' 'framework'[opt] string-literal
1857void ModuleMapParser::parseLinkDecl() {
1858 assert(Tok.is(MMToken::LinkKeyword));
1859 SourceLocation LinkLoc = consumeToken();
1860
1861 // Parse the optional 'framework' keyword.
1862 bool IsFramework = false;
1863 if (Tok.is(MMToken::FrameworkKeyword)) {
1864 consumeToken();
1865 IsFramework = true;
1866 }
1867
1868 // Parse the library name
1869 if (!Tok.is(MMToken::StringLiteral)) {
1870 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1871 << IsFramework << SourceRange(LinkLoc);
1872 HadError = true;
1873 return;
1874 }
1875
1876 std::string LibraryName = Tok.getString();
1877 consumeToken();
1878 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1879 IsFramework));
1880}
1881
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001882/// \brief Parse a configuration macro declaration.
1883///
1884/// module-declaration:
1885/// 'config_macros' attributes[opt] config-macro-list?
1886///
1887/// config-macro-list:
1888/// identifier (',' identifier)?
1889void ModuleMapParser::parseConfigMacros() {
1890 assert(Tok.is(MMToken::ConfigMacros));
1891 SourceLocation ConfigMacrosLoc = consumeToken();
1892
1893 // Only top-level modules can have configuration macros.
1894 if (ActiveModule->Parent) {
1895 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1896 }
1897
1898 // Parse the optional attributes.
1899 Attributes Attrs;
1900 parseOptionalAttributes(Attrs);
1901 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1902 ActiveModule->ConfigMacrosExhaustive = true;
1903 }
1904
1905 // If we don't have an identifier, we're done.
1906 if (!Tok.is(MMToken::Identifier))
1907 return;
1908
1909 // Consume the first identifier.
1910 if (!ActiveModule->Parent) {
1911 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1912 }
1913 consumeToken();
1914
1915 do {
1916 // If there's a comma, consume it.
1917 if (!Tok.is(MMToken::Comma))
1918 break;
1919 consumeToken();
1920
1921 // We expect to see a macro name here.
1922 if (!Tok.is(MMToken::Identifier)) {
1923 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1924 break;
1925 }
1926
1927 // Consume the macro name.
1928 if (!ActiveModule->Parent) {
1929 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1930 }
1931 consumeToken();
1932 } while (true);
1933}
1934
Douglas Gregorfb912652013-03-20 21:10:35 +00001935/// \brief Format a module-id into a string.
1936static std::string formatModuleId(const ModuleId &Id) {
1937 std::string result;
1938 {
1939 llvm::raw_string_ostream OS(result);
1940
1941 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
1942 if (I)
1943 OS << ".";
1944 OS << Id[I].first;
1945 }
1946 }
1947
1948 return result;
1949}
1950
1951/// \brief Parse a conflict declaration.
1952///
1953/// module-declaration:
1954/// 'conflict' module-id ',' string-literal
1955void ModuleMapParser::parseConflict() {
1956 assert(Tok.is(MMToken::Conflict));
1957 SourceLocation ConflictLoc = consumeToken();
1958 Module::UnresolvedConflict Conflict;
1959
1960 // Parse the module-id.
1961 if (parseModuleId(Conflict.Id))
1962 return;
1963
1964 // Parse the ','.
1965 if (!Tok.is(MMToken::Comma)) {
1966 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
1967 << SourceRange(ConflictLoc);
1968 return;
1969 }
1970 consumeToken();
1971
1972 // Parse the message.
1973 if (!Tok.is(MMToken::StringLiteral)) {
1974 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
1975 << formatModuleId(Conflict.Id);
1976 return;
1977 }
1978 Conflict.Message = Tok.getString().str();
1979 consumeToken();
1980
1981 // Add this unresolved conflict.
1982 ActiveModule->UnresolvedConflicts.push_back(Conflict);
1983}
1984
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001985/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00001986///
1987/// module-declaration:
1988/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
1989/// { inferred-module-member* }
1990///
1991/// inferred-module-member:
1992/// 'export' '*'
1993/// 'exclude' identifier
1994void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00001995 assert(Tok.is(MMToken::Star));
1996 SourceLocation StarLoc = consumeToken();
1997 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00001998
Douglas Gregor73441092011-12-05 22:27:44 +00001999 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002000 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002001 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2002 Failed = true;
2003 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002004
2005 if (ActiveModule) {
2006 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002007 if (!Failed && ActiveModule->IsAvailable &&
2008 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002009 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2010 Failed = true;
2011 }
2012
2013 // Check for redefinition of an inferred module.
2014 if (!Failed && ActiveModule->InferSubmodules) {
2015 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2016 if (ActiveModule->InferredSubmoduleLoc.isValid())
2017 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2018 diag::note_mmap_prev_definition);
2019 Failed = true;
2020 }
2021
2022 // Check for the 'framework' keyword, which is not permitted here.
2023 if (Framework) {
2024 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2025 Framework = false;
2026 }
2027 } else if (Explicit) {
2028 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2029 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002030 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002031
Douglas Gregor73441092011-12-05 22:27:44 +00002032 // If there were any problems with this inferred submodule, skip its body.
2033 if (Failed) {
2034 if (Tok.is(MMToken::LBrace)) {
2035 consumeToken();
2036 skipUntil(MMToken::RBrace);
2037 if (Tok.is(MMToken::RBrace))
2038 consumeToken();
2039 }
2040 HadError = true;
2041 return;
2042 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002043
2044 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002045 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002046 parseOptionalAttributes(Attrs);
2047
2048 if (ActiveModule) {
2049 // Note that we have an inferred submodule.
2050 ActiveModule->InferSubmodules = true;
2051 ActiveModule->InferredSubmoduleLoc = StarLoc;
2052 ActiveModule->InferExplicitSubmodules = Explicit;
2053 } else {
2054 // We'll be inferring framework modules for this directory.
2055 Map.InferredDirectories[Directory].InferModules = true;
2056 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002057 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002058 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002059 }
2060
Douglas Gregor73441092011-12-05 22:27:44 +00002061 // Parse the opening brace.
2062 if (!Tok.is(MMToken::LBrace)) {
2063 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2064 HadError = true;
2065 return;
2066 }
2067 SourceLocation LBraceLoc = consumeToken();
2068
2069 // Parse the body of the inferred submodule.
2070 bool Done = false;
2071 do {
2072 switch (Tok.Kind) {
2073 case MMToken::EndOfFile:
2074 case MMToken::RBrace:
2075 Done = true;
2076 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002077
2078 case MMToken::ExcludeKeyword: {
2079 if (ActiveModule) {
2080 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00002081 << (ActiveModule != 0);
Douglas Gregor9194a912012-11-06 19:39:40 +00002082 consumeToken();
2083 break;
2084 }
2085
2086 consumeToken();
2087 if (!Tok.is(MMToken::Identifier)) {
2088 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2089 break;
2090 }
2091
2092 Map.InferredDirectories[Directory].ExcludedModules
2093 .push_back(Tok.getString());
2094 consumeToken();
2095 break;
2096 }
2097
2098 case MMToken::ExportKeyword:
2099 if (!ActiveModule) {
2100 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00002101 << (ActiveModule != 0);
Douglas Gregor9194a912012-11-06 19:39:40 +00002102 consumeToken();
2103 break;
2104 }
2105
Douglas Gregor73441092011-12-05 22:27:44 +00002106 consumeToken();
2107 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002108 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002109 else
2110 Diags.Report(Tok.getLocation(),
2111 diag::err_mmap_expected_export_wildcard);
2112 consumeToken();
2113 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002114
Douglas Gregor73441092011-12-05 22:27:44 +00002115 case MMToken::ExplicitKeyword:
2116 case MMToken::ModuleKeyword:
2117 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002118 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002119 case MMToken::UmbrellaKeyword:
2120 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002121 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Douglas Gregor162405d2012-11-06 19:41:11 +00002122 << (ActiveModule != 0);
Douglas Gregor73441092011-12-05 22:27:44 +00002123 consumeToken();
2124 break;
2125 }
2126 } while (!Done);
2127
2128 if (Tok.is(MMToken::RBrace))
2129 consumeToken();
2130 else {
2131 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2132 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2133 HadError = true;
2134 }
2135}
2136
Douglas Gregor9194a912012-11-06 19:39:40 +00002137/// \brief Parse optional attributes.
2138///
2139/// attributes:
2140/// attribute attributes
2141/// attribute
2142///
2143/// attribute:
2144/// [ identifier ]
2145///
2146/// \param Attrs Will be filled in with the parsed attributes.
2147///
2148/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002149bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002150 bool HadError = false;
2151
2152 while (Tok.is(MMToken::LSquare)) {
2153 // Consume the '['.
2154 SourceLocation LSquareLoc = consumeToken();
2155
2156 // Check whether we have an attribute name here.
2157 if (!Tok.is(MMToken::Identifier)) {
2158 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2159 skipUntil(MMToken::RSquare);
2160 if (Tok.is(MMToken::RSquare))
2161 consumeToken();
2162 HadError = true;
2163 }
2164
2165 // Decode the attribute name.
2166 AttributeKind Attribute
2167 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002168 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002169 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002170 .Case("system", AT_system)
2171 .Default(AT_unknown);
2172 switch (Attribute) {
2173 case AT_unknown:
2174 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2175 << Tok.getString();
2176 break;
2177
2178 case AT_system:
2179 Attrs.IsSystem = true;
2180 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002181
Richard Smith77944862014-03-02 05:58:18 +00002182 case AT_extern_c:
2183 Attrs.IsExternC = true;
2184 break;
2185
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002186 case AT_exhaustive:
2187 Attrs.IsExhaustive = true;
2188 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002189 }
2190 consumeToken();
2191
2192 // Consume the ']'.
2193 if (!Tok.is(MMToken::RSquare)) {
2194 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2195 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2196 skipUntil(MMToken::RSquare);
2197 HadError = true;
2198 }
2199
2200 if (Tok.is(MMToken::RSquare))
2201 consumeToken();
2202 }
2203
2204 return HadError;
2205}
2206
Douglas Gregor718292f2011-11-11 19:10:28 +00002207/// \brief Parse a module map file.
2208///
2209/// module-map-file:
2210/// module-declaration*
2211bool ModuleMapParser::parseModuleMapFile() {
2212 do {
2213 switch (Tok.Kind) {
2214 case MMToken::EndOfFile:
2215 return HadError;
2216
Douglas Gregore7ab3662011-12-07 02:23:45 +00002217 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002218 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002219 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002220 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002221 parseModuleDecl();
2222 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002223
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002224 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002225 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002226 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002227 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002228 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002229 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002230 case MMToken::HeaderKeyword:
2231 case MMToken::Identifier:
2232 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002233 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002234 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002235 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002236 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002237 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002238 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002239 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002240 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002241 case MMToken::StringLiteral:
2242 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002243 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002244 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2245 HadError = true;
2246 consumeToken();
2247 break;
2248 }
2249 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002250}
2251
Douglas Gregor963c5532013-06-21 16:28:10 +00002252bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002253 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2254 = ParsedModuleMap.find(File);
2255 if (Known != ParsedModuleMap.end())
2256 return Known->second;
2257
Douglas Gregor89929282012-01-30 06:01:29 +00002258 assert(Target != 0 && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002259 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2260 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002261 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002262 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002263 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002264
2265 // Find the directory for the module. For frameworks, that may require going
2266 // up from the 'Modules' directory.
2267 const DirectoryEntry *Dir = File->getDir();
2268 StringRef DirName(Dir->getName());
2269 if (llvm::sys::path::filename(DirName) == "Modules") {
2270 DirName = llvm::sys::path::parent_path(DirName);
2271 if (DirName.endswith(".framework"))
2272 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2273 assert(Dir && "parent must exist");
2274 }
Douglas Gregor718292f2011-11-11 19:10:28 +00002275
2276 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002277 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002278 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002279 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002280 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002281 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002282 return Result;
2283}