blob: c191e0199a969c431a93df8281a0fa4f4c695b5d [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");
Craig Topperd2d442c2014-05-17 23:10:59 +000045 return Module::ExportDecl(nullptr, true);
Douglas Gregorf5eedd02011-12-05 17:28:06 +000046 }
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
Craig Topperd2d442c2014-05-17 23:10:59 +000065 return nullptr;
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
Craig Topperd2d442c2014-05-17 23:10:59 +000077 return nullptr;
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),
Craig Topperd2d442c2014-05-17 23:10:59 +000090 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
91 CompilingModule(nullptr), SourceModule(nullptr) {}
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;
Craig Topperd2d442c2014-05-17 23:10:59 +0000250 Module *Private = nullptr;
251 Module *NotUsed = nullptr;
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) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000256 // If 'File' is part of 'RequestingModule' we can definitely include it.
257 if (Header.getModule() == RequestingModule)
258 return;
259
260 // Remember private headers for later printing of a diagnostic.
261 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
262 Header.getModule())) {
263 Private = Header.getModule();
264 continue;
265 }
266
267 // If uses need to be specified explicitly, we are only allowed to return
268 // modules that are explicitly used by the requesting module.
269 if (RequestingModule && LangOpts.ModulesDeclUse &&
270 !directlyUses(RequestingModule, Header.getModule())) {
271 NotUsed = Header.getModule();
272 continue;
273 }
274
275 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000276 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000277 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000278
279 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000280 }
281
282 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000283 if (Private) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000284 Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module)
285 << Filename;
286 return;
287 }
288
289 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000290 if (NotUsed) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000291 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
292 << RequestingModule->getFullModuleName() << Filename;
293 return;
294 }
295
Ben Langmuir71e1a642014-05-05 21:44:13 +0000296 if (Excluded || isHeaderInUmbrellaDirs(File))
297 return;
298
299 // At this point, only non-modular includes remain.
300
301 if (LangOpts.ModulesStrictDeclUse) {
302 Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
303 << RequestingModule->getFullModuleName() << Filename;
304 } else if (RequestingModule) {
305 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
306 diag::warn_non_modular_include_in_framework_module :
307 diag::warn_non_modular_include_in_module;
308 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000309 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000310}
311
312ModuleMap::KnownHeader
313ModuleMap::findModuleForHeader(const FileEntry *File,
Richard Smith306d8922014-10-22 23:50:56 +0000314 Module *RequestingModule,
315 bool IncludeTextualHeaders) {
Daniel Jasper92669ee2013-12-20 12:09:36 +0000316 HeadersMap::iterator Known = findKnownHeader(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000317
Richard Smith306d8922014-10-22 23:50:56 +0000318 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
319 if (!IncludeTextualHeaders && R.getRole() == ModuleMap::TextualHeader)
320 return ModuleMap::KnownHeader();
321 return R;
322 };
323
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000324 if (Known != Headers.end()) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000325 ModuleMap::KnownHeader Result = KnownHeader();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000326
Daniel Jasper97da9172013-10-22 08:09:47 +0000327 // Iterate over all modules that 'File' is part of to find the best fit.
328 for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
329 E = Known->second.end();
330 I != E; ++I) {
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000331 // Cannot use a module if it is unavailable.
332 if (!I->getModule()->isAvailable())
Daniel Jasper97da9172013-10-22 08:09:47 +0000333 continue;
334
335 // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
336 // module we are looking for.
337 if (I->getModule() == RequestingModule)
Richard Smith306d8922014-10-22 23:50:56 +0000338 return MakeResult(*I);
Daniel Jasper97da9172013-10-22 08:09:47 +0000339
340 // If uses need to be specified explicitly, we are only allowed to return
341 // modules that are explicitly used by the requesting module.
342 if (RequestingModule && LangOpts.ModulesDeclUse &&
Daniel Jasper92669ee2013-12-20 12:09:36 +0000343 !directlyUses(RequestingModule, I->getModule()))
Daniel Jasper97da9172013-10-22 08:09:47 +0000344 continue;
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000345
Daniel Jasper97da9172013-10-22 08:09:47 +0000346 Result = *I;
347 // If 'File' is a public header of this module, this is as good as we
348 // are going to get.
Richard Smith8c71eba2014-03-05 20:51:45 +0000349 // FIXME: If we have a RequestingModule, we should prefer the header from
350 // that module.
Richard Smith306d8922014-10-22 23:50:56 +0000351 if (I->getRole() == ModuleMap::NormalHeader ||
352 I->getRole() == ModuleMap::TextualHeader)
Daniel Jasper97da9172013-10-22 08:09:47 +0000353 break;
354 }
Richard Smith306d8922014-10-22 23:50:56 +0000355 return MakeResult(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) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000370 const FileEntry *UmbrellaModuleMap =
371 getModuleMapFileForUniquing(UmbrellaModule);
372
Ben Langmuir44691382014-04-10 00:39:10 +0000373 // Infer submodules for each of the directories we found between
374 // the directory of the umbrella header and the directory where
375 // the actual header is located.
376 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000377
Ben Langmuir44691382014-04-10 00:39:10 +0000378 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
379 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000380 SmallString<32> NameBuf;
381 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000382 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000383 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
384 Explicit).first;
385 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000386 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000387
388 // Associate the module and the directory.
389 UmbrellaDirs[SkippedDirs[I-1]] = Result;
390
391 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000392 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000393 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000394 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000395 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000396
Ben Langmuir44691382014-04-10 00:39:10 +0000397 // Infer a submodule with the same name as this header file.
398 SmallString<32> NameBuf;
399 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000400 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000401 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
402 Explicit).first;
403 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000404 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000405 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000406
Ben Langmuir44691382014-04-10 00:39:10 +0000407 // If inferred submodules export everything they import, add a
408 // wildcard to the set of exports.
409 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000410 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000411 } else {
412 // Record each of the directories we stepped through as being part of
413 // the module we found, since the umbrella header covers them all.
414 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
415 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000416 }
Ben Langmuir44691382014-04-10 00:39:10 +0000417
418 Headers[File].push_back(KnownHeader(Result, NormalHeader));
419
420 // If a header corresponds to an unavailable module, don't report
421 // that it maps to anything.
422 if (!Result->isAvailable())
423 return KnownHeader();
424
Richard Smith306d8922014-10-22 23:50:56 +0000425 return MakeResult(Headers[File].back());
Ben Langmuir44691382014-04-10 00:39:10 +0000426 }
Richard Smith306d8922014-10-22 23:50:56 +0000427
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000428 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000429}
430
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000431bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000432 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000433}
434
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000435bool
436ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
437 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000438 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000439 if (Known != Headers.end()) {
440 for (SmallVectorImpl<KnownHeader>::const_iterator
441 I = Known->second.begin(),
442 E = Known->second.end();
443 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000444 if (I->isAvailable() && (!RequestingModule ||
445 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000446 return false;
447 }
448 return true;
449 }
Richard Smith50996ce2014-04-08 13:13:04 +0000450
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000451 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000452 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000453 StringRef DirName = Dir->getName();
454
Richard Smith50996ce2014-04-08 13:13:04 +0000455 auto IsUnavailable = [&](const Module *M) {
456 return !M->isAvailable() && (!RequestingModule ||
457 M->isSubModuleOf(RequestingModule));
458 };
459
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000460 // Keep walking up the directory hierarchy, looking for a directory with
461 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000462 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000463 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000464 = UmbrellaDirs.find(Dir);
465 if (KnownDir != UmbrellaDirs.end()) {
466 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000467 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000468 return true;
469
470 // Search up the module stack until we find a module with an umbrella
471 // directory.
472 Module *UmbrellaModule = Found;
473 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
474 UmbrellaModule = UmbrellaModule->Parent;
475
476 if (UmbrellaModule->InferSubmodules) {
477 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
478 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000479 SmallString<32> NameBuf;
480 StringRef Name = sanitizeFilenameAsIdentifier(
481 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
482 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000483 Found = lookupModuleQualified(Name, Found);
484 if (!Found)
485 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000486 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000487 return true;
488 }
489
490 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000491 SmallString<32> NameBuf;
492 StringRef Name = sanitizeFilenameAsIdentifier(
493 llvm::sys::path::stem(Header->getName()),
494 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000495 Found = lookupModuleQualified(Name, Found);
496 if (!Found)
497 return false;
498 }
499
Richard Smith50996ce2014-04-08 13:13:04 +0000500 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000501 }
502
503 SkippedDirs.push_back(Dir);
504
505 // Retrieve our parent path.
506 DirName = llvm::sys::path::parent_path(DirName);
507 if (DirName.empty())
508 break;
509
510 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000511 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000512 } while (Dir);
513
514 return false;
515}
516
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000517Module *ModuleMap::findModule(StringRef Name) const {
518 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000519 if (Known != Modules.end())
520 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000521
522 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000523}
524
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000525Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
526 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000527 for(; Context; Context = Context->Parent) {
528 if (Module *Sub = lookupModuleQualified(Name, Context))
529 return Sub;
530 }
531
532 return findModule(Name);
533}
534
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000535Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000536 if (!Context)
537 return findModule(Name);
538
Douglas Gregoreb90e832012-01-04 23:32:19 +0000539 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000540}
541
Douglas Gregorde3ef502011-11-30 23:21:26 +0000542std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000543ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000544 bool IsExplicit) {
545 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000546 if (Module *Sub = lookupModuleQualified(Name, Parent))
547 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000548
549 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000550 Module *Result = new Module(Name, SourceLocation(), Parent,
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000551 IsFramework, IsExplicit);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000552 if (LangOpts.CurrentModule == Name) {
553 SourceModule = Result;
554 SourceModuleName = Name;
555 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000556 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000557 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000558 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
559 Name == LangOpts.CurrentModule) {
560 CompilingModule = Result;
561 }
562 }
Douglas Gregor69021972011-11-30 17:33:56 +0000563 return std::make_pair(Result, true);
564}
565
Douglas Gregor9194a912012-11-06 19:39:40 +0000566bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000567 StringRef Name, bool &IsSystem) const {
Douglas Gregor9194a912012-11-06 19:39:40 +0000568 // Check whether we have already looked into the parent directory
569 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000570 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000571 inferred = InferredDirectories.find(ParentDir);
572 if (inferred == InferredDirectories.end())
573 return false;
574
575 if (!inferred->second.InferModules)
576 return false;
577
578 // We're allowed to infer for this directory, but make sure it's okay
579 // to infer this particular module.
580 bool canInfer = std::find(inferred->second.ExcludedModules.begin(),
581 inferred->second.ExcludedModules.end(),
582 Name) == inferred->second.ExcludedModules.end();
583
584 if (canInfer && inferred->second.InferSystemModules)
585 IsSystem = true;
586
587 return canInfer;
588}
589
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000590/// \brief For a framework module, infer the framework against which we
591/// should link.
592static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
593 FileManager &FileMgr) {
594 assert(Mod->IsFramework && "Can only infer linking for framework modules");
595 assert(!Mod->isSubFramework() &&
596 "Can only infer linking for top-level frameworks");
597
598 SmallString<128> LibName;
599 LibName += FrameworkDir->getName();
600 llvm::sys::path::append(LibName, Mod->Name);
601 if (FileMgr.getFile(LibName)) {
602 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
603 /*IsFramework=*/true));
604 }
605}
606
Douglas Gregorde3ef502011-11-30 23:21:26 +0000607Module *
Douglas Gregor9194a912012-11-06 19:39:40 +0000608ModuleMap::inferFrameworkModule(StringRef ModuleName,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000609 const DirectoryEntry *FrameworkDir,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000610 bool IsSystem,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000611 Module *Parent) {
Douglas Gregor56c64012011-11-17 01:41:17 +0000612 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000613 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
614 return Mod;
615
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000616 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000617
618 // If the framework has a parent path from which we're allowed to infer
619 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000620 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000621 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000622 // Determine whether we're allowed to infer a module map.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000623
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000624 // Note: as an egregious but useful hack we use the real path here, because
625 // we might be looking at an embedded framework that symlinks out to a
626 // top-level framework, and we need to infer as if we were naming the
627 // top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000628 StringRef FrameworkDirName
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000629 = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000630
Ben Langmuir6b7f7342014-07-14 19:45:12 +0000631 // In case this is a case-insensitive filesystem, make sure the canonical
632 // directory name matches ModuleName exactly. Modules are case-sensitive.
633 // FIXME: we should be able to give a fix-it hint for the correct spelling.
634 if (llvm::sys::path::stem(FrameworkDirName) != ModuleName)
635 return nullptr;
636
Douglas Gregor9194a912012-11-06 19:39:40 +0000637 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000638 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000639 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000640 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000641 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
642 // Check whether we have already looked into the parent directory
643 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000644 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000645 inferred = InferredDirectories.find(ParentDir);
646 if (inferred == InferredDirectories.end()) {
647 // We haven't looked here before. Load a module map, if there is
648 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000649 bool IsFrameworkDir = Parent.endswith(".framework");
650 if (const FileEntry *ModMapFile =
651 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Douglas Gregor963c5532013-06-21 16:28:10 +0000652 parseModuleMapFile(ModMapFile, IsSystem);
Douglas Gregor9194a912012-11-06 19:39:40 +0000653 inferred = InferredDirectories.find(ParentDir);
654 }
655
656 if (inferred == InferredDirectories.end())
657 inferred = InferredDirectories.insert(
658 std::make_pair(ParentDir, InferredDirectory())).first;
659 }
660
661 if (inferred->second.InferModules) {
662 // We're allowed to infer for this directory, but make sure it's okay
663 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000664 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000665 canInfer = std::find(inferred->second.ExcludedModules.begin(),
666 inferred->second.ExcludedModules.end(),
667 Name) == inferred->second.ExcludedModules.end();
668
669 if (inferred->second.InferSystemModules)
670 IsSystem = true;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000671 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000672 }
673 }
674 }
675
676 // If we're not allowed to infer a framework module, don't.
677 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000678 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000679 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000680 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000681
682
Douglas Gregor56c64012011-11-17 01:41:17 +0000683 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000684 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000685 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000686 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000687
688 // FIXME: If there's no umbrella header, we could probably scan the
689 // framework to load *everything*. But, it's not clear that this is a good
690 // idea.
691 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000692 return nullptr;
693
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000694 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Douglas Gregore89dbc12011-12-06 19:39:29 +0000695 /*IsFramework=*/true, /*IsExplicit=*/false);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000696 InferredModuleAllowedBy[Result] = ModuleMapFile;
697 Result->IsInferred = true;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000698 if (LangOpts.CurrentModule == ModuleName) {
699 SourceModule = Result;
700 SourceModuleName = ModuleName;
701 }
Douglas Gregora686e1b2012-01-27 19:52:33 +0000702 if (IsSystem)
703 Result->IsSystem = IsSystem;
704
Douglas Gregoreb90e832012-01-04 23:32:19 +0000705 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000706 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000707
Douglas Gregor322f6332011-12-08 18:00:48 +0000708 // umbrella header "umbrella-header-name"
Douglas Gregor73141fa2011-12-08 17:39:04 +0000709 Result->Umbrella = UmbrellaHeader;
Daniel Jasper97da9172013-10-22 08:09:47 +0000710 Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
Douglas Gregor4dc71832011-12-12 23:55:05 +0000711 UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
Douglas Gregord8bd7532011-12-05 17:40:25 +0000712
713 // export *
Craig Topperd2d442c2014-05-17 23:10:59 +0000714 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
715
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000716 // module * { export * }
717 Result->InferSubmodules = true;
718 Result->InferExportWildcard = true;
719
Douglas Gregore89dbc12011-12-06 19:39:29 +0000720 // Look for subframeworks.
Rafael Espindolac0809172014-06-12 14:02:15 +0000721 std::error_code EC;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000722 SmallString<128> SubframeworksDirName
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000723 = StringRef(FrameworkDir->getName());
Douglas Gregore89dbc12011-12-06 19:39:29 +0000724 llvm::sys::path::append(SubframeworksDirName, "Frameworks");
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000725 llvm::sys::path::native(SubframeworksDirName);
Douglas Gregorddaa69c2011-12-08 16:13:24 +0000726 for (llvm::sys::fs::directory_iterator
Benjamin Kramer2d4d8cb2013-09-11 11:23:15 +0000727 Dir(SubframeworksDirName.str(), EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000728 Dir != DirEnd && !EC; Dir.increment(EC)) {
729 if (!StringRef(Dir->path()).endswith(".framework"))
730 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000731
Douglas Gregore89dbc12011-12-06 19:39:29 +0000732 if (const DirectoryEntry *SubframeworkDir
733 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000734 // Note: as an egregious but useful hack, we use the real path here and
735 // check whether it is actually a subdirectory of the parent directory.
736 // This will not be the case if the 'subframework' is actually a symlink
737 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000738 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
739 bool FoundParent = false;
740 do {
741 // Get the parent directory name.
742 SubframeworkDirName
743 = llvm::sys::path::parent_path(SubframeworkDirName);
744 if (SubframeworkDirName.empty())
745 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000746
Douglas Gregore00c8b22013-01-26 00:55:12 +0000747 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
748 FoundParent = true;
749 break;
750 }
751 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000752
Douglas Gregore00c8b22013-01-26 00:55:12 +0000753 if (!FoundParent)
754 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000755
Douglas Gregore89dbc12011-12-06 19:39:29 +0000756 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Douglas Gregor056396a2012-10-12 21:15:50 +0000757 SmallString<32> NameBuf;
758 inferFrameworkModule(sanitizeFilenameAsIdentifier(
759 llvm::sys::path::stem(Dir->path()), NameBuf),
760 SubframeworkDir, IsSystem, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000761 }
762 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000763
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000764 // If the module is a top-level framework, automatically link against the
765 // framework.
766 if (!Result->isSubFramework()) {
767 inferFrameworkLink(Result, FrameworkDir, FileMgr);
768 }
769
Douglas Gregor56c64012011-11-17 01:41:17 +0000770 return Result;
771}
772
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000773void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
Daniel Jasper97da9172013-10-22 08:09:47 +0000774 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000775 Mod->Umbrella = UmbrellaHeader;
Douglas Gregor70331272011-12-09 02:04:43 +0000776 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000777}
778
Douglas Gregor524e33e2011-12-08 19:11:24 +0000779void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
780 Mod->Umbrella = UmbrellaDir;
781 UmbrellaDirs[UmbrellaDir] = Mod;
782}
783
Douglas Gregor59527662012-10-15 06:28:11 +0000784void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000785 ModuleHeaderRole Role) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000786 if (Role == TextualHeader) {
Richard Smith306d8922014-10-22 23:50:56 +0000787 Mod->TextualHeaders.push_back(Header);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000788 } else {
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000789 if (Role == PrivateHeader)
790 Mod->PrivateHeaders.push_back(Header);
791 else
792 Mod->NormalHeaders.push_back(Header);
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000793 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000794 HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +0000795 }
Daniel Jasper97da9172013-10-22 08:09:47 +0000796 Headers[Header].push_back(KnownHeader(Mod, Role));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000797}
798
Richard Smithfeb54b62014-10-23 02:01:19 +0000799void ModuleMap::excludeHeader(Module *Mod, const FileEntry *Header) {
800 Mod->ExcludedHeaders.push_back(Header);
801
802 // Add this as a known header so we won't implicitly add it to any
803 // umbrella directory module.
804 // FIXME: Should we only exclude it from umbrella modules within the
805 // specified module?
806 (void) Headers[Header];
807}
808
Douglas Gregor514b6362011-11-29 19:06:37 +0000809const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000810ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000811 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000812 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000813
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000814 return SourceMgr.getFileEntryForID(
815 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000816}
817
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000818const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000819 if (M->IsInferred) {
820 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
821 return InferredModuleAllowedBy.find(M)->second;
822 }
823 return getContainingModuleMapFile(M);
824}
825
826void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
827 assert(M->IsInferred && "module not inferred");
828 InferredModuleAllowedBy[M] = ModMap;
829}
830
Douglas Gregor718292f2011-11-11 19:10:28 +0000831void ModuleMap::dump() {
832 llvm::errs() << "Modules:";
833 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
834 MEnd = Modules.end();
835 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000836 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000837
838 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000839 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000840 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000841 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
842 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
843 E = H->second.end();
844 I != E; ++I) {
845 if (I != H->second.begin())
846 llvm::errs() << ",";
847 llvm::errs() << I->getModule()->getFullModuleName();
848 }
849 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000850 }
851}
852
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000853bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
854 bool HadError = false;
855 for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
856 Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
857 Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000858 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000859 Mod->Exports.push_back(Export);
860 else
861 HadError = true;
862 }
863 Mod->UnresolvedExports.clear();
864 return HadError;
865}
866
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000867bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
868 bool HadError = false;
869 for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
870 Module *DirectUse =
871 resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
872 if (DirectUse)
873 Mod->DirectUses.push_back(DirectUse);
874 else
875 HadError = true;
876 }
877 Mod->UnresolvedDirectUses.clear();
878 return HadError;
879}
880
Douglas Gregorfb912652013-03-20 21:10:35 +0000881bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
882 bool HadError = false;
883 for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
884 Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
885 Mod, Complain);
886 if (!OtherMod) {
887 HadError = true;
888 continue;
889 }
890
891 Module::Conflict Conflict;
892 Conflict.Other = OtherMod;
893 Conflict.Message = Mod->UnresolvedConflicts[I].Message;
894 Mod->Conflicts.push_back(Conflict);
895 }
896 Mod->UnresolvedConflicts.clear();
897 return HadError;
898}
899
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000900Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
901 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000902 return nullptr;
903
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000904 // Use the expansion location to determine which module we're in.
905 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
906 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000907 return nullptr;
908
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000909 const SourceManager &SrcMgr = Loc.getManager();
910 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000911
Douglas Gregor224d8a72012-01-06 17:19:32 +0000912 while (const FileEntry *ExpansionFile
913 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
914 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000915 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000916 return Mod;
917
918 // No module owns this header, so look up the inclusion chain to see if
919 // any included header has an associated module.
920 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
921 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000922 return nullptr;
923
Douglas Gregor224d8a72012-01-06 17:19:32 +0000924 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
925 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000926
927 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000928}
929
Douglas Gregor718292f2011-11-11 19:10:28 +0000930//----------------------------------------------------------------------------//
931// Module map file parser
932//----------------------------------------------------------------------------//
933
934namespace clang {
935 /// \brief A token in a module map file.
936 struct MMToken {
937 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000938 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000939 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000940 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000941 EndOfFile,
942 HeaderKeyword,
943 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000944 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000945 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000946 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000947 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000948 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000949 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000950 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000951 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000952 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000953 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000954 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000955 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000956 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000957 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000958 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000959 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000960 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000961 RBrace,
962 LSquare,
963 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000964 } Kind;
965
966 unsigned Location;
967 unsigned StringLength;
968 const char *StringData;
969
970 void clear() {
971 Kind = EndOfFile;
972 Location = 0;
973 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000974 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000975 }
976
977 bool is(TokenKind K) const { return Kind == K; }
978
979 SourceLocation getLocation() const {
980 return SourceLocation::getFromRawEncoding(Location);
981 }
982
983 StringRef getString() const {
984 return StringRef(StringData, StringLength);
985 }
986 };
Douglas Gregor9194a912012-11-06 19:39:40 +0000987
988 /// \brief The set of attributes that can be attached to a module.
Bill Wendling44426052012-12-20 19:22:21 +0000989 struct Attributes {
Richard Smith77944862014-03-02 05:58:18 +0000990 Attributes() : IsSystem(), IsExternC(), IsExhaustive() { }
Douglas Gregor9194a912012-11-06 19:39:40 +0000991
992 /// \brief Whether this is a system module.
993 unsigned IsSystem : 1;
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000994
Richard Smith77944862014-03-02 05:58:18 +0000995 /// \brief Whether this is an extern "C" module.
996 unsigned IsExternC : 1;
997
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000998 /// \brief Whether this is an exhaustive set of configuration macros.
999 unsigned IsExhaustive : 1;
Douglas Gregor9194a912012-11-06 19:39:40 +00001000 };
Douglas Gregor718292f2011-11-11 19:10:28 +00001001
Douglas Gregor9194a912012-11-06 19:39:40 +00001002
Douglas Gregor718292f2011-11-11 19:10:28 +00001003 class ModuleMapParser {
1004 Lexer &L;
1005 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001006
1007 /// \brief Default target information, used only for string literal
1008 /// parsing.
1009 const TargetInfo *Target;
1010
Douglas Gregor718292f2011-11-11 19:10:28 +00001011 DiagnosticsEngine &Diags;
1012 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001013
1014 /// \brief The current module map file.
1015 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001016
Douglas Gregor5257fc62011-11-11 21:55:48 +00001017 /// \brief The directory that this module map resides in.
1018 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001019
1020 /// \brief The directory containing Clang-supplied headers.
1021 const DirectoryEntry *BuiltinIncludeDir;
1022
Douglas Gregor963c5532013-06-21 16:28:10 +00001023 /// \brief Whether this module map is in a system header directory.
1024 bool IsSystem;
1025
Douglas Gregor718292f2011-11-11 19:10:28 +00001026 /// \brief Whether an error occurred.
1027 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001028
Douglas Gregor718292f2011-11-11 19:10:28 +00001029 /// \brief Stores string data for the various string literals referenced
1030 /// during parsing.
1031 llvm::BumpPtrAllocator StringData;
1032
1033 /// \brief The current token.
1034 MMToken Tok;
1035
1036 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001037 Module *ActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001038
1039 /// \brief Consume the current token and return its location.
1040 SourceLocation consumeToken();
1041
1042 /// \brief Skip tokens until we reach the a token with the given kind
1043 /// (or the end of the file).
1044 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001045
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001046 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001047 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001048 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001049 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001050 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001051 void parseHeaderDecl(clang::MMToken::TokenKind,
1052 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001053 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001054 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001055 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001056 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001057 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001058 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001059 void parseInferredModuleDecl(bool Framework, bool Explicit);
Bill Wendling44426052012-12-20 19:22:21 +00001060 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001061
Douglas Gregor718292f2011-11-11 19:10:28 +00001062 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001063 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001064 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001065 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001066 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001067 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001068 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001069 const DirectoryEntry *BuiltinIncludeDir,
1070 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001071 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001072 ModuleMapFile(ModuleMapFile), Directory(Directory),
1073 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001074 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001075 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001076 Tok.clear();
1077 consumeToken();
1078 }
1079
1080 bool parseModuleMapFile();
1081 };
1082}
1083
1084SourceLocation ModuleMapParser::consumeToken() {
1085retry:
1086 SourceLocation Result = Tok.getLocation();
1087 Tok.clear();
1088
1089 Token LToken;
1090 L.LexFromRawLexer(LToken);
1091 Tok.Location = LToken.getLocation().getRawEncoding();
1092 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001093 case tok::raw_identifier: {
1094 StringRef RI = LToken.getRawIdentifier();
1095 Tok.StringData = RI.data();
1096 Tok.StringLength = RI.size();
1097 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001098 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001099 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001100 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001101 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001102 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001103 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001104 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001105 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001106 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001107 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001108 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001109 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001110 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001111 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001112 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001113 .Default(MMToken::Identifier);
1114 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001115 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001116
1117 case tok::comma:
1118 Tok.Kind = MMToken::Comma;
1119 break;
1120
Douglas Gregor718292f2011-11-11 19:10:28 +00001121 case tok::eof:
1122 Tok.Kind = MMToken::EndOfFile;
1123 break;
1124
1125 case tok::l_brace:
1126 Tok.Kind = MMToken::LBrace;
1127 break;
1128
Douglas Gregora686e1b2012-01-27 19:52:33 +00001129 case tok::l_square:
1130 Tok.Kind = MMToken::LSquare;
1131 break;
1132
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001133 case tok::period:
1134 Tok.Kind = MMToken::Period;
1135 break;
1136
Douglas Gregor718292f2011-11-11 19:10:28 +00001137 case tok::r_brace:
1138 Tok.Kind = MMToken::RBrace;
1139 break;
1140
Douglas Gregora686e1b2012-01-27 19:52:33 +00001141 case tok::r_square:
1142 Tok.Kind = MMToken::RSquare;
1143 break;
1144
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001145 case tok::star:
1146 Tok.Kind = MMToken::Star;
1147 break;
1148
Richard Smitha3feee22013-10-28 22:18:19 +00001149 case tok::exclaim:
1150 Tok.Kind = MMToken::Exclaim;
1151 break;
1152
Douglas Gregor718292f2011-11-11 19:10:28 +00001153 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001154 if (LToken.hasUDSuffix()) {
1155 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1156 HadError = true;
1157 goto retry;
1158 }
1159
Douglas Gregor718292f2011-11-11 19:10:28 +00001160 // Parse the string literal.
1161 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001162 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001163 if (StringLiteral.hadError)
1164 goto retry;
1165
1166 // Copy the string literal into our string data allocator.
1167 unsigned Length = StringLiteral.GetStringLength();
1168 char *Saved = StringData.Allocate<char>(Length + 1);
1169 memcpy(Saved, StringLiteral.GetString().data(), Length);
1170 Saved[Length] = 0;
1171
1172 // Form the token.
1173 Tok.Kind = MMToken::StringLiteral;
1174 Tok.StringData = Saved;
1175 Tok.StringLength = Length;
1176 break;
1177 }
1178
1179 case tok::comment:
1180 goto retry;
1181
1182 default:
1183 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1184 HadError = true;
1185 goto retry;
1186 }
1187
1188 return Result;
1189}
1190
1191void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1192 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001193 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001194 do {
1195 switch (Tok.Kind) {
1196 case MMToken::EndOfFile:
1197 return;
1198
1199 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001200 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001201 return;
1202
1203 ++braceDepth;
1204 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001205
1206 case MMToken::LSquare:
1207 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1208 return;
1209
1210 ++squareDepth;
1211 break;
1212
Douglas Gregor718292f2011-11-11 19:10:28 +00001213 case MMToken::RBrace:
1214 if (braceDepth > 0)
1215 --braceDepth;
1216 else if (Tok.is(K))
1217 return;
1218 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001219
1220 case MMToken::RSquare:
1221 if (squareDepth > 0)
1222 --squareDepth;
1223 else if (Tok.is(K))
1224 return;
1225 break;
1226
Douglas Gregor718292f2011-11-11 19:10:28 +00001227 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001228 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001229 return;
1230 break;
1231 }
1232
1233 consumeToken();
1234 } while (true);
1235}
1236
Douglas Gregore7ab3662011-12-07 02:23:45 +00001237/// \brief Parse a module-id.
1238///
1239/// module-id:
1240/// identifier
1241/// identifier '.' module-id
1242///
1243/// \returns true if an error occurred, false otherwise.
1244bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1245 Id.clear();
1246 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001247 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001248 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1249 consumeToken();
1250 } else {
1251 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1252 return true;
1253 }
1254
1255 if (!Tok.is(MMToken::Period))
1256 break;
1257
1258 consumeToken();
1259 } while (true);
1260
1261 return false;
1262}
1263
Douglas Gregora686e1b2012-01-27 19:52:33 +00001264namespace {
1265 /// \brief Enumerates the known attributes.
1266 enum AttributeKind {
1267 /// \brief An unknown attribute.
1268 AT_unknown,
1269 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001270 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001271 /// \brief The 'extern_c' attribute.
1272 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001273 /// \brief The 'exhaustive' attribute.
1274 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001275 };
1276}
1277
Douglas Gregor718292f2011-11-11 19:10:28 +00001278/// \brief Parse a module declaration.
1279///
1280/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001281/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001282/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1283/// { module-member* }
1284///
Douglas Gregor718292f2011-11-11 19:10:28 +00001285/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001286/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001287/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001288/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001289/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001290/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001291///
1292/// submodule-declaration:
1293/// module-declaration
1294/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001295void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001296 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001297 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1298 if (Tok.is(MMToken::ExternKeyword)) {
1299 parseExternModuleDecl();
1300 return;
1301 }
1302
Douglas Gregorf2161a72011-12-06 17:16:41 +00001303 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001304 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001305 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001306 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001307
Douglas Gregorf2161a72011-12-06 17:16:41 +00001308 // Parse 'explicit' keyword, if present.
1309 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001310 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001311 Explicit = true;
1312 }
1313
1314 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001315 if (Tok.is(MMToken::FrameworkKeyword)) {
1316 consumeToken();
1317 Framework = true;
1318 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001319
1320 // Parse 'module' keyword.
1321 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001322 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001323 consumeToken();
1324 HadError = true;
1325 return;
1326 }
1327 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001328
1329 // If we have a wildcard for the module name, this is an inferred submodule.
1330 // Parse it.
1331 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001332 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001333
1334 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001335 ModuleId Id;
1336 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001337 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001338 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001339 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001340
Douglas Gregore7ab3662011-12-07 02:23:45 +00001341 if (ActiveModule) {
1342 if (Id.size() > 1) {
1343 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1344 << SourceRange(Id.front().second, Id.back().second);
1345
1346 HadError = true;
1347 return;
1348 }
1349 } else if (Id.size() == 1 && Explicit) {
1350 // Top-level modules can't be explicit.
1351 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1352 Explicit = false;
1353 ExplicitLoc = SourceLocation();
1354 HadError = true;
1355 }
1356
1357 Module *PreviousActiveModule = ActiveModule;
1358 if (Id.size() > 1) {
1359 // This module map defines a submodule. Go find the module of which it
1360 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001361 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001362 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001363 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1364 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001365 if (I == 0)
1366 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001367 ActiveModule = Next;
1368 continue;
1369 }
1370
1371 if (ActiveModule) {
1372 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001373 << Id[I].first
1374 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001375 } else {
1376 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1377 }
1378 HadError = true;
1379 return;
1380 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001381
1382 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1383 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1384 "submodule defined in same file as 'module *' that allowed its "
1385 "top-level module");
1386 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1387 }
1388 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001389
1390 StringRef ModuleName = Id.back().first;
1391 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001392
Douglas Gregora686e1b2012-01-27 19:52:33 +00001393 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001394 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001395 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001396
Douglas Gregor718292f2011-11-11 19:10:28 +00001397 // Parse the opening brace.
1398 if (!Tok.is(MMToken::LBrace)) {
1399 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1400 << ModuleName;
1401 HadError = true;
1402 return;
1403 }
1404 SourceLocation LBraceLoc = consumeToken();
1405
1406 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001407 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001408 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1409 // Skip the module definition.
1410 skipUntil(MMToken::RBrace);
1411 if (Tok.is(MMToken::RBrace))
1412 consumeToken();
1413 else {
1414 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1415 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1416 HadError = true;
1417 }
1418 return;
1419 }
1420
Douglas Gregor718292f2011-11-11 19:10:28 +00001421 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1422 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001423 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001424
1425 // Skip the module definition.
1426 skipUntil(MMToken::RBrace);
1427 if (Tok.is(MMToken::RBrace))
1428 consumeToken();
1429
1430 HadError = true;
1431 return;
1432 }
1433
1434 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001435 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1436 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001437 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001438 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001439 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001440 if (Attrs.IsExternC)
1441 ActiveModule->IsExternC = true;
1442
Douglas Gregor718292f2011-11-11 19:10:28 +00001443 bool Done = false;
1444 do {
1445 switch (Tok.Kind) {
1446 case MMToken::EndOfFile:
1447 case MMToken::RBrace:
1448 Done = true;
1449 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001450
1451 case MMToken::ConfigMacros:
1452 parseConfigMacros();
1453 break;
1454
Douglas Gregorfb912652013-03-20 21:10:35 +00001455 case MMToken::Conflict:
1456 parseConflict();
1457 break;
1458
Douglas Gregor718292f2011-11-11 19:10:28 +00001459 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001460 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001461 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001462 case MMToken::ModuleKeyword:
1463 parseModuleDecl();
1464 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001465
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001466 case MMToken::ExportKeyword:
1467 parseExportDecl();
1468 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001469
1470 case MMToken::UseKeyword:
1471 parseUseDecl();
1472 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001473
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001474 case MMToken::RequiresKeyword:
1475 parseRequiresDecl();
1476 break;
1477
Richard Smith306d8922014-10-22 23:50:56 +00001478 case MMToken::TextualKeyword: {
1479 SourceLocation TextualLoc = consumeToken();
1480 if (Tok.is(MMToken::HeaderKeyword)) {
1481 parseHeaderDecl(MMToken::TextualKeyword, TextualLoc);
1482 } else {
1483 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1484 << "textual";
1485 }
1486 break;
1487 }
1488
Douglas Gregor524e33e2011-12-08 19:11:24 +00001489 case MMToken::UmbrellaKeyword: {
1490 SourceLocation UmbrellaLoc = consumeToken();
1491 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001492 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001493 else
1494 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001495 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001496 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001497
Douglas Gregor59527662012-10-15 06:28:11 +00001498 case MMToken::ExcludeKeyword: {
1499 SourceLocation ExcludeLoc = consumeToken();
1500 if (Tok.is(MMToken::HeaderKeyword)) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001501 parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
Douglas Gregor59527662012-10-15 06:28:11 +00001502 } else {
1503 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1504 << "exclude";
1505 }
1506 break;
1507 }
1508
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001509 case MMToken::PrivateKeyword: {
1510 SourceLocation PrivateLoc = consumeToken();
1511 if (Tok.is(MMToken::HeaderKeyword)) {
1512 parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
1513 } else {
1514 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1515 << "private";
1516 }
1517 break;
1518 }
1519
Douglas Gregor322f6332011-12-08 18:00:48 +00001520 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001521 parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
Douglas Gregor718292f2011-11-11 19:10:28 +00001522 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001523
1524 case MMToken::LinkKeyword:
1525 parseLinkDecl();
1526 break;
1527
Douglas Gregor718292f2011-11-11 19:10:28 +00001528 default:
1529 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1530 consumeToken();
1531 break;
1532 }
1533 } while (!Done);
1534
1535 if (Tok.is(MMToken::RBrace))
1536 consumeToken();
1537 else {
1538 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1539 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1540 HadError = true;
1541 }
1542
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001543 // If the active module is a top-level framework, and there are no link
1544 // libraries, automatically link against the framework.
1545 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1546 ActiveModule->LinkLibraries.empty()) {
1547 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1548 }
1549
Ben Langmuirec8c9752014-04-18 22:07:31 +00001550 // If the module meets all requirements but is still unavailable, mark the
1551 // whole tree as unavailable to prevent it from building.
1552 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1553 ActiveModule->Parent) {
1554 ActiveModule->getTopLevelModule()->markUnavailable();
1555 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1556 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1557 }
1558
Douglas Gregore7ab3662011-12-07 02:23:45 +00001559 // We're done parsing this module. Pop back to the previous module.
1560 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001561}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001562
Daniel Jasper97292842013-09-11 07:20:44 +00001563/// \brief Parse an extern module declaration.
1564///
1565/// extern module-declaration:
1566/// 'extern' 'module' module-id string-literal
1567void ModuleMapParser::parseExternModuleDecl() {
1568 assert(Tok.is(MMToken::ExternKeyword));
1569 consumeToken(); // 'extern' keyword
1570
1571 // Parse 'module' keyword.
1572 if (!Tok.is(MMToken::ModuleKeyword)) {
1573 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1574 consumeToken();
1575 HadError = true;
1576 return;
1577 }
1578 consumeToken(); // 'module' keyword
1579
1580 // Parse the module name.
1581 ModuleId Id;
1582 if (parseModuleId(Id)) {
1583 HadError = true;
1584 return;
1585 }
1586
1587 // Parse the referenced module map file name.
1588 if (!Tok.is(MMToken::StringLiteral)) {
1589 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1590 HadError = true;
1591 return;
1592 }
1593 std::string FileName = Tok.getString();
1594 consumeToken(); // filename
1595
1596 StringRef FileNameRef = FileName;
1597 SmallString<128> ModuleMapFileName;
1598 if (llvm::sys::path::is_relative(FileNameRef)) {
1599 ModuleMapFileName += Directory->getName();
1600 llvm::sys::path::append(ModuleMapFileName, FileName);
1601 FileNameRef = ModuleMapFileName.str();
1602 }
1603 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
1604 Map.parseModuleMapFile(File, /*IsSystem=*/false);
1605}
1606
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001607/// \brief Parse a requires declaration.
1608///
1609/// requires-declaration:
1610/// 'requires' feature-list
1611///
1612/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001613/// feature ',' feature-list
1614/// feature
1615///
1616/// feature:
1617/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001618void ModuleMapParser::parseRequiresDecl() {
1619 assert(Tok.is(MMToken::RequiresKeyword));
1620
1621 // Parse 'requires' keyword.
1622 consumeToken();
1623
1624 // Parse the feature-list.
1625 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001626 bool RequiredState = true;
1627 if (Tok.is(MMToken::Exclaim)) {
1628 RequiredState = false;
1629 consumeToken();
1630 }
1631
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001632 if (!Tok.is(MMToken::Identifier)) {
1633 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1634 HadError = true;
1635 return;
1636 }
1637
1638 // Consume the feature name.
1639 std::string Feature = Tok.getString();
1640 consumeToken();
1641
1642 // Add this feature.
Richard Smitha3feee22013-10-28 22:18:19 +00001643 ActiveModule->addRequirement(Feature, RequiredState,
1644 Map.LangOpts, *Map.Target);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001645
1646 if (!Tok.is(MMToken::Comma))
1647 break;
1648
1649 // Consume the comma.
1650 consumeToken();
1651 } while (true);
1652}
1653
Douglas Gregorf2161a72011-12-06 17:16:41 +00001654/// \brief Append to \p Paths the set of paths needed to get to the
1655/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001656static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001657 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001658 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001659 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001660 for (; Mod; Mod = Mod->Parent) {
1661 if (Mod->IsFramework)
1662 Paths.push_back(Mod->Name);
1663 }
1664
1665 if (Paths.empty())
1666 return;
1667
1668 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001669 for (unsigned I = Paths.size() - 1; I != 0; --I)
1670 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001671}
1672
Douglas Gregor718292f2011-11-11 19:10:28 +00001673/// \brief Parse a header declaration.
1674///
1675/// header-declaration:
Douglas Gregor59527662012-10-15 06:28:11 +00001676/// 'exclude'[opt] 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001677/// 'private'[opt] 'header' string-literal
1678/// 'textual'[opt] 'header' string-literal
1679/// 'umbrella'[opt] 'header' string-literal
1680///
1681/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001682void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1683 SourceLocation LeadingLoc) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001684 assert(Tok.is(MMToken::HeaderKeyword));
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001685 consumeToken();
1686
Douglas Gregor718292f2011-11-11 19:10:28 +00001687 // Parse the header name.
1688 if (!Tok.is(MMToken::StringLiteral)) {
1689 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1690 << "header";
1691 HadError = true;
1692 return;
1693 }
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001694 Module::HeaderDirective Header;
1695 Header.FileName = Tok.getString();
1696 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001697
Douglas Gregor524e33e2011-12-08 19:11:24 +00001698 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001699 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001700 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001701 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001702 HadError = true;
1703 return;
1704 }
1705
Douglas Gregor5257fc62011-11-11 21:55:48 +00001706 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001707 const FileEntry *File = nullptr;
1708 const FileEntry *BuiltinFile = nullptr;
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001709 SmallString<128> PathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001710 if (llvm::sys::path::is_absolute(Header.FileName)) {
1711 PathName = Header.FileName;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001712 File = SourceMgr.getFileManager().getFile(PathName);
1713 } else {
1714 // Search for the header file within the search directory.
Douglas Gregor70331272011-12-09 02:04:43 +00001715 PathName = Directory->getName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001716 unsigned PathLength = PathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001717
Douglas Gregorf2161a72011-12-06 17:16:41 +00001718 if (ActiveModule->isPartOfFramework()) {
1719 appendSubframeworkPaths(ActiveModule, PathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001720
1721 // Check whether this file is in the public headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001722 llvm::sys::path::append(PathName, "Headers", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001723 File = SourceMgr.getFileManager().getFile(PathName);
1724
1725 if (!File) {
1726 // Check whether this file is in the private headers.
1727 PathName.resize(PathLength);
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001728 llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001729 File = SourceMgr.getFileManager().getFile(PathName);
1730 }
1731 } else {
1732 // Lookup for normal headers.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001733 llvm::sys::path::append(PathName, Header.FileName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001734 File = SourceMgr.getFileManager().getFile(PathName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001735
1736 // If this is a system module with a top-level header, this header
1737 // may have a counterpart (or replacement) in the set of headers
1738 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001739 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1740 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001741 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001742 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001743 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001744 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
1745
1746 // If Clang supplies this header but the underlying system does not,
1747 // just silently swap in our builtin version. Otherwise, we'll end
1748 // up adding both (later).
1749 if (!File && BuiltinFile) {
1750 File = BuiltinFile;
Craig Topperd2d442c2014-05-17 23:10:59 +00001751 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001752 }
1753 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001754 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001755 }
Douglas Gregor755b2052011-11-17 22:09:43 +00001756
Douglas Gregor5257fc62011-11-11 21:55:48 +00001757 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1758 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001759 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001760 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001761 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001762 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001763 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001764 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001765 HadError = true;
1766 } else {
1767 // Record this umbrella header.
1768 Map.setUmbrellaHeader(ActiveModule, File);
1769 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001770 } else if (LeadingToken == MMToken::ExcludeKeyword) {
1771 Map.excludeHeader(ActiveModule, File);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001772 } else {
Douglas Gregor322f6332011-12-08 18:00:48 +00001773 // Record this header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001774 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
Richard Smithfeb54b62014-10-23 02:01:19 +00001775 if (LeadingToken == MMToken::PrivateKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001776 Role = ModuleMap::PrivateHeader;
Richard Smith306d8922014-10-22 23:50:56 +00001777 else if (LeadingToken == MMToken::TextualKeyword)
1778 Role = ModuleMap::TextualHeader;
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001779 else
1780 assert(LeadingToken == MMToken::HeaderKeyword);
Richard Smith25d50752014-10-20 00:15:49 +00001781
1782 // If there is a builtin counterpart to this file, add it now, before
1783 // the "real" header, so we build the built-in one first when building
1784 // the module.
Douglas Gregor3ec66632012-02-02 18:42:48 +00001785 if (BuiltinFile)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001786 Map.addHeader(ActiveModule, BuiltinFile, Role);
Richard Smith25d50752014-10-20 00:15:49 +00001787
1788 Map.addHeader(ActiveModule, File, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001789 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001790 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001791 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001792
1793 // If we find a module that has a missing header, we mark this module as
1794 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001795 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001796 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001797 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001798 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001799}
1800
Douglas Gregor524e33e2011-12-08 19:11:24 +00001801/// \brief Parse an umbrella directory declaration.
1802///
1803/// umbrella-dir-declaration:
1804/// umbrella string-literal
1805void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1806 // Parse the directory name.
1807 if (!Tok.is(MMToken::StringLiteral)) {
1808 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1809 << "umbrella";
1810 HadError = true;
1811 return;
1812 }
1813
1814 std::string DirName = Tok.getString();
1815 SourceLocation DirNameLoc = consumeToken();
1816
1817 // Check whether we already have an umbrella.
1818 if (ActiveModule->Umbrella) {
1819 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1820 << ActiveModule->getFullModuleName();
1821 HadError = true;
1822 return;
1823 }
1824
1825 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001826 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001827 if (llvm::sys::path::is_absolute(DirName))
1828 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1829 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001830 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001831 PathName = Directory->getName();
1832 llvm::sys::path::append(PathName, DirName);
1833 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1834 }
1835
1836 if (!Dir) {
1837 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1838 << DirName;
1839 HadError = true;
1840 return;
1841 }
1842
1843 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1844 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1845 << OwningModule->getFullModuleName();
1846 HadError = true;
1847 return;
1848 }
1849
1850 // Record this umbrella directory.
1851 Map.setUmbrellaDir(ActiveModule, Dir);
1852}
1853
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001854/// \brief Parse a module export declaration.
1855///
1856/// export-declaration:
1857/// 'export' wildcard-module-id
1858///
1859/// wildcard-module-id:
1860/// identifier
1861/// '*'
1862/// identifier '.' wildcard-module-id
1863void ModuleMapParser::parseExportDecl() {
1864 assert(Tok.is(MMToken::ExportKeyword));
1865 SourceLocation ExportLoc = consumeToken();
1866
1867 // Parse the module-id with an optional wildcard at the end.
1868 ModuleId ParsedModuleId;
1869 bool Wildcard = false;
1870 do {
Richard Smith306d8922014-10-22 23:50:56 +00001871 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001872 if (Tok.is(MMToken::Identifier)) {
1873 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1874 Tok.getLocation()));
1875 consumeToken();
1876
1877 if (Tok.is(MMToken::Period)) {
1878 consumeToken();
1879 continue;
1880 }
1881
1882 break;
1883 }
1884
1885 if(Tok.is(MMToken::Star)) {
1886 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001887 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001888 break;
1889 }
1890
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001891 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001892 HadError = true;
1893 return;
1894 } while (true);
1895
1896 Module::UnresolvedExportDecl Unresolved = {
1897 ExportLoc, ParsedModuleId, Wildcard
1898 };
1899 ActiveModule->UnresolvedExports.push_back(Unresolved);
1900}
1901
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001902/// \brief Parse a module uses declaration.
1903///
1904/// uses-declaration:
1905/// 'uses' wildcard-module-id
1906void ModuleMapParser::parseUseDecl() {
1907 assert(Tok.is(MMToken::UseKeyword));
1908 consumeToken();
1909 // Parse the module-id.
1910 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001911 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001912
1913 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
1914}
1915
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001916/// \brief Parse a link declaration.
1917///
1918/// module-declaration:
1919/// 'link' 'framework'[opt] string-literal
1920void ModuleMapParser::parseLinkDecl() {
1921 assert(Tok.is(MMToken::LinkKeyword));
1922 SourceLocation LinkLoc = consumeToken();
1923
1924 // Parse the optional 'framework' keyword.
1925 bool IsFramework = false;
1926 if (Tok.is(MMToken::FrameworkKeyword)) {
1927 consumeToken();
1928 IsFramework = true;
1929 }
1930
1931 // Parse the library name
1932 if (!Tok.is(MMToken::StringLiteral)) {
1933 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
1934 << IsFramework << SourceRange(LinkLoc);
1935 HadError = true;
1936 return;
1937 }
1938
1939 std::string LibraryName = Tok.getString();
1940 consumeToken();
1941 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
1942 IsFramework));
1943}
1944
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001945/// \brief Parse a configuration macro declaration.
1946///
1947/// module-declaration:
1948/// 'config_macros' attributes[opt] config-macro-list?
1949///
1950/// config-macro-list:
1951/// identifier (',' identifier)?
1952void ModuleMapParser::parseConfigMacros() {
1953 assert(Tok.is(MMToken::ConfigMacros));
1954 SourceLocation ConfigMacrosLoc = consumeToken();
1955
1956 // Only top-level modules can have configuration macros.
1957 if (ActiveModule->Parent) {
1958 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
1959 }
1960
1961 // Parse the optional attributes.
1962 Attributes Attrs;
1963 parseOptionalAttributes(Attrs);
1964 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
1965 ActiveModule->ConfigMacrosExhaustive = true;
1966 }
1967
1968 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00001969 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001970 if (!Tok.is(MMToken::Identifier))
1971 return;
1972
1973 // Consume the first identifier.
1974 if (!ActiveModule->Parent) {
1975 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1976 }
1977 consumeToken();
1978
1979 do {
1980 // If there's a comma, consume it.
1981 if (!Tok.is(MMToken::Comma))
1982 break;
1983 consumeToken();
1984
1985 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00001986 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001987 if (!Tok.is(MMToken::Identifier)) {
1988 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
1989 break;
1990 }
1991
1992 // Consume the macro name.
1993 if (!ActiveModule->Parent) {
1994 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
1995 }
1996 consumeToken();
1997 } while (true);
1998}
1999
Douglas Gregorfb912652013-03-20 21:10:35 +00002000/// \brief Format a module-id into a string.
2001static std::string formatModuleId(const ModuleId &Id) {
2002 std::string result;
2003 {
2004 llvm::raw_string_ostream OS(result);
2005
2006 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2007 if (I)
2008 OS << ".";
2009 OS << Id[I].first;
2010 }
2011 }
2012
2013 return result;
2014}
2015
2016/// \brief Parse a conflict declaration.
2017///
2018/// module-declaration:
2019/// 'conflict' module-id ',' string-literal
2020void ModuleMapParser::parseConflict() {
2021 assert(Tok.is(MMToken::Conflict));
2022 SourceLocation ConflictLoc = consumeToken();
2023 Module::UnresolvedConflict Conflict;
2024
2025 // Parse the module-id.
2026 if (parseModuleId(Conflict.Id))
2027 return;
2028
2029 // Parse the ','.
2030 if (!Tok.is(MMToken::Comma)) {
2031 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2032 << SourceRange(ConflictLoc);
2033 return;
2034 }
2035 consumeToken();
2036
2037 // Parse the message.
2038 if (!Tok.is(MMToken::StringLiteral)) {
2039 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2040 << formatModuleId(Conflict.Id);
2041 return;
2042 }
2043 Conflict.Message = Tok.getString().str();
2044 consumeToken();
2045
2046 // Add this unresolved conflict.
2047 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2048}
2049
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002050/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002051///
2052/// module-declaration:
2053/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2054/// { inferred-module-member* }
2055///
2056/// inferred-module-member:
2057/// 'export' '*'
2058/// 'exclude' identifier
2059void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002060 assert(Tok.is(MMToken::Star));
2061 SourceLocation StarLoc = consumeToken();
2062 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002063
Douglas Gregor73441092011-12-05 22:27:44 +00002064 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002065 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002066 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2067 Failed = true;
2068 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002069
2070 if (ActiveModule) {
2071 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002072 if (!Failed && ActiveModule->IsAvailable &&
2073 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002074 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2075 Failed = true;
2076 }
2077
2078 // Check for redefinition of an inferred module.
2079 if (!Failed && ActiveModule->InferSubmodules) {
2080 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2081 if (ActiveModule->InferredSubmoduleLoc.isValid())
2082 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2083 diag::note_mmap_prev_definition);
2084 Failed = true;
2085 }
2086
2087 // Check for the 'framework' keyword, which is not permitted here.
2088 if (Framework) {
2089 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2090 Framework = false;
2091 }
2092 } else if (Explicit) {
2093 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2094 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002095 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002096
Douglas Gregor73441092011-12-05 22:27:44 +00002097 // If there were any problems with this inferred submodule, skip its body.
2098 if (Failed) {
2099 if (Tok.is(MMToken::LBrace)) {
2100 consumeToken();
2101 skipUntil(MMToken::RBrace);
2102 if (Tok.is(MMToken::RBrace))
2103 consumeToken();
2104 }
2105 HadError = true;
2106 return;
2107 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002108
2109 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002110 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002111 parseOptionalAttributes(Attrs);
2112
2113 if (ActiveModule) {
2114 // Note that we have an inferred submodule.
2115 ActiveModule->InferSubmodules = true;
2116 ActiveModule->InferredSubmoduleLoc = StarLoc;
2117 ActiveModule->InferExplicitSubmodules = Explicit;
2118 } else {
2119 // We'll be inferring framework modules for this directory.
2120 Map.InferredDirectories[Directory].InferModules = true;
2121 Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002122 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002123 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002124 }
2125
Douglas Gregor73441092011-12-05 22:27:44 +00002126 // Parse the opening brace.
2127 if (!Tok.is(MMToken::LBrace)) {
2128 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2129 HadError = true;
2130 return;
2131 }
2132 SourceLocation LBraceLoc = consumeToken();
2133
2134 // Parse the body of the inferred submodule.
2135 bool Done = false;
2136 do {
2137 switch (Tok.Kind) {
2138 case MMToken::EndOfFile:
2139 case MMToken::RBrace:
2140 Done = true;
2141 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002142
2143 case MMToken::ExcludeKeyword: {
2144 if (ActiveModule) {
2145 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002146 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002147 consumeToken();
2148 break;
2149 }
2150
2151 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002152 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002153 if (!Tok.is(MMToken::Identifier)) {
2154 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2155 break;
2156 }
2157
2158 Map.InferredDirectories[Directory].ExcludedModules
2159 .push_back(Tok.getString());
2160 consumeToken();
2161 break;
2162 }
2163
2164 case MMToken::ExportKeyword:
2165 if (!ActiveModule) {
2166 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002167 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002168 consumeToken();
2169 break;
2170 }
2171
Douglas Gregor73441092011-12-05 22:27:44 +00002172 consumeToken();
2173 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002174 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002175 else
2176 Diags.Report(Tok.getLocation(),
2177 diag::err_mmap_expected_export_wildcard);
2178 consumeToken();
2179 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002180
Douglas Gregor73441092011-12-05 22:27:44 +00002181 case MMToken::ExplicitKeyword:
2182 case MMToken::ModuleKeyword:
2183 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002184 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002185 case MMToken::UmbrellaKeyword:
2186 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002187 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002188 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002189 consumeToken();
2190 break;
2191 }
2192 } while (!Done);
2193
2194 if (Tok.is(MMToken::RBrace))
2195 consumeToken();
2196 else {
2197 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2198 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2199 HadError = true;
2200 }
2201}
2202
Douglas Gregor9194a912012-11-06 19:39:40 +00002203/// \brief Parse optional attributes.
2204///
2205/// attributes:
2206/// attribute attributes
2207/// attribute
2208///
2209/// attribute:
2210/// [ identifier ]
2211///
2212/// \param Attrs Will be filled in with the parsed attributes.
2213///
2214/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002215bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002216 bool HadError = false;
2217
2218 while (Tok.is(MMToken::LSquare)) {
2219 // Consume the '['.
2220 SourceLocation LSquareLoc = consumeToken();
2221
2222 // Check whether we have an attribute name here.
2223 if (!Tok.is(MMToken::Identifier)) {
2224 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2225 skipUntil(MMToken::RSquare);
2226 if (Tok.is(MMToken::RSquare))
2227 consumeToken();
2228 HadError = true;
2229 }
2230
2231 // Decode the attribute name.
2232 AttributeKind Attribute
2233 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002234 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002235 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002236 .Case("system", AT_system)
2237 .Default(AT_unknown);
2238 switch (Attribute) {
2239 case AT_unknown:
2240 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2241 << Tok.getString();
2242 break;
2243
2244 case AT_system:
2245 Attrs.IsSystem = true;
2246 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002247
Richard Smith77944862014-03-02 05:58:18 +00002248 case AT_extern_c:
2249 Attrs.IsExternC = true;
2250 break;
2251
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002252 case AT_exhaustive:
2253 Attrs.IsExhaustive = true;
2254 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002255 }
2256 consumeToken();
2257
2258 // Consume the ']'.
2259 if (!Tok.is(MMToken::RSquare)) {
2260 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2261 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2262 skipUntil(MMToken::RSquare);
2263 HadError = true;
2264 }
2265
2266 if (Tok.is(MMToken::RSquare))
2267 consumeToken();
2268 }
2269
2270 return HadError;
2271}
2272
Douglas Gregor718292f2011-11-11 19:10:28 +00002273/// \brief Parse a module map file.
2274///
2275/// module-map-file:
2276/// module-declaration*
2277bool ModuleMapParser::parseModuleMapFile() {
2278 do {
2279 switch (Tok.Kind) {
2280 case MMToken::EndOfFile:
2281 return HadError;
2282
Douglas Gregore7ab3662011-12-07 02:23:45 +00002283 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002284 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002285 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002286 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002287 parseModuleDecl();
2288 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002289
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002290 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002291 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002292 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002293 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002294 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002295 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002296 case MMToken::HeaderKeyword:
2297 case MMToken::Identifier:
2298 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002299 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002300 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002301 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002302 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002303 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002304 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002305 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002306 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002307 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002308 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002309 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002310 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002311 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2312 HadError = true;
2313 consumeToken();
2314 break;
2315 }
2316 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002317}
2318
Douglas Gregor963c5532013-06-21 16:28:10 +00002319bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002320 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2321 = ParsedModuleMap.find(File);
2322 if (Known != ParsedModuleMap.end())
2323 return Known->second;
2324
Craig Topperd2d442c2014-05-17 23:10:59 +00002325 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002326 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
2327 FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002328 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002329 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002330 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002331
2332 // Find the directory for the module. For frameworks, that may require going
2333 // up from the 'Modules' directory.
2334 const DirectoryEntry *Dir = File->getDir();
2335 StringRef DirName(Dir->getName());
2336 if (llvm::sys::path::filename(DirName) == "Modules") {
2337 DirName = llvm::sys::path::parent_path(DirName);
2338 if (DirName.endswith(".framework"))
2339 Dir = SourceMgr.getFileManager().getDirectory(DirName);
2340 assert(Dir && "parent must exist");
2341 }
Douglas Gregor718292f2011-11-11 19:10:28 +00002342
2343 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002344 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002345 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002346 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002347 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002348 ParsedModuleMap[File] = Result;
Douglas Gregor718292f2011-11-11 19:10:28 +00002349 return Result;
2350}