blob: e1594eee3686975b47c82b10df26ed816c576553 [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"
Richard Smith9acb99e32014-12-10 03:09:48 +000022#include "clang/Lex/HeaderSearchOptions.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000023#include "clang/Lex/LexDiagnostic.h"
24#include "clang/Lex/Lexer.h"
25#include "clang/Lex/LiteralSupport.h"
26#include "llvm/ADT/StringRef.h"
27#include "llvm/ADT/StringSwitch.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000028#include "llvm/Support/Allocator.h"
Douglas Gregore89dbc12011-12-06 19:39:29 +000029#include "llvm/Support/FileSystem.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000030#include "llvm/Support/Host.h"
Rafael Espindola552c1692013-06-11 22:15:02 +000031#include "llvm/Support/Path.h"
Douglas Gregor718292f2011-11-11 19:10:28 +000032#include "llvm/Support/raw_ostream.h"
Douglas Gregor07c22b72012-09-27 14:50:15 +000033#include <stdlib.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000034#if defined(LLVM_ON_UNIX)
Dmitri Gribenkoeadae012013-01-26 16:29:36 +000035#include <limits.h>
Douglas Gregor01c7cfa2013-01-22 23:49:45 +000036#endif
Douglas Gregor718292f2011-11-11 19:10:28 +000037using namespace clang;
38
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000039Module::ExportDecl
40ModuleMap::resolveExport(Module *Mod,
41 const Module::UnresolvedExportDecl &Unresolved,
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +000042 bool Complain) const {
Douglas Gregorf5eedd02011-12-05 17:28:06 +000043 // We may have just a wildcard.
44 if (Unresolved.Id.empty()) {
45 assert(Unresolved.Wildcard && "Invalid unresolved export");
Craig Topperd2d442c2014-05-17 23:10:59 +000046 return Module::ExportDecl(nullptr, true);
Douglas Gregorf5eedd02011-12-05 17:28:06 +000047 }
48
Douglas Gregorfb912652013-03-20 21:10:35 +000049 // Resolve the module-id.
50 Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain);
51 if (!Context)
52 return Module::ExportDecl();
53
54 return Module::ExportDecl(Context, Unresolved.Wildcard);
55}
56
57Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
58 bool Complain) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000059 // Find the starting module.
Douglas Gregorfb912652013-03-20 21:10:35 +000060 Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000061 if (!Context) {
62 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000063 Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
Douglas Gregorfb912652013-03-20 21:10:35 +000064 << Id[0].first << Mod->getFullModuleName();
65
Craig Topperd2d442c2014-05-17 23:10:59 +000066 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000067 }
68
69 // Dig into the module path.
Douglas Gregorfb912652013-03-20 21:10:35 +000070 for (unsigned I = 1, N = Id.size(); I != N; ++I) {
71 Module *Sub = lookupModuleQualified(Id[I].first, Context);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000072 if (!Sub) {
73 if (Complain)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000074 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Douglas Gregorfb912652013-03-20 21:10:35 +000075 << Id[I].first << Context->getFullModuleName()
76 << SourceRange(Id[0].second, Id[I-1].second);
77
Craig Topperd2d442c2014-05-17 23:10:59 +000078 return nullptr;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000079 }
Douglas Gregorfb912652013-03-20 21:10:35 +000080
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000081 Context = Sub;
82 }
Douglas Gregorfb912652013-03-20 21:10:35 +000083
84 return Context;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +000085}
86
Daniel Jasper0761a8a2013-12-17 10:31:37 +000087ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
Argyrios Kyrtzidisb146baa2013-03-13 21:13:51 +000088 const LangOptions &LangOpts, const TargetInfo *Target,
89 HeaderSearch &HeaderInfo)
Daniel Jasper0761a8a2013-12-17 10:31:37 +000090 : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
Craig Topperd2d442c2014-05-17 23:10:59 +000091 HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
Richard Smitha7e2cc62015-05-01 01:53:09 +000092 CompilingModule(nullptr), SourceModule(nullptr), NumCreatedModules(0) {
Richard Smith0414b852015-02-14 05:32:00 +000093 MMapLangOpts.LineComment = true;
94}
Douglas Gregor718292f2011-11-11 19:10:28 +000095
96ModuleMap::~ModuleMap() {
Douglas Gregor5acdf592011-11-17 02:05:44 +000097 for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
98 IEnd = Modules.end();
99 I != IEnd; ++I) {
100 delete I->getValue();
101 }
Douglas Gregor718292f2011-11-11 19:10:28 +0000102}
103
Douglas Gregor89929282012-01-30 06:01:29 +0000104void ModuleMap::setTarget(const TargetInfo &Target) {
105 assert((!this->Target || this->Target == &Target) &&
106 "Improper target override");
107 this->Target = &Target;
108}
109
Douglas Gregor056396a2012-10-12 21:15:50 +0000110/// \brief "Sanitize" a filename so that it can be used as an identifier.
111static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
112 SmallVectorImpl<char> &Buffer) {
113 if (Name.empty())
114 return Name;
115
Jordan Rosea7d03842013-02-08 22:30:41 +0000116 if (!isValidIdentifier(Name)) {
Douglas Gregor056396a2012-10-12 21:15:50 +0000117 // If we don't already have something with the form of an identifier,
118 // create a buffer with the sanitized name.
119 Buffer.clear();
Jordan Rosea7d03842013-02-08 22:30:41 +0000120 if (isDigit(Name[0]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000121 Buffer.push_back('_');
122 Buffer.reserve(Buffer.size() + Name.size());
123 for (unsigned I = 0, N = Name.size(); I != N; ++I) {
Jordan Rosea7d03842013-02-08 22:30:41 +0000124 if (isIdentifierBody(Name[I]))
Douglas Gregor056396a2012-10-12 21:15:50 +0000125 Buffer.push_back(Name[I]);
126 else
127 Buffer.push_back('_');
128 }
129
130 Name = StringRef(Buffer.data(), Buffer.size());
131 }
132
133 while (llvm::StringSwitch<bool>(Name)
134#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
135#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
136#include "clang/Basic/TokenKinds.def"
137 .Default(false)) {
138 if (Name.data() != Buffer.data())
139 Buffer.append(Name.begin(), Name.end());
140 Buffer.push_back('_');
141 Name = StringRef(Buffer.data(), Buffer.size());
142 }
143
144 return Name;
145}
146
Douglas Gregor34d52742013-05-02 17:58:30 +0000147/// \brief Determine whether the given file name is the name of a builtin
148/// header, supplied by Clang to replace, override, or augment existing system
149/// headers.
150static bool isBuiltinHeader(StringRef FileName) {
151 return llvm::StringSwitch<bool>(FileName)
152 .Case("float.h", true)
153 .Case("iso646.h", true)
154 .Case("limits.h", true)
155 .Case("stdalign.h", true)
156 .Case("stdarg.h", true)
157 .Case("stdbool.h", true)
158 .Case("stddef.h", true)
159 .Case("stdint.h", true)
160 .Case("tgmath.h", true)
161 .Case("unwind.h", true)
162 .Default(false);
163}
164
Daniel Jasper92669ee2013-12-20 12:09:36 +0000165ModuleMap::HeadersMap::iterator
166ModuleMap::findKnownHeader(const FileEntry *File) {
Douglas Gregor59527662012-10-15 06:28:11 +0000167 HeadersMap::iterator Known = Headers.find(File);
Richard Smith47972af2015-06-16 00:08:24 +0000168 if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
169 Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000170 isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
171 HeaderInfo.loadTopLevelSystemModules();
Daniel Jasper92669ee2013-12-20 12:09:36 +0000172 return Headers.find(File);
Daniel Jasper4eaf0a62013-12-11 12:13:00 +0000173 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000174 return Known;
175}
176
Ben Langmuir44691382014-04-10 00:39:10 +0000177ModuleMap::KnownHeader
178ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
179 SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
Richard Smith47972af2015-06-16 00:08:24 +0000180 if (UmbrellaDirs.empty())
181 return KnownHeader();
182
Ben Langmuir44691382014-04-10 00:39:10 +0000183 const DirectoryEntry *Dir = File->getDir();
184 assert(Dir && "file in no directory");
185
186 // Note: as an egregious but useful hack we use the real path here, because
187 // frameworks moving from top-level frameworks to embedded frameworks tend
188 // to be symlinked from the top-level location to the embedded location,
189 // and we need to resolve lookups as if we had found the embedded location.
190 StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
191
192 // Keep walking up the directory hierarchy, looking for a directory with
193 // an umbrella header.
194 do {
195 auto KnownDir = UmbrellaDirs.find(Dir);
196 if (KnownDir != UmbrellaDirs.end())
197 return KnownHeader(KnownDir->second, NormalHeader);
198
199 IntermediateDirs.push_back(Dir);
200
201 // Retrieve our parent path.
202 DirName = llvm::sys::path::parent_path(DirName);
203 if (DirName.empty())
204 break;
205
206 // Resolve the parent path to a directory entry.
207 Dir = SourceMgr.getFileManager().getDirectory(DirName);
208 } while (Dir);
209 return KnownHeader();
210}
211
Daniel Jasper92669ee2013-12-20 12:09:36 +0000212static bool violatesPrivateInclude(Module *RequestingModule,
213 const FileEntry *IncFileEnt,
214 ModuleMap::ModuleHeaderRole Role,
215 Module *RequestedModule) {
Richard Smith202210b2014-10-24 20:23:01 +0000216 bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
217#ifndef NDEBUG
Richard Smith2708e522015-03-10 00:19:04 +0000218 if (IsPrivateRole) {
219 // Check for consistency between the module header role
220 // as obtained from the lookup and as obtained from the module.
221 // This check is not cheap, so enable it only for debugging.
222 bool IsPrivate = false;
223 SmallVectorImpl<Module::Header> *HeaderList[] = {
224 &RequestedModule->Headers[Module::HK_Private],
225 &RequestedModule->Headers[Module::HK_PrivateTextual]};
226 for (auto *Hs : HeaderList)
227 IsPrivate |=
228 std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
Richard Smith00bc95e2015-03-09 23:46:50 +0000229 return H.Entry == IncFileEnt;
Richard Smith2708e522015-03-10 00:19:04 +0000230 }) != Hs->end();
231 assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles");
232 }
Richard Smith202210b2014-10-24 20:23:01 +0000233#endif
234 return IsPrivateRole &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000235 // FIXME: Should we map RequestingModule to its top-level module here
236 // too? This check is redundant with the isSubModuleOf check in
237 // diagnoseHeaderInclusion.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000238 RequestedModule->getTopLevelModule() != RequestingModule;
239}
240
Ben Langmuir71e1a642014-05-05 21:44:13 +0000241static Module *getTopLevelOrNull(Module *M) {
242 return M ? M->getTopLevelModule() : nullptr;
243}
244
Daniel Jasper92669ee2013-12-20 12:09:36 +0000245void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
246 SourceLocation FilenameLoc,
247 StringRef Filename,
248 const FileEntry *File) {
249 // No errors for indirect modules. This may be a bit of a problem for modules
250 // with no source files.
Ben Langmuir71e1a642014-05-05 21:44:13 +0000251 if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
Daniel Jasper92669ee2013-12-20 12:09:36 +0000252 return;
253
254 if (RequestingModule)
255 resolveUses(RequestingModule, /*Complain=*/false);
256
Ben Langmuir71e1a642014-05-05 21:44:13 +0000257 bool Excluded = false;
Craig Topperd2d442c2014-05-17 23:10:59 +0000258 Module *Private = nullptr;
259 Module *NotUsed = nullptr;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000260
Ben Langmuir71e1a642014-05-05 21:44:13 +0000261 HeadersMap::iterator Known = findKnownHeader(File);
262 if (Known != Headers.end()) {
263 for (const KnownHeader &Header : Known->second) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000264 // If 'File' is part of 'RequestingModule' we can definitely include it.
Daniel Jasper0ab544f2015-03-13 14:29:39 +0000265 if (Header.getModule() &&
266 Header.getModule()->isSubModuleOf(RequestingModule))
Ben Langmuir71e1a642014-05-05 21:44:13 +0000267 return;
268
269 // Remember private headers for later printing of a diagnostic.
270 if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
271 Header.getModule())) {
272 Private = Header.getModule();
273 continue;
274 }
275
276 // If uses need to be specified explicitly, we are only allowed to return
277 // modules that are explicitly used by the requesting module.
278 if (RequestingModule && LangOpts.ModulesDeclUse &&
Richard Smith8f4d3ff2015-03-26 22:10:01 +0000279 !RequestingModule->directlyUses(Header.getModule())) {
Ben Langmuir71e1a642014-05-05 21:44:13 +0000280 NotUsed = Header.getModule();
281 continue;
282 }
283
284 // We have found a module that we can happily use.
Daniel Jasper92669ee2013-12-20 12:09:36 +0000285 return;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000286 }
Richard Smithfeb54b62014-10-23 02:01:19 +0000287
288 Excluded = true;
Daniel Jasper92669ee2013-12-20 12:09:36 +0000289 }
290
291 // We have found a header, but it is private.
Craig Topperd2d442c2014-05-17 23:10:59 +0000292 if (Private) {
Richard Smith11152dd2015-02-19 00:10:28 +0000293 Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000294 << Filename;
295 return;
296 }
297
298 // We have found a module, but we don't use it.
Craig Topperd2d442c2014-05-17 23:10:59 +0000299 if (NotUsed) {
Richard Smith11152dd2015-02-19 00:10:28 +0000300 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Daniel Jasper92669ee2013-12-20 12:09:36 +0000301 << RequestingModule->getFullModuleName() << Filename;
302 return;
303 }
304
Ben Langmuir71e1a642014-05-05 21:44:13 +0000305 if (Excluded || isHeaderInUmbrellaDirs(File))
306 return;
307
308 // At this point, only non-modular includes remain.
309
310 if (LangOpts.ModulesStrictDeclUse) {
Richard Smith11152dd2015-02-19 00:10:28 +0000311 Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
Ben Langmuir71e1a642014-05-05 21:44:13 +0000312 << RequestingModule->getFullModuleName() << Filename;
313 } else if (RequestingModule) {
314 diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
315 diag::warn_non_modular_include_in_framework_module :
316 diag::warn_non_modular_include_in_module;
317 Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
Ben Langmuir71e1a642014-05-05 21:44:13 +0000318 }
Daniel Jasper92669ee2013-12-20 12:09:36 +0000319}
320
Richard Smithec87a502015-02-13 23:50:20 +0000321static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
322 const ModuleMap::KnownHeader &Old) {
Sean Silva8b7c0392015-08-17 16:39:30 +0000323 // Prefer available modules.
324 if (New.getModule()->isAvailable() && !Old.getModule()->isAvailable())
325 return true;
326
Richard Smithec87a502015-02-13 23:50:20 +0000327 // Prefer a public header over a private header.
328 if ((New.getRole() & ModuleMap::PrivateHeader) !=
329 (Old.getRole() & ModuleMap::PrivateHeader))
330 return !(New.getRole() & ModuleMap::PrivateHeader);
331
332 // Prefer a non-textual header over a textual header.
333 if ((New.getRole() & ModuleMap::TextualHeader) !=
334 (Old.getRole() & ModuleMap::TextualHeader))
335 return !(New.getRole() & ModuleMap::TextualHeader);
336
337 // Don't have a reason to choose between these. Just keep the first one.
338 return false;
339}
340
Sean Silva4881e8b2015-06-10 01:37:59 +0000341ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
Richard Smith306d8922014-10-22 23:50:56 +0000342 auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
Sean Silva8230e5e2015-06-04 23:38:11 +0000343 if (R.getRole() & ModuleMap::TextualHeader)
Richard Smith306d8922014-10-22 23:50:56 +0000344 return ModuleMap::KnownHeader();
345 return R;
346 };
347
Sean Silva4881e8b2015-06-10 01:37:59 +0000348 HeadersMap::iterator Known = findKnownHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000349 if (Known != Headers.end()) {
Richard Smith202210b2014-10-24 20:23:01 +0000350 ModuleMap::KnownHeader Result;
Daniel Jasper97da9172013-10-22 08:09:47 +0000351 // Iterate over all modules that 'File' is part of to find the best fit.
Sean Silva4881e8b2015-06-10 01:37:59 +0000352 for (KnownHeader &H : Known->second) {
Richard Smith2f633e72015-06-22 22:20:47 +0000353 // Prefer a header from the current module over all others.
Richard Smith8692a4d2015-07-10 20:09:49 +0000354 if (H.getModule()->getTopLevelModule() == CompilingModule)
Richard Smith2f633e72015-06-22 22:20:47 +0000355 return MakeResult(H);
Sean Silva4881e8b2015-06-10 01:37:59 +0000356 if (!Result || isBetterKnownHeader(H, Result))
357 Result = H;
Daniel Jasper97da9172013-10-22 08:09:47 +0000358 }
Richard Smith306d8922014-10-22 23:50:56 +0000359 return MakeResult(Result);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000360 }
Douglas Gregor34d52742013-05-02 17:58:30 +0000361
Richard Smith386bb072015-08-18 23:42:23 +0000362 return MakeResult(findOrCreateModuleForHeaderInUmbrellaDir(File));
363}
364
365ModuleMap::KnownHeader
366ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
367 assert(!Headers.count(File) && "already have a module for this header");
368
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000369 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Ben Langmuir44691382014-04-10 00:39:10 +0000370 KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
371 if (H) {
372 Module *Result = H.getModule();
Douglas Gregore00c8b22013-01-26 00:55:12 +0000373
Ben Langmuir44691382014-04-10 00:39:10 +0000374 // Search up the module stack until we find a module with an umbrella
375 // directory.
376 Module *UmbrellaModule = Result;
377 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
378 UmbrellaModule = UmbrellaModule->Parent;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000379
Ben Langmuir44691382014-04-10 00:39:10 +0000380 if (UmbrellaModule->InferSubmodules) {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000381 const FileEntry *UmbrellaModuleMap =
382 getModuleMapFileForUniquing(UmbrellaModule);
383
Ben Langmuir44691382014-04-10 00:39:10 +0000384 // Infer submodules for each of the directories we found between
385 // the directory of the umbrella header and the directory where
386 // the actual header is located.
387 bool Explicit = UmbrellaModule->InferExplicitSubmodules;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000388
Ben Langmuir44691382014-04-10 00:39:10 +0000389 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
390 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000391 SmallString<32> NameBuf;
392 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuir44691382014-04-10 00:39:10 +0000393 llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000394 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
395 Explicit).first;
396 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000397 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000398
399 // Associate the module and the directory.
400 UmbrellaDirs[SkippedDirs[I-1]] = Result;
401
402 // If inferred submodules export everything they import, add a
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000403 // wildcard to the set of exports.
Douglas Gregor930a85c2011-12-06 16:17:15 +0000404 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000405 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000406 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000407
Ben Langmuir44691382014-04-10 00:39:10 +0000408 // Infer a submodule with the same name as this header file.
409 SmallString<32> NameBuf;
410 StringRef Name = sanitizeFilenameAsIdentifier(
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000411 llvm::sys::path::stem(File->getName()), NameBuf);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000412 Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
413 Explicit).first;
414 InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
Ben Langmuirffbafa22014-04-23 21:10:46 +0000415 Result->IsInferred = true;
Ben Langmuir44691382014-04-10 00:39:10 +0000416 Result->addTopHeader(File);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000417
Ben Langmuir44691382014-04-10 00:39:10 +0000418 // If inferred submodules export everything they import, add a
419 // wildcard to the set of exports.
420 if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
Craig Topperd2d442c2014-05-17 23:10:59 +0000421 Result->Exports.push_back(Module::ExportDecl(nullptr, true));
Ben Langmuir44691382014-04-10 00:39:10 +0000422 } else {
423 // Record each of the directories we stepped through as being part of
424 // the module we found, since the umbrella header covers them all.
425 for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
426 UmbrellaDirs[SkippedDirs[I]] = Result;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000427 }
Ben Langmuir44691382014-04-10 00:39:10 +0000428
Richard Smith386bb072015-08-18 23:42:23 +0000429 KnownHeader Header(Result, NormalHeader);
430 Headers[File].push_back(Header);
431 return Header;
Ben Langmuir44691382014-04-10 00:39:10 +0000432 }
Richard Smith306d8922014-10-22 23:50:56 +0000433
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000434 return KnownHeader();
Douglas Gregorab0c8a82011-11-11 22:18:48 +0000435}
436
Richard Smith386bb072015-08-18 23:42:23 +0000437ArrayRef<ModuleMap::KnownHeader>
438ModuleMap::findAllModulesForHeader(const FileEntry *File) const {
439 auto It = Headers.find(File);
440 if (It == Headers.end())
441 return None;
442 return It->second;
443}
444
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000445bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
Craig Topperd2d442c2014-05-17 23:10:59 +0000446 return isHeaderUnavailableInModule(Header, nullptr);
Richard Smith50996ce2014-04-08 13:13:04 +0000447}
448
Dmitri Gribenko62bcd922014-04-18 14:36:51 +0000449bool
450ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
451 const Module *RequestingModule) const {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000452 HeadersMap::const_iterator Known = Headers.find(Header);
Daniel Jasper97da9172013-10-22 08:09:47 +0000453 if (Known != Headers.end()) {
454 for (SmallVectorImpl<KnownHeader>::const_iterator
455 I = Known->second.begin(),
456 E = Known->second.end();
457 I != E; ++I) {
Richard Smith50996ce2014-04-08 13:13:04 +0000458 if (I->isAvailable() && (!RequestingModule ||
459 I->getModule()->isSubModuleOf(RequestingModule)))
Daniel Jasper97da9172013-10-22 08:09:47 +0000460 return false;
461 }
462 return true;
463 }
Richard Smith50996ce2014-04-08 13:13:04 +0000464
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000465 const DirectoryEntry *Dir = Header->getDir();
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000466 SmallVector<const DirectoryEntry *, 2> SkippedDirs;
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000467 StringRef DirName = Dir->getName();
468
Richard Smith50996ce2014-04-08 13:13:04 +0000469 auto IsUnavailable = [&](const Module *M) {
470 return !M->isAvailable() && (!RequestingModule ||
471 M->isSubModuleOf(RequestingModule));
472 };
473
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000474 // Keep walking up the directory hierarchy, looking for a directory with
475 // an umbrella header.
Richard Smith50996ce2014-04-08 13:13:04 +0000476 do {
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000477 llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000478 = UmbrellaDirs.find(Dir);
479 if (KnownDir != UmbrellaDirs.end()) {
480 Module *Found = KnownDir->second;
Richard Smith50996ce2014-04-08 13:13:04 +0000481 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000482 return true;
483
484 // Search up the module stack until we find a module with an umbrella
485 // directory.
486 Module *UmbrellaModule = Found;
487 while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
488 UmbrellaModule = UmbrellaModule->Parent;
489
490 if (UmbrellaModule->InferSubmodules) {
491 for (unsigned I = SkippedDirs.size(); I != 0; --I) {
492 // Find or create the module that corresponds to this directory name.
Douglas Gregor056396a2012-10-12 21:15:50 +0000493 SmallString<32> NameBuf;
494 StringRef Name = sanitizeFilenameAsIdentifier(
495 llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
496 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000497 Found = lookupModuleQualified(Name, Found);
498 if (!Found)
499 return false;
Richard Smith50996ce2014-04-08 13:13:04 +0000500 if (IsUnavailable(Found))
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000501 return true;
502 }
503
504 // Infer a submodule with the same name as this header file.
Douglas Gregor056396a2012-10-12 21:15:50 +0000505 SmallString<32> NameBuf;
506 StringRef Name = sanitizeFilenameAsIdentifier(
507 llvm::sys::path::stem(Header->getName()),
508 NameBuf);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000509 Found = lookupModuleQualified(Name, Found);
510 if (!Found)
511 return false;
512 }
513
Richard Smith50996ce2014-04-08 13:13:04 +0000514 return IsUnavailable(Found);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000515 }
516
517 SkippedDirs.push_back(Dir);
518
519 // Retrieve our parent path.
520 DirName = llvm::sys::path::parent_path(DirName);
521 if (DirName.empty())
522 break;
523
524 // Resolve the parent path to a directory entry.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000525 Dir = SourceMgr.getFileManager().getDirectory(DirName);
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000526 } while (Dir);
527
528 return false;
529}
530
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000531Module *ModuleMap::findModule(StringRef Name) const {
532 llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000533 if (Known != Modules.end())
534 return Known->getValue();
Craig Topperd2d442c2014-05-17 23:10:59 +0000535
536 return nullptr;
Douglas Gregor88bdfb02011-11-11 23:20:24 +0000537}
538
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000539Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
540 Module *Context) const {
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000541 for(; Context; Context = Context->Parent) {
542 if (Module *Sub = lookupModuleQualified(Name, Context))
543 return Sub;
544 }
545
546 return findModule(Name);
547}
548
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000549Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000550 if (!Context)
551 return findModule(Name);
552
Douglas Gregoreb90e832012-01-04 23:32:19 +0000553 return Context->findSubmodule(Name);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000554}
555
Douglas Gregorde3ef502011-11-30 23:21:26 +0000556std::pair<Module *, bool>
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000557ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
Douglas Gregor69021972011-11-30 17:33:56 +0000558 bool IsExplicit) {
559 // Try to find an existing module with this name.
Douglas Gregoreb90e832012-01-04 23:32:19 +0000560 if (Module *Sub = lookupModuleQualified(Name, Parent))
561 return std::make_pair(Sub, false);
Douglas Gregor69021972011-11-30 17:33:56 +0000562
563 // Create a new module with this name.
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000564 Module *Result = new Module(Name, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000565 IsFramework, IsExplicit, NumCreatedModules++);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000566 if (LangOpts.CurrentModule == Name) {
567 SourceModule = Result;
568 SourceModuleName = Name;
569 }
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000570 if (!Parent) {
Douglas Gregor69021972011-11-30 17:33:56 +0000571 Modules[Name] = Result;
Argyrios Kyrtzidis6f722b42013-05-08 23:46:46 +0000572 if (!LangOpts.CurrentModule.empty() && !CompilingModule &&
573 Name == LangOpts.CurrentModule) {
574 CompilingModule = Result;
575 }
576 }
Douglas Gregor69021972011-11-30 17:33:56 +0000577 return std::make_pair(Result, true);
578}
579
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000580/// \brief For a framework module, infer the framework against which we
581/// should link.
582static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
583 FileManager &FileMgr) {
584 assert(Mod->IsFramework && "Can only infer linking for framework modules");
585 assert(!Mod->isSubFramework() &&
586 "Can only infer linking for top-level frameworks");
587
588 SmallString<128> LibName;
589 LibName += FrameworkDir->getName();
590 llvm::sys::path::append(LibName, Mod->Name);
591 if (FileMgr.getFile(LibName)) {
592 Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
593 /*IsFramework=*/true));
594 }
595}
596
Ben Langmuira5254002015-07-02 13:19:48 +0000597Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
598 bool IsSystem, Module *Parent) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000599 Attributes Attrs;
600 Attrs.IsSystem = IsSystem;
Ben Langmuira5254002015-07-02 13:19:48 +0000601 return inferFrameworkModule(FrameworkDir, Attrs, Parent);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000602}
603
Ben Langmuira5254002015-07-02 13:19:48 +0000604Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000605 Attributes Attrs, Module *Parent) {
Ben Langmuira5254002015-07-02 13:19:48 +0000606 // Note: as an egregious but useful hack we use the real path here, because
607 // we might be looking at an embedded framework that symlinks out to a
608 // top-level framework, and we need to infer as if we were naming the
609 // top-level framework.
610 StringRef FrameworkDirName =
611 SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
612
613 // In case this is a case-insensitive filesystem, use the canonical
614 // directory name as the ModuleName, since modules are case-sensitive.
615 // FIXME: we should be able to give a fix-it hint for the correct spelling.
616 SmallString<32> ModuleNameStorage;
617 StringRef ModuleName = sanitizeFilenameAsIdentifier(
618 llvm::sys::path::stem(FrameworkDirName), ModuleNameStorage);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000619
Douglas Gregor56c64012011-11-17 01:41:17 +0000620 // Check whether we've already found this module.
Douglas Gregore89dbc12011-12-06 19:39:29 +0000621 if (Module *Mod = lookupModuleQualified(ModuleName, Parent))
622 return Mod;
623
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000624 FileManager &FileMgr = SourceMgr.getFileManager();
Douglas Gregor9194a912012-11-06 19:39:40 +0000625
626 // If the framework has a parent path from which we're allowed to infer
627 // a framework module, do so.
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000628 const FileEntry *ModuleMapFile = nullptr;
Douglas Gregor9194a912012-11-06 19:39:40 +0000629 if (!Parent) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000630 // Determine whether we're allowed to infer a module map.
Douglas Gregor9194a912012-11-06 19:39:40 +0000631 bool canInfer = false;
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000632 if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
Douglas Gregor9194a912012-11-06 19:39:40 +0000633 // Figure out the parent path.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000634 StringRef Parent = llvm::sys::path::parent_path(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000635 if (const DirectoryEntry *ParentDir = FileMgr.getDirectory(Parent)) {
636 // Check whether we have already looked into the parent directory
637 // for a module map.
Argyrios Kyrtzidise4412642013-02-19 19:58:45 +0000638 llvm::DenseMap<const DirectoryEntry *, InferredDirectory>::const_iterator
Douglas Gregor9194a912012-11-06 19:39:40 +0000639 inferred = InferredDirectories.find(ParentDir);
640 if (inferred == InferredDirectories.end()) {
641 // We haven't looked here before. Load a module map, if there is
642 // one.
Ben Langmuir984e1df2014-03-19 20:23:34 +0000643 bool IsFrameworkDir = Parent.endswith(".framework");
644 if (const FileEntry *ModMapFile =
645 HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000646 parseModuleMapFile(ModMapFile, Attrs.IsSystem, ParentDir);
Douglas Gregor9194a912012-11-06 19:39:40 +0000647 inferred = InferredDirectories.find(ParentDir);
648 }
649
650 if (inferred == InferredDirectories.end())
651 inferred = InferredDirectories.insert(
652 std::make_pair(ParentDir, InferredDirectory())).first;
653 }
654
655 if (inferred->second.InferModules) {
656 // We're allowed to infer for this directory, but make sure it's okay
657 // to infer this particular module.
Douglas Gregor4ddf2222013-01-10 01:43:00 +0000658 StringRef Name = llvm::sys::path::stem(FrameworkDirName);
Douglas Gregor9194a912012-11-06 19:39:40 +0000659 canInfer = std::find(inferred->second.ExcludedModules.begin(),
660 inferred->second.ExcludedModules.end(),
661 Name) == inferred->second.ExcludedModules.end();
662
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000663 Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
664 Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
665 Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000666 ModuleMapFile = inferred->second.ModuleMapFile;
Douglas Gregor9194a912012-11-06 19:39:40 +0000667 }
668 }
669 }
670
671 // If we're not allowed to infer a framework module, don't.
672 if (!canInfer)
Craig Topperd2d442c2014-05-17 23:10:59 +0000673 return nullptr;
Ben Langmuirbeee15e2014-04-14 18:00:01 +0000674 } else
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000675 ModuleMapFile = getModuleMapFileForUniquing(Parent);
Douglas Gregor9194a912012-11-06 19:39:40 +0000676
677
Douglas Gregor56c64012011-11-17 01:41:17 +0000678 // Look for an umbrella header.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000679 SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
Benjamin Kramer17381a02013-06-28 16:25:46 +0000680 llvm::sys::path::append(UmbrellaName, "Headers", ModuleName + ".h");
Douglas Gregore89dbc12011-12-06 19:39:29 +0000681 const FileEntry *UmbrellaHeader = FileMgr.getFile(UmbrellaName);
Douglas Gregor56c64012011-11-17 01:41:17 +0000682
683 // FIXME: If there's no umbrella header, we could probably scan the
684 // framework to load *everything*. But, it's not clear that this is a good
685 // idea.
686 if (!UmbrellaHeader)
Craig Topperd2d442c2014-05-17 23:10:59 +0000687 return nullptr;
688
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000689 Module *Result = new Module(ModuleName, SourceLocation(), Parent,
Richard Smitha7e2cc62015-05-01 01:53:09 +0000690 /*IsFramework=*/true, /*IsExplicit=*/false,
691 NumCreatedModules++);
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000692 InferredModuleAllowedBy[Result] = ModuleMapFile;
693 Result->IsInferred = true;
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000694 if (LangOpts.CurrentModule == ModuleName) {
695 SourceModule = Result;
696 SourceModuleName = ModuleName;
697 }
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000698
699 Result->IsSystem |= Attrs.IsSystem;
700 Result->IsExternC |= Attrs.IsExternC;
701 Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
Richard Smith2b63d152015-05-16 02:28:53 +0000702 Result->Directory = FrameworkDir;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +0000703
Douglas Gregoreb90e832012-01-04 23:32:19 +0000704 if (!Parent)
Douglas Gregore89dbc12011-12-06 19:39:29 +0000705 Modules[ModuleName] = Result;
Douglas Gregoreb90e832012-01-04 23:32:19 +0000706
Douglas Gregor322f6332011-12-08 18:00:48 +0000707 // umbrella header "umbrella-header-name"
Richard Smith2b63d152015-05-16 02:28:53 +0000708 //
709 // The "Headers/" component of the name is implied because this is
710 // a framework module.
711 setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
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);
Yaron Keren92e1b622015-03-18 10:17:07 +0000726 for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
Douglas Gregore89dbc12011-12-06 19:39:29 +0000727 Dir != DirEnd && !EC; Dir.increment(EC)) {
728 if (!StringRef(Dir->path()).endswith(".framework"))
729 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000730
Douglas Gregore89dbc12011-12-06 19:39:29 +0000731 if (const DirectoryEntry *SubframeworkDir
732 = FileMgr.getDirectory(Dir->path())) {
Douglas Gregor07c22b72012-09-27 14:50:15 +0000733 // Note: as an egregious but useful hack, we use the real path here and
734 // check whether it is actually a subdirectory of the parent directory.
735 // This will not be the case if the 'subframework' is actually a symlink
736 // out to a top-level framework.
Douglas Gregore00c8b22013-01-26 00:55:12 +0000737 StringRef SubframeworkDirName = FileMgr.getCanonicalName(SubframeworkDir);
738 bool FoundParent = false;
739 do {
740 // Get the parent directory name.
741 SubframeworkDirName
742 = llvm::sys::path::parent_path(SubframeworkDirName);
743 if (SubframeworkDirName.empty())
744 break;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000745
Douglas Gregore00c8b22013-01-26 00:55:12 +0000746 if (FileMgr.getDirectory(SubframeworkDirName) == FrameworkDir) {
747 FoundParent = true;
748 break;
749 }
750 } while (true);
Douglas Gregor07c22b72012-09-27 14:50:15 +0000751
Douglas Gregore00c8b22013-01-26 00:55:12 +0000752 if (!FoundParent)
753 continue;
Douglas Gregor07c22b72012-09-27 14:50:15 +0000754
Douglas Gregore89dbc12011-12-06 19:39:29 +0000755 // FIXME: Do we want to warn about subframeworks without umbrella headers?
Ben Langmuira5254002015-07-02 13:19:48 +0000756 inferFrameworkModule(SubframeworkDir, Attrs, Result);
Douglas Gregore89dbc12011-12-06 19:39:29 +0000757 }
758 }
Douglas Gregor09a22f02012-01-13 16:54:27 +0000759
Douglas Gregor11dfe6f2013-01-14 17:57:51 +0000760 // If the module is a top-level framework, automatically link against the
761 // framework.
762 if (!Result->isSubFramework()) {
763 inferFrameworkLink(Result, FrameworkDir, FileMgr);
764 }
765
Douglas Gregor56c64012011-11-17 01:41:17 +0000766 return Result;
767}
768
Richard Smith2b63d152015-05-16 02:28:53 +0000769void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
770 Twine NameAsWritten) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000771 Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Douglas Gregor73141fa2011-12-08 17:39:04 +0000772 Mod->Umbrella = UmbrellaHeader;
Richard Smith2b63d152015-05-16 02:28:53 +0000773 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor70331272011-12-09 02:04:43 +0000774 UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000775}
776
Richard Smith2b63d152015-05-16 02:28:53 +0000777void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
778 Twine NameAsWritten) {
Douglas Gregor524e33e2011-12-08 19:11:24 +0000779 Mod->Umbrella = UmbrellaDir;
Richard Smith2b63d152015-05-16 02:28:53 +0000780 Mod->UmbrellaAsWritten = NameAsWritten.str();
Douglas Gregor524e33e2011-12-08 19:11:24 +0000781 UmbrellaDirs[UmbrellaDir] = Mod;
782}
783
Richard Smith3c1a41a2014-12-02 00:08:08 +0000784static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000785 switch ((int)Role) {
Richard Smith3c1a41a2014-12-02 00:08:08 +0000786 default: llvm_unreachable("unknown header role");
787 case ModuleMap::NormalHeader:
788 return Module::HK_Normal;
789 case ModuleMap::PrivateHeader:
790 return Module::HK_Private;
791 case ModuleMap::TextualHeader:
792 return Module::HK_Textual;
793 case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
794 return Module::HK_PrivateTextual;
NAKAMURA Takumi0e98d932014-10-26 13:12:35 +0000795 }
Douglas Gregora89c5ac2011-12-06 01:10:29 +0000796}
797
Richard Smith3c1a41a2014-12-02 00:08:08 +0000798void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Richard Smithd8879c82015-08-24 21:59:32 +0000799 ModuleHeaderRole Role, bool Imported) {
Richard Smith386bb072015-08-18 23:42:23 +0000800 KnownHeader KH(Mod, Role);
Richard Smithfeb54b62014-10-23 02:01:19 +0000801
Richard Smith386bb072015-08-18 23:42:23 +0000802 // Only add each header to the headers list once.
803 // FIXME: Should we diagnose if a header is listed twice in the
804 // same module definition?
805 auto &HeaderList = Headers[Header.Entry];
806 for (auto H : HeaderList)
807 if (H == KH)
808 return;
809
810 HeaderList.push_back(KH);
Richard Smith3c1a41a2014-12-02 00:08:08 +0000811 Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
Richard Smith386bb072015-08-18 23:42:23 +0000812
813 bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
Richard Smithd8879c82015-08-24 21:59:32 +0000814 if (!Imported || isCompilingModuleHeader) {
815 // When we import HeaderFileInfo, the external source is expected to
816 // set the isModuleHeader flag itself.
817 HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
818 isCompilingModuleHeader);
819 }
Richard Smith3c1a41a2014-12-02 00:08:08 +0000820}
821
822void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Richard Smithfeb54b62014-10-23 02:01:19 +0000823 // Add this as a known header so we won't implicitly add it to any
824 // umbrella directory module.
825 // FIXME: Should we only exclude it from umbrella modules within the
826 // specified module?
Richard Smith3c1a41a2014-12-02 00:08:08 +0000827 (void) Headers[Header.Entry];
828
829 Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
Richard Smithfeb54b62014-10-23 02:01:19 +0000830}
831
Douglas Gregor514b6362011-11-29 19:06:37 +0000832const FileEntry *
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000833ModuleMap::getContainingModuleMapFile(const Module *Module) const {
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000834 if (Module->DefinitionLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000835 return nullptr;
Douglas Gregor514b6362011-11-29 19:06:37 +0000836
Manuel Klimek1f76c4e2013-10-24 07:51:24 +0000837 return SourceMgr.getFileEntryForID(
838 SourceMgr.getFileID(Module->DefinitionLoc));
Douglas Gregor514b6362011-11-29 19:06:37 +0000839}
840
Ben Langmuir4b8a9e92014-08-12 16:42:33 +0000841const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
Ben Langmuir9d6448b2014-08-09 00:57:23 +0000842 if (M->IsInferred) {
843 assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
844 return InferredModuleAllowedBy.find(M)->second;
845 }
846 return getContainingModuleMapFile(M);
847}
848
849void ModuleMap::setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap) {
850 assert(M->IsInferred && "module not inferred");
851 InferredModuleAllowedBy[M] = ModMap;
852}
853
Douglas Gregor718292f2011-11-11 19:10:28 +0000854void ModuleMap::dump() {
855 llvm::errs() << "Modules:";
856 for (llvm::StringMap<Module *>::iterator M = Modules.begin(),
857 MEnd = Modules.end();
858 M != MEnd; ++M)
Douglas Gregord28d1b82011-11-29 18:17:59 +0000859 M->getValue()->print(llvm::errs(), 2);
Douglas Gregor718292f2011-11-11 19:10:28 +0000860
861 llvm::errs() << "Headers:";
Douglas Gregor59527662012-10-15 06:28:11 +0000862 for (HeadersMap::iterator H = Headers.begin(), HEnd = Headers.end();
Douglas Gregor718292f2011-11-11 19:10:28 +0000863 H != HEnd; ++H) {
Daniel Jasper97da9172013-10-22 08:09:47 +0000864 llvm::errs() << " \"" << H->first->getName() << "\" -> ";
865 for (SmallVectorImpl<KnownHeader>::const_iterator I = H->second.begin(),
866 E = H->second.end();
867 I != E; ++I) {
868 if (I != H->second.begin())
869 llvm::errs() << ",";
870 llvm::errs() << I->getModule()->getFullModuleName();
871 }
872 llvm::errs() << "\n";
Douglas Gregor718292f2011-11-11 19:10:28 +0000873 }
874}
875
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000876bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000877 auto Unresolved = std::move(Mod->UnresolvedExports);
878 Mod->UnresolvedExports.clear();
879 for (auto &UE : Unresolved) {
880 Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
Douglas Gregorf5eedd02011-12-05 17:28:06 +0000881 if (Export.getPointer() || Export.getInt())
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000882 Mod->Exports.push_back(Export);
883 else
Richard Smith42413142015-05-15 20:05:43 +0000884 Mod->UnresolvedExports.push_back(UE);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000885 }
Richard Smith42413142015-05-15 20:05:43 +0000886 return !Mod->UnresolvedExports.empty();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000887}
888
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000889bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000890 auto Unresolved = std::move(Mod->UnresolvedDirectUses);
891 Mod->UnresolvedDirectUses.clear();
892 for (auto &UDU : Unresolved) {
893 Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000894 if (DirectUse)
895 Mod->DirectUses.push_back(DirectUse);
896 else
Richard Smith42413142015-05-15 20:05:43 +0000897 Mod->UnresolvedDirectUses.push_back(UDU);
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000898 }
Richard Smith42413142015-05-15 20:05:43 +0000899 return !Mod->UnresolvedDirectUses.empty();
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000900}
901
Douglas Gregorfb912652013-03-20 21:10:35 +0000902bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
Richard Smith42413142015-05-15 20:05:43 +0000903 auto Unresolved = std::move(Mod->UnresolvedConflicts);
Douglas Gregorfb912652013-03-20 21:10:35 +0000904 Mod->UnresolvedConflicts.clear();
Richard Smith42413142015-05-15 20:05:43 +0000905 for (auto &UC : Unresolved) {
906 if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
907 Module::Conflict Conflict;
908 Conflict.Other = OtherMod;
909 Conflict.Message = UC.Message;
910 Mod->Conflicts.push_back(Conflict);
911 } else
912 Mod->UnresolvedConflicts.push_back(UC);
913 }
914 return !Mod->UnresolvedConflicts.empty();
Douglas Gregorfb912652013-03-20 21:10:35 +0000915}
916
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000917Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
918 if (Loc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000919 return nullptr;
920
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000921 // Use the expansion location to determine which module we're in.
922 FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
923 if (!ExpansionLoc.isFileID())
Craig Topperd2d442c2014-05-17 23:10:59 +0000924 return nullptr;
925
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000926 const SourceManager &SrcMgr = Loc.getManager();
927 FileID ExpansionFileID = ExpansionLoc.getFileID();
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000928
Douglas Gregor224d8a72012-01-06 17:19:32 +0000929 while (const FileEntry *ExpansionFile
930 = SrcMgr.getFileEntryForID(ExpansionFileID)) {
931 // Find the module that owns this header (if any).
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000932 if (Module *Mod = findModuleForHeader(ExpansionFile).getModule())
Douglas Gregor224d8a72012-01-06 17:19:32 +0000933 return Mod;
934
935 // No module owns this header, so look up the inclusion chain to see if
936 // any included header has an associated module.
937 SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
938 if (IncludeLoc.isInvalid())
Craig Topperd2d442c2014-05-17 23:10:59 +0000939 return nullptr;
940
Douglas Gregor224d8a72012-01-06 17:19:32 +0000941 ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
942 }
Craig Topperd2d442c2014-05-17 23:10:59 +0000943
944 return nullptr;
Douglas Gregor0093b3c2011-12-05 16:33:54 +0000945}
946
Douglas Gregor718292f2011-11-11 19:10:28 +0000947//----------------------------------------------------------------------------//
948// Module map file parser
949//----------------------------------------------------------------------------//
950
951namespace clang {
952 /// \brief A token in a module map file.
953 struct MMToken {
954 enum TokenKind {
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000955 Comma,
Douglas Gregor35b13ec2013-03-20 00:22:05 +0000956 ConfigMacros,
Douglas Gregorfb912652013-03-20 21:10:35 +0000957 Conflict,
Douglas Gregor718292f2011-11-11 19:10:28 +0000958 EndOfFile,
959 HeaderKeyword,
960 Identifier,
Richard Smitha3feee22013-10-28 22:18:19 +0000961 Exclaim,
Douglas Gregor59527662012-10-15 06:28:11 +0000962 ExcludeKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000963 ExplicitKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000964 ExportKeyword,
Daniel Jasper97292842013-09-11 07:20:44 +0000965 ExternKeyword,
Douglas Gregor755b2052011-11-17 22:09:43 +0000966 FrameworkKeyword,
Douglas Gregor6ddfca92013-01-14 17:21:00 +0000967 LinkKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000968 ModuleKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000969 Period,
Lawrence Crowlb53e5482013-06-20 21:14:14 +0000970 PrivateKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000971 UmbrellaKeyword,
Daniel Jasperba7f2f72013-09-24 09:14:14 +0000972 UseKeyword,
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +0000973 RequiresKeyword,
Douglas Gregor2b82c2a2011-12-02 01:47:07 +0000974 Star,
Douglas Gregor718292f2011-11-11 19:10:28 +0000975 StringLiteral,
Richard Smith306d8922014-10-22 23:50:56 +0000976 TextualKeyword,
Douglas Gregor718292f2011-11-11 19:10:28 +0000977 LBrace,
Douglas Gregora686e1b2012-01-27 19:52:33 +0000978 RBrace,
979 LSquare,
980 RSquare
Douglas Gregor718292f2011-11-11 19:10:28 +0000981 } Kind;
982
983 unsigned Location;
984 unsigned StringLength;
985 const char *StringData;
986
987 void clear() {
988 Kind = EndOfFile;
989 Location = 0;
990 StringLength = 0;
Craig Topperd2d442c2014-05-17 23:10:59 +0000991 StringData = nullptr;
Douglas Gregor718292f2011-11-11 19:10:28 +0000992 }
993
994 bool is(TokenKind K) const { return Kind == K; }
995
996 SourceLocation getLocation() const {
997 return SourceLocation::getFromRawEncoding(Location);
998 }
999
1000 StringRef getString() const {
1001 return StringRef(StringData, StringLength);
1002 }
1003 };
Douglas Gregor9194a912012-11-06 19:39:40 +00001004
Douglas Gregor718292f2011-11-11 19:10:28 +00001005 class ModuleMapParser {
1006 Lexer &L;
1007 SourceManager &SourceMgr;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001008
1009 /// \brief Default target information, used only for string literal
1010 /// parsing.
1011 const TargetInfo *Target;
1012
Douglas Gregor718292f2011-11-11 19:10:28 +00001013 DiagnosticsEngine &Diags;
1014 ModuleMap &Map;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001015
1016 /// \brief The current module map file.
1017 const FileEntry *ModuleMapFile;
Douglas Gregor718292f2011-11-11 19:10:28 +00001018
Richard Smith9acb99e32014-12-10 03:09:48 +00001019 /// \brief The directory that file names in this module map file should
1020 /// be resolved relative to.
Douglas Gregor5257fc62011-11-11 21:55:48 +00001021 const DirectoryEntry *Directory;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001022
1023 /// \brief The directory containing Clang-supplied headers.
1024 const DirectoryEntry *BuiltinIncludeDir;
1025
Douglas Gregor963c5532013-06-21 16:28:10 +00001026 /// \brief Whether this module map is in a system header directory.
1027 bool IsSystem;
1028
Douglas Gregor718292f2011-11-11 19:10:28 +00001029 /// \brief Whether an error occurred.
1030 bool HadError;
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001031
Douglas Gregor718292f2011-11-11 19:10:28 +00001032 /// \brief Stores string data for the various string literals referenced
1033 /// during parsing.
1034 llvm::BumpPtrAllocator StringData;
1035
1036 /// \brief The current token.
1037 MMToken Tok;
1038
1039 /// \brief The active module.
Douglas Gregorde3ef502011-11-30 23:21:26 +00001040 Module *ActiveModule;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001041
1042 /// \brief Whether a module uses the 'requires excluded' hack to mark its
1043 /// contents as 'textual'.
1044 ///
1045 /// On older Darwin SDK versions, 'requires excluded' is used to mark the
1046 /// contents of the Darwin.C.excluded (assert.h) and Tcl.Private modules as
1047 /// non-modular headers. For backwards compatibility, we continue to
1048 /// support this idiom for just these modules, and map the headers to
1049 /// 'textual' to match the original intent.
1050 llvm::SmallPtrSet<Module *, 2> UsesRequiresExcludedHack;
1051
Douglas Gregor718292f2011-11-11 19:10:28 +00001052 /// \brief Consume the current token and return its location.
1053 SourceLocation consumeToken();
1054
1055 /// \brief Skip tokens until we reach the a token with the given kind
1056 /// (or the end of the file).
1057 void skipUntil(MMToken::TokenKind K);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001058
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001059 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001060 bool parseModuleId(ModuleId &Id);
Douglas Gregor718292f2011-11-11 19:10:28 +00001061 void parseModuleDecl();
Daniel Jasper97292842013-09-11 07:20:44 +00001062 void parseExternModuleDecl();
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001063 void parseRequiresDecl();
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001064 void parseHeaderDecl(clang::MMToken::TokenKind,
1065 SourceLocation LeadingLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001066 void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001067 void parseExportDecl();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001068 void parseUseDecl();
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001069 void parseLinkDecl();
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001070 void parseConfigMacros();
Douglas Gregorfb912652013-03-20 21:10:35 +00001071 void parseConflict();
Douglas Gregor9194a912012-11-06 19:39:40 +00001072 void parseInferredModuleDecl(bool Framework, bool Explicit);
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00001073
1074 typedef ModuleMap::Attributes Attributes;
Bill Wendling44426052012-12-20 19:22:21 +00001075 bool parseOptionalAttributes(Attributes &Attrs);
Douglas Gregor70331272011-12-09 02:04:43 +00001076
Douglas Gregor718292f2011-11-11 19:10:28 +00001077 public:
Douglas Gregor718292f2011-11-11 19:10:28 +00001078 explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001079 const TargetInfo *Target,
Douglas Gregor718292f2011-11-11 19:10:28 +00001080 DiagnosticsEngine &Diags,
Douglas Gregor5257fc62011-11-11 21:55:48 +00001081 ModuleMap &Map,
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001082 const FileEntry *ModuleMapFile,
Douglas Gregor3ec66632012-02-02 18:42:48 +00001083 const DirectoryEntry *Directory,
Douglas Gregor963c5532013-06-21 16:28:10 +00001084 const DirectoryEntry *BuiltinIncludeDir,
1085 bool IsSystem)
Douglas Gregorbc10b9f2012-10-15 16:45:32 +00001086 : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
Ben Langmuirbeee15e2014-04-14 18:00:01 +00001087 ModuleMapFile(ModuleMapFile), Directory(Directory),
1088 BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
Craig Topperd2d442c2014-05-17 23:10:59 +00001089 HadError(false), ActiveModule(nullptr)
Douglas Gregor718292f2011-11-11 19:10:28 +00001090 {
Douglas Gregor718292f2011-11-11 19:10:28 +00001091 Tok.clear();
1092 consumeToken();
1093 }
1094
1095 bool parseModuleMapFile();
1096 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001097}
Douglas Gregor718292f2011-11-11 19:10:28 +00001098
1099SourceLocation ModuleMapParser::consumeToken() {
1100retry:
1101 SourceLocation Result = Tok.getLocation();
1102 Tok.clear();
1103
1104 Token LToken;
1105 L.LexFromRawLexer(LToken);
1106 Tok.Location = LToken.getLocation().getRawEncoding();
1107 switch (LToken.getKind()) {
Alp Toker2d57cea2014-05-17 04:53:25 +00001108 case tok::raw_identifier: {
1109 StringRef RI = LToken.getRawIdentifier();
1110 Tok.StringData = RI.data();
1111 Tok.StringLength = RI.size();
1112 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001113 .Case("config_macros", MMToken::ConfigMacros)
Douglas Gregorfb912652013-03-20 21:10:35 +00001114 .Case("conflict", MMToken::Conflict)
Douglas Gregor59527662012-10-15 06:28:11 +00001115 .Case("exclude", MMToken::ExcludeKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001116 .Case("explicit", MMToken::ExplicitKeyword)
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001117 .Case("export", MMToken::ExportKeyword)
Daniel Jasper97292842013-09-11 07:20:44 +00001118 .Case("extern", MMToken::ExternKeyword)
Douglas Gregor755b2052011-11-17 22:09:43 +00001119 .Case("framework", MMToken::FrameworkKeyword)
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001120 .Case("header", MMToken::HeaderKeyword)
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001121 .Case("link", MMToken::LinkKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001122 .Case("module", MMToken::ModuleKeyword)
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001123 .Case("private", MMToken::PrivateKeyword)
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001124 .Case("requires", MMToken::RequiresKeyword)
Richard Smith306d8922014-10-22 23:50:56 +00001125 .Case("textual", MMToken::TextualKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001126 .Case("umbrella", MMToken::UmbrellaKeyword)
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001127 .Case("use", MMToken::UseKeyword)
Douglas Gregor718292f2011-11-11 19:10:28 +00001128 .Default(MMToken::Identifier);
1129 break;
Alp Toker2d57cea2014-05-17 04:53:25 +00001130 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001131
1132 case tok::comma:
1133 Tok.Kind = MMToken::Comma;
1134 break;
1135
Douglas Gregor718292f2011-11-11 19:10:28 +00001136 case tok::eof:
1137 Tok.Kind = MMToken::EndOfFile;
1138 break;
1139
1140 case tok::l_brace:
1141 Tok.Kind = MMToken::LBrace;
1142 break;
1143
Douglas Gregora686e1b2012-01-27 19:52:33 +00001144 case tok::l_square:
1145 Tok.Kind = MMToken::LSquare;
1146 break;
1147
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001148 case tok::period:
1149 Tok.Kind = MMToken::Period;
1150 break;
1151
Douglas Gregor718292f2011-11-11 19:10:28 +00001152 case tok::r_brace:
1153 Tok.Kind = MMToken::RBrace;
1154 break;
1155
Douglas Gregora686e1b2012-01-27 19:52:33 +00001156 case tok::r_square:
1157 Tok.Kind = MMToken::RSquare;
1158 break;
1159
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001160 case tok::star:
1161 Tok.Kind = MMToken::Star;
1162 break;
1163
Richard Smitha3feee22013-10-28 22:18:19 +00001164 case tok::exclaim:
1165 Tok.Kind = MMToken::Exclaim;
1166 break;
1167
Douglas Gregor718292f2011-11-11 19:10:28 +00001168 case tok::string_literal: {
Richard Smithd67aea22012-03-06 03:21:47 +00001169 if (LToken.hasUDSuffix()) {
1170 Diags.Report(LToken.getLocation(), diag::err_invalid_string_udl);
1171 HadError = true;
1172 goto retry;
1173 }
1174
Douglas Gregor718292f2011-11-11 19:10:28 +00001175 // Parse the string literal.
1176 LangOptions LangOpts;
Craig Topper9d5583e2014-06-26 04:58:39 +00001177 StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
Douglas Gregor718292f2011-11-11 19:10:28 +00001178 if (StringLiteral.hadError)
1179 goto retry;
1180
1181 // Copy the string literal into our string data allocator.
1182 unsigned Length = StringLiteral.GetStringLength();
1183 char *Saved = StringData.Allocate<char>(Length + 1);
1184 memcpy(Saved, StringLiteral.GetString().data(), Length);
1185 Saved[Length] = 0;
1186
1187 // Form the token.
1188 Tok.Kind = MMToken::StringLiteral;
1189 Tok.StringData = Saved;
1190 Tok.StringLength = Length;
1191 break;
1192 }
1193
1194 case tok::comment:
1195 goto retry;
1196
1197 default:
1198 Diags.Report(LToken.getLocation(), diag::err_mmap_unknown_token);
1199 HadError = true;
1200 goto retry;
1201 }
1202
1203 return Result;
1204}
1205
1206void ModuleMapParser::skipUntil(MMToken::TokenKind K) {
1207 unsigned braceDepth = 0;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001208 unsigned squareDepth = 0;
Douglas Gregor718292f2011-11-11 19:10:28 +00001209 do {
1210 switch (Tok.Kind) {
1211 case MMToken::EndOfFile:
1212 return;
1213
1214 case MMToken::LBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001215 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
Douglas Gregor718292f2011-11-11 19:10:28 +00001216 return;
1217
1218 ++braceDepth;
1219 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001220
1221 case MMToken::LSquare:
1222 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1223 return;
1224
1225 ++squareDepth;
1226 break;
1227
Douglas Gregor718292f2011-11-11 19:10:28 +00001228 case MMToken::RBrace:
1229 if (braceDepth > 0)
1230 --braceDepth;
1231 else if (Tok.is(K))
1232 return;
1233 break;
Douglas Gregora686e1b2012-01-27 19:52:33 +00001234
1235 case MMToken::RSquare:
1236 if (squareDepth > 0)
1237 --squareDepth;
1238 else if (Tok.is(K))
1239 return;
1240 break;
1241
Douglas Gregor718292f2011-11-11 19:10:28 +00001242 default:
Douglas Gregora686e1b2012-01-27 19:52:33 +00001243 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
Douglas Gregor718292f2011-11-11 19:10:28 +00001244 return;
1245 break;
1246 }
1247
1248 consumeToken();
1249 } while (true);
1250}
1251
Douglas Gregore7ab3662011-12-07 02:23:45 +00001252/// \brief Parse a module-id.
1253///
1254/// module-id:
1255/// identifier
1256/// identifier '.' module-id
1257///
1258/// \returns true if an error occurred, false otherwise.
1259bool ModuleMapParser::parseModuleId(ModuleId &Id) {
1260 Id.clear();
1261 do {
Daniel Jasper3cd34c72013-12-06 09:25:54 +00001262 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001263 Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
1264 consumeToken();
1265 } else {
1266 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1267 return true;
1268 }
1269
1270 if (!Tok.is(MMToken::Period))
1271 break;
1272
1273 consumeToken();
1274 } while (true);
1275
1276 return false;
1277}
1278
Douglas Gregora686e1b2012-01-27 19:52:33 +00001279namespace {
1280 /// \brief Enumerates the known attributes.
1281 enum AttributeKind {
1282 /// \brief An unknown attribute.
1283 AT_unknown,
1284 /// \brief The 'system' attribute.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001285 AT_system,
Richard Smith77944862014-03-02 05:58:18 +00001286 /// \brief The 'extern_c' attribute.
1287 AT_extern_c,
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001288 /// \brief The 'exhaustive' attribute.
1289 AT_exhaustive
Douglas Gregora686e1b2012-01-27 19:52:33 +00001290 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001291}
Douglas Gregora686e1b2012-01-27 19:52:33 +00001292
Douglas Gregor718292f2011-11-11 19:10:28 +00001293/// \brief Parse a module declaration.
1294///
1295/// module-declaration:
Daniel Jasper97292842013-09-11 07:20:44 +00001296/// 'extern' 'module' module-id string-literal
Douglas Gregora686e1b2012-01-27 19:52:33 +00001297/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt]
1298/// { module-member* }
1299///
Douglas Gregor718292f2011-11-11 19:10:28 +00001300/// module-member:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001301/// requires-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001302/// header-declaration
Douglas Gregore7ab3662011-12-07 02:23:45 +00001303/// submodule-declaration
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001304/// export-declaration
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001305/// link-declaration
Douglas Gregor73441092011-12-05 22:27:44 +00001306///
1307/// submodule-declaration:
1308/// module-declaration
1309/// inferred-submodule-declaration
Douglas Gregor718292f2011-11-11 19:10:28 +00001310void ModuleMapParser::parseModuleDecl() {
Douglas Gregor755b2052011-11-17 22:09:43 +00001311 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
Daniel Jasper97292842013-09-11 07:20:44 +00001312 Tok.is(MMToken::FrameworkKeyword) || Tok.is(MMToken::ExternKeyword));
1313 if (Tok.is(MMToken::ExternKeyword)) {
1314 parseExternModuleDecl();
1315 return;
1316 }
1317
Douglas Gregorf2161a72011-12-06 17:16:41 +00001318 // Parse 'explicit' or 'framework' keyword, if present.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001319 SourceLocation ExplicitLoc;
Douglas Gregor718292f2011-11-11 19:10:28 +00001320 bool Explicit = false;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001321 bool Framework = false;
Douglas Gregor755b2052011-11-17 22:09:43 +00001322
Douglas Gregorf2161a72011-12-06 17:16:41 +00001323 // Parse 'explicit' keyword, if present.
1324 if (Tok.is(MMToken::ExplicitKeyword)) {
Douglas Gregore7ab3662011-12-07 02:23:45 +00001325 ExplicitLoc = consumeToken();
Douglas Gregorf2161a72011-12-06 17:16:41 +00001326 Explicit = true;
1327 }
1328
1329 // Parse 'framework' keyword, if present.
Douglas Gregor755b2052011-11-17 22:09:43 +00001330 if (Tok.is(MMToken::FrameworkKeyword)) {
1331 consumeToken();
1332 Framework = true;
1333 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001334
1335 // Parse 'module' keyword.
1336 if (!Tok.is(MMToken::ModuleKeyword)) {
Douglas Gregord6343c92011-12-06 19:57:48 +00001337 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
Douglas Gregor718292f2011-11-11 19:10:28 +00001338 consumeToken();
1339 HadError = true;
1340 return;
1341 }
1342 consumeToken(); // 'module' keyword
Douglas Gregor73441092011-12-05 22:27:44 +00001343
1344 // If we have a wildcard for the module name, this is an inferred submodule.
1345 // Parse it.
1346 if (Tok.is(MMToken::Star))
Douglas Gregor9194a912012-11-06 19:39:40 +00001347 return parseInferredModuleDecl(Framework, Explicit);
Douglas Gregor718292f2011-11-11 19:10:28 +00001348
1349 // Parse the module name.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001350 ModuleId Id;
1351 if (parseModuleId(Id)) {
Douglas Gregor718292f2011-11-11 19:10:28 +00001352 HadError = true;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001353 return;
Douglas Gregor718292f2011-11-11 19:10:28 +00001354 }
Douglas Gregor9194a912012-11-06 19:39:40 +00001355
Douglas Gregore7ab3662011-12-07 02:23:45 +00001356 if (ActiveModule) {
1357 if (Id.size() > 1) {
1358 Diags.Report(Id.front().second, diag::err_mmap_nested_submodule_id)
1359 << SourceRange(Id.front().second, Id.back().second);
1360
1361 HadError = true;
1362 return;
1363 }
1364 } else if (Id.size() == 1 && Explicit) {
1365 // Top-level modules can't be explicit.
1366 Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
1367 Explicit = false;
1368 ExplicitLoc = SourceLocation();
1369 HadError = true;
1370 }
1371
1372 Module *PreviousActiveModule = ActiveModule;
1373 if (Id.size() > 1) {
1374 // This module map defines a submodule. Go find the module of which it
1375 // is a submodule.
Craig Topperd2d442c2014-05-17 23:10:59 +00001376 ActiveModule = nullptr;
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001377 const Module *TopLevelModule = nullptr;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001378 for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
1379 if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001380 if (I == 0)
1381 TopLevelModule = Next;
Douglas Gregore7ab3662011-12-07 02:23:45 +00001382 ActiveModule = Next;
1383 continue;
1384 }
1385
1386 if (ActiveModule) {
1387 Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
Richard Smith5b5d21e2014-03-12 23:36:42 +00001388 << Id[I].first
1389 << ActiveModule->getTopLevelModule()->getFullModuleName();
Douglas Gregore7ab3662011-12-07 02:23:45 +00001390 } else {
1391 Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
1392 }
1393 HadError = true;
1394 return;
1395 }
Ben Langmuir4b8a9e92014-08-12 16:42:33 +00001396
1397 if (ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
1398 assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
1399 "submodule defined in same file as 'module *' that allowed its "
1400 "top-level module");
1401 Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
1402 }
1403 }
Douglas Gregore7ab3662011-12-07 02:23:45 +00001404
1405 StringRef ModuleName = Id.back().first;
1406 SourceLocation ModuleNameLoc = Id.back().second;
Douglas Gregor718292f2011-11-11 19:10:28 +00001407
Douglas Gregora686e1b2012-01-27 19:52:33 +00001408 // Parse the optional attribute list.
Bill Wendling44426052012-12-20 19:22:21 +00001409 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00001410 parseOptionalAttributes(Attrs);
Douglas Gregora686e1b2012-01-27 19:52:33 +00001411
Douglas Gregor718292f2011-11-11 19:10:28 +00001412 // Parse the opening brace.
1413 if (!Tok.is(MMToken::LBrace)) {
1414 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
1415 << ModuleName;
1416 HadError = true;
1417 return;
1418 }
1419 SourceLocation LBraceLoc = consumeToken();
1420
1421 // Determine whether this (sub)module has already been defined.
Douglas Gregoreb90e832012-01-04 23:32:19 +00001422 if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
Douglas Gregorfcc54a32012-01-05 00:12:00 +00001423 if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
1424 // Skip the module definition.
1425 skipUntil(MMToken::RBrace);
1426 if (Tok.is(MMToken::RBrace))
1427 consumeToken();
1428 else {
1429 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1430 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1431 HadError = true;
1432 }
1433 return;
1434 }
1435
Douglas Gregor718292f2011-11-11 19:10:28 +00001436 Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
1437 << ModuleName;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001438 Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
Douglas Gregor718292f2011-11-11 19:10:28 +00001439
1440 // Skip the module definition.
1441 skipUntil(MMToken::RBrace);
1442 if (Tok.is(MMToken::RBrace))
1443 consumeToken();
1444
1445 HadError = true;
1446 return;
1447 }
1448
1449 // Start defining this module.
Ben Langmuir9d6448b2014-08-09 00:57:23 +00001450 ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
1451 Explicit).first;
Douglas Gregoreb90e832012-01-04 23:32:19 +00001452 ActiveModule->DefinitionLoc = ModuleNameLoc;
Douglas Gregor963c5532013-06-21 16:28:10 +00001453 if (Attrs.IsSystem || IsSystem)
Douglas Gregora686e1b2012-01-27 19:52:33 +00001454 ActiveModule->IsSystem = true;
Richard Smith77944862014-03-02 05:58:18 +00001455 if (Attrs.IsExternC)
1456 ActiveModule->IsExternC = true;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001457 ActiveModule->Directory = Directory;
Richard Smith77944862014-03-02 05:58:18 +00001458
Douglas Gregor718292f2011-11-11 19:10:28 +00001459 bool Done = false;
1460 do {
1461 switch (Tok.Kind) {
1462 case MMToken::EndOfFile:
1463 case MMToken::RBrace:
1464 Done = true;
1465 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00001466
1467 case MMToken::ConfigMacros:
1468 parseConfigMacros();
1469 break;
1470
Douglas Gregorfb912652013-03-20 21:10:35 +00001471 case MMToken::Conflict:
1472 parseConflict();
1473 break;
1474
Douglas Gregor718292f2011-11-11 19:10:28 +00001475 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00001476 case MMToken::ExternKeyword:
Douglas Gregorf2161a72011-12-06 17:16:41 +00001477 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00001478 case MMToken::ModuleKeyword:
1479 parseModuleDecl();
1480 break;
Daniel Jasper97292842013-09-11 07:20:44 +00001481
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001482 case MMToken::ExportKeyword:
1483 parseExportDecl();
1484 break;
Daniel Jasperba7f2f72013-09-24 09:14:14 +00001485
1486 case MMToken::UseKeyword:
1487 parseUseDecl();
1488 break;
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001489
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001490 case MMToken::RequiresKeyword:
1491 parseRequiresDecl();
1492 break;
1493
Richard Smith202210b2014-10-24 20:23:01 +00001494 case MMToken::TextualKeyword:
1495 parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
Richard Smith306d8922014-10-22 23:50:56 +00001496 break;
Richard Smith306d8922014-10-22 23:50:56 +00001497
Douglas Gregor524e33e2011-12-08 19:11:24 +00001498 case MMToken::UmbrellaKeyword: {
1499 SourceLocation UmbrellaLoc = consumeToken();
1500 if (Tok.is(MMToken::HeaderKeyword))
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001501 parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001502 else
1503 parseUmbrellaDirDecl(UmbrellaLoc);
Douglas Gregor718292f2011-11-11 19:10:28 +00001504 break;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001505 }
Richard Smith202210b2014-10-24 20:23:01 +00001506
1507 case MMToken::ExcludeKeyword:
1508 parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
Douglas Gregor59527662012-10-15 06:28:11 +00001509 break;
Richard Smith202210b2014-10-24 20:23:01 +00001510
1511 case MMToken::PrivateKeyword:
1512 parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001513 break;
Richard Smith202210b2014-10-24 20:23:01 +00001514
Douglas Gregor322f6332011-12-08 18:00:48 +00001515 case MMToken::HeaderKeyword:
Richard Smith202210b2014-10-24 20:23:01 +00001516 parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
Douglas Gregor718292f2011-11-11 19:10:28 +00001517 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00001518
1519 case MMToken::LinkKeyword:
1520 parseLinkDecl();
1521 break;
1522
Douglas Gregor718292f2011-11-11 19:10:28 +00001523 default:
1524 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
1525 consumeToken();
1526 break;
1527 }
1528 } while (!Done);
1529
1530 if (Tok.is(MMToken::RBrace))
1531 consumeToken();
1532 else {
1533 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
1534 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
1535 HadError = true;
1536 }
1537
Douglas Gregor11dfe6f2013-01-14 17:57:51 +00001538 // If the active module is a top-level framework, and there are no link
1539 // libraries, automatically link against the framework.
1540 if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
1541 ActiveModule->LinkLibraries.empty()) {
1542 inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
1543 }
1544
Ben Langmuirec8c9752014-04-18 22:07:31 +00001545 // If the module meets all requirements but is still unavailable, mark the
1546 // whole tree as unavailable to prevent it from building.
1547 if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
1548 ActiveModule->Parent) {
1549 ActiveModule->getTopLevelModule()->markUnavailable();
1550 ActiveModule->getTopLevelModule()->MissingHeaders.append(
1551 ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
1552 }
1553
Douglas Gregore7ab3662011-12-07 02:23:45 +00001554 // We're done parsing this module. Pop back to the previous module.
1555 ActiveModule = PreviousActiveModule;
Douglas Gregor718292f2011-11-11 19:10:28 +00001556}
Douglas Gregorf2161a72011-12-06 17:16:41 +00001557
Daniel Jasper97292842013-09-11 07:20:44 +00001558/// \brief Parse an extern module declaration.
1559///
1560/// extern module-declaration:
1561/// 'extern' 'module' module-id string-literal
1562void ModuleMapParser::parseExternModuleDecl() {
1563 assert(Tok.is(MMToken::ExternKeyword));
Richard Smithae6df272015-07-14 02:06:01 +00001564 SourceLocation ExternLoc = consumeToken(); // 'extern' keyword
Daniel Jasper97292842013-09-11 07:20:44 +00001565
1566 // Parse 'module' keyword.
1567 if (!Tok.is(MMToken::ModuleKeyword)) {
1568 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
1569 consumeToken();
1570 HadError = true;
1571 return;
1572 }
1573 consumeToken(); // 'module' keyword
1574
1575 // Parse the module name.
1576 ModuleId Id;
1577 if (parseModuleId(Id)) {
1578 HadError = true;
1579 return;
1580 }
1581
1582 // Parse the referenced module map file name.
1583 if (!Tok.is(MMToken::StringLiteral)) {
1584 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
1585 HadError = true;
1586 return;
1587 }
1588 std::string FileName = Tok.getString();
1589 consumeToken(); // filename
1590
1591 StringRef FileNameRef = FileName;
1592 SmallString<128> ModuleMapFileName;
1593 if (llvm::sys::path::is_relative(FileNameRef)) {
1594 ModuleMapFileName += Directory->getName();
1595 llvm::sys::path::append(ModuleMapFileName, FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001596 FileNameRef = ModuleMapFileName;
Daniel Jasper97292842013-09-11 07:20:44 +00001597 }
1598 if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Richard Smith9acb99e32014-12-10 03:09:48 +00001599 Map.parseModuleMapFile(
1600 File, /*IsSystem=*/false,
1601 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
1602 ? Directory
Richard Smithae6df272015-07-14 02:06:01 +00001603 : File->getDir(), ExternLoc);
Daniel Jasper97292842013-09-11 07:20:44 +00001604}
1605
Ben Langmuir7ff29142015-08-13 17:13:33 +00001606/// Whether to add the requirement \p Feature to the module \p M.
1607///
1608/// This preserves backwards compatibility for two hacks in the Darwin system
1609/// module map files:
1610///
1611/// 1. The use of 'requires excluded' to make headers non-modular, which
1612/// should really be mapped to 'textual' now that we have this feature. We
1613/// drop the 'excluded' requirement, and set \p IsRequiresExcludedHack to
1614/// true. Later, this bit will be used to map all the headers inside this
1615/// module to 'textual'.
1616///
1617/// This affects Darwin.C.excluded (for assert.h) and Tcl.Private.
1618///
1619/// 2. Removes a bogus cplusplus requirement from IOKit.avc. This requirement
1620/// was never correct and causes issues now that we check it, so drop it.
1621static bool shouldAddRequirement(Module *M, StringRef Feature,
1622 bool &IsRequiresExcludedHack) {
1623 static const StringRef DarwinCExcluded[] = {"Darwin", "C", "excluded"};
1624 static const StringRef TclPrivate[] = {"Tcl", "Private"};
1625 static const StringRef IOKitAVC[] = {"IOKit", "avc"};
1626
1627 if (Feature == "excluded" && (M->fullModuleNameIs(DarwinCExcluded) ||
1628 M->fullModuleNameIs(TclPrivate))) {
1629 IsRequiresExcludedHack = true;
1630 return false;
1631 } else if (Feature == "cplusplus" && M->fullModuleNameIs(IOKitAVC)) {
1632 return false;
1633 }
1634
1635 return true;
1636}
1637
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001638/// \brief Parse a requires declaration.
1639///
1640/// requires-declaration:
1641/// 'requires' feature-list
1642///
1643/// feature-list:
Richard Smitha3feee22013-10-28 22:18:19 +00001644/// feature ',' feature-list
1645/// feature
1646///
1647/// feature:
1648/// '!'[opt] identifier
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001649void ModuleMapParser::parseRequiresDecl() {
1650 assert(Tok.is(MMToken::RequiresKeyword));
1651
1652 // Parse 'requires' keyword.
1653 consumeToken();
1654
1655 // Parse the feature-list.
1656 do {
Richard Smitha3feee22013-10-28 22:18:19 +00001657 bool RequiredState = true;
1658 if (Tok.is(MMToken::Exclaim)) {
1659 RequiredState = false;
1660 consumeToken();
1661 }
1662
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001663 if (!Tok.is(MMToken::Identifier)) {
1664 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_feature);
1665 HadError = true;
1666 return;
1667 }
1668
1669 // Consume the feature name.
1670 std::string Feature = Tok.getString();
1671 consumeToken();
1672
Ben Langmuir7ff29142015-08-13 17:13:33 +00001673 bool IsRequiresExcludedHack = false;
1674 bool ShouldAddRequirement =
1675 shouldAddRequirement(ActiveModule, Feature, IsRequiresExcludedHack);
1676
1677 if (IsRequiresExcludedHack)
1678 UsesRequiresExcludedHack.insert(ActiveModule);
1679
1680 if (ShouldAddRequirement) {
1681 // Add this feature.
1682 ActiveModule->addRequirement(Feature, RequiredState, Map.LangOpts,
1683 *Map.Target);
1684 }
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00001685
1686 if (!Tok.is(MMToken::Comma))
1687 break;
1688
1689 // Consume the comma.
1690 consumeToken();
1691 } while (true);
1692}
1693
Douglas Gregorf2161a72011-12-06 17:16:41 +00001694/// \brief Append to \p Paths the set of paths needed to get to the
1695/// subframework in which the given module lives.
Benjamin Kramerbf8da9d2012-02-06 11:13:08 +00001696static void appendSubframeworkPaths(Module *Mod,
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001697 SmallVectorImpl<char> &Path) {
Douglas Gregorf2161a72011-12-06 17:16:41 +00001698 // Collect the framework names from the given module to the top-level module.
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001699 SmallVector<StringRef, 2> Paths;
Douglas Gregorf2161a72011-12-06 17:16:41 +00001700 for (; Mod; Mod = Mod->Parent) {
1701 if (Mod->IsFramework)
1702 Paths.push_back(Mod->Name);
1703 }
1704
1705 if (Paths.empty())
1706 return;
1707
1708 // Add Frameworks/Name.framework for each subframework.
Benjamin Kramer17381a02013-06-28 16:25:46 +00001709 for (unsigned I = Paths.size() - 1; I != 0; --I)
1710 llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
Douglas Gregorf2161a72011-12-06 17:16:41 +00001711}
1712
Douglas Gregor718292f2011-11-11 19:10:28 +00001713/// \brief Parse a header declaration.
1714///
1715/// header-declaration:
Richard Smith306d8922014-10-22 23:50:56 +00001716/// 'textual'[opt] 'header' string-literal
Richard Smith202210b2014-10-24 20:23:01 +00001717/// 'private' 'textual'[opt] 'header' string-literal
1718/// 'exclude' 'header' string-literal
1719/// 'umbrella' 'header' string-literal
Richard Smith306d8922014-10-22 23:50:56 +00001720///
1721/// FIXME: Support 'private textual header'.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001722void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
1723 SourceLocation LeadingLoc) {
Richard Smith202210b2014-10-24 20:23:01 +00001724 // We've already consumed the first token.
1725 ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
1726 if (LeadingToken == MMToken::PrivateKeyword) {
1727 Role = ModuleMap::PrivateHeader;
1728 // 'private' may optionally be followed by 'textual'.
1729 if (Tok.is(MMToken::TextualKeyword)) {
1730 LeadingToken = Tok.Kind;
1731 consumeToken();
1732 }
1733 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001734
Richard Smith202210b2014-10-24 20:23:01 +00001735 if (LeadingToken == MMToken::TextualKeyword)
1736 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1737
Ben Langmuir7ff29142015-08-13 17:13:33 +00001738 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1739 // Mark this header 'textual' (see doc comment for
1740 // Module::UsesRequiresExcludedHack).
1741 Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
1742 }
1743
Richard Smith202210b2014-10-24 20:23:01 +00001744 if (LeadingToken != MMToken::HeaderKeyword) {
1745 if (!Tok.is(MMToken::HeaderKeyword)) {
1746 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1747 << (LeadingToken == MMToken::PrivateKeyword ? "private" :
1748 LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
1749 LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
1750 return;
1751 }
1752 consumeToken();
1753 }
Benjamin Kramer1871ed32011-11-13 16:52:09 +00001754
Douglas Gregor718292f2011-11-11 19:10:28 +00001755 // Parse the header name.
1756 if (!Tok.is(MMToken::StringLiteral)) {
1757 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1758 << "header";
1759 HadError = true;
1760 return;
1761 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001762 Module::UnresolvedHeaderDirective Header;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001763 Header.FileName = Tok.getString();
1764 Header.FileNameLoc = consumeToken();
Douglas Gregor718292f2011-11-11 19:10:28 +00001765
Douglas Gregor524e33e2011-12-08 19:11:24 +00001766 // Check whether we already have an umbrella.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001767 if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001768 Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor524e33e2011-12-08 19:11:24 +00001769 << ActiveModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001770 HadError = true;
1771 return;
1772 }
1773
Douglas Gregor5257fc62011-11-11 21:55:48 +00001774 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001775 const FileEntry *File = nullptr;
1776 const FileEntry *BuiltinFile = nullptr;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001777 SmallString<128> RelativePathName;
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001778 if (llvm::sys::path::is_absolute(Header.FileName)) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001779 RelativePathName = Header.FileName;
1780 File = SourceMgr.getFileManager().getFile(RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001781 } else {
1782 // Search for the header file within the search directory.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001783 SmallString<128> FullPathName(Directory->getName());
1784 unsigned FullPathLength = FullPathName.size();
Douglas Gregorf545f672011-11-29 21:59:16 +00001785
Douglas Gregorf2161a72011-12-06 17:16:41 +00001786 if (ActiveModule->isPartOfFramework()) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001787 appendSubframeworkPaths(ActiveModule, RelativePathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001788
1789 // Check whether this file is in the public headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001790 llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001791 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001792 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001793
1794 if (!File) {
1795 // Check whether this file is in the private headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001796 // FIXME: Should we retain the subframework paths here?
1797 RelativePathName.clear();
1798 FullPathName.resize(FullPathLength);
1799 llvm::sys::path::append(RelativePathName, "PrivateHeaders",
1800 Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001801 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001802 File = SourceMgr.getFileManager().getFile(FullPathName);
Douglas Gregore7ab3662011-12-07 02:23:45 +00001803 }
1804 } else {
1805 // Lookup for normal headers.
Richard Smith3c1a41a2014-12-02 00:08:08 +00001806 llvm::sys::path::append(RelativePathName, Header.FileName);
Yaron Keren92e1b622015-03-18 10:17:07 +00001807 llvm::sys::path::append(FullPathName, RelativePathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001808 File = SourceMgr.getFileManager().getFile(FullPathName);
1809
Douglas Gregor3ec66632012-02-02 18:42:48 +00001810 // If this is a system module with a top-level header, this header
1811 // may have a counterpart (or replacement) in the set of headers
1812 // supplied by Clang. Find that builtin header.
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001813 if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
1814 BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001815 isBuiltinHeader(Header.FileName)) {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001816 SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001817 llvm::sys::path::append(BuiltinPathName, Header.FileName);
Douglas Gregor3ec66632012-02-02 18:42:48 +00001818 BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
Richard Smith3c1a41a2014-12-02 00:08:08 +00001819
Douglas Gregor3ec66632012-02-02 18:42:48 +00001820 // If Clang supplies this header but the underlying system does not,
1821 // just silently swap in our builtin version. Otherwise, we'll end
1822 // up adding both (later).
Richard Smith42413142015-05-15 20:05:43 +00001823 //
1824 // For local visibility, entirely replace the system file with our
1825 // one and textually include the system one. We need to pass macros
1826 // from our header to the system one if we #include_next it.
1827 //
1828 // FIXME: Can we do this in all cases?
1829 if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
Douglas Gregor3ec66632012-02-02 18:42:48 +00001830 File = BuiltinFile;
Richard Smith3c1a41a2014-12-02 00:08:08 +00001831 RelativePathName = BuiltinPathName;
Craig Topperd2d442c2014-05-17 23:10:59 +00001832 BuiltinFile = nullptr;
Douglas Gregor3ec66632012-02-02 18:42:48 +00001833 }
1834 }
Douglas Gregorf2161a72011-12-06 17:16:41 +00001835 }
Douglas Gregorf545f672011-11-29 21:59:16 +00001836 }
Richard Smith3c1a41a2014-12-02 00:08:08 +00001837
Douglas Gregor5257fc62011-11-11 21:55:48 +00001838 // FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
1839 // Come up with a lazy way to do this.
Douglas Gregore7ab3662011-12-07 02:23:45 +00001840 if (File) {
Daniel Jasper97da9172013-10-22 08:09:47 +00001841 if (LeadingToken == MMToken::UmbrellaKeyword) {
Douglas Gregor322f6332011-12-08 18:00:48 +00001842 const DirectoryEntry *UmbrellaDir = File->getDir();
Douglas Gregor59527662012-10-15 06:28:11 +00001843 if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001844 Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
Douglas Gregor59527662012-10-15 06:28:11 +00001845 << UmbrellaModule->getFullModuleName();
Douglas Gregor322f6332011-12-08 18:00:48 +00001846 HadError = true;
1847 } else {
1848 // Record this umbrella header.
Richard Smith2b63d152015-05-16 02:28:53 +00001849 Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
Douglas Gregor322f6332011-12-08 18:00:48 +00001850 }
Richard Smithfeb54b62014-10-23 02:01:19 +00001851 } else if (LeadingToken == MMToken::ExcludeKeyword) {
Hans Wennborg0101b542014-12-02 02:13:09 +00001852 Module::Header H = {RelativePathName.str(), File};
1853 Map.excludeHeader(ActiveModule, H);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001854 } else {
Richard Smith25d50752014-10-20 00:15:49 +00001855 // If there is a builtin counterpart to this file, add it now, before
1856 // the "real" header, so we build the built-in one first when building
1857 // the module.
Hans Wennborg0101b542014-12-02 02:13:09 +00001858 if (BuiltinFile) {
Richard Smith3c1a41a2014-12-02 00:08:08 +00001859 // FIXME: Taking the name from the FileEntry is unstable and can give
1860 // different results depending on how we've previously named that file
1861 // in this build.
Hans Wennborg0101b542014-12-02 02:13:09 +00001862 Module::Header H = { BuiltinFile->getName(), BuiltinFile };
1863 Map.addHeader(ActiveModule, H, Role);
1864 }
Richard Smith25d50752014-10-20 00:15:49 +00001865
Richard Smith202210b2014-10-24 20:23:01 +00001866 // Record this header.
Hans Wennborg0101b542014-12-02 02:13:09 +00001867 Module::Header H = { RelativePathName.str(), File };
1868 Map.addHeader(ActiveModule, H, Role);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001869 }
Lawrence Crowlb53e5482013-06-20 21:14:14 +00001870 } else if (LeadingToken != MMToken::ExcludeKeyword) {
Douglas Gregor4b27a642012-11-15 19:47:16 +00001871 // Ignore excluded header files. They're optional anyway.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001872
1873 // If we find a module that has a missing header, we mark this module as
1874 // unavailable and store the header directive for displaying diagnostics.
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001875 Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
Ben Langmuirec8c9752014-04-18 22:07:31 +00001876 ActiveModule->markUnavailable();
Daniel Jasper0761a8a2013-12-17 10:31:37 +00001877 ActiveModule->MissingHeaders.push_back(Header);
Douglas Gregor5257fc62011-11-11 21:55:48 +00001878 }
Douglas Gregor718292f2011-11-11 19:10:28 +00001879}
1880
Ben Langmuir41f81992015-08-13 17:30:07 +00001881static int compareModuleHeaders(const Module::Header *A,
1882 const Module::Header *B) {
1883 return A->NameAsWritten.compare(B->NameAsWritten);
1884}
1885
Douglas Gregor524e33e2011-12-08 19:11:24 +00001886/// \brief Parse an umbrella directory declaration.
1887///
1888/// umbrella-dir-declaration:
1889/// umbrella string-literal
1890void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
1891 // Parse the directory name.
1892 if (!Tok.is(MMToken::StringLiteral)) {
1893 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
1894 << "umbrella";
1895 HadError = true;
1896 return;
1897 }
1898
1899 std::string DirName = Tok.getString();
1900 SourceLocation DirNameLoc = consumeToken();
1901
1902 // Check whether we already have an umbrella.
1903 if (ActiveModule->Umbrella) {
1904 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_clash)
1905 << ActiveModule->getFullModuleName();
1906 HadError = true;
1907 return;
1908 }
1909
1910 // Look for this file.
Craig Topperd2d442c2014-05-17 23:10:59 +00001911 const DirectoryEntry *Dir = nullptr;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001912 if (llvm::sys::path::is_absolute(DirName))
1913 Dir = SourceMgr.getFileManager().getDirectory(DirName);
1914 else {
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +00001915 SmallString<128> PathName;
Douglas Gregor524e33e2011-12-08 19:11:24 +00001916 PathName = Directory->getName();
1917 llvm::sys::path::append(PathName, DirName);
1918 Dir = SourceMgr.getFileManager().getDirectory(PathName);
1919 }
1920
1921 if (!Dir) {
1922 Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
1923 << DirName;
1924 HadError = true;
1925 return;
1926 }
Ben Langmuir7ff29142015-08-13 17:13:33 +00001927
1928 if (UsesRequiresExcludedHack.count(ActiveModule)) {
1929 // Mark this header 'textual' (see doc comment for
1930 // ModuleMapParser::UsesRequiresExcludedHack). Although iterating over the
1931 // directory is relatively expensive, in practice this only applies to the
1932 // uncommonly used Tcl module on Darwin platforms.
1933 std::error_code EC;
1934 SmallVector<Module::Header, 6> Headers;
1935 for (llvm::sys::fs::recursive_directory_iterator I(Dir->getName(), EC), E;
1936 I != E && !EC; I.increment(EC)) {
1937 if (const FileEntry *FE = SourceMgr.getFileManager().getFile(I->path())) {
1938
1939 Module::Header Header = {I->path(), FE};
1940 Headers.push_back(std::move(Header));
1941 }
1942 }
1943
1944 // Sort header paths so that the pcm doesn't depend on iteration order.
Ben Langmuir41f81992015-08-13 17:30:07 +00001945 llvm::array_pod_sort(Headers.begin(), Headers.end(), compareModuleHeaders);
1946
Ben Langmuir7ff29142015-08-13 17:13:33 +00001947 for (auto &Header : Headers)
1948 Map.addHeader(ActiveModule, std::move(Header), ModuleMap::TextualHeader);
1949 return;
1950 }
1951
Douglas Gregor524e33e2011-12-08 19:11:24 +00001952 if (Module *OwningModule = Map.UmbrellaDirs[Dir]) {
1953 Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_clash)
1954 << OwningModule->getFullModuleName();
1955 HadError = true;
1956 return;
Ben Langmuir7ff29142015-08-13 17:13:33 +00001957 }
1958
Douglas Gregor524e33e2011-12-08 19:11:24 +00001959 // Record this umbrella directory.
Richard Smith2b63d152015-05-16 02:28:53 +00001960 Map.setUmbrellaDir(ActiveModule, Dir, DirName);
Douglas Gregor524e33e2011-12-08 19:11:24 +00001961}
1962
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001963/// \brief Parse a module export declaration.
1964///
1965/// export-declaration:
1966/// 'export' wildcard-module-id
1967///
1968/// wildcard-module-id:
1969/// identifier
1970/// '*'
1971/// identifier '.' wildcard-module-id
1972void ModuleMapParser::parseExportDecl() {
1973 assert(Tok.is(MMToken::ExportKeyword));
1974 SourceLocation ExportLoc = consumeToken();
1975
1976 // Parse the module-id with an optional wildcard at the end.
1977 ModuleId ParsedModuleId;
1978 bool Wildcard = false;
1979 do {
Richard Smith306d8922014-10-22 23:50:56 +00001980 // FIXME: Support string-literal module names here.
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001981 if (Tok.is(MMToken::Identifier)) {
1982 ParsedModuleId.push_back(std::make_pair(Tok.getString(),
1983 Tok.getLocation()));
1984 consumeToken();
1985
1986 if (Tok.is(MMToken::Period)) {
1987 consumeToken();
1988 continue;
1989 }
1990
1991 break;
1992 }
1993
1994 if(Tok.is(MMToken::Star)) {
1995 Wildcard = true;
Douglas Gregorf5eedd02011-12-05 17:28:06 +00001996 consumeToken();
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00001997 break;
1998 }
1999
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002000 Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002001 HadError = true;
2002 return;
2003 } while (true);
2004
2005 Module::UnresolvedExportDecl Unresolved = {
2006 ExportLoc, ParsedModuleId, Wildcard
2007 };
2008 ActiveModule->UnresolvedExports.push_back(Unresolved);
2009}
2010
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002011/// \brief Parse a module use declaration.
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002012///
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002013/// use-declaration:
2014/// 'use' wildcard-module-id
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002015void ModuleMapParser::parseUseDecl() {
2016 assert(Tok.is(MMToken::UseKeyword));
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002017 auto KWLoc = consumeToken();
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002018 // Parse the module-id.
2019 ModuleId ParsedModuleId;
Daniel Jasper3cd34c72013-12-06 09:25:54 +00002020 parseModuleId(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002021
Richard Smith8f4d3ff2015-03-26 22:10:01 +00002022 if (ActiveModule->Parent)
2023 Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
2024 else
2025 ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002026}
2027
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002028/// \brief Parse a link declaration.
2029///
2030/// module-declaration:
2031/// 'link' 'framework'[opt] string-literal
2032void ModuleMapParser::parseLinkDecl() {
2033 assert(Tok.is(MMToken::LinkKeyword));
2034 SourceLocation LinkLoc = consumeToken();
2035
2036 // Parse the optional 'framework' keyword.
2037 bool IsFramework = false;
2038 if (Tok.is(MMToken::FrameworkKeyword)) {
2039 consumeToken();
2040 IsFramework = true;
2041 }
2042
2043 // Parse the library name
2044 if (!Tok.is(MMToken::StringLiteral)) {
2045 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
2046 << IsFramework << SourceRange(LinkLoc);
2047 HadError = true;
2048 return;
2049 }
2050
2051 std::string LibraryName = Tok.getString();
2052 consumeToken();
2053 ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
2054 IsFramework));
2055}
2056
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002057/// \brief Parse a configuration macro declaration.
2058///
2059/// module-declaration:
2060/// 'config_macros' attributes[opt] config-macro-list?
2061///
2062/// config-macro-list:
2063/// identifier (',' identifier)?
2064void ModuleMapParser::parseConfigMacros() {
2065 assert(Tok.is(MMToken::ConfigMacros));
2066 SourceLocation ConfigMacrosLoc = consumeToken();
2067
2068 // Only top-level modules can have configuration macros.
2069 if (ActiveModule->Parent) {
2070 Diags.Report(ConfigMacrosLoc, diag::err_mmap_config_macro_submodule);
2071 }
2072
2073 // Parse the optional attributes.
2074 Attributes Attrs;
2075 parseOptionalAttributes(Attrs);
2076 if (Attrs.IsExhaustive && !ActiveModule->Parent) {
2077 ActiveModule->ConfigMacrosExhaustive = true;
2078 }
2079
2080 // If we don't have an identifier, we're done.
Richard Smith306d8922014-10-22 23:50:56 +00002081 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002082 if (!Tok.is(MMToken::Identifier))
2083 return;
2084
2085 // Consume the first identifier.
2086 if (!ActiveModule->Parent) {
2087 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2088 }
2089 consumeToken();
2090
2091 do {
2092 // If there's a comma, consume it.
2093 if (!Tok.is(MMToken::Comma))
2094 break;
2095 consumeToken();
2096
2097 // We expect to see a macro name here.
Richard Smith306d8922014-10-22 23:50:56 +00002098 // FIXME: Support macros with the same name as a keyword here.
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002099 if (!Tok.is(MMToken::Identifier)) {
2100 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
2101 break;
2102 }
2103
2104 // Consume the macro name.
2105 if (!ActiveModule->Parent) {
2106 ActiveModule->ConfigMacros.push_back(Tok.getString().str());
2107 }
2108 consumeToken();
2109 } while (true);
2110}
2111
Douglas Gregorfb912652013-03-20 21:10:35 +00002112/// \brief Format a module-id into a string.
2113static std::string formatModuleId(const ModuleId &Id) {
2114 std::string result;
2115 {
2116 llvm::raw_string_ostream OS(result);
2117
2118 for (unsigned I = 0, N = Id.size(); I != N; ++I) {
2119 if (I)
2120 OS << ".";
2121 OS << Id[I].first;
2122 }
2123 }
2124
2125 return result;
2126}
2127
2128/// \brief Parse a conflict declaration.
2129///
2130/// module-declaration:
2131/// 'conflict' module-id ',' string-literal
2132void ModuleMapParser::parseConflict() {
2133 assert(Tok.is(MMToken::Conflict));
2134 SourceLocation ConflictLoc = consumeToken();
2135 Module::UnresolvedConflict Conflict;
2136
2137 // Parse the module-id.
2138 if (parseModuleId(Conflict.Id))
2139 return;
2140
2141 // Parse the ','.
2142 if (!Tok.is(MMToken::Comma)) {
2143 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
2144 << SourceRange(ConflictLoc);
2145 return;
2146 }
2147 consumeToken();
2148
2149 // Parse the message.
2150 if (!Tok.is(MMToken::StringLiteral)) {
2151 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
2152 << formatModuleId(Conflict.Id);
2153 return;
2154 }
2155 Conflict.Message = Tok.getString().str();
2156 consumeToken();
2157
2158 // Add this unresolved conflict.
2159 ActiveModule->UnresolvedConflicts.push_back(Conflict);
2160}
2161
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002162/// \brief Parse an inferred module declaration (wildcard modules).
Douglas Gregor9194a912012-11-06 19:39:40 +00002163///
2164/// module-declaration:
2165/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
2166/// { inferred-module-member* }
2167///
2168/// inferred-module-member:
2169/// 'export' '*'
2170/// 'exclude' identifier
2171void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
Douglas Gregor73441092011-12-05 22:27:44 +00002172 assert(Tok.is(MMToken::Star));
2173 SourceLocation StarLoc = consumeToken();
2174 bool Failed = false;
Douglas Gregor9194a912012-11-06 19:39:40 +00002175
Douglas Gregor73441092011-12-05 22:27:44 +00002176 // Inferred modules must be submodules.
Douglas Gregor9194a912012-11-06 19:39:40 +00002177 if (!ActiveModule && !Framework) {
Douglas Gregor73441092011-12-05 22:27:44 +00002178 Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
2179 Failed = true;
2180 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002181
2182 if (ActiveModule) {
2183 // Inferred modules must have umbrella directories.
Ben Langmuir4898cde2014-04-21 19:49:57 +00002184 if (!Failed && ActiveModule->IsAvailable &&
2185 !ActiveModule->getUmbrellaDir()) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002186 Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
2187 Failed = true;
2188 }
2189
2190 // Check for redefinition of an inferred module.
2191 if (!Failed && ActiveModule->InferSubmodules) {
2192 Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
2193 if (ActiveModule->InferredSubmoduleLoc.isValid())
2194 Diags.Report(ActiveModule->InferredSubmoduleLoc,
2195 diag::note_mmap_prev_definition);
2196 Failed = true;
2197 }
2198
2199 // Check for the 'framework' keyword, which is not permitted here.
2200 if (Framework) {
2201 Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
2202 Framework = false;
2203 }
2204 } else if (Explicit) {
2205 Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
2206 Explicit = false;
Douglas Gregor73441092011-12-05 22:27:44 +00002207 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002208
Douglas Gregor73441092011-12-05 22:27:44 +00002209 // If there were any problems with this inferred submodule, skip its body.
2210 if (Failed) {
2211 if (Tok.is(MMToken::LBrace)) {
2212 consumeToken();
2213 skipUntil(MMToken::RBrace);
2214 if (Tok.is(MMToken::RBrace))
2215 consumeToken();
2216 }
2217 HadError = true;
2218 return;
2219 }
Douglas Gregor9194a912012-11-06 19:39:40 +00002220
2221 // Parse optional attributes.
Bill Wendling44426052012-12-20 19:22:21 +00002222 Attributes Attrs;
Douglas Gregor9194a912012-11-06 19:39:40 +00002223 parseOptionalAttributes(Attrs);
2224
2225 if (ActiveModule) {
2226 // Note that we have an inferred submodule.
2227 ActiveModule->InferSubmodules = true;
2228 ActiveModule->InferredSubmoduleLoc = StarLoc;
2229 ActiveModule->InferExplicitSubmodules = Explicit;
2230 } else {
2231 // We'll be inferring framework modules for this directory.
2232 Map.InferredDirectories[Directory].InferModules = true;
Ben Langmuirc1d88ea2015-01-13 17:47:44 +00002233 Map.InferredDirectories[Directory].Attrs = Attrs;
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002234 Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Richard Smith131daca2014-03-06 21:59:38 +00002235 // FIXME: Handle the 'framework' keyword.
Douglas Gregor9194a912012-11-06 19:39:40 +00002236 }
2237
Douglas Gregor73441092011-12-05 22:27:44 +00002238 // Parse the opening brace.
2239 if (!Tok.is(MMToken::LBrace)) {
2240 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace_wildcard);
2241 HadError = true;
2242 return;
2243 }
2244 SourceLocation LBraceLoc = consumeToken();
2245
2246 // Parse the body of the inferred submodule.
2247 bool Done = false;
2248 do {
2249 switch (Tok.Kind) {
2250 case MMToken::EndOfFile:
2251 case MMToken::RBrace:
2252 Done = true;
2253 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002254
2255 case MMToken::ExcludeKeyword: {
2256 if (ActiveModule) {
2257 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002258 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002259 consumeToken();
2260 break;
2261 }
2262
2263 consumeToken();
Richard Smith306d8922014-10-22 23:50:56 +00002264 // FIXME: Support string-literal module names here.
Douglas Gregor9194a912012-11-06 19:39:40 +00002265 if (!Tok.is(MMToken::Identifier)) {
2266 Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
2267 break;
2268 }
2269
2270 Map.InferredDirectories[Directory].ExcludedModules
2271 .push_back(Tok.getString());
2272 consumeToken();
2273 break;
2274 }
2275
2276 case MMToken::ExportKeyword:
2277 if (!ActiveModule) {
2278 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002279 << (ActiveModule != nullptr);
Douglas Gregor9194a912012-11-06 19:39:40 +00002280 consumeToken();
2281 break;
2282 }
2283
Douglas Gregor73441092011-12-05 22:27:44 +00002284 consumeToken();
2285 if (Tok.is(MMToken::Star))
Douglas Gregordd005f62011-12-06 17:34:58 +00002286 ActiveModule->InferExportWildcard = true;
Douglas Gregor73441092011-12-05 22:27:44 +00002287 else
2288 Diags.Report(Tok.getLocation(),
2289 diag::err_mmap_expected_export_wildcard);
2290 consumeToken();
2291 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002292
Douglas Gregor73441092011-12-05 22:27:44 +00002293 case MMToken::ExplicitKeyword:
2294 case MMToken::ModuleKeyword:
2295 case MMToken::HeaderKeyword:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002296 case MMToken::PrivateKeyword:
Douglas Gregor73441092011-12-05 22:27:44 +00002297 case MMToken::UmbrellaKeyword:
2298 default:
Douglas Gregor9194a912012-11-06 19:39:40 +00002299 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
Craig Topperd2d442c2014-05-17 23:10:59 +00002300 << (ActiveModule != nullptr);
Douglas Gregor73441092011-12-05 22:27:44 +00002301 consumeToken();
2302 break;
2303 }
2304 } while (!Done);
2305
2306 if (Tok.is(MMToken::RBrace))
2307 consumeToken();
2308 else {
2309 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
2310 Diags.Report(LBraceLoc, diag::note_mmap_lbrace_match);
2311 HadError = true;
2312 }
2313}
2314
Douglas Gregor9194a912012-11-06 19:39:40 +00002315/// \brief Parse optional attributes.
2316///
2317/// attributes:
2318/// attribute attributes
2319/// attribute
2320///
2321/// attribute:
2322/// [ identifier ]
2323///
2324/// \param Attrs Will be filled in with the parsed attributes.
2325///
2326/// \returns true if an error occurred, false otherwise.
Bill Wendling44426052012-12-20 19:22:21 +00002327bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Douglas Gregor9194a912012-11-06 19:39:40 +00002328 bool HadError = false;
2329
2330 while (Tok.is(MMToken::LSquare)) {
2331 // Consume the '['.
2332 SourceLocation LSquareLoc = consumeToken();
2333
2334 // Check whether we have an attribute name here.
2335 if (!Tok.is(MMToken::Identifier)) {
2336 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
2337 skipUntil(MMToken::RSquare);
2338 if (Tok.is(MMToken::RSquare))
2339 consumeToken();
2340 HadError = true;
2341 }
2342
2343 // Decode the attribute name.
2344 AttributeKind Attribute
2345 = llvm::StringSwitch<AttributeKind>(Tok.getString())
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002346 .Case("exhaustive", AT_exhaustive)
Richard Smith77944862014-03-02 05:58:18 +00002347 .Case("extern_c", AT_extern_c)
Douglas Gregor9194a912012-11-06 19:39:40 +00002348 .Case("system", AT_system)
2349 .Default(AT_unknown);
2350 switch (Attribute) {
2351 case AT_unknown:
2352 Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
2353 << Tok.getString();
2354 break;
2355
2356 case AT_system:
2357 Attrs.IsSystem = true;
2358 break;
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002359
Richard Smith77944862014-03-02 05:58:18 +00002360 case AT_extern_c:
2361 Attrs.IsExternC = true;
2362 break;
2363
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002364 case AT_exhaustive:
2365 Attrs.IsExhaustive = true;
2366 break;
Douglas Gregor9194a912012-11-06 19:39:40 +00002367 }
2368 consumeToken();
2369
2370 // Consume the ']'.
2371 if (!Tok.is(MMToken::RSquare)) {
2372 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
2373 Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match);
2374 skipUntil(MMToken::RSquare);
2375 HadError = true;
2376 }
2377
2378 if (Tok.is(MMToken::RSquare))
2379 consumeToken();
2380 }
2381
2382 return HadError;
2383}
2384
Douglas Gregor718292f2011-11-11 19:10:28 +00002385/// \brief Parse a module map file.
2386///
2387/// module-map-file:
2388/// module-declaration*
2389bool ModuleMapParser::parseModuleMapFile() {
2390 do {
2391 switch (Tok.Kind) {
2392 case MMToken::EndOfFile:
2393 return HadError;
2394
Douglas Gregore7ab3662011-12-07 02:23:45 +00002395 case MMToken::ExplicitKeyword:
Daniel Jasper97292842013-09-11 07:20:44 +00002396 case MMToken::ExternKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002397 case MMToken::ModuleKeyword:
Douglas Gregor755b2052011-11-17 22:09:43 +00002398 case MMToken::FrameworkKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002399 parseModuleDecl();
2400 break;
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002401
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002402 case MMToken::Comma:
Douglas Gregor35b13ec2013-03-20 00:22:05 +00002403 case MMToken::ConfigMacros:
Douglas Gregorfb912652013-03-20 21:10:35 +00002404 case MMToken::Conflict:
Richard Smitha3feee22013-10-28 22:18:19 +00002405 case MMToken::Exclaim:
Douglas Gregor59527662012-10-15 06:28:11 +00002406 case MMToken::ExcludeKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002407 case MMToken::ExportKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002408 case MMToken::HeaderKeyword:
2409 case MMToken::Identifier:
2410 case MMToken::LBrace:
Douglas Gregor6ddfca92013-01-14 17:21:00 +00002411 case MMToken::LinkKeyword:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002412 case MMToken::LSquare:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002413 case MMToken::Period:
Lawrence Crowlb53e5482013-06-20 21:14:14 +00002414 case MMToken::PrivateKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002415 case MMToken::RBrace:
Douglas Gregora686e1b2012-01-27 19:52:33 +00002416 case MMToken::RSquare:
Douglas Gregor1fb5c3a2011-12-31 04:05:44 +00002417 case MMToken::RequiresKeyword:
Douglas Gregor2b82c2a2011-12-02 01:47:07 +00002418 case MMToken::Star:
Douglas Gregor718292f2011-11-11 19:10:28 +00002419 case MMToken::StringLiteral:
Richard Smithb8afebe2014-10-23 01:03:45 +00002420 case MMToken::TextualKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002421 case MMToken::UmbrellaKeyword:
Daniel Jasperba7f2f72013-09-24 09:14:14 +00002422 case MMToken::UseKeyword:
Douglas Gregor718292f2011-11-11 19:10:28 +00002423 Diags.Report(Tok.getLocation(), diag::err_mmap_expected_module);
2424 HadError = true;
2425 consumeToken();
2426 break;
2427 }
2428 } while (true);
Douglas Gregor718292f2011-11-11 19:10:28 +00002429}
2430
Richard Smith9acb99e32014-12-10 03:09:48 +00002431bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
Richard Smithae6df272015-07-14 02:06:01 +00002432 const DirectoryEntry *Dir,
2433 SourceLocation ExternModuleLoc) {
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002434 llvm::DenseMap<const FileEntry *, bool>::iterator Known
2435 = ParsedModuleMap.find(File);
2436 if (Known != ParsedModuleMap.end())
2437 return Known->second;
2438
Craig Topperd2d442c2014-05-17 23:10:59 +00002439 assert(Target && "Missing target information");
Ben Langmuircb69b572014-03-07 06:40:32 +00002440 auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
Richard Smithae6df272015-07-14 02:06:01 +00002441 FileID ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter);
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002442 const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
Douglas Gregor718292f2011-11-11 19:10:28 +00002443 if (!Buffer)
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002444 return ParsedModuleMap[File] = true;
Ben Langmuir984e1df2014-03-19 20:23:34 +00002445
Douglas Gregor718292f2011-11-11 19:10:28 +00002446 // Parse this module map file.
Manuel Klimek1f76c4e2013-10-24 07:51:24 +00002447 Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
Richard Smith2a6edb32015-08-09 04:46:57 +00002448 SourceLocation Start = L.getSourceLocation();
Ben Langmuirbeee15e2014-04-14 18:00:01 +00002449 ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
Douglas Gregor963c5532013-06-21 16:28:10 +00002450 BuiltinIncludeDir, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002451 bool Result = Parser.parseModuleMapFile();
Douglas Gregor4ddf2222013-01-10 01:43:00 +00002452 ParsedModuleMap[File] = Result;
Richard Smith2a6edb32015-08-09 04:46:57 +00002453
2454 // Notify callbacks that we parsed it.
2455 for (const auto &Cb : Callbacks)
2456 Cb->moduleMapFileRead(Start, *File, IsSystem);
Douglas Gregor718292f2011-11-11 19:10:28 +00002457 return Result;
2458}